private IMethodInfo getPropertyGetMethod(IPropertyInfo pi, IJavaType ownerType) { JavaTypeInfo ti; if (!(pi.getOwnersType() instanceof IJavaType)) { return null; } if (ownerType.getTypeInfo() instanceof JavaTypeInfo) { ti = (JavaTypeInfo) ownerType.getTypeInfo(); } else { throw new IllegalArgumentException(ownerType + " is not a recognized Java type"); } IType propType = pi.getFeatureType(); String strAccessor = "get" + pi.getDisplayName(); IMethodInfo mi = ti.getMethod(ownerType, strAccessor); if (mi == null || mi.getReturnType() != propType) { strAccessor = "is" + pi.getDisplayName(); mi = ti.getMethod(ownerType, strAccessor); } if (mi != null && mi.getReturnType() == propType) { return mi; } return null; }
private static String getLongName(IPropertyInfo propertyInfo) { String shortName = makeCmdLineOptionName(propertyInfo); if (propertyInfo.hasAnnotation(TypeSystem.get(LongName.class))) { IAnnotationInfo annotation = propertyInfo.getAnnotationsOfType(TypeSystem.get(LongName.class)).get(0); LongName value = (LongName) annotation.getInstance(); shortName = value.name(); } return shortName; }
private static boolean needsArg(IPropertyInfo propertyInfo) { boolean requiresArgument = true; if (isBooleanProp(propertyInfo)) { requiresArgument = false; } else if (propertyInfo.getFeatureType().isArray()) { requiresArgument = false; } else if (propertyInfo.hasAnnotation(TypeSystem.get(ArgOptional.class))) { requiresArgument = false; } return requiresArgument; }
private void genProperty(IPropertyInfo pi, StringBuilder sb, IJavaType type) { if (pi.isPrivate() || pi.isInternal()) { return; } if (pi.isStatic()) { genStaticProperty(pi, sb, type); } else { genMemberProperty(pi, sb, type); } }
private void genInterfacePropertyDecl(StringBuilder sb, IPropertyInfo pi, IJavaType javaType) { if (pi.isStatic()) { genStaticProperty(pi, sb, javaType); return; } if (!pi.isReadable()) { return; } if (!(pi instanceof JavaBaseFeatureInfo)) { // It is possible that a methodinfo on a java type originates outside of java. // E.g., enhancement methods. Gosu does not support extending these. return; } IType type = getGenericType(pi); if (pi.getDescription() != null) { sb.append("/** ").append(pi.getDescription()).append(" */"); } sb.append(" property get ") .append(pi.getName()) .append("() : ") .append(type.getName()) .append("\n"); if (pi.isWritable(pi.getOwnersType())) { sb.append(" property set ") .append(pi.getName()) .append("( _proxy_arg_value : ") .append(type.getName()) .append(" )\n"); } }
public void testInternalAPIHidesMembers() { IType scriptableTestExampleType = TypeSystem.get(ScriptableTestExample.class); IPropertyInfo exampleProperty = scriptableTestExampleType.getTypeInfo().getProperty("ExampleProperty"); assertTrue(exampleProperty.isVisible(ScriptabilityModifiers.SCRIPTABLE)); IPropertyInfo internalProperty = scriptableTestExampleType.getTypeInfo().getProperty("InternalProperty"); assertFalse(internalProperty.isVisible(ScriptabilityModifiers.SCRIPTABLE)); IMethodInfo exampleMethod = scriptableTestExampleType.getTypeInfo().getMethod("exampleMethod"); assertTrue(exampleMethod.isVisible(ScriptabilityModifiers.SCRIPTABLE)); IMethodInfo internalMethod = scriptableTestExampleType.getTypeInfo().getMethod("internalMethod"); assertFalse(internalMethod.isVisible(ScriptabilityModifiers.SCRIPTABLE)); }
protected static String deriveDescription(IPropertyInfo propertyInfo) { IType intrinsicType = propertyInfo.getOwnersType(); String description; try { ResourceBundle resourceBundle = ResourceBundle.getBundle( intrinsicType.getName(), Locale.getDefault(), TypeSystem.getGosuClassLoader().getActualLoader()); description = resourceBundle.getString(propertyInfo.getName()); } catch (MissingResourceException e) { description = propertyInfo.getDescription(); } return description == null ? "" : description.replaceAll("\n", " "); }
@Override public int hashCode() { int result = _root != null ? _root.hashCode() : 0; result = 31 * result + (_rootType != null ? _rootType.hashCode() : 0); result = 31 * result + (_pi != null ? _pi.hashCode() : 0); return result; }
private boolean isPropertyGetter(IMethodInfo mi, String strPrefix) { String strMethod = mi.getDisplayName(); if (strMethod.startsWith(strPrefix) && mi.getParameters().length == 0) { String strProp = strMethod.substring(strPrefix.length()); if (strProp.length() > 0 && Character.isUpperCase(strProp.charAt(0))) { ITypeInfo ti = (ITypeInfo) mi.getContainer(); IPropertyInfo pi = ti instanceof IRelativeTypeInfo ? ((IRelativeTypeInfo) ti).getProperty(mi.getOwnersType(), strProp) : ti.getProperty(strProp); if (pi != null && getGenericType(pi).getName().equals(getGenericReturnType(mi).getName())) { return !Keyword.isReserved(pi.getName()) || Keyword.isReservedValue(pi.getName()); } } } return false; }
private boolean isPropertySetter(IMethodInfo mi) { String strMethod = mi.getDisplayName(); if (strMethod.startsWith("set") && strMethod.length() > 3 && mi.getParameters().length == 1 && mi.getReturnType() == JavaTypes.pVOID()) { String strProp = strMethod.substring("set".length()); if (Character.isUpperCase(strProp.charAt(0))) { ITypeInfo ti = (ITypeInfo) mi.getContainer(); IPropertyInfo pi = ti instanceof IRelativeTypeInfo ? ((IRelativeTypeInfo) ti).getProperty(mi.getOwnersType(), strProp) : ti.getProperty(strProp); if (pi != null && pi.isReadable() && getGenericType(pi) .getName() .equals(getGenericParameters(mi)[0].getFeatureType().getName())) { return !Keyword.isReserved(pi.getName()) || Keyword.isReservedValue(pi.getName()); } } } return false; }
private static String makeCmdLineOptionName(IPropertyInfo propertyInfo) { String name = propertyInfo.getName(); name = name.substring(0, 1).toLowerCase() + name.substring(1); StringBuilder optionName = new StringBuilder(); boolean lastWasLowerCase = false; for (int i = 0; i < name.length(); i++) { if (i == 0) { optionName.append(Character.toLowerCase(name.charAt(i))); lastWasLowerCase = false; } else if (Character.isUpperCase(name.charAt(i))) { if (lastWasLowerCase) { optionName.append("_"); } optionName.append(Character.toLowerCase(name.charAt(i))); lastWasLowerCase = false; } else { char c = name.charAt(i); optionName.append(c); lastWasLowerCase = Character.isLetter(c) && Character.isLowerCase(c); } } return optionName.toString(); }
@Override public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } BoundSimplePropertyChainReference that = (BoundSimplePropertyChainReference) o; if (_pi != null ? !_pi.equals(that._pi) : that._pi != null) { return false; } if (_root != null ? !_root.equals(that._root) : that._root != null) { return false; } if (_rootType != null ? !_rootType.equals(that._rootType) : that._rootType != null) { return false; } return true; }
private void genMemberProperty(IPropertyInfo pi, StringBuilder sb, IJavaType type) { if (pi.isStatic()) { return; } if (!(pi instanceof JavaBaseFeatureInfo)) { // It is possible that a propertyinfo on a java type originates outside of java. // E.g., enhancement properties. Gosu does not support extending these. return; } if (Keyword.isReserved(pi.getName()) && !Keyword.isReservedValue(pi.getName())) { // Sorry these won't compile // ## todo: handle them reflectively? return; } if (pi instanceof JavaFieldPropertyInfo) { StringBuilder sbModifiers = appendFieldVisibilityModifier(pi); sb.append(" ") .append(sbModifiers) .append(" var ") .append(pi.getName()) .append(" : ") .append(getGenericType(pi).getName()) .append("\n"); } else { IMethodInfo mi = getPropertyGetMethod(pi, type); boolean bFinal = false; if (mi != null) { int iMethodModifiers = ((IJavaMethodInfo) mi).getModifiers(); bFinal = java.lang.reflect.Modifier.isFinal(iMethodModifiers); } if (mi != null && !bFinal) { if (mi.getDescription() != null) { sb.append("/** ").append(mi.getDescription()).append(" */"); } StringBuilder sbModifiers = buildModifiers(mi); sb.append(" ") .append(sbModifiers) .append("property get ") .append(pi.getName()) .append("() : ") .append(getGenericType(pi).getName()) .append("\n"); if (!mi.isAbstract()) { generateStub(sb, mi.getReturnType()); } } else { String strJavaClassName = type.getName(); StringBuilder sbModifiers; boolean bAbstact = false; if (bFinal) { bAbstact = mi.isAbstract(); sbModifiers = buildModifiers(mi); } else { sbModifiers = appendVisibilityModifier(pi); } sb.append(" ") .append(sbModifiers) .append("property get ") .append(pi.getName()) .append("() : ") .append(getGenericType(pi).getName()) .append("\n"); if (!bAbstact) { generateStub(sb, getGenericType(pi)); } } mi = getPropertySetMethod(pi, type); bFinal = false; if (mi != null) { int iMethodModifiers = ((IJavaMethodInfo) mi).getModifiers(); bFinal = java.lang.reflect.Modifier.isFinal(iMethodModifiers); } if (mi != null && !bFinal) { StringBuilder sbModifiers = buildModifiers(mi); if (pi.isWritable(pi.getOwnersType())) { sb.append(" ") .append(sbModifiers) .append("property set ") .append(pi.getName()) .append("( _proxy_arg_value : ") .append(getGenericType(pi).getName()) .append(" )\n"); if (!mi.isAbstract()) { generateStub(sb, JavaTypes.pVOID()); } } } else { if (pi.isWritable(type.getEnclosingType() != null ? null : pi.getOwnersType())) { String strJavaClassName = type.getName(); StringBuilder sbModifiers; boolean bAbstact = false; if (bFinal) { bAbstact = mi.isAbstract(); sbModifiers = buildModifiers(mi); } else { sbModifiers = appendVisibilityModifier(pi); } sb.append(" ") .append(sbModifiers) .append("property set ") .append(pi.getName()) .append("( _proxy_arg_value : ") .append(getGenericType(pi).getName()) .append(" )\n"); if (!bAbstact) { generateStub(sb, JavaTypes.pVOID()); } } } } }
/** * Initializes the properties on the given object based on the command line arguments. If the * object passed in is a type, static properties will be initialized. * * <p>Note that you will get -h, -help and --help for free, there is no need to explicitly include * a help property on your command line class. * * @param obj the class to initialize from the passed in arguments * @param exitOnBadArgs if true is passed in and the arguments incorrectly map to the given type, * a help message will be printed and the JVM will exit with a -1 return value, otherwise a * false value will be returned * @return true if initialization was successful */ public static boolean initialize(Object obj, boolean exitOnBadArgs) { List<IPropertyInfo> propsToSet = new ArrayList<IPropertyInfo>(); IType type = obj instanceof IType ? ((IType) obj) : TypeSystem.getFromObject(obj); ITypeInfo typeInfo = type.getTypeInfo(); Options options = deriveOptionsFromTypeInfo(typeInfo, propsToSet, obj instanceof IType); CommandLineParser parser = new BasicParser(); try { CommandLine cl = parser.parse(options, _args.toArray(new String[_args.size()])); for (IPropertyInfo propertyInfo : propsToSet) { propertyInfo = typeInfo.getProperty(propertyInfo.getName()); if (isBooleanProp(propertyInfo)) { propertyInfo.getAccessor().setValue(obj, cl.hasOption(getShortName(propertyInfo))); } else { String defaultValue = null; if (propertyInfo.hasAnnotation(TypeSystem.get(DefaultValue.class))) { IAnnotationInfo annotationInfo = propertyInfo.getAnnotationsOfType(TypeSystem.get(DefaultValue.class)).get(0); defaultValue = ((DefaultValue) annotationInfo.getInstance()).value(); } String shortName = getShortName(propertyInfo); Object value; if (propertyInfo.getFeatureType().isArray()) { value = cl.getOptionValues(shortName); if (propertyInfo.hasAnnotation(TypeSystem.get(Args.class))) { value = cl.getArgs(); } else if (value == null) { if (defaultValue != null) { value = defaultValue.split(" +"); } else { // Set the value to an empty array if the option is present if (cl.hasOption(shortName)) { value = new String[0]; } } } } else { if (!needsArg(propertyInfo) && defaultValue == null) { defaultValue = ""; } value = cl.getOptionValue(shortName, defaultValue); } try { propertyInfo .getAccessor() .setValue(obj, convertValue(propertyInfo.getFeatureType(), value)); } catch (Exception e) { throw new ParseException( "The parameter \"" + shortName + "\" requires an argument of type " + propertyInfo.getFeatureType().getRelativeName() + ". The value \"" + value + "\" cannot be converted to this type. Please pass in a valid value." + (e.getMessage() == null ? "" : " Error message was : " + e.getMessage())); } } } } catch (ParseException e) { if (exitOnBadArgs) { if (!e.getMessage().endsWith("-help") && !e.getMessage().endsWith("-h") && !e.getMessage().endsWith("--help")) { System.out.println("\nArgument problem: " + e.getMessage() + "\n"); } try { showHelp(getCurrentProgramName(), type); } catch (StringIndexOutOfBoundsException e1) { System.out.println("Unable to print help message. Exiting."); } if (_exitEnabled) { System.exit(-1); } throw new SystemExitIgnoredException(); } return false; } return true; }
@Override protected Object evaluate(Iterator args) { Object ctx = _root.evaluate(args); return _pi.getAccessor().getValue(ctx); }
private void genStaticProperty(IPropertyInfo pi, StringBuilder sb, IJavaType type) { if (!pi.isStatic()) { return; } if (!(pi instanceof JavaBaseFeatureInfo)) { // It is possible that a methodinfo on a java type originates outside of java. // E.g., enhancement methods. Gosu does not support extending these. return; } if (Keyword.isReserved(pi.getName())) { // Sorry these won't compile // ## todo: handle them reflectively? return; } if (pi.getDescription() != null) { sb.append("/** ").append(pi.getDescription()).append(" */"); } if (pi instanceof JavaFieldPropertyInfo) { StringBuilder sbModifiers = appendFieldVisibilityModifier(pi); sb.append(" ") .append(sbModifiers) .append("static var ") .append(pi.getName()) .append(" : ") .append(getGenericType(pi).getName()) .append("\n"); } else { StringBuilder sbModifiers = appendVisibilityModifier(pi); sb.append(" ") .append(sbModifiers) .append("static property get ") .append(pi.getName()) .append("() : ") .append(getGenericType(pi).getName()) .append("\n") .append(" {\n") .append(" return ") .append(type.getName()) .append('.') .append(pi.getName()) .append(";\n") .append(" }\n"); if (pi.isWritable(pi.getOwnersType())) { sb.append(" static property set ") .append(pi.getName()) .append("( _proxy_arg_value : ") .append(getGenericType(pi).getName()) .append(" )\n") .append(" {\n") .append(" ") .append(type.getName()) .append('.') .append(pi.getName()) .append(" = _proxy_arg_value;\n") .append(" }\n"); } } }
private static Options deriveOptionsFromTypeInfo( ITypeInfo typeInfo, /*IN-OUT*/ List<IPropertyInfo> propsToSet, boolean useStaticProps) { List<? extends IPropertyInfo> propertyInfos = typeInfo.getProperties(); Options options = new Options(); for (IPropertyInfo propertyInfo : propertyInfos) { if (propertyInfo instanceof IGosuVarPropertyInfo) { IGosuVarPropertyInfo gsVarPropInfo = (IGosuVarPropertyInfo) propertyInfo; if (gsVarPropInfo.hasDeclaredProperty() || gsVarPropInfo.isFinal()) { continue; } } if (useStaticProps == propertyInfo.isStatic() && propertyInfo.isWritable(null)) { String shortName = getShortName(propertyInfo); boolean needsArg = needsArg(propertyInfo); GosuOption opt = new GosuOption( shortName, getLongName(propertyInfo), needsArg, deriveDescription(propertyInfo)); opt.setHidden(propertyInfo.hasAnnotation(TypeSystem.get(Hidden.class))); opt.setRequired(propertyInfo.hasAnnotation(TypeSystem.get(Required.class))); if (propertyInfo.getFeatureType().isArray()) { opt.setType(propertyInfo.getFeatureType().getComponentType().getName()); if (propertyInfo.hasAnnotation(TypeSystem.get(ArgNames.class))) { ArgNames argNames = (ArgNames) propertyInfo .getAnnotationsOfType(TypeSystem.get(ArgNames.class)) .get(0) .getInstance(); if (argNames.names() != null && argNames.names().length > 0) { String compoundNames = ""; for (int i = 0; i < argNames.names().length; i++) { if (i != 0) { compoundNames += " "; } compoundNames += argNames.names()[i]; } opt.setArgName(compoundNames); if (propertyInfo.hasAnnotation(TypeSystem.get(ArgOptional.class))) { opt.setOptionalArg(true); } opt.setArgs(argNames.names().length); } } else { opt.setArgs(Option.UNLIMITED_VALUES); } if (propertyInfo.hasAnnotation(TypeSystem.get(Separator.class))) { Separator argNames = (Separator) propertyInfo .getAnnotationsOfType(TypeSystem.get(Separator.class)) .get(0) .getInstance(); opt.setValueSeparator(argNames.value().charAt(0)); } } else { opt.setType(propertyInfo.getFeatureType().getName()); if (propertyInfo.hasAnnotation(TypeSystem.get(ArgNames.class))) { ArgNames argNames = (ArgNames) propertyInfo .getAnnotationsOfType(TypeSystem.get(ArgNames.class)) .get(0) .getInstance(); if (argNames.names() != null && argNames.names().length > 0) { opt.setArgName(argNames.names()[0]); } } } propsToSet.add(propertyInfo); options.addOption(opt); } } return options; }
private IType getGenericType(IPropertyInfo pi) { return (pi instanceof JavaPropertyInfo) ? ((JavaPropertyInfo) pi).getGenericIntrinsicType() : pi.getFeatureType(); }
private static boolean isBooleanProp(IPropertyInfo propertyInfo) { return propertyInfo.getFeatureType().equals(JavaTypes.BOOLEAN()) || propertyInfo.getFeatureType().equals(JavaTypes.pBOOLEAN()); }