188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar/*
288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * Copyright (C) 2015 The Android Open Source Project
388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar *
488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * you may not use this file except in compliance with the License.
688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * You may obtain a copy of the License at
788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar *
888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar *
1088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * Unless required by applicable law or agreed to in writing, software
1188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
1288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * See the License for the specific language governing permissions and
1488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * limitations under the License.
1588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar */
1688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
1788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyarpackage android.databinding.tool.util;
1888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
1988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyarimport android.databinding.tool.reflection.Callable;
2088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
2188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar/**
2288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar * Central place to convert method/field names to BR observable fields
2388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar */
2488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyarpublic class BrNameUtil {
2588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    private static String stripPrefixFromField(String name) {
2688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        if (name.length() >= 2) {
2788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            char firstChar = name.charAt(0);
2888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            char secondChar = name.charAt(1);
2988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            if (name.length() > 2 && firstChar == 'm' && secondChar == '_') {
3088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                char thirdChar = name.charAt(2);
3188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                if (Character.isJavaIdentifierStart(thirdChar)) {
3288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                    return "" + Character.toLowerCase(thirdChar) +
3388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                            name.subSequence(3, name.length());
3488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                }
3588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            } else if ((firstChar == 'm' && Character.isUpperCase(secondChar)) ||
3688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                    (firstChar == '_' && Character.isJavaIdentifierStart(secondChar))) {
3788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                return "" + Character.toLowerCase(secondChar) + name.subSequence(2, name.length());
3888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            }
3988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        }
4088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        return name;
4188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    }
4288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
4388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    public static String brKey(Callable callable) {
4488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        if (callable.type == Callable.Type.FIELD) {
4588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            return stripPrefixFromField(callable.name);
4688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        }
4788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        CharSequence propertyName;
4888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        final String name = callable.name;
4988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        if (isGetter(callable) || isSetter(callable)) {
5088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            propertyName = name.subSequence(3, name.length());
5188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        } else if (isBooleanGetter(callable)) {
5288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            propertyName = name.subSequence(2, name.length());
5388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        } else {
5488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            L.e("@Bindable associated with method must follow JavaBeans convention %s", callable);
5588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            return null;
5688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        }
5788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        char firstChar = propertyName.charAt(0);
5888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        return "" + Character.toLowerCase(firstChar) +
5988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                propertyName.subSequence(1, propertyName.length());
6088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    }
6188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
6288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    private static boolean isGetter(Callable callable) {
6388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        return prefixes(callable.name, "get") &&
6488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                Character.isJavaIdentifierStart(callable.name.charAt(3)) &&
6588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                callable.getParameterCount() == 0 &&
6688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                !callable.resolvedType.isVoid();
6788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    }
6888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
6988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    private static boolean isSetter(Callable callable) {
7088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        return prefixes(callable.name, "set") &&
7188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                Character.isJavaIdentifierStart(callable.name.charAt(3)) &&
7288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                callable.getParameterCount() == 1 &&
7388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                callable.resolvedType.isVoid();
7488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    }
7588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
7688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    private static boolean isBooleanGetter(Callable callable) {
7788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        return prefixes(callable.name, "is") &&
7888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                Character.isJavaIdentifierStart(callable.name.charAt(2)) &&
7988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                callable.getParameterCount() == 0 &&
8088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                callable.resolvedType.isBoolean();
8188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    }
8288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar
8388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    private static boolean prefixes(CharSequence sequence, String prefix) {
8488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        boolean prefixes = false;
8588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        if (sequence.length() > prefix.length()) {
8688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            int count = prefix.length();
8788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            prefixes = true;
8888ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            for (int i = 0; i < count; i++) {
8988ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                if (sequence.charAt(i) != prefix.charAt(i)) {
9088ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                    prefixes = false;
9188ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                    break;
9288ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar                }
9388ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar            }
9488ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        }
9588ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar        return prefixes;
9688ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar    }
9788ce44ccc65e74a8553244ca246cc9f4c48483e0Yigit Boyar}
98