r1101 - in lutinjaxx/branches: . storm_1 storm_1/jaxx-compiler-api storm_1/jaxx-compiler-api/src storm_1/jaxx-compiler-api/src/main storm_1/jaxx-compiler-api/src/main/java storm_1/jaxx-compiler-api/src/main/java/jaxx storm_1/jaxx-compiler-api/src/main/java/jaxx/beaninfos storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler storm_1/jaxx-compiler-api/src/main/java/jaxx/css storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection storm_1/jaxx-compiler-api/src/main/java/jaxx/parser storm_1/jax
Author: tchemit Date: 2008-12-30 09:05:37 +0000 (Tue, 30 Dec 2008) New Revision: 1101 Added: lutinjaxx/branches/storm_1/ lutinjaxx/branches/storm_1/jaxx-compiler-api/ lutinjaxx/branches/storm_1/jaxx-compiler-api/LICENSE.txt lutinjaxx/branches/storm_1/jaxx-compiler-api/README.txt lutinjaxx/branches/storm_1/jaxx-compiler-api/changelog.txt lutinjaxx/branches/storm_1/jaxx-compiler-api/pom.xml lutinjaxx/branches/storm_1/jaxx-compiler-api/src/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ClassMap.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/CompilerException.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/DefaultInitializer.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/PrintTagInfo.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ScriptException.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedAttributeException.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedTagException.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/beaninfos/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/beaninfos/BeanInfoUtil.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompilerOptions.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataBinding.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataSource.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/EventHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/Generator.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/I18nHelper.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXObjectGenerator.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaArgument.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaField.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaFile.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaMethod.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptInitializer.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptManager.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/SymbolTable.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jj lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jjt lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParser.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserConstants.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTokenManager.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTreeConstants.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/JJTCSSParserState.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Node.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/ParseException.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleCharStream.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleNode.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/StylesheetHelper.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Token.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/TokenMgrError.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanInfo.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXEventSetDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXFeatureDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXIntrospector.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXPropertyDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JJTJavaParserState.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jj lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jjt lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaCharStream.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParser.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserConstants.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTokenManager.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTreeConstants.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Node.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/ParseException.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/SimpleNode.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Token.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/TokenMgrError.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptorLoader.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/FieldDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/JavaFileParser.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MemberDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MethodDescriptor.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/runtime/css/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/spi/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/spi/Initializer.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultComponentHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultObjectHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/ScriptHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/StyleHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/PrimitiveConverter.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeConverter.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeManager.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.compiler.Generator lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/BeanValidator.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/I18n.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Interface.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JAXXContext.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JavaBean.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/NavigationTreeModel.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Todo.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/index.rst lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/beaninfos/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/beaninfos/BeanIntoUtilTest.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/ClassDescriptorTest.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaFileParserTest.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaMethodTest.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/PrimitiveConverterTest.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/resources/ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/resources/log4j.properties lutinjaxx/branches/storm_1/jaxx-compiler-swing/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/LICENSE.txt lutinjaxx/branches/storm_1/jaxx-compiler-swing/README.txt lutinjaxx/branches/storm_1/jaxx-compiler-swing/changelog.txt lutinjaxx/branches/storm_1/jaxx-compiler-swing/pom.xml lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingCompiler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingGenerator.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ApplicationHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CellHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CompiledItemContainer.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ItemHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JAXXTabHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JCheckBoxHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JComboBoxHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JListHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JMenuHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPasswordFieldHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPopupMenuHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JProgressBarHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JScrollPaneHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSliderHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSpinnerHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSplitPaneHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTabbedPaneHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTextComponentHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JToolBarHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTreeHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JWindowHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/RowHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/SwingInitializer.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TabHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TableHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/validator/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/ColorConverter.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/GridBagConstraintsConverter.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/InsetsConverter.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/KeyStrokeConverter.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.compiler.Generator lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.spi.Initializer lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/site/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/site/fr/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/site/fr/rst/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/ColorConverterTest.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/InsetsConverterTest.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/TagManagerTest.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/runtime/swing/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/runtime/swing/navigation/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/resources/ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/resources/log4j.properties lutinjaxx/branches/storm_1/jaxx-compiler-validator/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/LICENSE.txt lutinjaxx/branches/storm_1/jaxx-compiler-validator/README.txt lutinjaxx/branches/storm_1/jaxx-compiler-validator/changelog.txt lutinjaxx/branches/storm_1/jaxx-compiler-validator/pom.xml lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/compiler/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/types/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/types/BeanValidatorScopeConverter.java lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.compiler.Generator lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.spi.Initializer lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/site/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/site/fr/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/site/fr/rst/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/jaxx/junit/ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/resources/ lutinjaxx/branches/storm_1/jaxx-example/Components/ lutinjaxx/branches/storm_1/jaxx-runtime-api/ lutinjaxx/branches/storm_1/jaxx-runtime-api/LICENSE.txt lutinjaxx/branches/storm_1/jaxx-runtime-api/README.txt lutinjaxx/branches/storm_1/jaxx-runtime-api/changelog.txt lutinjaxx/branches/storm_1/jaxx-runtime-api/pom.xml lutinjaxx/branches/storm_1/jaxx-runtime-api/src/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/Base64Coder.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Rule.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Selector.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Stylesheet.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/ComponentDescriptor.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingListener.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingUpdateListener.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXAction.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContext.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContextEntryDef.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXInitialContext.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObject.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/MultiJXPathDecorator.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/PropertyDecorator.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Util.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/DataBinding.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/Pseudoclasses.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/resources/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/site/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/site/fr/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/site/fr/rst/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/DefaultJAXXContextTest.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/JXPathDecoratorTest.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/UtilTest.java lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/resources/ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/resources/log4j.properties lutinjaxx/branches/storm_1/jaxx-runtime-swing/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/LICENSE.txt lutinjaxx/branches/storm_1/jaxx-runtime-swing/README.txt lutinjaxx/branches/storm_1/jaxx-runtime-swing/changelog.txt lutinjaxx/branches/storm_1/jaxx-runtime-swing/pom.xml lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Application.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBox.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBoxLayout.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Item.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXComboBox.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXList.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTab.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXToggleButton.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTree.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Spacer.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfo.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfoPropertyChangeListener.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Table.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Utils.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBox.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBoxLayout.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeCellRenderer.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapterWithCardLayout.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/resources/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/site/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/site/fr/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/site/fr/rst/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/java/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/java/jaxx/junit/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/resources/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/resources/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/test/resources/jaxx/junit/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/LICENSE.txt lutinjaxx/branches/storm_1/jaxx-runtime-validator/README.txt lutinjaxx/branches/storm_1/jaxx-runtime-validator/changelog.txt lutinjaxx/branches/storm_1/jaxx-runtime-validator/pom.xml lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidator.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingFileFieldValidator.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidator.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingFileFieldValidator.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/RequiredFileFieldValidator.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/icons/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/icons/error.png lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/icons/warning.png lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/validators.xml lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/site/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/site/fr/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/site/fr/rst/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorBean.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorTest.java lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/runtime/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/jaxx/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/jaxx/junit/ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/jaxx/junit/ValidatorBean-validation.xml lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/log4j.properties lutinjaxx/branches/storm_1/src/site/fr/rst/BeanValidator.rst lutinjaxx/branches/storm_1/src/site/fr/rst/I18n.rst lutinjaxx/branches/storm_1/src/site/fr/rst/Interface.rst lutinjaxx/branches/storm_1/src/site/fr/rst/JAXXContext.rst lutinjaxx/branches/storm_1/src/site/fr/rst/JavaBean.rst lutinjaxx/branches/storm_1/src/site/fr/rst/NavigationTreeModel.rst Removed: lutinjaxx/branches/storm_1/jaxx-core/ lutinjaxx/branches/storm_1/jaxx-example/Components/ Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/CapturedObject.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/JAXXCapture.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/handlers/ObjectHandler.java lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.spi.Initializer lutinjaxx/branches/storm_1/jaxx-example/Calculator/ lutinjaxx/branches/storm_1/jaxx-example/Validation/pom.xml lutinjaxx/branches/storm_1/jaxx-example/pom.xml lutinjaxx/branches/storm_1/jaxx-swing-action/pom.xml lutinjaxx/branches/storm_1/maven-jaxx-plugin/pom.xml lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1751Test.java lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/resources/testcases/Bug_1751.xml lutinjaxx/branches/storm_1/pom.xml lutinjaxx/branches/storm_1/src/site/fr/rst/Todo.rst lutinjaxx/branches/storm_1/src/site/fr/rst/index.rst Log: gros commit de refactor) Copied: lutinjaxx/branches/storm_1 (from rev 1092, lutinjaxx/trunk) Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-api ___________________________________________________________________ Name: svn:ignore + target *.log *.iml Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/LICENSE.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/LICENSE.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/LICENSE.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/README.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/README.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/README.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/changelog.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/changelog.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/changelog.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,90 @@ +1.0 ???? 200812?? + +0.8 ??? 200812?? + * 20081228 [chemit] - generify ClassDescriptor + - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from + JAXXCompiler and make possible to extract compiler engine from runtime + + * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation + * 20081218 [chemit] - improve generation of methods + * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) + - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option) + - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection + - add addSourcesToClassPath property to add sources directories in class-path + - improve classloader managment + - keep in DataSource objetCode + - fix bug when processDataBinding on a null objectCode + - always clean node cached values when selected it + - add usefull databinding method in Util + +* 20081213 [chemit] - improve navigation tree node rendering with some caches + - introduce a ChildBuilder to simplify building of child nodes from a collection or array + +0.7 chemit 20081210 +* 20081210 [chemit] - fix bug 1751 +* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) +* 20081208 [chemit] - javabBean attribute use to initialize bean + - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) + - introduce MultiJXPathDecorator + - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers + + * 20081207 [chemit] use lutinproject 3.1 + - can exclude field from validator + * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter + - fix bug when searching for a inner class + + * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator + - add setcontextValue and removeContextValue on JAXXContextEntryDef + - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff + - only enter once in $initialize method in generated code + + 0.6 chemit 20081117 + * 20081118 [chemit] introduce NavigationUtil, save in context selected node + * 20081107 [chemit] improve data binding and code generation : + - make possible inheritance in binding + - add an attribute javaBean to an object : will generate a full java bean support property + - make possible binding to the javaBean added properties + - clean generated code + + * 20081105 [chemit] introduce a CardLayout2 to extends awt CardLayout + introduce a NavigationTreeModel + introduce a Decorator to render Object + propagate constructor JAXXContext(JAXXContext) in JAXXObject generation + begin of rst documentation + + * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer + * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor. + * 20081102 [chemit] improve JAXXContext : + - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext + - do javadoc in JAXXContext + - add logic in DefaultJAXXContext : seek in parent context if entry not found + * 20081102 [chemit] improve tests : + - fix the last failed test from Jaxx original version :) + - dumps tests to JUnit4 :) + * 20081030 [chemit] improve BeanValidator : + - add full PropertyChangeEvent java-bean support and a property valid + - when remove bean from validator, must remove errors from model + - make possible to have a dynamic errorListModel in jaxx files + * 20081030 [chemit] improve JAXXContext : + - fix setContextValue bug when setting twice a same type for a same key + - implements a DefaultJAXXContext + - use this default implementation with delegate pattern in JAXXObject + * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext + * 20081027 [chemit] fix bug 1722 + * 20081027 [chemit] add conversion support in validator + * 20081025 [chemit] improve BeanValidator tag : + - add a errorList attribute for set a ErrorListMouseListener on the errorList + - add a beanInitializer attribute for set the validator's bean at runtime + - add a default errorListModel value 'errors' + * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method + * 20081024 [chemit] fix validator context lost if UI is launched from another thread + ver-0-5 chemit 20081002 + * 20081017 [chemit] add validator support + * 20081013 [chemit] can generate logger on jaxx files + * 20081011 [chemit] improve site + * 20081011 [chemit] fix bug on JavaFileParser : works again + * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin + * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules) + * 20081002 [chemit] Introduce JAXXContext + * 20081002 [chemit] Fix bug on method creation via scripting + * 20081002 [chemit] Improve i18n integration (works now also for tabs) Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/pom.xml =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/pom.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.codelutin</groupId> + <artifactId>lutinjaxx</artifactId> + <version>0.8-SNAPSHOT</version> + </parent> + + <artifactId>jaxx-compiler-api</artifactId> + + <dependencies> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-api</artifactId> + </dependency> + + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + <name>jaxx-compiler-api</name> + <description>Jaxx compiler api</description> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + <packaging>jar</packaging> + + <build> + <defaultGoal>install</defaultGoal> + </build> + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + <scm> + <connection>${maven.scm.connection.child}</connection> + <developerConnection>${maven.scm.developerConnection.child}</developerConnection> + <url>${maven.scm.url.child}</url> + </scm> +</project> Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ClassMap.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/ClassMap.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ClassMap.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ClassMap.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,95 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; + +/** + * A Map implementation which uses Classes as keys. <code>ClassMap</code> differs from typical maps + * in that it takes subclasses into account; mapping a class to a value also maps all subclasses of + * that class to the value. + * <p/> + * A <code>get</code> operation will return the value associated with the class itself, or failing + * that, with its nearest ancestor for which there exists a mapping. + */ +public class ClassMap<T> extends HashMap<ClassDescriptor, T> { + /** log */ + protected static final Log log = LogFactory.getLog(ClassMap.class); + + /** + * Keeps track of automatically-added Classes so we can distinguish them from user-added + * Classes. Unknown Classes are automatically added to the map during <code>get</code> + * calls to speed up subsequent requests, but they must be updated when the mappings + * for their superclasses are modified. + */ + private List<ClassDescriptor> autoKeys = new ArrayList<ClassDescriptor>(); + private static final long serialVersionUID = 5149779660675529037L; + + + /** + * Returns the value associated with the key <code>Class</code>. If the class itself does not have + * a mapping, its superclass will be checked, and so on until an ancestor class with a mapping is + * located. If none of the class' ancestors have a mapping, <code>null</code> is returned. + * + * @param key the class to check + * @return the mapping for the class + */ + @Override + public T get(Object key) { + T result = null; + ClassDescriptor c = (ClassDescriptor) key; + while (c != null) { + result = super.get(c); + if (result != null) { + break; + } + c = c.getSuperclass(); + } + + if (result == null && ((ClassDescriptor) key).isInterface()) { + result = get(ClassDescriptorLoader.getClassDescriptor(Object.class)); + } + + if (c != key && result != null) { // no mapping for the class itself, but found one for a superclass + put((ClassDescriptor) key, result); + autoKeys.add((ClassDescriptor) key); + } + return result; + } + + + /** + * Associates a value with a class and all of its descendents. + * + * @param key the class to map + * @param value the value to map to the class + * @return the old value associated with the class + */ + @Override + public T put(ClassDescriptor key, T value) { + //if (!(key instanceof ClassDescriptor)) { + // throw new IllegalArgumentException("expected ClassDescriptor, got " + key); + //} + if (autoKeys.size() > 0) { // remove all automatic keys which descend from the class being modified + Iterator<ClassDescriptor> i = autoKeys.iterator(); + while (i.hasNext()) { + ClassDescriptor auto = i.next(); + if (key.isAssignableFrom(auto)) { + i.remove(); + remove(auto); + } + } + } + return super.put(key, value); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/CompilerException.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/CompilerException.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/CompilerException.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/CompilerException.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,52 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx; + +/** Thrown by the compiler when an error occurs. */ +public class CompilerException extends RuntimeException { + private static final long serialVersionUID = -9099889519671482440L; + + /** Creates a new <code>ParseException</code>. */ + public CompilerException() { + } + + + /** + * Creates a new <code>ParseException</code> with the specified detail message. + * + * @param msg the exception's detail message + */ + public CompilerException(String msg) { + super(msg); + } + + + /** + * Creates a new <code>ParseException</code> with the specified cause. + * + * @param initCause the exception's initCause + */ + public CompilerException(Throwable initCause) { + super(initCause); + } + + + /** + * Creates a new <code>ParseException</code> with the specified detail message and cause. + * + * @param msg the exception's detail message + * @param initCause the exception's initCause + */ + public CompilerException(String msg, Throwable initCause) { + super(msg, initCause); + } + + + public void printStackTrace() { + super.printStackTrace(); + System.err.println("CompilerException printed from:"); + Thread.dumpStack(); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/DefaultInitializer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/DefaultInitializer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/DefaultInitializer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/DefaultInitializer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,48 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx; + +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.ScriptHandler; +import jaxx.tags.StyleHandler; +import jaxx.tags.TagManager; +import jaxx.types.PrimitiveConverter; +import jaxx.types.TypeManager; + +import java.awt.Component; + +/** Initializes support for java. */ +public class DefaultInitializer implements jaxx.spi.Initializer { + + @Override + public void initialize() { + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(Object.class), DefaultObjectHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(Component.class), DefaultComponentHandler.class); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "script", new ScriptHandler()); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "style", new StyleHandler()); + + PrimitiveConverter primitiveConverter = new PrimitiveConverter(); + TypeManager.registerTypeConverter(boolean.class, primitiveConverter); + TypeManager.registerTypeConverter(Boolean.class, primitiveConverter); + TypeManager.registerTypeConverter(byte.class, primitiveConverter); + TypeManager.registerTypeConverter(Byte.class, primitiveConverter); + TypeManager.registerTypeConverter(short.class, primitiveConverter); + TypeManager.registerTypeConverter(Short.class, primitiveConverter); + TypeManager.registerTypeConverter(int.class, primitiveConverter); + TypeManager.registerTypeConverter(Integer.class, primitiveConverter); + TypeManager.registerTypeConverter(long.class, primitiveConverter); + TypeManager.registerTypeConverter(Long.class, primitiveConverter); + TypeManager.registerTypeConverter(float.class, primitiveConverter); + TypeManager.registerTypeConverter(Float.class, primitiveConverter); + TypeManager.registerTypeConverter(double.class, primitiveConverter); + TypeManager.registerTypeConverter(Double.class, primitiveConverter); + TypeManager.registerTypeConverter(char.class, primitiveConverter); + TypeManager.registerTypeConverter(Character.class, primitiveConverter); + TypeManager.registerTypeConverter(String.class, primitiveConverter); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/PrintTagInfo.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/PrintTagInfo.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/PrintTagInfo.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/PrintTagInfo.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,118 @@ +package jaxx; + +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerLaunchor; +import jaxx.introspection.JAXXPropertyDescriptor; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.MethodDescriptor; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.TagManager; + +import java.io.BufferedWriter; +import java.io.FileWriter; +import java.io.IOException; +import java.io.OutputStreamWriter; + +/** Generates information about a tag for use on the jaxxframework.org web site. */ +public class PrintTagInfo { + /** + * Displays information about the class name in arg[0]. + * + * @param arg command-line arguments + * @throws Exception if an error occurs + */ + public static void main(String[] arg) throws Exception { + if (arg.length < 1) { + throw new IllegalArgumentException("programm needs at least two parameters : the file where to put the result, and at least one fqn class to treate"); + } + String firstarg = arg[0]; + boolean toFile = false; + BufferedWriter w; + if (firstarg.startsWith("file:")) { + w = new BufferedWriter(new FileWriter(firstarg.substring(5))); + toFile = true; + } else { + w = new BufferedWriter(new OutputStreamWriter(System.out)); + } + + try { + JAXXCompilerLaunchor.loadLibraries(false); + for (int i = toFile ? 1 : 0; i < arg.length; i++) { + String className = arg[i]; + treateClass(w, className); + } + } finally { + w.flush(); + w.close(); + } + + } + + protected static void treateClass(BufferedWriter w, String className) throws ClassNotFoundException, IOException { + + ClassDescriptor beanClass = ClassDescriptorLoader.getClassDescriptor(className); + DefaultObjectHandler handler = TagManager.getTagHandler(beanClass); + + DefaultObjectHandler superHandler = TagManager.getTagHandler(beanClass.getSuperclass()); + + // dump all bean properties + w.append("Properties in ").append(String.valueOf(beanClass)); + w.newLine(); + JAXXPropertyDescriptor[] properties = handler.getJAXXBeanInfo().getJAXXPropertyDescriptors(); + JAXXPropertyDescriptor[] superProperties = superHandler.getJAXXBeanInfo().getJAXXPropertyDescriptors(); + for (JAXXPropertyDescriptor property : properties) { + if (property.getWriteMethodDescriptor() == null) { + continue; + } + + boolean found = false; + String name = property.getName(); + for (JAXXPropertyDescriptor superProperty : superProperties) { + if (superProperty.getName().equals(name)) { + found = true; + break; + } + } + if (!found) { + if (property.getPropertyType() == null) { + System.err.println(name + " has null type"); + } else { + w.append("{{EquivalentAttribute|"); + w.append(name); + w.append("|"); + w.append(className.replace('.', '/')); + w.append("|set"); + w.append(org.apache.commons.lang.StringUtils.capitalize(name)); + w.append("|"); + w.append(JAXXCompiler.getCanonicalName(property.getPropertyType())); + w.append("}}"); + w.append("|-"); + w.newLine(); + } + } + } + + w.newLine(); + w.newLine(); + + // dump all bound methods + dumpMethods(w, beanClass, handler); + } + + protected static void dumpMethods(BufferedWriter w, ClassDescriptor beanClass, DefaultObjectHandler handler) throws IOException { + MethodDescriptor[] methods = beanClass.getMethodDescriptors(); + w.append("Bound methods in ").append(String.valueOf(beanClass)); + w.newLine(); + for (MethodDescriptor method : methods) { + try { + if (handler.isMemberBound(method.getName())) { + w.append("* <tt>").append(method.getName()).append("()</tt>"); + w.newLine(); + } + } catch (Throwable e) { + // ignore ? + } + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ScriptException.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/ScriptException.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ScriptException.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/ScriptException.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,45 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx; + +/** Thrown by the runtime engine when a script error occurs. */ +public class ScriptException extends RuntimeException { + private static final long serialVersionUID = 5687529939397610336L; + + /** Creates a new <code>ScriptException</code>. */ + public ScriptException() { + } + + + /** + * Creates a new <code>ScriptException</code> with the specified detail message. + * + * @param msg the exception's detail message + */ + public ScriptException(String msg) { + super(msg); + } + + + /** + * Creates a new <code>ScriptException</code> with the specified cause. + * + * @param initCause the exception's initCause + */ + public ScriptException(Throwable initCause) { + super(initCause); + } + + + /** + * Creates a new <code>ScriptException</code> with the specified detail message and cause. + * + * @param msg the exception's detail message + * @param initCause the exception's initCause + */ + public ScriptException(String msg, Throwable initCause) { + super(msg, initCause); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedAttributeException.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/UnsupportedAttributeException.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedAttributeException.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedAttributeException.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,49 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx; + +/** + * Thrown by <code>TagHandler</code> when an unsupported attribute is encountered. + * + * @see jaxx.tags.TagHandler + */ +public class UnsupportedAttributeException extends CompilerException { + private static final long serialVersionUID = -6919583037172920343L; + + /** Creates a new <code>UnsupportedAttributeException</code>. */ + public UnsupportedAttributeException() { + } + + + /** + * Creates a new <code>UnsupportedAttributeException</code> with the specified detail message. + * + * @param msg the exception's detail message + */ + public UnsupportedAttributeException(String msg) { + super(msg); + } + + + /** + * Creates a new <code>UnsupportedAttributeException</code> with the specified cause. + * + * @param initCause the exception's initCause + */ + public UnsupportedAttributeException(Throwable initCause) { + super(initCause); + } + + + /** + * Creates a new <code>UnsupportedAttributeException</code> with the specified detail message and cause. + * + * @param msg the exception's detail message + * @param initCause the exception's initCause + */ + public UnsupportedAttributeException(String msg, Throwable initCause) { + super(msg, initCause); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedTagException.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/UnsupportedTagException.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedTagException.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/UnsupportedTagException.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,45 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx; + +/** Thrown by the compiler when an unregistered tag is encountered. */ +public class UnsupportedTagException extends CompilerException { + private static final long serialVersionUID = 3199732135804426699L; + + /** Creates a new <code>UnsupportedTagException</code>. */ + public UnsupportedTagException() { + } + + + /** + * Creates a new <code>UnsupportedTagException</code> with the specified detail message. + * + * @param msg the exception's detail message + */ + public UnsupportedTagException(String msg) { + super(msg); + } + + + /** + * Creates a new <code>UnsupportedTagException</code> with the specified cause. + * + * @param initCause the exception's initCause + */ + public UnsupportedTagException(Throwable initCause) { + super(initCause); + } + + + /** + * Creates a new <code>UnsupportedTagException</code> with the specified detail message and cause. + * + * @param msg the exception's detail message + * @param initCause the exception's initCause + */ + public UnsupportedTagException(String msg, Throwable initCause) { + super(msg, initCause); + } +} \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/beaninfos/BeanInfoUtil.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/beaninfos/BeanInfoUtil.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/beaninfos/BeanInfoUtil.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,36 @@ +package jaxx.beaninfos; + +import java.beans.Introspector; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +/** @author chemit */ +public class BeanInfoUtil { + + public static String[] originalBeanInfoSearchPath; + + public static void addJaxxBeanInfoPath(String... packageNames) { + + String[] searchPath = Introspector.getBeanInfoSearchPath(); + if (originalBeanInfoSearchPath == null) { + originalBeanInfoSearchPath = searchPath; + } + List<String> listSearchPath = new ArrayList<String>(Arrays.asList(searchPath)); + for (String packageName : packageNames) { + if (!listSearchPath.contains(packageName)) { + listSearchPath.add(packageName); + } + } + + Introspector.setBeanInfoSearchPath(listSearchPath.toArray(new String[listSearchPath.size()])); + } + + public static void reset() { + if (originalBeanInfoSearchPath != null) { + Introspector.setBeanInfoSearchPath(originalBeanInfoSearchPath); + originalBeanInfoSearchPath = null; + } + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java (from rev 1098, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompiledObject.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,653 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.CompilerException; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.MethodDescriptor; +import jaxx.tags.DefaultComponentHandler; +import jaxx.tags.TagHandler; +import jaxx.tags.TagManager; +import jaxx.types.TypeManager; + +import java.awt.Container; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + + +/** + * Represents an object in the <code>.java</code> file being generated during compilation. There is + * a <code>CompiledObject</code> for each class tag encountered, and certain tags may generate + * additional objects for various reasons. + */ +public class CompiledObject { + /** The object's id. */ + private String id; + + /** Java code referring to the object. */ + private String javaCode; + + /** The object's class. */ + private ClassDescriptor objectClass; + + /** The style class. */ + private String styleClass; + + /** The container containing this CompiledObject. */ + private CompiledObject parent; + + /** true if this object overrides an object of the same id in a superclass of the object being compiled */ + private boolean override; + + /** + * Comma-separated Java code snippets representing the parameters that should be passed to the object's + * constructor. + */ + private String constructorParams; + + /** + * Java code snippet which performs basic initialization of the object (after it has already been constructed). + * Because CompiledObject initialization order cannot be guaranteed, it is not safe to refer to other + * CompiledObjects from initializationCode -- you must refer to them from additionCode instead. + */ + private StringBuffer initializationCode = new StringBuffer(); + + /** + * Java code snippet which completes setup by adding any child objects, or otherwise manipulates any refererenced + * objects. Because CompiledObject initialization order cannot be guaranteed, it is not safe to refer to other + * CompiledObjects from initializationCode -- you must refer to them from additionCode instead. + */ + private StringBuffer additionCode = new StringBuffer(); + + /** List of all registered event handlers. */ + private List<EventHandler> eventHandlers = new ArrayList<EventHandler>(); + + /** All properties that have been applied to this CompiledObject. */ + private Map<String, String> properties = new HashMap<String, String>(); + + /** generic types of the compiled object */ + private String[] genericTypes; + + /** a flag to indicate if javaBean full support must be support for this object by root object */ + private boolean javaBean; + + /** code to initialize the bean (can be null) */ + private String javaBeanInitCode; + + /** the type of the override object (can be null if no oveeride) */ + private ClassDescriptor overrideType; + + public class ChildRef { + CompiledObject child; + String constraints; + String childJavaCode; + String delegateCode; + + public ChildRef(CompiledObject child, String constraints, String childJavaCode, String delegateCode) { + this.child = child; + this.constraints = constraints; + this.childJavaCode = childJavaCode; + this.delegateCode = delegateCode; + } + + public CompiledObject getChild() { + return child; + } + + public void setChild(CompiledObject child) { + this.child = child; + } + + public String getConstraints() { + return constraints; + } + + public void setConstraints(String constraints) { + this.constraints = constraints; + } + + public String getChildJavaCode() { + return childJavaCode; + } + + public void setChildJavaCode(String childJavaCode) { + this.childJavaCode = childJavaCode; + } + + public String getDelegateCode() { + return delegateCode; + } + + public void setDelegateCode(String delegateCode) { + this.delegateCode = delegateCode; + } + + public void addToAdditionCode(StringBuffer buffer) { + if (constraints != null) { + buffer.append(javaCode).append(delegateCode).append(".add(").append(childJavaCode).append(", ").append(constraints).append(");"); + } else { + buffer.append(javaCode).append(delegateCode).append(".add(").append(childJavaCode).append(");"); + } + buffer.append(JAXXCompiler.getLineSeparator()); + } + } + + private List<ChildRef> childs; + + /** + * Creates a new <code>CompiledObject</code>. To be useful, the object should be registered with a + * <code>JAXXCompiler</code> using {@link JAXXCompiler#registerCompiledObject registerCompiledObject}. + * + * @param id the object's id + * @param objectClass the object's class + * @param compiler the current <code>JAXXCompiler</code> + * @throws NullPointerException if id or class is null + */ + public CompiledObject(String id, ClassDescriptor objectClass, JAXXCompiler compiler) { + this(id, objectClass, compiler, false); + } + + + /** + * Creates a new <code>CompiledObject</code>. To be useful, the object should be registered with a + * <code>JAXXCompiler</code> using {@link JAXXCompiler#registerCompiledObject registerCompiledObject}. + * + * @param id the object's id + * @param objectClass the object's class + * @param compiler the current <code>JAXXCompiler</code> + * @param force <code>true</code> to force acceptance of invalid ids + * @throws NullPointerException if id or class is null + */ + public CompiledObject(String id, ClassDescriptor objectClass, JAXXCompiler compiler, boolean force) { + this(id, id, objectClass, compiler, force); + } + + + /** + * Creates a new <code>CompiledObject</code>. To be useful, the object should be registered with a + * <code>JAXXCompiler</code> using {@link JAXXCompiler#registerCompiledObject registerCompiledObject}. + * + * @param id the object's id + * @param javaCode Java code referring to the object + * @param objectClass the object's class + * @param force <code>true</code> to force acceptance of invalid ids + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if the id is not a valid Java identifier + * @throws NullPointerException if id or class is null + */ + public CompiledObject(String id, String javaCode, ClassDescriptor objectClass, JAXXCompiler compiler, boolean force) throws CompilerException { + if (!force) { + if (!isValidID(id)) { + compiler.reportError("the id '" + id + "' is not a valid Java identifier"); + } + } + this.id = id; + this.javaCode = javaCode; + + if (objectClass == null) { + throw new NullPointerException(); + } + this.objectClass = objectClass; + this.childs = new ArrayList<ChildRef>(); + } + + + public static boolean isValidID(String id) { + boolean valid = true; + if (id.length() == 0) { + valid = false; + } + if (valid) { + if (!Character.isJavaIdentifierStart(id.charAt(0))) { + valid = false; + } + if (valid) { + for (int i = 1; i < id.length(); i++) { + if (!Character.isJavaIdentifierPart(id.charAt(i))) { + valid = false; + break; + } + } + } + } + return valid; + } + + + /** + * True if this object overrides an object in the superclass of the class being compiled. For this to be true, the + * class currently being compiled must be a subclass of another <code>JAXXObject</code> which has an + * identically-named object. + * + * @return <code>true</code> if this object is an override + * @see #setOverride + */ + public boolean isOverride() { + return override; + } + + + /** + * Sets whether this class overrides an identically-named object in the parent class. + * + * @param override <code>true</code> if this object is an override + * @see #isOverride + */ + public void setOverride(boolean override) { + this.override = override; + } + + + /** + * Returns this object's CSS style class. + * + * @return the value of the <code>styleClass</code> attribute + */ + public String getStyleClass() { + return styleClass; + } + + + /** + * Sets this object's CSS style class. + * + * @param styleClass the new style class + */ + public void setStyleClass(String styleClass) { + this.styleClass = styleClass; + } + + + /** + * Returns this object's parent container. Non-visual components (and the root container) return <code>null</code>. + * + * @return the object's parent container + */ + public CompiledObject getParent() { + return parent; + } + + + /** + * Sets this object's parent container. + * + * @param parent the parent container + */ + public void setParent(CompiledObject parent) { + if (!ClassDescriptorLoader.getClassDescriptor(Container.class).isAssignableFrom(parent.getObjectClass())) { + throw new IllegalArgumentException("parent must descend from java.awt.Container"); + } + this.parent = parent; + } + + + /** + * Returns the name of the method that should be generated in the compiled <code>.java</code> file + * in order to create this object. This is just a suggestion and may be ignored. + * + * @return the suggested name of the method which initializes this object + */ + public String getCreationMethodName() { + return "create" + org.apache.commons.lang.StringUtils.capitalize(getId()); + } + + + /** + * Returns the name of the method that should be generated in the compiled <code>.java</code> file + * in order to add children to this object. This is just a suggestion and may be ignored. + * + * @return the suggested name of the method which completes this object's setup + */ + public String getAdditionMethodName() { + return "addChildrenTo" + org.apache.commons.lang.StringUtils.capitalize(getId()); + } + + + /** + * Returns the type of this object. + * + * @return the class this <code>CompiledObject</code> represents + */ + public ClassDescriptor getObjectClass() { + return objectClass; + } + + + /** + * Returns this object's id. Generally, a field with this name will be created in the compiled <code>.java</code> + * file in order to represent this object. + * + * @return the id used to refer to this object + */ + public String getId() { + return id; + } + + + /** + * Returns Java code used to refer to this object in the compiled Java file. This is usually the same as its + * id. + * + * @return the Java code for this object + */ + public String getJavaCode() { + String result = javaCode; + if (isOverride()) { + // handle cases where object is overridden to be a different class + result = "((" + JAXXCompiler.getCanonicalName(getObjectClass()) + ") " + javaCode + ")"; + } + return result; + } + + public String getJavaCodeForProperty(String property) { + if (!override) { + return javaCode; + } + String result = "((" + JAXXCompiler.getCanonicalName(getObjectClass()) + ") " + javaCode + ")"; + + String methodName = org.apache.commons.lang.StringUtils.capitalize(property); + try { + MethodDescriptor methodDescriptor = overrideType.getMethodDescriptor("get" + methodName); + if (methodDescriptor != null) { + if (overrideType.getMethodDescriptor("set" + methodName, methodDescriptor.getReturnType()) != null) { + // handle cases where object is overridden to be a different class + result = javaCode; + } + } + } catch (NoSuchMethodException e) { + // lazy error, do nothing + } + return result; + } + + /** + * Returns a list of comma-separated Java code snippets that represent the parameters to pass to this + * object's constructor. + * + * @return the raw constructor params + * @see #setConstructorParams + */ + public String getConstructorParams() { + return constructorParams; + } + + + /** + * Sets the parameters to pass to this object's constructor. + * + * @param constructorParams comma-separated Java code snippets representing constructor params + * @see #getConstructorParams + */ + public void setConstructorParams(String constructorParams) { + this.constructorParams = constructorParams; + } + + + /** + * Returns the code that performs basic initialization of this object, after it has already been constructed. + * This basic code should not reference any other <code>CompiledObjects</code> as they may not have + * been created yet. + * + * @param compiler compiler to use + * @return the code which initializes this object + */ + public String getInitializationCode(JAXXCompiler compiler) { + StringBuffer result = new StringBuffer(initializationCode.toString()); + for (Object eventHandler : eventHandlers) { + EventHandler handler = (EventHandler) eventHandler; + result.append(getInitializationCode(handler, compiler)); + } + return result.toString(); + } + + + protected String getInitializationCode(EventHandler handler, JAXXCompiler compiler) { + MethodDescriptor addMethod = handler.getAddMethod(); + ClassDescriptor listenerClass = addMethod.getParameterTypes()[0]; + return getJavaCode() + '.' + addMethod.getName() + "((" + JAXXCompiler.getCanonicalName(listenerClass) + + ") jaxx.runtime.Util.getEventListener(" + JAXXCompiler.getCanonicalName(listenerClass) + ".class, " + + TypeManager.getJavaCode(handler.getListenerMethod().getName()) + ", " + compiler.getRootObject().getJavaCode() + ", " + + TypeManager.getJavaCode(compiler.getEventHandlerMethodName(handler)) + "));" + JAXXCompiler.getLineSeparator(); + } + + + /** + * Returns Java code to complete final setup on this object. This code may reference other + * <code>CompiledObjects</code>, as they are guaranteed to have all been created by this point. + * + * @return code which adds children and performs final setup + */ + public String getAdditionCode() { + return additionCode.toString(); + } + + + /** + * Appends code to the initialization code block. A line separator is automatically appended to the end. + * + * @param code the code to add to the initialization block + * @see #getInitializationCode + */ + public void appendInitializationCode(String code) { + this.initializationCode.append(code); + this.initializationCode.append(JAXXCompiler.getLineSeparator()); + } + + + /** + * Appends code to the addition code block. A line separator is automatically appended to the end. + * + * @param code the code to add to the addition block + * @see #getAdditionCode + */ + public void appendAdditionCode(String code) { + this.additionCode.append(code); + this.additionCode.append(JAXXCompiler.getLineSeparator()); + } + + + /** + * Stores a property for this object. The only effect of calling this method is that the property will + * be returned by <code>getProperties()</code>. + * + * @param property the name of the property + * @param value the property's value + * @see #getProperties + */ + public void addProperty(String property, String value) { + properties.put(property, value); + } + + + /** + * Returns all properties which have been set for this object. + * + * @return a <code>Map</code> containing all properties defined for this object + * @see #addProperty + */ + public Map/*<String, String>*/ getProperties() { + return properties; + } + + + // TODO: remove this temporary method and complete switchover to MethodDescriptors + public void addEventHandler(String eventId, Method addMethod, Method listenerMethod, String code, JAXXCompiler compiler) { + try { + ClassDescriptor descriptor = ClassDescriptorLoader.getClassDescriptor(getObjectClass().getName()); + String listenerClassName = addMethod.getParameterTypes()[0].getName(); + ClassDescriptor listenerDescriptor = ClassDescriptorLoader.getClassDescriptor(listenerClassName); + MethodDescriptor addMethodDescriptor = descriptor.getMethodDescriptor(addMethod.getName(), listenerDescriptor); + MethodDescriptor listenerMethodDescriptor = listenerDescriptor.getMethodDescriptor(listenerMethod.getName(), ClassDescriptorLoader.getClassDescriptor(listenerMethod.getParameterTypes()[0].getName())); + addEventHandler(eventId, addMethodDescriptor, listenerMethodDescriptor, code, compiler); + } + catch (Exception e) { + throw new RuntimeException(e); + } + } + + + /** + * Adds an event listener to this object. The generated code will appear in the initialization block. + * + * @param eventId unique (per CompiledObject) identifier for the event handler + * @param addMethod the method which adds the event listener + * @param listenerMethod the method (in the listener class) which is called when the event is fired + * @param code the Java code for the listenerMethod's body + * @param compiler the current <code>JAXXCompiler</code> + * @see #getInitializationCode + */ + public void addEventHandler(String eventId, MethodDescriptor addMethod, MethodDescriptor listenerMethod, String code, JAXXCompiler compiler) { + EventHandler handler = new EventHandler(getId() + "." + eventId, getJavaCode(), addMethod, addMethod.getParameterTypes()[0], listenerMethod, code); + compiler.registerEventHandler(handler); + eventHandlers.add(handler); + + if (getJavaCode().indexOf(".") != -1) { // object lives in another JAXX file and consequently its initialization code won't be output + compiler.appendInitializerCode(getInitializationCode(handler, compiler)); + } + } + + + /** + * Adds a child component to this container. The child is added without layout constraints. + * + * @param child the component to add + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if this object is not a container + * @see #addChild(CompiledObject, String, JAXXCompiler) + */ + public void addChild(CompiledObject child, JAXXCompiler compiler) throws CompilerException { + addChild(child, null, compiler); + } + + + /** + * Adds a child component to this container. This variant allows the Java code for a layout constraints + * object to be specified. + * + * @param child the component to add + * @param constraints Java code for the layout constraints object + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if this object is not a container + * @see #addChild(CompiledObject, JAXXCompiler) + */ + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + try { + if (constraints != null) { + constraints = compiler.checkJavaCode(constraints); + } + } + catch (CompilerException e) { + compiler.reportError("While parsing 'constraints' attribute: " + e.getMessage()); + } + + if (!child.isOverride()) { + TagHandler tagHandler = TagManager.getTagHandler(getObjectClass()); + if (tagHandler instanceof DefaultComponentHandler && !((DefaultComponentHandler) tagHandler).isContainer()) { + compiler.reportError("component " + this + " may not have children"); + } + + String containerDelegate = ((DefaultComponentHandler) tagHandler).getContainerDelegate(); + String delegateCode = containerDelegate != null ? "." + containerDelegate + "()" : ""; + + child.setParent(this); + /*String javaCode = child.getJavaCode(); + if (compiler.hasValidator()) { + // some validators are defined on this object + boolean found = compiler.isComponentUsedByValidator(child.getId()); + if (found) { + // box the child component in a JxLayer + javaCode = "jaxx.runtime.Util.boxComponentWithJxLayer(" + javaCode + ")"; + } + }*/ + + childs.add(new ChildRef(child, constraints, child.getJavaCode(), delegateCode)); + /*if (constraints != null) { + appendAdditionCode(this.javaCode + delegateCode + ".add(" + javaCode + ", " + constraints + ");"); + //appendAdditionCode(getJavaCode() + delegateCode + ".add(" + javaCode + ", " + constraints + ");"); + } else { + appendAdditionCode(this.javaCode + delegateCode + ".add(" + javaCode + ");"); + //appendAdditionCode(getJavaCode() + delegateCode + ".add(" + javaCode + ");"); + }*/ + } + } + + @Override + public String toString() { + return getObjectClass().getName() + "[id='" + id + "']"; + } + + + public void registerDataBinding(String src, String property, String assignment, JAXXCompiler compiler) throws CompilerException { + compiler.registerDataBinding(src, getId() + "." + property, assignment); + } + + /** @return the array of generic types of the compiled object, or a empty array if none defined */ + public ClassDescriptor[] getGenericTypes() { + if (genericTypes == null) { + return new ClassDescriptor[0]; + } + try { + ClassDescriptor[] result = new ClassDescriptor[genericTypes.length]; + for (int i = 0; i < result.length; i++) { + result[i] = ClassDescriptorLoader.getClassDescriptor(genericTypes[i], getObjectClass().getClassLoader()); + } + return result; + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + public void setGenericTypes(String[] genericTypes) { + this.genericTypes = genericTypes; + } + + public boolean isJavaBean() { + return javaBean; + } + + public void setJavaBean(boolean javaBean) { + this.javaBean = javaBean; + } + + public ClassDescriptor getOverrideType() { + return overrideType; + } + + public void setOverrideType(ClassDescriptor overrideType) { + this.overrideType = overrideType; + } + + public String getJavaBeanInitCode() { + return javaBeanInitCode; + } + + public void setJavaBeanInitCode(String javaBeanInitCode) { + this.javaBeanInitCode = javaBeanInitCode; + } + + public List<ChildRef> getChilds() { + return childs; + } + + public void finalizeCompiler() { + StringBuffer buffer = new StringBuffer(); + + List<CompiledObject.ChildRef> refList = getChilds(); + if (refList == null || refList.isEmpty()) { + return; + } + + for (ChildRef childRef : refList) { + childRef.addToAdditionCode(buffer); + } + + additionCode = buffer.append(additionCode); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompilerOptions.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompilerOptions.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompilerOptions.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/CompilerOptions.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,262 @@ +package jaxx.compiler; + +import java.io.File; + +/** + * Stores options which affect the jaxxc tool's operation. These options are generally specified by the + * user on the command line. + */ +public class CompilerOptions { + private File targetDirectory; + private File javacTargetDirectory; + private String classPath; + private String javacOpts; + private boolean keepJavaFiles; + private boolean optimize; + private boolean verbose; + /** a flag to enable or disable i18n generation */ + private boolean i18nable; + + /** a flag to add or not logger on generated jaxx files */ + private boolean addLogger; + + /** a flag to not reset compiler after a compile */ + private boolean resetAfterCompile; + + /** the name of implementation of {@link jaxx.runtime.JAXXContext} to be used on {@link jaxx.runtime.JAXXObject}. */ + protected String jaxxContextImplementorClass; + + /** list of fqn of class toimport for all generated jaxx files */ + protected String[] extraImports; + + /** default error ui */ + private Class<?> defaultErrorUI; + + private ClassLoader classLoader; + + private Class<? extends JAXXCompiler> compilerClass; + /** + * Returns the target directory, generally specified with the "-d" option on the command line. + * + * @return the target directory + * @see #setTargetDirectory + */ + public File getJavacTargetDirectory() { + if (javacTargetDirectory == null) { + // to use the old way : if javacTargetDirectory not specified, + // use same directory as targetDirectory (says where the java sources + // are generated) + return targetDirectory; + } + return javacTargetDirectory; + } + + /** + * Returns the target directory, generally specified with the "-d" option on the command line. + * + * @return the target directory + * @see #setTargetDirectory + */ + public File getTargetDirectory() { + return targetDirectory; + } + + + /** + * Sets the target directory into which compiled classes will be placed. + * + * @param targetDirectory the target directory + * @see #getTargetDirectory + */ + public void setTargetDirectory(File targetDirectory) { + this.targetDirectory = targetDirectory; + } + + public void setJavacTargetDirectory(File javacTargetDirectory) { + this.javacTargetDirectory = javacTargetDirectory; + } + + /** + * Returns the class path to be used during compilation. + * + * @return the class path to be used during compilation + * @see #setClassPath + */ + public String getClassPath() { + return classPath; + } + + /** + * Sets the class path to be used during compilation. + * + * @param classPath the compilation class path + * @see #getClassPath + */ + public void setClassPath(String classPath) { + this.classPath = classPath; + } + + + /** + * Returns the options to be passed into <code>javac</code>. + * + * @return options to be passed into <code>javac</code> + * @see #setJavacOpts + */ + public String getJavacOpts() { + return javacOpts; + } + + + /** + * Sets options to be passed into <code>javac</code>. + * + * @param javacOpts options to be passed into <code>javac</code> + * @see #getJavacOpts + */ + public void setJavacOpts(String javacOpts) { + this.javacOpts = javacOpts; + } + + + /** + * Returns whether or not generated Java files should be preserved after compilation. + * + * @return <code>true</code> if generated Java files should be preserved, <code>false</code> to delete + * @see #setKeepJavaFiles + */ + public boolean getKeepJavaFiles() { + return keepJavaFiles; + } + + + /** + * Sets whether or not generated Java files should be preserved after compilation. + * + * @param keepJavaFiles <code>true</code> if generated Java files should be preserved, <code>false</code> to delete + * @see #getKeepJavaFiles + */ + public void setKeepJavaFiles(boolean keepJavaFiles) { + this.keepJavaFiles = keepJavaFiles; + } + + + /** + * Returns whether or not optimization should be performed. + * + * @return whether or not optimizations should be performed + */ + public boolean getOptimize() { + return optimize; + } + + + /** + * Sets whether or not optimizations should be performed. + * + * @param optimize <code>true</code> to perform optimizations during compilation + * @see #getOptimize + */ + public void setOptimize(boolean optimize) { + this.optimize = optimize; + } + + public boolean isVerbose() { + return verbose; + } + + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } + + public boolean isI18nable() { + return i18nable; + } + + public void setI18nable(boolean i18nable) { + this.i18nable = i18nable; + } + + public boolean isAddLogger() { + return addLogger; + } + + public void setAddLogger(boolean addLogger) { + this.addLogger = addLogger; + } + + public String getJaxxContextImplementorClass() { + return jaxxContextImplementorClass; + } + + public void setJaxxContextImplementorClass(String jaxxContextImplementorClass) { + this.jaxxContextImplementorClass = jaxxContextImplementorClass; + } + + public String[] getExtraImports() { + return extraImports; + } + + public void setExtraImports(String[] extraImports) { + this.extraImports = extraImports; + } + + public boolean isResetAfterCompile() { + return resetAfterCompile; + } + + public void setResetAfterCompile(boolean resetAfterCompile) { + this.resetAfterCompile = resetAfterCompile; + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(super.toString()); + sb.append("\nclassPath : ").append(getClassPath()); + sb.append("\ncompilerClass : ").append(compilerClass); + sb.append("\njavaOut : ").append(getTargetDirectory()); + sb.append("\noutClass : ").append(getJavacTargetDirectory()); + sb.append("\njavacOpts : ").append(getJavacOpts()); + sb.append("\nverbose : ").append(isVerbose()); + sb.append("\noptiomize : ").append(getOptimize()); + sb.append("\ni18nable : ").append(isI18nable()); + sb.append("\naddLogger : ").append(isAddLogger()); + sb.append("\nresetAfterCompile : ").append(isResetAfterCompile()); + sb.append("\njaxxContextImplementorClass : ").append(getJaxxContextImplementorClass()); + sb.append("\nextraImports : ").append(getExtraImports()); + return sb.toString(); + } + + + public void setDefaultErrorUI(Class<?> defaultErrorUI) { + this.defaultErrorUI = defaultErrorUI; + } + + public boolean isKeepJavaFiles() { + return keepJavaFiles; + } + + public boolean isOptimize() { + return optimize; + } + + public Class<?> getDefaultErrorUI() { + return defaultErrorUI; + } + + public ClassLoader getClassLoader() { + return classLoader; + } + + public void setClassLoader(ClassLoader classLoader) { + this.classLoader = classLoader; + } + + public Class<? extends JAXXCompiler> getCompilerClass() { + return compilerClass; + } + + public void setCompilerClass(Class<? extends JAXXCompiler> compilerClass) { + this.compilerClass = compilerClass; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataBinding.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataBinding.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataBinding.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataBinding.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,92 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.CompilerException; +import jaxx.types.TypeManager; + +/** + * Represents a data binding in a JAXX file. <code>DataBinding</code> uses {@link DataSource} to + * track changes to a source expression and update the destination. + */ +public class DataBinding { + private String id; + + /** The DatSource which tracks source expression changes. */ + private DataSource dataSource; + + /** The data binding destination in the form <code><id>.<propertyName></code>. */ + private String dest; + + /** + * A Java snippet which will cause the destination property to be updated with the current value of + * the binding. + */ + private String assignment; + + /** The current <code>JAXXCompiler</code>. */ + private JAXXCompiler compiler; + + + /** + * Creates a new data binding. + * + * @param source the Java source code for the data binding expression + * @param dest the data binding destination in the form <code><id>.<propertyName></code> + * @param assignment Java snippet which will cause the destination property to be updated with the current value of the binding + * @param compiler the current <code>JAXXCompiler</code> + */ + public DataBinding(String source, String dest, String assignment, JAXXCompiler compiler) { + this.id = dest; + this.dataSource = new DataSource(id, source, compiler); + this.dest = dest; + this.assignment = assignment; + this.compiler = compiler; + } + + + public String getId() { + return id; + } + + + /** + * Compiles the data binding expression. This method calls methods in <code>JAXXCompiler</code> + * to add the Java code that performs the data binding setup. + * + * @param quickNoDependencies true to optimize bindings with no dependencies by simply running them at startup time + * @return <code>true</code> if the expression has dependencies, <code>false</code> otherwise + * @throws CompilerException if a compilation error occurs + */ + public boolean compile(boolean quickNoDependencies) throws CompilerException { + // DataSource.compile handles all of the listener additions + boolean result = dataSource.compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + TypeManager.getJavaCode(id) + ")"); + + if (!result && quickNoDependencies) { + if (!dest.endsWith(".layout")) // layout is specially handled early in the chain + { + compiler.appendInitDataBindings(assignment + JAXXCompiler.getLineSeparator()); + } + return false; // no dependencies, just a static expression + } + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding(" else "); + } else { + compiler.appendProcessDataBinding(" "); + } + compiler.appendProcessDataBinding("if (" + TypeManager.getJavaCode(id) + ".equals($dest)) {" + JAXXCompiler.getLineSeparator()); + String objectCode = dataSource.getObjectCode(); + if (objectCode != null) { + compiler.appendProcessDataBinding(" if (" + objectCode + " != null) {" + JAXXCompiler.getLineSeparator()); + compiler.appendProcessDataBinding(" "); + } + compiler.appendProcessDataBinding(" " + assignment.trim()); + if (objectCode != null) { + compiler.appendProcessDataBinding(JAXXCompiler.getLineSeparator() + " }"); + } + compiler.appendProcessDataBinding(JAXXCompiler.getLineSeparator() + " }"); + return true; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataSource.java (from rev 1098, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataSource.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataSource.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/DataSource.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,454 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.parser.JavaParser; +import jaxx.parser.JavaParserConstants; +import jaxx.parser.JavaParserTreeConstants; +import jaxx.parser.SimpleNode; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.FieldDescriptor; +import jaxx.reflect.MethodDescriptor; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.TagManager; +import jaxx.types.TypeManager; + +import java.beans.Introspector; +import java.beans.PropertyChangeListener; +import java.io.StringReader; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; + +/** + * Represents a Java expression which fires a <code>PropertyChangeEvent</code> when it can be + * determined that its value may have changed. Events are fired on a "best effort" basis, and events + * may either be fired too often (the value has not actually changed) or not often enough (the value + * changed but no event was fired). + */ +public class DataSource { + private class NULL { + } // type attached to "null" constants in parsed expressions + + private String id; + + /** The Java source code for the expression. */ + private String source; + + /** The current <code>JAXXCompiler</code>. */ + private JAXXCompiler compiler; + + /** List of symbols which this data source expression depends on. */ + private List<String> dependencySymbols = new ArrayList<String>(); + + private StringBuffer addListenerCode = new StringBuffer(); + private StringBuffer removeListenerCode = new StringBuffer(); + private boolean compiled; + + /** the delegate of property to be required */ + private String objectCode; + + /** + * Creates a new data source. After creating a <code>DataSource</code>, use {@link #compile} + * to cause it to function at runtime. + * + * @param id the DataSource's id + * @param source the Java source code for the data source expression + * @param compiler the current <code>JAXXCompiler</code> + */ + public DataSource(String id, String source, JAXXCompiler compiler) { + this.id = id; + this.source = source; + this.compiler = compiler; + } + + + public String getId() { + return id; + } + + public String getSource() { + return source; + } + + public String getObjectCode() { + return objectCode; + } + + /** + * Compiles the data source expression and listener. This method calls methods in <code>JAXXCompiler</code> + * to add the Java code that performs the data source setup. Adding listeners to <code>DataSource</code> is + * slightly more complicated than with ordinary classes, because <code>DataSource</code> only exists at compile + * time. You must pass in a Java expression which evaluates to a <code>PropertyChangeListener</code>; this + * expression will be compiled and evaluated at runtime to yield the <code>DataSource's</code> listener. + * + * @param propertyChangeListenerCode Java code snippet which evaluates to a <code>PropertyChangeListener</code> + * @return <code>true</code> if the expression has dependencies, <code>false</code> otherwise + * @throws CompilerException if a compilation error occurs + */ + public boolean compile(String propertyChangeListenerCode) throws CompilerException { + if (compiled) { + throw new IllegalStateException(this + " has already been compiled"); + } + String id = compiler.getAutoId(ClassDescriptorLoader.getClassDescriptor(getClass())); + JavaParser p = new JavaParser(new StringReader(source + ";")); + while (!p.Line()) { + SimpleNode node = p.popNode(); + scanNode(node, id); + } + + if (dependencySymbols.size() > 0) { + //TC 20081108 prefer add a real JavaField instead of raw code + //compiler.appendBodyCode("private PropertyChangeListener " + id + " = " + propertyChangeListenerCode + ";\n"); + compiler.addSimpleField(new JavaField(Modifier.PRIVATE, PropertyChangeListener.class.getName(), id, propertyChangeListenerCode)); + } + + compileListeners(); + compiled = true; + + return dependencySymbols.size() > 0; + } + + /** @return a list of symbols on which this data source depends. */ + public Collection<String> getDependencies() { + return Collections.unmodifiableList(dependencySymbols); + } + + /** + * Examines a node to identify any dependencies it contains. + * + * @param node node to scan + * @param listenerId id of listener + * @throws jaxx.CompilerException ? + */ + private void scanNode(SimpleNode node, String listenerId) throws CompilerException { + switch (node.getId()) { + case JavaParserTreeConstants.JJTMETHODDECLARATION: + break; + case JavaParserTreeConstants.JJTFIELDDECLARATION: + break; + + default: + int count = node.jjtGetNumChildren(); + for (int i = 0; i < count; i++) { + scanNode(node.getChild(i), listenerId); + } + determineNodeType(node, listenerId); + } + } + + private ClassDescriptor determineLiteralType(SimpleNode node) { + assert node.getId() == JavaParserTreeConstants.JJTLITERAL; + if (node.jjtGetNumChildren() == 1) { + int id = node.getChild(0).getId(); + if (id == JavaParserTreeConstants.JJTBOOLEANLITERAL) { + return ClassDescriptorLoader.getClassDescriptor(boolean.class); + } + if (id == JavaParserTreeConstants.JJTNULLLITERAL) { + return ClassDescriptorLoader.getClassDescriptor(NULL.class); + } + throw new RuntimeException("Expected BooleanLiteral or NullLiteral, found " + JavaParserTreeConstants.jjtNodeName[id]); + } + int id = node.firstToken.kind; + switch (id) { + case JavaParserConstants.INTEGER_LITERAL: + if (node.firstToken.image.toLowerCase().endsWith("l")) { + return ClassDescriptorLoader.getClassDescriptor(long.class); + } + return ClassDescriptorLoader.getClassDescriptor(int.class); + case JavaParserConstants.CHARACTER_LITERAL: + return ClassDescriptorLoader.getClassDescriptor(char.class); + case JavaParserConstants.FLOATING_POINT_LITERAL: + if (node.firstToken.image.toLowerCase().endsWith("f")) { + return ClassDescriptorLoader.getClassDescriptor(float.class); + } + return ClassDescriptorLoader.getClassDescriptor(double.class); + case JavaParserConstants.STRING_LITERAL: + return ClassDescriptorLoader.getClassDescriptor(String.class); + default: + throw new RuntimeException("Expected literal token, found " + JavaParserConstants.tokenImage[id]); + } + } + + /** + * Scans through a compound symbol (foo.bar.baz) to identify and track all trackable pieces of it. + * + * @param symbol symbol to scan + * @param contextClass current class context + * @param isMethod flag to search a method + * @param listenerId id of the listener + * @return the type of the symbol (or null if it could not be determined). + */ + private ClassDescriptor scanCompoundSymbol(String symbol, ClassDescriptor contextClass, boolean isMethod, String listenerId) { + String[] tokens = symbol.split("\\s*\\.\\s*"); + StringBuffer currentSymbol = new StringBuffer(); + StringBuffer tokensSeenSoFar = new StringBuffer(); + boolean accepted; // if this ends up false, it means we weren't able to figure out + // which object the method is being invoked on + boolean recognizeClassNames = true; + for (int j = 0; j < tokens.length - (isMethod ? 1 : 0); j++) { + accepted = false; + + if (tokensSeenSoFar.length() > 0) { + tokensSeenSoFar.append('.'); + } + tokensSeenSoFar.append(tokens[j]); + if (currentSymbol.length() > 0) { + currentSymbol.append('.'); + } + currentSymbol.append(tokens[j]); + + if (currentSymbol.indexOf(".") == -1) { + String memberName = currentSymbol.toString(); + CompiledObject object = compiler.getCompiledObject(memberName); + if (object != null) { + contextClass = object.getObjectClass(); + currentSymbol.setLength(0); + accepted = true; + recognizeClassNames = false; + } else { + try { + FieldDescriptor field = contextClass.getFieldDescriptor(memberName); + trackMemberIfPossible(tokensSeenSoFar.toString(), contextClass, field.getName(), false, listenerId); + contextClass = field.getType(); + currentSymbol.setLength(0); + accepted = true; + recognizeClassNames = false; + } + catch (NoSuchFieldException e) { + if (j == 0 || j == 1 && tokens[0].equals(compiler.getRootObject().getId())) { // still in root context + FieldDescriptor[] newFields = compiler.getScriptFields(); + for (FieldDescriptor newField : newFields) { + if (newField.getName().equals(memberName)) { + addListener(tokensSeenSoFar.toString(), + null, + "addPropertyChangeListener(\"" + memberName + "\", " + listenerId + ");" + JAXXCompiler.getLineSeparator(), + "removePropertyChangeListener(\"" + memberName + "\", " + listenerId + ");" + JAXXCompiler.getLineSeparator()); + contextClass = newField.getType(); + assert contextClass != null : "script field '" + memberName + "' is defined, but has type null"; + currentSymbol.setLength(0); + accepted = true; + recognizeClassNames = false; + break; + } + } + } + } + } + } + if (currentSymbol.length() > 0 && recognizeClassNames) { + contextClass = TagManager.resolveClass(currentSymbol.toString(), compiler); + if (contextClass != null) { + currentSymbol.setLength(0); + //accepted = true; + //recognizeClassNames = false; + // TODO: for now we don't handle statics + return null; + } + } + if (!accepted) { + return null; + } + } + + return contextClass; + } + + /** + * Adds type information to nodes where possible, and as a side effect adds event listeners to nodes which + * can be tracked. + * + * @param expression the node to scan + * @param listenerId id of the listener + * @return the class descriptor of the return type or null + */ + private ClassDescriptor determineExpressionType(SimpleNode expression, String listenerId) { + assert expression.getId() == JavaParserTreeConstants.JJTPRIMARYEXPRESSION; + SimpleNode prefix = expression.getChild(0); + if (prefix.jjtGetNumChildren() == 1) { + int type = prefix.getChild(0).getId(); + if (type == JavaParserTreeConstants.JJTLITERAL || type == JavaParserTreeConstants.JJTEXPRESSION) { + prefix.setJavaType(prefix.getChild(0).getJavaType()); + } else if (type == JavaParserTreeConstants.JJTNAME && expression.jjtGetNumChildren() == 1) // name with no arguments after it + { + prefix.setJavaType(scanCompoundSymbol(prefix.getText().trim(), compiler.getRootObject().getObjectClass(), false, listenerId)); + } + } + + if (expression.jjtGetNumChildren() == 1) { + return prefix.getJavaType(); + } + + ClassDescriptor contextClass = prefix.getJavaType(); + if (contextClass == null) { + contextClass = compiler.getRootObject().getObjectClass(); + } + String lastNode = prefix.getText().trim(); + + for (int i = 1; i < expression.jjtGetNumChildren(); i++) { + SimpleNode suffix = expression.getChild(i); + if (suffix.jjtGetNumChildren() == 1 && suffix.getChild(0).getId() == JavaParserTreeConstants.JJTARGUMENTS) { + if (suffix.getChild(0).jjtGetNumChildren() == 0) { // at the moment only no-argument methods are trackable + contextClass = scanCompoundSymbol(lastNode, contextClass, true, listenerId); + if (contextClass == null) { + return null; + } + int dotPos = lastNode.lastIndexOf("."); + String objectCode = dotPos == -1 ? "" : lastNode.substring(0, dotPos); + for (int j = i - 2; j >= 0; j--) { + objectCode = expression.getChild(j).getText() + objectCode; + } + if (objectCode.length() == 0) { + objectCode = compiler.getRootObject().getJavaCode(); + } + String methodName = lastNode.substring(dotPos + 1).trim(); + try { + MethodDescriptor method = contextClass.getMethodDescriptor(methodName); + trackMemberIfPossible(objectCode, contextClass, method.getName(), true, listenerId); + return method.getReturnType(); + } + catch (NoSuchMethodException e) { + // happens for methods defined in the current JAXX file via scripts + String propertyName = null; + if (methodName.startsWith("is")) { + propertyName = Introspector.decapitalize(methodName.substring("is".length())); + } else if (methodName.startsWith("get")) { + propertyName = Introspector.decapitalize(methodName.substring("get".length())); + } + if (propertyName != null) { + MethodDescriptor[] newMethods = compiler.getScriptMethods(); + for (MethodDescriptor newMethod : newMethods) { + if (newMethod.getName().equals(methodName)) { + addListener(compiler.getRootObject().getId(), + null, + "addPropertyChangeListener(\"" + propertyName + "\", " + listenerId + ");" + JAXXCompiler.getLineSeparator(), + "removePropertyChangeListener(\"" + propertyName + "\", " + listenerId + ");" + JAXXCompiler.getLineSeparator()); + contextClass = newMethod.getReturnType(); + break; + } + } + } + } + } + } + lastNode = suffix.getText().trim(); + if (lastNode.startsWith(".")) { + lastNode = lastNode.substring(1); + } + } + + return null; + } + + private void trackMemberIfPossible(String objectCode, ClassDescriptor objectClass, String memberName, boolean method, String listenerId) { + if (objectClass.isInterface()) // might be technically possible to track in some cases, but for now + { + return; // we can't create a DefaultObjectHandler for interfaces + } + + DefaultObjectHandler handler = TagManager.getTagHandler(objectClass); + try { + if (handler.isMemberBound(memberName)) { + addListener(objectCode + "." + memberName + (method ? "()" : ""), + objectCode, + handler.getAddMemberListenerCode(objectCode, id, memberName, listenerId, compiler), + handler.getRemoveMemberListenerCode(objectCode, id, memberName, listenerId, compiler)); + } + } + catch (UnsupportedAttributeException e) { + // ignore -- this is thrown for methods like toString(), for which there is no tracking and + // no setting support + } + } + + /** + * Adds type information to nodes where possible, and as a side effect adds event listeners to nodes which + * can be tracked. + * + * @param node node to scan + * @param listenerId the listener id + */ + private void determineNodeType(SimpleNode node, String listenerId) { + ClassDescriptor type = null; + if (node.jjtGetNumChildren() == 1) { + type = node.getChild(0).getJavaType(); + } + switch (node.getId()) { + case JavaParserTreeConstants.JJTCLASSORINTERFACETYPE: + type = ClassDescriptorLoader.getClassDescriptor(Class.class); + break; + case JavaParserTreeConstants.JJTPRIMARYEXPRESSION: + type = determineExpressionType(node, listenerId); + break; + case JavaParserTreeConstants.JJTLITERAL: + type = determineLiteralType(node); + break; + case JavaParserTreeConstants.JJTCASTEXPRESSION: + type = TagManager.resolveClass(node.getChild(0).getText(), compiler); + break; + } + node.setJavaType(type); + } + + private void addListener(String dependencySymbol, String objectCode, String addCode, String removeCode) { + this.objectCode = objectCode; + if (!dependencySymbols.contains(dependencySymbol)) { + dependencySymbols.add(dependencySymbol); + if (objectCode != null) { + addListenerCode.append("if (").append(objectCode).append(" != null) {").append(JAXXCompiler.getLineSeparator()); + addListenerCode.append(" "); + } + addListenerCode.append(" ").append(addCode); + if (objectCode != null) { + addListenerCode.append(" ").append("}"); + } + + if (objectCode != null) { + removeListenerCode.append("if (").append(objectCode).append(" != null) {").append(JAXXCompiler.getLineSeparator()); + removeListenerCode.append(" "); + } + removeListenerCode.append(" ").append(removeCode); + if (objectCode != null) { + removeListenerCode.append(" }"); + } + } + } + + private void compileListeners() { + String javaCodeId = TypeManager.getJavaCode(id); + if (addListenerCode.length() > 0) { + if (compiler.haveApplyDataBinding()) { + compiler.appendApplyDataBinding(" else "); + } + compiler.appendApplyDataBinding("if (" + javaCodeId + ".equals($binding)) {" + JAXXCompiler.getLineSeparator()); + compiler.appendApplyDataBinding(" " + addListenerCode + JAXXCompiler.getLineSeparator()); + compiler.appendApplyDataBinding("}"); + //if (compiler.applyDataBinding.length() > 0) + // compiler.applyDataBinding.append("else "); + //compiler.applyDataBinding.append("if ($binding.equals(").append(TypeManager.getJavaCode(id)).append(")) {").append(JAXXCompiler.getLineSeparator()); + //compiler.applyDataBinding.append(" ").append(addListenerCode).append(JAXXCompiler.getLineSeparator()); + //compiler.applyDataBinding.append("}").append(JAXXCompiler.getLineSeparator()); + } + + if (removeListenerCode.length() > 0) { + if (compiler.haveRemoveDataBinding()) { + compiler.appendRemoveDataBinding(" else "); + } + compiler.appendRemoveDataBinding("if (" + javaCodeId + ".equals($binding)) {" + JAXXCompiler.getLineSeparator()); + compiler.appendRemoveDataBinding(" " + removeListenerCode + JAXXCompiler.getLineSeparator()); + compiler.appendRemoveDataBinding("}"); + //if (compiler.removeDataBinding.length() > 0) + // compiler.removeDataBinding.append("else "); + //compiler.removeDataBinding.append("if ($binding.equals(").append(TypeManager.getJavaCode(id)).append(")) {").append(JAXXCompiler.getLineSeparator()); + //compiler.removeDataBinding.append(" ").append(removeListenerCode).append(JAXXCompiler.getLineSeparator()); + //compiler.removeDataBinding.append("}").append(JAXXCompiler.getLineSeparator()); + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/EventHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/EventHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/EventHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/EventHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,61 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.MethodDescriptor; + +public class EventHandler { + private String eventId; + private String objectCode; + private ClassDescriptor listenerClass; + private MethodDescriptor addMethod; + private MethodDescriptor listenerMethod; + private String javaCode; + + public EventHandler(String eventId, String objectCode, MethodDescriptor addMethod, ClassDescriptor listenerClass, MethodDescriptor listenerMethod, String javaCode) { + this.eventId = eventId; + this.objectCode = objectCode; + this.addMethod = addMethod; + this.listenerClass = listenerClass; + this.listenerMethod = listenerMethod; + this.javaCode = javaCode; + } + + + public String getEventId() { + return eventId; + } + + + public String getObjectCode() { + return objectCode; + } + + + public MethodDescriptor getAddMethod() { + return addMethod; + } + + + public ClassDescriptor getListenerClass() { + return listenerClass; + } + + + public MethodDescriptor getListenerMethod() { + return listenerMethod; + } + + + public String getJavaCode() { + return javaCode; + } + + + public String toString() { + return "EventHandler[" + eventId + ", " + listenerClass.getName() + ", " + objectCode + ", " + javaCode + "]"; + } +} \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/Generator.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/Generator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/Generator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,10 @@ +package jaxx.compiler; + +/** @author chemit */ +public interface Generator { + + void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className); + + void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException; + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/I18nHelper.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/I18nHelper.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/I18nHelper.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/I18nHelper.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,70 @@ +package jaxx.compiler; + +import jaxx.tags.DefaultComponentHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.Arrays; +import java.util.List; + +/** + * I18n methods to add {@link org.codelutin.i18n.I18n#_(String, Object[])} method on some attributes. + * <p/> + * Make sure to set an i18nable compiler to have his {@link CompilerOptions#isI18nable()} returning true. + * + * @author chemit + */ +public class I18nHelper { + + protected static final Log log = LogFactory.getLog(DefaultComponentHandler.class); + + public static final List<String> I18N_ATTRIBUTES = Arrays.asList("text", "title", "toolTipText"); + + /** + * Test if we have an active i18n attribute (says an i18n attribute on a i18neable compiler). + * + * @param attributeName name of attribute to test + * @param compiler current used compiler (contains options) + * @return <code>true</code> if wa have an active i18n attribute, <code>false</code> otherwise. + */ + public static boolean isI18nableAttribute(String attributeName, JAXXCompiler compiler) { + return compiler.getOptions().isI18nable() && isI18nAttribute(attributeName); + } + + /** + * Test if we have an i18n attribute. + * + * @param attributeName name of attribute to test + * @return <code>true</code> if wa have an active i18n attribute, <code>false</code> otherwise. + */ + public static boolean isI18nAttribute(String attributeName) { + return I18N_ATTRIBUTES.contains(attributeName); + } + /** + * Add the i18n on a attribute. + * <p/> + * Note: <b>Be ware : </b> no test is done here to ensure we are on a i18neable attribute for an i18nable compiler. + * <p/> + * Make sure with the method {@link jaxx.compiler.I18nHelper#isI18nableAttribute(String, JAXXCompiler)} returns + * <code>true</code< before using this method. + * + * @param widgetId the id of the widget + * @param attributeName the name of the attribute + * @param attributeValueCode the value code of the attribute value + * @param compiler the current used compile + * @return the surrender i18n call if attribute name is matchrf the attributeValueCode otherwise + */ + public static String addI18nInvocation(String widgetId, String attributeName, String attributeValueCode, JAXXCompiler compiler) { + + if (log.isDebugEnabled()) { + log.debug(" try i18n support for [" + widgetId + ":" + attributeName + "] : " + attributeValueCode); + } + if (attributeValueCode.contains("_(") && attributeValueCode.contains(")")) { + compiler.reportWarning("\n\tjaxx supports i18n, no need to add explicit call to I18n._ for attribute '" + attributeName + "' in component '" + widgetId + "' : ["+attributeValueCode+"]"); + } else { + attributeValueCode = "_(" + attributeValueCode + ")"; + } + + return attributeValueCode; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java (from rev 1097, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompiler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,1669 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.UnsupportedTagException; +import jaxx.css.Rule; +import jaxx.css.Stylesheet; +import jaxx.css.StylesheetHelper; +import jaxx.parser.ParseException; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.FieldDescriptor; +import jaxx.reflect.MethodDescriptor; +import jaxx.runtime.ComponentDescriptor; +import jaxx.runtime.JAXXObjectDescriptor; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.TagHandler; +import jaxx.tags.TagManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.xml.sax.Attributes; +import org.xml.sax.InputSource; +import org.xml.sax.Locator; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; +import org.xml.sax.helpers.AttributesImpl; +import org.xml.sax.helpers.XMLFilterImpl; + +import javax.xml.parsers.ParserConfigurationException; +import javax.xml.parsers.SAXParser; +import javax.xml.parsers.SAXParserFactory; +import javax.xml.transform.ErrorListener; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerConfigurationException; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMResult; +import javax.xml.transform.sax.SAXSource; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.lang.reflect.Modifier; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLDecoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.Stack; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Compiles JAXX files into Java classes. + * <p/> + * use {@link Generator} ... todo finish javadoc + */ +public class JAXXCompiler { + + /** log */ + protected static final Log log = LogFactory.getLog(JAXXCompiler.class); + + /** + * True to throw exceptions when we encounter unresolvable classes, false to ignore. + * This is currently set to false until JAXX has full support for inner classes + * (including enumerations), because currently they don't always resolve (but will + * generally compile without error anyway). + */ + public static final boolean STRICT_CHECKS = false; + public static final String JAXX_NAMESPACE = "http://www.jaxxframework.org/"; + public static final String JAXX_INTERNAL_NAMESPACE = "http://www.jaxxframework.org/internal"; + + /** Maximum length of an inlinable creation method. */ + public static final int INLINE_THRESHOLD = 300; + + protected final DefaultObjectHandler firstPassClassTagHandler; + + protected List<String> staticImports = new ArrayList<String>(); + + /*---------------------------------------------------------------------------------*/ + /*-- compiler fields --------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + /** flag to detec if an error occurs while compiling jaxx file */ + protected boolean failed; + + /** Object corresponding to the root tag in the document. */ + protected CompiledObject root; + + /** Contains strings of the form "javax.swing." */ + protected Set<String> importedPackages = new HashSet<String>(); + + /** Contains strings of the form "javax.swing.Timer" */ + protected Set<String> importedClasses = new HashSet<String>(); + + /** Keeps track of open components (components still having children added). */ + protected Stack<CompiledObject> openComponents = new Stack<CompiledObject>(); + + /** Sequence number used to create automatic variable names. */ + protected int autogenID = 0; + + protected List<DataBinding> dataBindings = new ArrayList<DataBinding>(); + + protected SymbolTable symbolTable = new SymbolTable(); + + /** Base directory used for path resolution (normally the directory in which the .jaxx file resides). */ + protected File baseDir; + + /** .jaxx file being compiled. */ + protected File src; + + /** Parsed XML of src file. */ + protected Document document; + + /** Name of class being compiled. */ + protected String outputClassName; + + protected ScriptManager scriptManager = new ScriptManager(this); + + /** Combination of all stylesheets registered using {@link #registerStylesheet}. */ + protected Stylesheet stylesheet; + + /** Contains all attributes defined inline on class tags. */ + protected List<Rule> inlineStyles = new ArrayList<Rule>(); + + /** + * Maps objects (expressed in Java code) to event listener classes (e.g. MouseListener) to Lists of EventHandlers. The final list + * contains all event handlers of a particular type attached to a particular object (again, as represented by a Java expression). + */ + protected Map<String, Map<ClassDescriptor, List<EventHandler>>> eventHandlers = new HashMap<String, Map<ClassDescriptor, List<EventHandler>>>(); + + /** Maps of uniqued id for objects used in compiler */ + protected Map<Object, String> uniqueIds = new HashMap<Object, String>(); + + /** Map of event handler method names used in compiler */ + protected Map<EventHandler, String> eventHandlerMethodNames = new HashMap<EventHandler, String>(); + + /** ClassLoader which searches the user-specified class path in addition to the normal class path */ + protected ClassLoader classLoader; + + /** + * A list of Runnables which will be run after the first compilation pass. This is primarily used + * to trigger the creation of CompiledObjects, which cannot be created during the first pass and must be + * created in document order. + */ + protected List<Runnable> initializers = new ArrayList<Runnable>(); + + /** left brace matcher */ + protected Matcher leftBraceMatcher = Pattern.compile("^(\\{)|[^\\\\](\\{)").matcher(""); + + /** right brace matcher */ + protected Matcher rightBraceMatcher = Pattern.compile("^(\\})|[^\\\\](\\})").matcher(""); + + /** extra interfaces which can by passed to root object via the 'implements' attribute */ + private String[] extraInterfaces; + + /** Extra code to be added to the instance initializer. */ + protected StringBuffer initializer = new StringBuffer(); + + /** Extra code to be added at the end of the instance initializer. */ + protected StringBuffer lateInitializer = new StringBuffer(); + + /** Extra code to be added to the class body. */ + protected StringBuffer bodyCode = new StringBuffer(); + + /** Code to initialize data bindings. */ + protected StringBuffer initDataBindings = new StringBuffer(); + + /** Body of the applyDataBinding method. */ + protected StringBuffer applyDataBinding = new StringBuffer(); + + /** Body of the removeDataBinding method. */ + protected StringBuffer removeDataBinding = new StringBuffer(); + + /** Body of the processDataBinding method. */ + protected StringBuffer processDataBinding = new StringBuffer(); + + /** true if a main() method has been declared in a script */ + protected boolean mainDeclared; + + /** the file to be generated */ + protected JavaFile javaFile; + + + protected CompilerOptions options; + + /** Used for error reporting purposes, so we can report the right line number. */ + protected Stack<Element> tagsBeingCompiled = new Stack<Element>(); + + /** Used for error reporting purposes, so we can report the right source file. */ + protected Stack<File> sourceFiles = new Stack<File>(); + + /** Maps object ID strings to the objects themselves. These are created during the second compilation pass. */ + protected Map<String, CompiledObject> objects = new LinkedHashMap<String, CompiledObject>(); + + /** Maps objects to their ID strings. These are created during the second compilation pass. */ + protected Map<CompiledObject, String> ids = new LinkedHashMap<CompiledObject, String>(); + + /*---------------------------------------------------------------------------------*/ + /*-- Constructor methods ----------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + protected JAXXCompiler(ClassLoader classLoader, DefaultObjectHandler firstPassClassTagHandler, String... staticImports) { + this.firstPassClassTagHandler = firstPassClassTagHandler; + this.options = new CompilerOptions(); + this.classLoader = classLoader; + if (staticImports == null || staticImports.length == 0) { + staticImports = new String[0]; + } + this.staticImports = Arrays.asList(staticImports); + addImport("java.lang.*"); + } + + /** + * Creates a new JAXXCompiler. + * + * @param baseDir classpath location + * @param src location of file to compile + * @param outputClassName the out file name + * @param options options to pass to javac + * @param firstPassClassTagHandler handler to use for first pass + * @param staticImports statics imports + */ + protected JAXXCompiler(File baseDir, File src, String outputClassName, CompilerOptions options, DefaultObjectHandler firstPassClassTagHandler, String... staticImports) { + this.baseDir = baseDir; + this.src = src; + this.firstPassClassTagHandler = firstPassClassTagHandler; + this.staticImports = Arrays.asList(staticImports); + sourceFiles.push(src); + this.outputClassName = outputClassName; + this.options = options; + addImport(outputClassName.substring(0, outputClassName.lastIndexOf(".") + 1) + "*"); + if (staticImports == null || staticImports.length == 0) { + staticImports = new String[]{"java.lang.*"}; + } + for (Object staticImport : staticImports) { + addImport((String) staticImport); + } + // add extra imports from options + if (options.getExtraImports() != null) { + for (String extraImport : options.getExtraImports()) { + addImport(extraImport); + } + } + } + + /*---------------------------------------------------------------------------------*/ + /*-- Initializer methods -----------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void runInitializers() { + for (Runnable runnable : initializers) { + if (log.isDebugEnabled()) { + log.debug(runnable); + } + try { + runnable.run(); + } catch (Exception e) { + //TC - 20081018 report error and quit + reportError(e.getMessage()); + return; + } + } + initializers.clear(); + } + + + /** + * Registers a <code>Runnable</code> which will be executed after the first + * compilation pass is complete. + * + * @param r runnable to register + */ + public void registerInitializer(Runnable r) { + initializers.add(r); + } + + /*---------------------------------------------------------------------------------*/ + /*-- Compile methods --------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void compileFirstPass(final Element tag) throws IOException { + tagsBeingCompiled.push(tag); + + String namespace = tag.getNamespaceURI(); + String fullClassName; + String localName = tag.getLocalName(); + boolean namespacePrefix = tag.getPrefix() != null; + // resolve class tags into fully-qualified class name + if (namespace != null && namespace.endsWith("*")) { + String packageName = namespace.substring(0, namespace.length() - 1); + if (localName.startsWith(packageName)) // class name is fully-qualified already + { + fullClassName = TagManager.resolveClassName(localName, this); + } else { // namespace not included in class name, probably need the namespace to resolve + fullClassName = TagManager.resolveClassName(packageName + localName, this); + if (fullClassName == null && !namespacePrefix) // it was just a default namespace, try again without using the namespace + { + fullClassName = TagManager.resolveClassName(localName, this); + } + } + } else { + fullClassName = TagManager.resolveClassName(localName, this); + } + + if (fullClassName != null) { // we are definitely dealing with a class tag + addDependencyClass(fullClassName); + namespace = fullClassName.substring(0, fullClassName.lastIndexOf(".") + 1) + "*"; + if (symbolTable.getSuperclassName() == null) { + symbolTable.setSuperclassName(fullClassName); + } + String id = tag.getAttribute("id"); + if (id.length() > 0) { + symbolTable.getClassTagIds().put(id, fullClassName); + if (tag.getAttributeNode("javaBean") != null) { + // add java bean support for this property + String capitalizeName = org.apache.commons.lang.StringUtils.capitalize(id); + // add method + symbolTable.getScriptMethods().add(new MethodDescriptor("get" + capitalizeName, Modifier.PUBLIC, fullClassName, new String[0], classLoader)); + if (Boolean.class.getName().equals(fullClassName)) { + symbolTable.getScriptMethods().add(new MethodDescriptor("is" + capitalizeName, Modifier.PUBLIC, fullClassName, new String[0], classLoader)); + } + symbolTable.getScriptMethods().add(new MethodDescriptor("set" + capitalizeName, Modifier.PUBLIC, "void", new String[]{fullClassName}, classLoader)); + } + } + } + // during the first pass, we can't create ClassDescriptors for JAXX files because they may not have been processed yet + // (and we can't wait until they have been processed because of circular dependencies). So we don't do any processing + // during the first pass which requires having a ClassDescriptor; here we determine whether we have a class tag or not + // (class tag namespaces end in "*") and use a generic handler if so. The real handler is used during the second pass. + TagHandler handler = (namespace != null && namespace.endsWith("*")) ? firstPassClassTagHandler : TagManager.getTagHandler(tag.getNamespaceURI(), localName, namespacePrefix, this); + if (handler != firstPassClassTagHandler && handler instanceof DefaultObjectHandler) { + fullClassName = ((DefaultObjectHandler) handler).getBeanClass().getName(); + //namespace = fullClassName.substring(0, fullClassName.lastIndexOf(".") + 1) + "*"; + handler = firstPassClassTagHandler; + } + if (handler == firstPassClassTagHandler) { + final String finalClassName = fullClassName; + registerInitializer(new Runnable() { // register an initializer which will create the CompiledObject after pass 1 + + public void run() { + DefaultObjectHandler handler = (DefaultObjectHandler) TagManager.getTagHandler(null, finalClassName, JAXXCompiler.this); + if (handler == null) { + throw new CompilerException("Internal error: missing TagHandler for '" + finalClassName + "'"); + } + handler.registerCompiledObject(tag, JAXXCompiler.this); + } + }); + } + if (handler != null) { + try { + handler.compileFirstPass(tag, this); + } + catch (CompilerException e) { + reportError(e); + } + } else { + reportError("Could not find a Java class corresponding to: <" + tag.getTagName() + ">"); + failed = true; + } + + Element finished = tagsBeingCompiled.pop(); + if (finished != tag) { + throw new RuntimeException("internal error: just finished compiling " + tag + ", but top of tagsBeingCompiled stack is " + finished); + } + } + + + public void compileSecondPass(Element tag) throws IOException { + tagsBeingCompiled.push(tag); + + TagHandler handler = TagManager.getTagHandler(tag.getNamespaceURI(), tag.getLocalName(), tag.getPrefix() != null, this); + if (handler != null) { + handler.compileSecondPass(tag, this); + } else { + reportError("Could not find a Java class corresponding to: <" + tag.getTagName() + ">"); + assert false : "can't-happen error: error should have been reported during the fast pass and caused an abort"; + failed = true; + } + + Element finished = tagsBeingCompiled.pop(); + if (finished != tag) { + throw new RuntimeException("internal error: just finished compiling " + tag + ", but top of tagsBeingCompiled stack is " + finished); + } + + } + + protected void compileFirstPass() throws IOException { + try { + InputStream in = new FileInputStream(src); + document = parseDocument(in); + in.close(); + compileFirstPass(document.getDocumentElement()); + } + catch (SAXParseException e) { + reportError(e.getLineNumber(), "Invalid XML: " + e.getMessage()); + } + catch (SAXException e) { + reportError(null, "Error parsing XML document: " + e); + } + } + + protected void compileSecondPass() throws IOException { + if (!tagsBeingCompiled.isEmpty()) { + throw new RuntimeException("Internal error: starting pass two, but tagsBeingCompiled is not empty: " + tagsBeingCompiled); + } + compileSecondPass(document.getDocumentElement()); + } + + /*---------------------------------------------------------------------------------*/ + /*-- CompiledObject methods -------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void openComponent(CompiledObject component) throws CompilerException { + openComponent(component, null); + } + + public void openComponent(CompiledObject component, String constraints) throws CompilerException { + CompiledObject parent = getOpenComponent(); + openInvisibleComponent(component); + if (parent != null && !component.isOverride()) { + parent.addChild(component, constraints, this); + } + } + + public void openInvisibleComponent(CompiledObject component) { + if (!ids.containsKey(component)) { + registerCompiledObject(component); + } + openComponents.push(component); + } + + public CompiledObject getOpenComponent() { + if (openComponents.isEmpty()) { + return null; + } + return openComponents.peek(); + } + + public void closeComponent(CompiledObject component) { + if (openComponents.pop() != component) { + throw new IllegalArgumentException("can only close the topmost open object"); + } + } + + public void registerCompiledObject(CompiledObject object) { + assert JAXXCompilerLaunchor.get().symbolTables.values().contains(symbolTable) : "attempting to register CompiledObject before pass 1 is complete"; + if (root == null) { + root = object; + } + + String id = object.getId(); + if (ids.containsKey(object)) { + reportError("object '" + object + "' is already registered with id '" + ids.get(object) + "', cannot re-register as '" + id + "'"); + } + if (objects.containsKey(id) && !(objects.get(id) instanceof Element)) { + reportError("id '" + id + "' is already registered to component " + objects.get(id)); + } + objects.put(id, object); + ids.put(object, id); + } + + public CompiledObject getCompiledObject(String id) { + runInitializers(); + assert JAXXCompilerLaunchor.get().symbolTables.values().contains(symbolTable) : "attempting to retrieve CompiledObject before pass 1 is complete"; + return objects.get(id); + } + + + public boolean inlineCreation(CompiledObject object) { + return object.getId().startsWith("$") && object.getInitializationCode(this).length() < INLINE_THRESHOLD; + } + + public void checkOverride(CompiledObject object) throws CompilerException { + if (object.getId().startsWith("$")) { + return; + } + ClassDescriptor ancestor = root.getObjectClass(); + if (ancestor == object.getObjectClass()) { + return; + } + while (ancestor != null) { + try { + FieldDescriptor f = ancestor.getDeclaredFieldDescriptor(object.getId()); + if (!f.getType().isAssignableFrom(object.getObjectClass())) { + reportError("attempting to redefine superclass member '" + object.getId() + "' as incompatible type (was " + f.getType() + ", redefined as " + object.getObjectClass() + ")"); + } + object.setOverride(true); + object.setOverrideType(f.getType()); + break; + } + catch (NoSuchFieldException e) { + ancestor = ancestor.getSuperclass(); + } + } + } + + /*---------------------------------------------------------------------------------*/ + /*-- DataBinding methods ----------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + /** + * Examine an attribute value for data binding expressions. Returns a 'cooked' expression which + * can be used to determine the resulting value. It is expected that this expression will be used + * as the source expression in a call to {@link #registerDataBinding}. + * If the attribute value does not invoke data binding, this method returns <code>null</code> + * + * @param stringValue the string value of the property from the XML + * @param type the type of the property, from the <code>JAXXPropertyDescriptor</code> + * @return a processed version of the expression + * @throws jaxx.CompilerException ? + */ + public String processDataBindings(String stringValue, ClassDescriptor type) throws CompilerException { + int pos = getNextLeftBrace(stringValue, 0); + if (pos != -1) { + StringBuffer expression = new StringBuffer(); + int lastPos = 0; + while (pos != -1 && pos < stringValue.length()) { + if (pos > lastPos) { + if (expression.length() > 0) { + expression.append(" + "); + } + expression.append('"'); + expression.append(escapeJavaString(stringValue.substring(lastPos, pos))); + expression.append('"'); + } + + if (expression.length() > 0) { + expression.append(" + "); + } + expression.append('('); + int pos2 = getNextRightBrace(stringValue, pos + 1); + if (pos2 == -1) { + reportError("unmatched '{' in expression: " + stringValue); + return ""; + } + expression.append(stringValue.substring(pos + 1, pos2)); + expression.append(')'); + pos2++; + if (pos2 < stringValue.length()) { + pos = getNextLeftBrace(stringValue, pos2); + lastPos = pos2; + } else { + pos = stringValue.length(); + lastPos = pos; + } + } + if (lastPos < stringValue.length()) { + if (expression.length() > 0) { + expression.append(" + "); + } + expression.append('"'); + expression.append(escapeJavaString(stringValue.substring(lastPos))); + expression.append('"'); + } + return type == ClassDescriptorLoader.getClassDescriptor(String.class) ? "String.valueOf(" + expression + ")" : expression.toString(); + } + return null; + } + + + public void registerDataBinding(String src, String dest, String assignment) { + try { + src = checkJavaCode(src); + dataBindings.add(new DataBinding(src, dest, assignment, this)); + } + catch (CompilerException e) { + reportError("While parsing data binding for '" + dest.substring(dest.lastIndexOf(".") + 1) + "': " + e.getMessage()); + } + } + + public void registerEventHandler(EventHandler handler) { + String objectCode = handler.getObjectCode(); + Map<ClassDescriptor, List<EventHandler>> listeners = eventHandlers.get(objectCode); + if (listeners == null) { + listeners = new HashMap<ClassDescriptor, List<EventHandler>>(); + eventHandlers.put(objectCode, listeners); + } + ClassDescriptor listenerClass = handler.getListenerClass(); + List<EventHandler> handlerList = listeners.get(listenerClass); + if (handlerList == null) { + handlerList = new ArrayList<EventHandler>(); + listeners.put(listenerClass, handlerList); + } + handlerList.add(handler); + } + + public String getEventHandlerMethodName(EventHandler handler) { + String result = eventHandlerMethodNames.get(handler); + if (result == null) { + if (getOptions().isOptimize()) { + result = "$ev" + eventHandlerMethodNames.size(); + } else { + result = "do" + org.apache.commons.lang.StringUtils.capitalize(handler.getListenerMethod().getName()) + "__on__" + handler.getObjectCode(); + } + eventHandlerMethodNames.put(handler, result); + } + return result; + } + + /*---------------------------------------------------------------------------------*/ + /*-- Script methods ---------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void addScriptField(FieldDescriptor field) { + symbolTable.getScriptFields().add(field); + } + + public void addScriptMethod(MethodDescriptor method) { + if (method.getName().equals("main") && method.getParameterTypes().length == 1 && method.getParameterTypes()[0].getName().equals("[Ljava.lang.String;")) { + setMainDeclared(true); + } + symbolTable.getScriptMethods().add(method); + } + + public void registerScript(String script) throws CompilerException { + registerScript(script, null); + } + + public void registerScript(String script, File sourceFile) throws CompilerException { + if (sourceFile != null) { + sourceFiles.push(sourceFile); + } + script = script.trim(); + if (!"".equals(script) && !script.endsWith("}") && !script.endsWith(";")) { + script += ";"; + } + scriptManager.registerScript(script); + + if (sourceFile != null) { + File pop = sourceFiles.pop(); + if (pop != sourceFile) { + throw new RuntimeException("leaving registerScript(), but " + sourceFile + " was not the top entry on the stack (found " + pop + " instead)"); + } + } + } + + public String preprocessScript(String script) throws CompilerException { + return scriptManager.preprocessScript(script); + } + + /*---------------------------------------------------------------------------------*/ + /*-- StyleSheet methods -----------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void applyStylesheets() { + for (Object o : new ArrayList<CompiledObject>(objects.values())) { + CompiledObject object = (CompiledObject) o; + TagManager.getTagHandler(object.getObjectClass()).applyStylesheets(object, this); + } + } + + public void registerStylesheet(Stylesheet stylesheet) { + if (this.stylesheet == null) { + this.stylesheet = stylesheet; + } else { + this.stylesheet.add(stylesheet.getRules()); + } + } + + public void addInlineStyle(CompiledObject object, String propertyName, boolean dataBinding) { + inlineStyles.add(StylesheetHelper.inlineAttribute(object, propertyName, dataBinding)); + } + + /*---------------------------------------------------------------------------------*/ + /*-- Report methods ---------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void reportWarning(String warning) { + Element currentTag = null; + if (!tagsBeingCompiled.isEmpty()) { + currentTag = tagsBeingCompiled.peek(); + } + reportWarning(currentTag, warning, 0); + } + + + public void reportWarning(Element tag, String warning, int lineOffset) { + String lineNumber = null; + if (tag != null) { + String lineAttr = tag.getAttributeNS(JAXX_INTERNAL_NAMESPACE, "line"); + if (lineAttr.length() > 0) { + lineNumber = lineAttr; + } + } + File src = sourceFiles.peek(); + try { + src = src.getCanonicalFile(); + } + catch (IOException e) { + // ignore ? + } + + System.err.print(src); + if (lineNumber != null) { + System.err.print(":" + ((sourceFiles.size() == 1) ? Integer.parseInt(lineNumber) + lineOffset : lineOffset + 1)); + } + System.err.println(": Warning: " + warning); + JAXXCompilerLaunchor.get().warningCount++; + } + + + public void reportError(String error) { + Element currentTag = null; + if (!tagsBeingCompiled.isEmpty()) { + currentTag = tagsBeingCompiled.peek(); + } + reportError(currentTag, error); + } + + public void reportError(CompilerException ex) { + reportError(null, ex); + } + + public void reportError(String extraMessage, CompilerException ex) { + String message = ex.getMessage(); + if (ex.getClass() == UnsupportedAttributeException.class || ex.getClass() == UnsupportedTagException.class) { + message = ex.getClass().getName().substring(ex.getClass().getName().lastIndexOf(".") + 1) + ": " + message; + } + int lineOffset; + if (ex instanceof ParseException) { + lineOffset = Math.max(0, ((ParseException) ex).getLine() - 1); + } else { + lineOffset = 0; + } + Element currentTag = null; + if (!tagsBeingCompiled.isEmpty()) { + currentTag = tagsBeingCompiled.peek(); + } + reportError(currentTag, extraMessage != null ? extraMessage + message : message, lineOffset); + } + + public void reportError(Element tag, String error) { + reportError(tag, error, 0); + } + + public void reportError(Element tag, String error, int lineOffset) { + int lineNumber = 0; + if (tag != null) { + String lineAttr = tag.getAttributeNS(JAXX_INTERNAL_NAMESPACE, "line"); + if (lineAttr.length() > 0) { + lineNumber = Integer.parseInt(lineAttr); + } + } + lineNumber = Math.max(lineNumber, 1) + lineOffset; + reportError(lineNumber, error); + } + + public void reportError(int lineNumber, String error) { + File src = sourceFiles.isEmpty() ? null : sourceFiles.peek(); + try { + if (src != null) { + src = src.getCanonicalFile(); + } + } + catch (IOException e) { + // ignore ? + } + + System.err.print(src != null ? src.getPath() : "<unknown source>"); + if (lineNumber > 0) { + System.err.print(":" + lineNumber); + } + System.err.println(": " + error); + JAXXCompilerLaunchor.get().errorCount++; + failed = true; + } + + /*---------------------------------------------------------------------------------*/ + /*-- Getter methods ---------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public Map<String, CompiledObject> getObjects() { + return objects; + } + + public List<DataBinding> getDataBindings() { + return dataBindings; + } + + /*public List<CompiledBeanValidator> getValidators() { + return validators; + }*/ + + public Map<String, Map<ClassDescriptor, List<EventHandler>>> getEventHandlers() { + return eventHandlers; + } + + public CompilerOptions getOptions() { + return options; + } + + public String getOutputClassName() { + return outputClassName; + } + + public File getBaseDir() { + return baseDir; + } + + public Set<String> getImportedClasses() { + return importedClasses; + } + + public Set<String> getImportedPackages() { + return importedPackages; + } + + public Iterator<CompiledObject> getObjectCreationOrder() { + return objects.values().iterator(); + } + + public CompiledObject getRootObject() { + return root; + } + + public Stack<File> getSourceFiles() { + return sourceFiles; + } + + public ScriptManager getScriptManager() { + return scriptManager; + } + + public SymbolTable getSymbolTable() { + return symbolTable; + } + + public Stylesheet getStylesheet() { + Stylesheet merged = new Stylesheet(); + if (stylesheet != null) { + merged.add(stylesheet.getRules()); + } + merged.add(inlineStyles.toArray(new Rule[inlineStyles.size()])); + return merged; + } + + public FieldDescriptor[] getScriptFields() { + List<FieldDescriptor> scriptFields = symbolTable.getScriptFields(); + return scriptFields.toArray(new FieldDescriptor[scriptFields.size()]); + } + + public MethodDescriptor[] getScriptMethods() { + List<MethodDescriptor> scriptMethods = symbolTable.getScriptMethods(); + return scriptMethods.toArray(new MethodDescriptor[scriptMethods.size()]); + } + + public boolean isFailed() { + return failed; + } + + /** + * Returns a <code>ClassLoader</code> which searches the user-specified class path in addition + * to the normal system class path. + * + * @return <code>ClassLoader</code> to use while resolving class references + */ + public ClassLoader getClassLoader() { + if (classLoader == null) { + if (options.getClassLoader() != null) { + classLoader = options.getClassLoader(); + } else { + String classPath = options.getClassPath(); + if (classPath == null) { + classPath = "."; + } + String[] paths = classPath.split(File.pathSeparator); + URL[] urls = new URL[paths.length]; + for (int i = 0; i < paths.length; i++) { + try { + urls[i] = new File(paths[i]).toURI().toURL(); + } + catch (MalformedURLException e) { + throw new RuntimeException(e); + } + } + classLoader = new URLClassLoader(urls, getClass().getClassLoader()); + } + } + + return classLoader; + } + + public JAXXObjectDescriptor getJAXXObjectDescriptor() { + runInitializers(); + CompiledObject[] components = new ArrayList<CompiledObject>(objects.values()).toArray(new CompiledObject[objects.size()]); + assert initializers.isEmpty() : "there are pending initializers remaining"; + assert root != null : "root object has not been defined"; + assert Arrays.asList(components).contains(root) : "root object is not registered"; + ComponentDescriptor[] descriptors = new ComponentDescriptor[components.length]; + // as we print, sort the array so that component's parents are always before the components themselves + for (int i = 0; i < components.length; i++) { + CompiledObject parent = components[i].getParent(); + while (parent != null) { + boolean found = false; + for (int j = i + 1; j < components.length; j++) { // found parent after component, swap them + if (components[j] == parent) { + components[j] = components[i]; + components[i] = parent; + found = true; + break; + } + } + if (!found) { + break; + } + parent = components[i].getParent(); + } + int parentIndex = -1; + if (parent != null) { + for (int j = 0; j < i; j++) { + if (components[j] == parent) { + parentIndex = j; + break; + } + } + } + descriptors[i] = new ComponentDescriptor(components[i].getId(), components[i] == root ? outputClassName : components[i].getObjectClass().getName(), + components[i].getStyleClass(), parentIndex != -1 ? descriptors[parentIndex] : null); + } + + Stylesheet stylesheet = getStylesheet(); + if (stylesheet == null) { + stylesheet = new Stylesheet(); + } + + return new JAXXObjectDescriptor(descriptors, stylesheet); + } + + /*---------------------------------------------------------------------------------*/ + /*-- Setter methods ---------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void setFailed(boolean failed) { + this.failed = failed; + } + + /*---------------------------------------------------------------------------------*/ + /*-- Buffer ------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public StringBuffer getInitializer() { + return initializer; + } + + public StringBuffer getLateInitializer() { + return lateInitializer; + } + + public StringBuffer getBodyCode() { + return bodyCode; + } + + public StringBuffer getInitDataBindings() { + return initDataBindings; + } + + public StringBuffer getApplyDataBinding() { + return applyDataBinding; + } + + public StringBuffer getRemoveDataBinding() { + return removeDataBinding; + } + + public StringBuffer getProcessDataBinding() { + return processDataBinding; + } + + public boolean isMainDeclared() { + return mainDeclared; + } + + public void setMainDeclared(boolean mainDeclared) { + this.mainDeclared = mainDeclared; + } + + public void appendInitializerCode(String code) { + getInitializer().append(code); + } + + public void appendBodyCode(String code) { + getBodyCode().append(code); + } + + public void appendInitDataBindings(String code) { + getInitDataBindings().append(code); + } + + public void appendProcessDataBinding(String code) { + getProcessDataBinding().append(code); + } + + public void appendApplyDataBinding(String code) { + getApplyDataBinding().append(code); + } + + public void appendRemoveDataBinding(String code) { + getRemoveDataBinding().append(code); + } + + public void appendLateInitializer(String code) { + getLateInitializer().append(code); + } + + public boolean haveProcessDataBinding() { + return getProcessDataBinding().length() > 0; + } + + public boolean haveApplyDataBinding() { + return getApplyDataBinding().length() > 0; + } + + public boolean haveRemoveDataBinding() { + return getRemoveDataBinding().length() > 0; + } + + public void addMethodToJavaFile(JavaMethod method) { + getJavaFile().addMethod(method); + } + + public boolean hasMethod(String methodName) { + JavaMethod[] methods = getJavaFile().getMethods(); + for (JavaMethod method : methods) { + if (methodName.equals(method.getName())) { + return true; + } + } + return false; + } + + /*---------------------------------------------------------------------------------*/ + /*-- Other methods ----------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public void addImport(String text) { + if (text.endsWith("*")) { + importedPackages.add(text.substring(0, text.length() - 1)); + } else { + importedClasses.add(text); + } + + if (!text.equals("*")) { + getJavaFile().addImport(text); + } + } + + public void addDependencyClass(String className) { + if (!JAXXCompilerLaunchor.get().jaxxFileClassNames.contains(className)) { + URL jaxxURL = getClassLoader().getResource(className.replace('.', '/') + ".jaxx"); + URL classURL = getClassLoader().getResource(className.replace('.', '/') + ".class"); + if (jaxxURL != null && classURL != null) { + try { + File jaxxFile = URLtoFile(jaxxURL); + File classFile = URLtoFile(classURL); + if (classFile.lastModified() > jaxxFile.lastModified()) { + return; // class file is newer, no need to recompile + } + } + catch (Exception e) { + // do nothing + } + } + + if (jaxxURL != null && jaxxURL.toString().startsWith("file:")) { + File jaxxFile = URLtoFile(jaxxURL); + try { + jaxxFile = jaxxFile.getCanonicalFile(); + } + catch (IOException ex) { + // ignore ? + } + assert jaxxFile.getName().equalsIgnoreCase(className.substring(className.lastIndexOf(".") + 1) + ".jaxx") : + "expecting file name to match " + className + ", but found " + jaxxFile.getName(); + if (jaxxFile.getName().equals(className.substring(className.lastIndexOf(".") + 1) + ".jaxx")) { // check case match + if (JAXXCompilerLaunchor.get().currentPass == JAXXCompilerLaunchor.PASS_2) { + throw new AssertionError("Internal error: adding dependency class " + className + " during second compilation pass"); + } + JAXXCompilerLaunchor.get().jaxxFileClassNames.add(className); + JAXXCompilerLaunchor.get().jaxxFiles.add(jaxxFile); + } + } + } + } + + /** + * Verifies that a snippet of Java code parses correctly. A warning is generated if the string has enclosing + * curly braces. + * + * @param javaCode the Java code snippet to test + * @return a "cooked" version of the string which has enclosing curly braces removed. + * @throws jaxx.CompilerException if the code cannot be parsed + */ + public String checkJavaCode(String javaCode) { + javaCode = scriptManager.trimScript(javaCode); + scriptManager.checkParse(javaCode); + return javaCode; + } + + /** + * Check that a reference exists in symbol table on second compil pass + * + * @param tag the current tag + * @param reference the required reference + * @param strict flag to report an error if reference was not found + * @param attribute (if not null reference the attribute where is defined the reference) + * @return <code>true</code> if reference was found, <code>false</code> otherwise and add an error in compiler + */ + public boolean checkReference(Element tag, String reference, boolean strict, String attribute) { + String component = getSymbolTable().getClassTagIds().get(reference); + if (component == null) { + if (strict) { + String msg; + if (attribute != null) { + msg = "tag '" + tag.getLocalName() + "' could not find the reference '" + reference + "' on attribute [" + attribute + "]"; + } else { + msg = "tag '" + tag.getLocalName() + "' could not find the reference '" + reference + "'"; + } + reportError(msg); + } + return false; + } + return true; + } + + protected int getNextLeftBrace(String string, int pos) { + leftBraceMatcher.reset(string); + return leftBraceMatcher.find(pos) ? Math.max(leftBraceMatcher.start(1), leftBraceMatcher.start(2)) : -1; + } + + protected int getNextRightBrace(String string, int pos) { + leftBraceMatcher.reset(string); + rightBraceMatcher.reset(string); + int openCount = 1; + int rightPos; + while (openCount > 0) { + pos++; + int leftPos = leftBraceMatcher.find(pos) ? Math.max(leftBraceMatcher.start(1), leftBraceMatcher.start(2)) : -1; + rightPos = rightBraceMatcher.find(pos) ? Math.max(rightBraceMatcher.start(1), rightBraceMatcher.start(2)) : -1; + assert leftPos == -1 || leftPos >= pos; + assert rightPos == -1 || rightPos >= pos; + if (leftPos != -1 && leftPos < rightPos) { + pos = leftPos; + openCount++; + } else if (rightPos != -1) { + pos = rightPos; + openCount--; + } else { + openCount = 0; + } + } + return pos; + } + + public String[] parseParameterList(String parameters) throws CompilerException { + List<String> result = new ArrayList<String>(); + StringBuffer current = new StringBuffer(); + int state = 0; // normal + for (int i = 0; i < parameters.length(); i++) { + char c = parameters.charAt(i); + switch (state) { + case 0: // normal + switch (c) { + case '"': + current.append(c); + state = 1; + break; // in quoted string + case '\\': + current.append(c); + state = 2; + break; // immediately after backslash + case ',': + if (current.length() > 0) { + result.add(current.toString()); + current.setLength(0); + break; + } else { + reportError("error parsing parameter list: " + parameters); + } + default: + current.append(c); + } + break; + case 1: // in quoted string + switch (c) { + case '"': + current.append(c); + state = 0; + break; // normal + case '\\': + current.append(c); + state = 3; + break; // immediate after backslash in quoted string + default: + current.append(c); + } + break; + case 2: // immediately after backslash + current.append(c); + state = 0; // normal + break; + case 3: // immediately after backslash in quoted string + current.append(c); + state = 1; // in quoted string + break; + } + } + if (current.length() > 0) { + result.add(current.toString()); + } + return result.toArray(new String[result.size()]); + } + + public String getAutoId(ClassDescriptor objectClass) { + if (options.getOptimize()) { + return "$" + Integer.toString(autogenID++, 36); + } else { + String name = objectClass.getName(); + name = name.substring(name.lastIndexOf(".") + 1); + return "$" + name + autogenID++; + } + } + + public String getUniqueId(Object object) { + String result = uniqueIds.get(object); + if (result == null) { + result = "$u" + uniqueIds.size(); + uniqueIds.put(object, result); + } + return result; + } + + public void setExtraInterfaces(String[] extraInterfaces) { + this.extraInterfaces = extraInterfaces; + } + + public String[] getExtraInterfaces() { + return extraInterfaces; + } + + public void addSimpleField(JavaField javaField) { + getJavaFile().addSimpleField(javaField); + } + + public JavaFile getJavaFile() { + if (javaFile == null) { + javaFile = new JavaFile(); + } + return javaFile; + } + + public void generateCode(Iterable<Generator> generatorIterator) throws IOException { + File dest; + if (getOptions().getTargetDirectory() != null) { + dest = new File(getOptions().getTargetDirectory(), getOutputClassName().replace('.', File.separatorChar) + ".java"); + } else { + dest = new File(getBaseDir(), getOutputClassName().substring(getOutputClassName().lastIndexOf(".") + 1) + ".java"); + } + if (dest.exists() && !dest.setLastModified(System.currentTimeMillis())) { + log.warn("could not touch file " + dest); + } + try { + PrintWriter out = new PrintWriter(new FileWriter(dest)); + int dotPos = getOutputClassName().lastIndexOf("."); + String packageName = dotPos != -1 ? getOutputClassName().substring(0, dotPos) : null; + String simpleClassName = getOutputClassName().substring(dotPos + 1); + CompiledObject compiledObject = getRootObject(); + for (Generator generator : generatorIterator) { + generator.finalizeCompiler(compiledObject, this, javaFile, packageName, simpleClassName); + } + + for (CompiledObject object : getObjects().values()) { + object.finalizeCompiler(); + } + + for (Generator generator : generatorIterator) { + generator.prepareJavaFile(compiledObject, this, javaFile, packageName, simpleClassName); + } + out.println(javaFile.toString(getLineSeparator())); + out.close(); + } catch (RuntimeException e) { + // file could not be generated, so delete it... + if (!dest.delete()) { + log.warn("could not delete file " + dest); + } + throw e; + } catch (ClassNotFoundException e) { + // file could not be generated, so delete it... + if (!dest.delete()) { + log.warn("could not delete file " + dest); + } + throw new CompilerException(e); + } + } + + /** + * Returns the system line separator string. + * + * @return the string used to separate lines + */ + public static String getLineSeparator() { + return System.getProperty("line.separator", "\n"); + } + + /** + * Compiled a set of files, with the class names specified explicitly. The class compiled from files[i] will be named classNames[i]. + * Returns <code>true</code> if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to + * <code>System.err</code>. + * + * @param files the .jaxx files to compile + * @param classNames the names of the classes being compiled + * @param options the compiler options to use + * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + */ + /*public static synchronized boolean compile(File[] files, String[] classNames, CompilerOptions options) { + reset(); // just to be safe... + jaxxFiles.addAll(Arrays.asList(files)); + jaxxFileClassNames.addAll(Arrays.asList(classNames)); + try { + boolean success = true; + + // pass 1 + currentPass = PASS_1; + boolean compiled; + do { + compiled = false; + assert jaxxFiles.size() == jaxxFileClassNames.size(); + java.util.Iterator<File> filesIterator = new ArrayList<File>(jaxxFiles).iterator(); // clone it so it can safely be modified while we're iterating + java.util.Iterator<String> classNamesIterator = new ArrayList<String>(jaxxFileClassNames).iterator(); + while (filesIterator.hasNext()) { + File file = filesIterator.next(); + String className = classNamesIterator.next(); + if (options.isVerbose()) { + log.info("compile first pass for " + className); + } + if (symbolTables.get(file) == null) { + compiled = true; + if (compilers.containsKey(className)) { + throw new CompilerException("Internal error: " + className + " is already being compiled, attempting to compile it again"); + } + + File destDir = options.getTargetDirectory(); + if (destDir != null) { + int dotPos = className.lastIndexOf("."); + if (dotPos != -1) { + destDir = new File(destDir, className.substring(0, dotPos).replace('.', File.separatorChar)); + } + if (!destDir.exists() && !destDir.mkdirs()) { + log.warn("could not create directory " + destDir); + continue; + } + } else { + //destDir = file.getParentFile(); + } + Compiler compiler = new JAXXCompiler(file.getParentFile(), file, className, options); + compilers.put(className, compiler); + compiler.compileFirstPass(); + assert !symbolTables.values().contains(compiler.getSymbolTable()) : "symbolTable is already registered"; + symbolTables.put(file, compiler.getSymbolTable()); + if (compiler.isFailed()) { + success = false; + } + } + } + + } while (compiled); + + // pass 2 + currentPass = PASS_2; + if (success) { + assert jaxxFiles.size() == jaxxFileClassNames.size(); + List<File> jaxxFilesClone = new ArrayList<File>(jaxxFiles); + for (String className : jaxxFileClassNames) { + Compiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during second pass"); + } + if (options.isVerbose()) { + + log.info("runInitializers for " + className); + } + if (!compiler.isFailed()) { + compiler.runInitializers(); + } + if (options.isVerbose()) { + + log.info("compile second pass for " + className); + } + compiler.compileSecondPass(); + if (options.isVerbose()) { + + log.info("done with result [" + !compiler.isFailed() + "] for " + className); + } + if (!compiler.isFailed()) { + + } else { + success = false; + } + } + if (!jaxxFilesClone.equals(jaxxFiles)) { + throw new AssertionError("Internal error: compilation set altered during pass 2 (was " + jaxxFilesClone + ", modified to " + jaxxFiles + ")"); + } + } + + // stylesheet application + if (success) { + assert jaxxFiles.size() == jaxxFileClassNames.size(); + for (String className : jaxxFileClassNames) { + Compiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during stylesheet application"); + } + compiler.applyStylesheets(); + if (compiler.isFailed()) { + success = false; + } + } + } + + // code generation + if (success) { + assert jaxxFiles.size() == jaxxFileClassNames.size(); + List<Generator> generators = new ArrayList<Generator>(); + for (Generator generator : ServiceLoader.load(Generator.class)) { + generators.add(generator); + } + for (String className : jaxxFileClassNames) { + Compiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during code generation"); + } + compiler.generateCode(generators); + //compiler.generateCode(); + if (compiler.isFailed()) { + success = false; + } + } + } + + if (warningCount == 1) { + System.err.println("1 warning"); + } else if (warningCount > 0) { + System.err.println(warningCount + " warnings"); + } + if (errorCount == 1) { + System.err.println("1 error"); + } else if (errorCount > 0) { + System.err.println(errorCount + " errors"); + } + return success; + } + catch (CompilerException e) { + System.err.println(e.getMessage()); + e.printStackTrace(); + return false; + } + catch (Throwable e) { + e.printStackTrace(); + return false; + } + finally { + //TC - 20081018 only reset when no error was detected + if (options.isResetAfterCompile() && errorCount == 0) { + reset(); + } + } + }*/ + + // 1.5 adds getCanonicalName; unfortunately we can't depend on 1.5 features yet + public static String getCanonicalName(Class clazz) { + if (clazz.isArray()) { + String canonicalName = getCanonicalName(clazz.getComponentType()); + if (canonicalName != null) { + return canonicalName + "[]"; + } + return null; + } + return clazz.getName().replace('$', '.'); + } + + public static String getCanonicalName(ClassDescriptor clazz) { + if (clazz.isArray()) { + String canonicalName = getCanonicalName(clazz.getComponentType()); + if (canonicalName != null) { + return canonicalName + "[]"; + } + return null; + } + return clazz.getName().replace('$', '.'); + } + + public static String getCanonicalName(CompiledObject compiled) { + ClassDescriptor clazz = compiled.getObjectClass(); + if (clazz.isArray()) { + String canonicalName = getCanonicalName(clazz.getComponentType()); + if (canonicalName != null) { + if (compiled.getGenericTypes().length > 0) { + canonicalName += "<"; + for (int i = 0; i < compiled.getGenericTypes().length; i++) { + ClassDescriptor classDescriptor = compiled.getGenericTypes()[i]; + if (i > 0) { + canonicalName += " ,"; + } + canonicalName += classDescriptor.getName(); + } + canonicalName += ">"; + } + return canonicalName + "[]"; + } + return null; + } + + String canonicalName = clazz.getName().replace('$', '.'); + if (compiled.getGenericTypes().length > 0) { + canonicalName += "<"; + for (int i = 0; i < compiled.getGenericTypes().length; i++) { + ClassDescriptor classDescriptor = compiled.getGenericTypes()[i]; + if (i > 0) { + canonicalName += " ,"; + } + canonicalName += classDescriptor.getName(); + } + canonicalName += ">"; + } + return canonicalName; + } + + /** + * Escapes a string using standard Java escape sequences, generally in preparation to including it in a string literal + * in a compiled Java file. + * + * @param raw the raw string to be escape + * @return a string in which all 'dangerous' characters have been replaced by equivalent Java escape sequences + */ + public static String escapeJavaString(String raw) { + StringBuffer out = new StringBuffer(raw); + for (int i = 0; i < out.length(); i++) { + char c = out.charAt(i); + if (c == '\\' || c == '"') { + out.insert(i, '\\'); + i++; + } else if (c == '\n') { + out.replace(i, i + 1, "\\n"); + i++; + } else if (c == '\r') { + out.replace(i, i + 1, "\\r"); + i++; + } else if (c < 32 || c > 127) { + String value = Integer.toString((int) c, 16); + while (value.length() < 4) { + value = "0" + value; + } + out.replace(i, i + 1, "\\u" + value); + i += 5; + } + } + return out.toString(); + } + + public static File URLtoFile(URL url) { + return URLtoFile(url.toString()); + } + + public static File URLtoFile(String urlString) { + if (!urlString.startsWith("file:")) { + throw new IllegalArgumentException("url must start with 'file:'"); + } + urlString = urlString.substring("file:".length()); + if (urlString.startsWith("/") && System.getProperty("os.name").startsWith("Windows")) { + urlString = urlString.substring(1); + } + try { + return new File(URLDecoder.decode(urlString.replace('/', File.separatorChar), "utf-8")); + } + catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + + public static SAXParser getSAXParser() { + try { + SAXParserFactory factory = SAXParserFactory.newInstance(); + factory.setNamespaceAware(true); + SAXParser parser; + parser = factory.newSAXParser(); + return parser; + } + catch (SAXException e) { + throw new RuntimeException(e); + } + catch (ParserConfigurationException e) { + throw new RuntimeException(e); + } + } + + public static Document parseDocument(InputStream in) throws IOException, SAXException { + try { + TransformerFactory factory = TransformerFactory.newInstance(); + Transformer transformer = factory.newTransformer(); + transformer.setErrorListener(new ErrorListener() { + public void warning(TransformerException ex) throws TransformerException { + throw ex; + } + + public void error(TransformerException ex) throws TransformerException { + throw ex; + } + + public void fatalError(TransformerException ex) throws TransformerException { + throw ex; + } + }); + + DOMResult result = new DOMResult(); + transformer.transform(new SAXSource(new XMLFilterImpl(getSAXParser().getXMLReader()) { + Locator locator; + + @Override + public void setDocumentLocator(Locator locator) { + this.locator = locator; + } + + @Override + public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException { + AttributesImpl resultAtts = new AttributesImpl(atts); + resultAtts.addAttribute(JAXX_INTERNAL_NAMESPACE, "line", "internal:line", "CDATA", String.valueOf(locator.getLineNumber())); + getContentHandler().startElement(uri, localName, qName, resultAtts); + } + }, new InputSource(in)), result); + return (Document) result.getNode(); + } + catch (TransformerConfigurationException e) { + throw new RuntimeException(e); + } + catch (TransformerException e) { + Throwable ex = e; + while (ex.getCause() != null) { + ex = ex.getCause(); + } + if (ex instanceof IOException) { + throw (IOException) ex; + } + if (ex instanceof SAXException) { + throw (SAXException) ex; + } + if (ex instanceof RuntimeException) { + throw (RuntimeException) ex; + } + throw new RuntimeException(ex); + } + } +} Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXCompilerLaunchor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,479 @@ +package jaxx.compiler; + +import jaxx.CompilerException; +import jaxx.spi.Initializer; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultObjectHandler; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.File; +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; + +/** @author chemit */ +public class JAXXCompilerLaunchor { + + + /** log */ + protected static final Log log = LogFactory.getLog(JAXXCompilerLaunchor.class); + + protected static final int PASS_1 = 0; + + protected static final int PASS_2 = 1; + protected static JAXXCompilerLaunchor singleton; + + protected CompilerOptions options; + + protected final File[] files; + protected final String[] classNames; + + public JAXXCompilerLaunchor(File base, String[] relativePaths, CompilerOptions options) { + this.options = options; + files = new File[relativePaths.length]; + classNames = new String[relativePaths.length]; + for (int i = 0; i < files.length; i++) { + files[i] = new File(base, relativePaths[i]); + classNames[i] = relativePaths[i].substring(0, relativePaths[i].lastIndexOf(".")); + classNames[i] = classNames[i].replace(File.separatorChar, '.'); + classNames[i] = classNames[i].replace('/', '.'); + classNames[i] = classNames[i].replace('\\', '.'); + classNames[i] = classNames[i].replace(':', '.'); + } + if (options.isVerbose()) { + log.info("files : " + Arrays.toString(files)); + } + } + + public JAXXCompilerLaunchor(File[] files, String[] classNames, CompilerOptions options) { + this.options = options; + this.files = files; + this.classNames = classNames; + if (options.isVerbose()) { + log.info("files : " + Arrays.toString(files)); + } + } + + public JAXXCompilerLaunchor() { + this.options = new CompilerOptions(); + files = null; + classNames = null; + } + + /** + * Compiled a set of files, expressed as paths relative to a base directory. The class names of the compiled files are derived + * from the relative path strings (e.g. "example/Foo.jaxx" compiles into a class named "example.Foo"). Returns <code>true</code> + * if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to <code>System.err</code>. + * + * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + */ + public static JAXXCompilerLaunchor newLaunchor() { + if (singleton != null) { + //singleton.reset(); + } + singleton = new JAXXCompilerLaunchor(); + + return singleton; + } + + /** + * Compiled a set of files, expressed as paths relative to a base directory. The class names of the compiled files are derived + * from the relative path strings (e.g. "example/Foo.jaxx" compiles into a class named "example.Foo"). Returns <code>true</code> + * if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to <code>System.err</code>. + * + * @param base the directory against which to resolve relative paths + * @param relativePaths a list of relative paths to .jaxx files being compiled + * @param options the compiler options to use + * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + */ + public static JAXXCompilerLaunchor newLaunchor(File base, String[] relativePaths, CompilerOptions options) { + if (singleton != null) { + //singleton.reset(); + } + singleton = new JAXXCompilerLaunchor(base, relativePaths, options); + + return singleton; + } + + /** + * Compiled a set of files, with the class names specified explicitly. The class compiled from files[i] will be named classNames[i]. + * Returns <code>true</code> if compilation succeeds, <code>false</code> if it fails. Warning and error messages are sent to + * <code>System.err</code>. + * + * @param files the .jaxx files to compile + * @param classNames the names of the classes being compiled + * @param options the compiler options to use + * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + */ + public static JAXXCompilerLaunchor newLaunchor(File[] files, String[] classNames, CompilerOptions options) { + if (singleton != null) { + //singleton.reset(); + } + singleton = new JAXXCompilerLaunchor(files, classNames, options); + return singleton; + } + + public static JAXXCompilerLaunchor get() { + if (singleton == null) { + throw new NullPointerException("no launchor was registred via newLaunchor method"); + } + return singleton; + } + + public static boolean isRegistred() { + return singleton != null; + } + + protected List<File> jaxxFiles = new ArrayList<File>(); + + /** Class names corresponding to the files in the jaxxFiles list. */ + protected List<String> jaxxFileClassNames = new ArrayList<String>(); + + /** Maps the names of classes being compiled to the compiler instance handling the compilation. */ + protected Map<String, JAXXCompiler> compilers = new HashMap<String, JAXXCompiler>(); + + /** Maps the names of classes being compiled to their symbol tables (created after the first compiler pass). */ + protected Map<File, SymbolTable> symbolTables = new HashMap<File, SymbolTable>(); + + protected int currentPass; + + protected int errorCount; + protected int warningCount; + + public static void loadLibraries(boolean verbose) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { + //BeanInfoUtil.reset(); + ClassLoader classloader = Thread.currentThread().getContextClassLoader(); + if (verbose) { + log.info("with cl " + classloader); + } + ServiceLoader<Initializer> loader = ServiceLoader.load(Initializer.class, classloader); + for (Initializer initializer : loader) { + if (verbose) { + log.info("load initializer " + initializer); + } + initializer.initialize(); + } + } + + public void init() { + // forces static initializer to run if it hasn't yet + } + + /** Resets all state in preparation for a new compilation session. */ + protected void reset() { + log.info("do reset!!!!!!!!!!!!"); + errorCount = warningCount = 0; + jaxxFiles.clear(); + jaxxFileClassNames.clear(); + symbolTables.clear(); + compilers.clear(); + } + public String getVersion() { + return "1.0.4"; + } + + /** + * Creates a dummy Compiler for use in unit testing. + * + * @return the compiler + */ + public static JAXXCompiler createDummyCompiler() { + return createDummyCompiler(JAXXCompiler.class.getClassLoader()); + } + + /** + * Creates a dummy Compiler for use in unit testing. + * + * @param classLoader class loader to use + * @return the compiler + */ + public static JAXXCompiler createDummyCompiler(ClassLoader classLoader) { + return new JAXXCompiler(classLoader, new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(Object.class))) { + }; + } + + /** + * @param className the name of the class to use + * @return the compiler instance which is processing the specified JAXX class. Each class is compiled by a + * different compiler instance. + */ + public JAXXCompiler getJAXXCompiler(String className) { + return compilers != null ? compilers.get(className) : null; + } + + /** + * @param className the name of the class to use + * @return the symbol table for the specified JAXX class. Must be called during the second compiler pass. + * Returns <code>null</code> if no such symbol table could be found. + */ + public SymbolTable getSymbolTable(String className) { + JAXXCompiler compiler = getJAXXCompiler(className); + if (compiler == null) { + return null; + } + return compiler.getSymbolTable(); + } + + /** + * Returns the system line separator string. + * + * @return the string used to separate lines + */ + public String getLineSeparator() { + return System.getProperty("line.separator", "\n"); + } + + /** + * Compiled a set of files. + * + * @return <code>true</code> if compilation succeeds, <code>false</code> otherwise + */ + public synchronized boolean compile() { + //reset(); // just to be safe... + jaxxFiles.addAll(Arrays.asList(files)); + jaxxFileClassNames.addAll(Arrays.asList(classNames)); + try { + boolean success = true; + + // pass 1 + currentPass = PASS_1; + boolean compiled; + do { + compiled = false; + assert jaxxFiles.size() == jaxxFileClassNames.size(); + java.util.Iterator<File> filesIterator = new ArrayList<File>(jaxxFiles).iterator(); // clone it so it can safely be modified while we're iterating + java.util.Iterator<String> classNamesIterator = new ArrayList<String>(jaxxFileClassNames).iterator(); + while (filesIterator.hasNext()) { + File file = filesIterator.next(); + String className = classNamesIterator.next(); + if (options.isVerbose()) { + log.info("compile first pass for " + className); + } + if (symbolTables.get(file) == null) { + compiled = true; + if (compilers.containsKey(className)) { + throw new CompilerException("Internal error: " + className + " is already being compiled, attempting to compile it again"); + } + + File destDir = options.getTargetDirectory(); + if (destDir != null) { + int dotPos = className.lastIndexOf("."); + if (dotPos != -1) { + destDir = new File(destDir, className.substring(0, dotPos).replace('.', File.separatorChar)); + } + if (!destDir.exists() && !destDir.mkdirs()) { + log.warn("could not create directory " + destDir); + continue; + } + } else { + //destDir = file.getParentFile(); + } + JAXXCompiler compiler = newCompiler(file.getParentFile(), file, className); + compilers.put(className, compiler); + compiler.compileFirstPass(); + assert !symbolTables.values().contains(compiler.getSymbolTable()) : "symbolTable is already registered"; + symbolTables.put(file, compiler.getSymbolTable()); + if (compiler.isFailed()) { + success = false; + } + } + } + + } while (compiled); + + // pass 2 + currentPass = PASS_2; + if (success) { + assert jaxxFiles.size() == jaxxFileClassNames.size(); + List<File> jaxxFilesClone = new ArrayList<File>(jaxxFiles); + for (String className : jaxxFileClassNames) { + JAXXCompiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during second pass"); + } + if (options.isVerbose()) { + + log.info("runInitializers for " + className); + } + if (!compiler.isFailed()) { + compiler.runInitializers(); + } + if (options.isVerbose()) { + + log.info("compile second pass for " + className); + } + compiler.compileSecondPass(); + if (options.isVerbose()) { + + log.info("done with result [" + !compiler.isFailed() + "] for " + className); + } + if (!compiler.isFailed()) { + + } else { + success = false; + } + } + if (!jaxxFilesClone.equals(jaxxFiles)) { + throw new AssertionError("Internal error: compilation set altered during pass 2 (was " + jaxxFilesClone + ", modified to " + jaxxFiles + ")"); + } + } + + // stylesheet application + if (success) { + assert jaxxFiles.size() == jaxxFileClassNames.size(); + for (String className : jaxxFileClassNames) { + JAXXCompiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during stylesheet application"); + } + compiler.applyStylesheets(); + if (compiler.isFailed()) { + success = false; + } + } + } + + // code generation + if (success) { + assert jaxxFiles.size() == jaxxFileClassNames.size(); + List<Generator> generators = new ArrayList<Generator>(); + for (Generator generator : ServiceLoader.load(Generator.class)) { + generators.add(generator); + } + for (String className : jaxxFileClassNames) { + JAXXCompiler compiler = compilers.get(className); + if (compiler == null) { + throw new CompilerException("Internal error: could not find compiler for " + className + " during code generation"); + } + compiler.generateCode(generators); + //compiler.generateCode(); + if (compiler.isFailed()) { + success = false; + } + } + } + + if (warningCount == 1) { + System.err.println("1 warning"); + } else if (warningCount > 0) { + System.err.println(warningCount + " warnings"); + } + if (errorCount == 1) { + System.err.println("1 error"); + } else if (errorCount > 0) { + System.err.println(errorCount + " errors"); + } + return success; + } + catch (CompilerException e) { + System.err.println(e.getMessage()); + e.printStackTrace(); + return false; + } + catch (Throwable e) { + e.printStackTrace(); + return false; + } + finally { + //TC - 20081018 only reset when no error was detected + if (options.isResetAfterCompile() && errorCount == 0) { + //reset(); + } + } + } + + protected JAXXCompiler newCompiler(File parentFile, File file, String className) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + Constructor<? extends JAXXCompiler> cons = options.getCompilerClass().getConstructor(File.class, File.class, String.class, CompilerOptions.class); + return cons.newInstance(parentFile, file, className, options); + } + + + protected static void showUsage() { + System.out.println("Usage: jaxxc <options> <source files>"); + System.out.println(); + System.out.println("Source files must end in extension .jaxx"); + System.out.println("Use JAXX_OPTS environment variable to pass arguments to Java runtime"); + System.out.println(); + System.out.println("Supported options include:"); + System.out.println(" -classpath <paths> paths to search for user classes"); + System.out.println(" -cp <paths> same as -classpath"); + System.out.println(" -d <directory> target directory for generated class files"); + System.out.println(" -java or -j produce .java files, but do not compile them"); + System.out.println(" -keep or -k preserve generated .java files after compilation"); + System.out.println(" -optimize or -o optimize during compilation"); + System.out.println(" -version display version information"); + System.out.println(); + System.out.println("See http://www.jaxxframework.org/ for full documentation."); + } + + public static void main(String[] arg) throws Exception { + //todo make this works again + /*boolean success = true; + + CompilerOptions options = new CompilerOptions(); + List<String> files = new ArrayList<String>(); + for (int i = 0; i < arg.length; i++) { + if (arg[i].endsWith(".jaxx")) { + files.add(arg[i]); + } else if (arg[i].equals("-d")) { + if (++i < arg.length) { + File targetDirectory = new File(arg[i]); + if (!targetDirectory.exists()) { + System.err.println("Error: could not find target directory: " + targetDirectory); + errorCount++; + success = false; + } + options.setTargetDirectory(targetDirectory); + } else { + success = false; + } + } else if (arg[i].equals("-cp") || arg[i].equals("-classpath")) { + if (++i < arg.length) { + options.setClassPath(arg[i]); + } else { + success = false; + } + } else if (arg[i].equals("-javac_opts")) { + if (++i < arg.length) { + options.setJavacOpts(arg[i]); + } else { + success = false; + } + } else if (arg[i].equals("-k") || arg[i].equals("-keep")) { + options.setKeepJavaFiles(true); + } else if (arg[i].equals("-j") || arg[i].equals("-java")) { + options.setKeepJavaFiles(true); + } else if (arg[i].equals("-o") || arg[i].equals("-optimize")) { + options.setOptimize(true); + } else if (arg[i].equals("-version")) { + System.err.println("jaxxc version " + getVersion() + " by Ethan Nicholas"); + System.err.println("http://www.jaxxframework.org/"); + System.exit(0); + } else if (arg[i].equals("-internalDumpVersion")) { // used by ant to extract the version info + System.out.println("jaxx.version=" + getVersion()); + return; + } else { + success = false; + } + } + + success &= (errorCount == 0 && files.size() > 0); + + if (success) { + success = compile(new File("."), files.toArray(new String[files.size()]), options); + } else { + showUsage(); + System.exit(1); + } + + System.exit(success ? 0 : 1);*/ + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXObjectGenerator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXObjectGenerator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JAXXObjectGenerator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,592 @@ +package jaxx.compiler; + +import jaxx.Base64Coder; +import jaxx.CompilerException; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.MethodDescriptor; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.JAXXObjectDescriptor; +import jaxx.types.TypeManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.IOException; +import java.lang.reflect.Modifier; +import static java.lang.reflect.Modifier.FINAL; +import static java.lang.reflect.Modifier.PROTECTED; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/** + * This class is a refactoring of the {@link jaxx.compiler.JAXXCompiler}. + * <p/> + * We delegate now the generation of a {@link jaxx.runtime.JAXXObject} to this class, the + * {@link jaxx.compiler.JAXXCompiler} now only deals with the compilation of files. + * + * @author chemit + */ +public class JAXXObjectGenerator implements Generator { + + /** log */ + protected static final Log log = LogFactory.getLog(JAXXObjectGenerator.class); + + protected static final JavaField ACTIVE_BINDINGS_FIELD = JavaField.newField(PROTECTED, + "java.util.List<Object>", "$activeBindings", "new ArrayList<Object>()" + ); + protected static final JavaField BINDING_SOURCES_FIELD = JavaField.newField(PROTECTED, + "java.util.Map<String,Object>", "$bindingSources", "new HashMap<String,Object>()" + ); + protected static final JavaField OBJECT_MAP_FIELD = JavaField.newField(PROTECTED, + "Map<String,Object>", "$objectMap", "new HashMap<String,Object>()" + ); + protected static final JavaField ALL_COMPONENTS_CREATED_FIELD = JavaField.newField(java.lang.reflect.Modifier.PRIVATE, + "boolean", "allComponentsCreated" + ); + protected static final JavaField PREVIOUS_VALUES_FIELD = JavaField.newField(0, + "java.util.Map", "$previousValues", "new java.util.HashMap()" + ); + protected static final JavaField DELEGATE_CONTEXT_FIELD = JavaField.newField(PROTECTED, + "jaxx.runtime.JAXXContext", "delegateContext" + ); + protected static final JavaField PROPERTY_CHANGE_SUPPORT_FIELD = JavaField.newField(0, + "java.beans.PropertyChangeSupport", "$propertyChangeSupport" + ); + protected static final JavaMethod GET_CONTEXT_VALUE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> T", "getContextValue", + "return delegateContext.getContextValue(clazz, null);", + new JavaArgument("Class<T>", "clazz") + ); + protected static final JavaMethod GET_CONTEXT_VALUE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> T", "getContextValue", + "return delegateContext.getContextValue(clazz, name);", + new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name") + ); + protected static final JavaMethod SET_CONTEXT_VALUE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "setContextValue", + "delegateContext.setContextValue(o, name);", + new JavaArgument("T", "o"), new JavaArgument("String", "name") + ); + protected static final JavaMethod SET_CONTEXT_VALUE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "setContextValue", + "delegateContext.setContextValue(o, null);", + new JavaArgument("T", "o") + ); + protected static final JavaMethod REMOVE_CONTEXT_VALUE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "removeContextValue", + "delegateContext.removeContextValue(clazz, name);", + new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name") + ); + protected static final JavaMethod REMOVE_CONTEXT_VALUE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<T> void", "removeContextValue", + "delegateContext.removeContextValue(clazz, null);", + new JavaArgument("Class<T>", "clazz") + ); + protected static final JavaMethod GET_PARENT_CONTAINER_MORE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<O extends Container> O", "getParentContainer", + "return delegateContext.getParentContainer(source, clazz);", + new JavaArgument("Object", "source"), new JavaArgument("Class<O>", "clazz") + ); + protected static final JavaMethod GET_PARENT_CONTAINER_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "<O extends Container> O", "getParentContainer", + "return delegateContext.getParentContainer(clazz);", + new JavaArgument("Class<O>", "clazz") + ); + protected static final JavaMethod GET_OBJECT_BY_ID_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "java.lang.Object", "getObjectById", + "return $objectMap.get(id);", + new JavaArgument("String", "id") + ); + protected static final JavaMethod GET_JAXX_OBJECT_DESCRIPTOR_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC | java.lang.reflect.Modifier.STATIC, "jaxx.runtime.JAXXObjectDescriptor", "$getJAXXObjectDescriptor", + "return jaxx.runtime.Util.decodeCompressedJAXXObjectDescriptor($jaxxObjectDescriptor);" + ); + protected static final JavaMethod PROCESS_DATA_BINDING_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "processDataBinding", + "processDataBinding(dest, false);", + new JavaArgument("String", "dest") + ); + protected static final JavaMethod FIRE_PROPERTY_CHANGE_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "firePropertyChange", + "super.firePropertyChange(propertyName, oldValue, newValue);", + new JavaArgument("String", "propertyName"), new JavaArgument("Object", "oldValue"), new JavaArgument("Object", "newValue") + ); + protected static final JavaMethod FIRE_PROPERTY_CHANGE_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "firePropertyChange", + "$getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue);", + new JavaArgument("String", "propertyName"), new JavaArgument("Object", "oldValue"), new JavaArgument("Object", "newValue") + ); + protected static final JavaMethod GET_PROPERTY_CHANGE_SUPPORT_METHOD = JavaMethod.newMethod(0, "java.beans.PropertyChangeSupport", "$getPropertyChangeSupport", + "if ($propertyChangeSupport == null)\n" + + " $propertyChangeSupport = new PropertyChangeSupport(this);\n" + + "return $propertyChangeSupport;"); + protected static final JavaMethod ADD_PROPERTY_CHANGE_SUPPORT_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "addPropertyChangeListener", + "$getPropertyChangeSupport().addPropertyChangeListener(listener);", + new JavaArgument("java.beans.PropertyChangeListener", "listener") + ); + protected static final JavaMethod ADD_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "addPropertyChangeListener", + "$getPropertyChangeSupport().addPropertyChangeListener(property, listener);", + new JavaArgument("String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener") + ); + protected static final JavaMethod REMOVE_PROPERTY_CHANGE_SUPPORT_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "removePropertyChangeListener", + "$getPropertyChangeSupport().removePropertyChangeListener(listener);", + new JavaArgument("java.beans.PropertyChangeListener", "listener") + ); + protected static final JavaMethod REMOVE_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "void", "removePropertyChangeListener", + "$getPropertyChangeSupport().removePropertyChangeListener(property, listener);", + new JavaArgument("String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener") + ); + + @Override + public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { + + String fullClassName = packageName != null ? packageName + "." + className : className; + if (root == null) { + throw new CompilerException("root tag must be a class tag"); + } + //Map<String, CompiledObject> objects = compiler.getObjects(); + ClassDescriptor superclass = root.getObjectClass(); + boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(superclass); + javaFile.setModifiers(Modifier.PUBLIC); + javaFile.setClassName(fullClassName); + javaFile.setSuperClass(JAXXCompiler.getCanonicalName(superclass)); + javaFile.setSuperclassIsJAXXObject(superclassIsJAXXObject); + + // can have extra interfaces from compiler + if (compiler.getExtraInterfaces() != null) { + javaFile.addInterfaces(java.util.Arrays.asList(compiler.getExtraInterfaces())); + } + + for (CompiledObject object : compiler.getObjects().values()) { + if (!object.isOverride() && !(object instanceof ScriptInitializer)) { + String id = object.getId(); + int access = id.startsWith("$") ? Modifier.PRIVATE : Modifier.PROTECTED; + if (object == root) { + javaFile.addField(new JavaField(access, fullClassName, id, "this")); + } else { + //TC -20081017 can have generic on compiled Object + javaFile.addField(JavaField.newField(access, JAXXCompiler.getCanonicalName(object), id), object.isJavaBean()); + } + } + + if (!compiler.inlineCreation(object) && object != root) { + javaFile.addMethod(JavaMethod.newMethod(Modifier.PROTECTED, "void", object.getCreationMethodName(), getCreationCode(compiler, object))); + } + } + + // DataBinding + for (DataBinding dataBinding : compiler.getDataBindings()) { + if (dataBinding.compile(true)) { + compiler.getInitDataBindings().append("applyDataBinding(").append(TypeManager.getJavaCode(dataBinding.getId())).append(");").append(JAXXCompiler.getLineSeparator()); + } + } + + if (superclassIsJAXXObject) { + boolean hasBind = compiler.getApplyDataBinding().length() > 0; + if (hasBind) { + compiler.appendApplyDataBinding(" else {"); + compiler.appendApplyDataBinding(JAXXCompiler.getLineSeparator()); + compiler.appendApplyDataBinding(" "); + } + compiler.appendApplyDataBinding("super.applyDataBinding($binding);"); + compiler.appendApplyDataBinding(JAXXCompiler.getLineSeparator()); + + if (hasBind) { + compiler.appendApplyDataBinding(" return;"); + compiler.appendApplyDataBinding(JAXXCompiler.getLineSeparator()); + compiler.appendApplyDataBinding("}"); + } + + + hasBind = compiler.getRemoveDataBinding().length() > 0; + if (hasBind) { + compiler.appendRemoveDataBinding(" else {"); + compiler.appendRemoveDataBinding(JAXXCompiler.getLineSeparator()); + compiler.appendRemoveDataBinding(" "); + } + compiler.appendRemoveDataBinding("super.removeDataBinding($binding);"); + compiler.appendRemoveDataBinding(JAXXCompiler.getLineSeparator()); + + if (hasBind) { + compiler.appendRemoveDataBinding("}"); + } + } else { + javaFile.addInterface(JAXXCompiler.getCanonicalName(JAXXObject.class)); + } + } + + @Override + public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { + + String fullClassName = javaFile.getClassName(); + + String jaxxContextImplementorClass = compiler.getOptions().getJaxxContextImplementorClass(); + boolean superclassIsJAXXObject = javaFile.isSuperclassIsJAXXObject(); + if (!superclassIsJAXXObject) { + // add logger + if (compiler.getOptions().isAddLogger()) { + javaFile.addImport(Log.class); + javaFile.addImport(LogFactory.class); + javaFile.addField(JavaField.newField(Modifier.PUBLIC + Modifier.STATIC + FINAL, "Log", "log", "LogFactory.getLog(" + fullClassName + ".class)")); + } + + // JAXXObject + javaFile.addField(OBJECT_MAP_FIELD); + javaFile.addMethod(GET_OBJECT_BY_ID_METHOD); + javaFile.addField(BINDING_SOURCES_FIELD); + javaFile.addField(ACTIVE_BINDINGS_FIELD); + + // JAXXContext + javaFile.addField(JavaField.newField(PROTECTED | FINAL, JAXXContext.class.getName(), "delegateContext", "new " + jaxxContextImplementorClass + "(this);")); + javaFile.addMethod(SET_CONTEXT_VALUE_METHOD); + javaFile.addMethod(SET_CONTEXT_VALUE_NAMED_METHOD); + javaFile.addMethod(GET_CONTEXT_VALUE_METHOD); + javaFile.addMethod(GET_CONTEXT_VALUE_NAMED_METHOD); + javaFile.addMethod(REMOVE_CONTEXT_VALUE_METHOD); + javaFile.addMethod(REMOVE_CONTEXT_VALUE_NAMED_METHOD); + javaFile.addMethod(GET_PARENT_CONTAINER_METHOD); + javaFile.addMethod(GET_PARENT_CONTAINER_MORE_METHOD); + + // PropertyChangeSupport + addPropertyChangeSupport(root, javaFile); + + // DataBinding + javaFile.addMethod(PROCESS_DATA_BINDING_METHOD); + } + + javaFile.addField(ALL_COMPONENTS_CREATED_FIELD); + javaFile.addField(createJAXXObjectDescriptorField(compiler, javaFile)); + + if (compiler.getStylesheet() != null) { + javaFile.addField(PREVIOUS_VALUES_FIELD); + } + + /*for (CompiledObject object : compiler.getObjects().values()) { + List<CompiledObject.ChildRef> refList = object.getChilds(); + if (refList==null || refList.isEmpty()) { + continue; + } + for (ChildRef childRef : refList) { + childRef.addToAdditionCode(buffer); + } + }*/ + javaFile.addMethod(createConstructor(compiler, className, superclassIsJAXXObject)); + javaFile.addMethod(createConstructorWithInitialContext(compiler, className, superclassIsJAXXObject)); + + javaFile.addMethod(createInitializer(compiler)); + javaFile.addMethod(GET_JAXX_OBJECT_DESCRIPTOR_METHOD); + + javaFile.addBodyCode(compiler.getBodyCode().toString()); + + javaFile.addMethod(createCompleteSetupMethod(compiler, javaFile, compiler.getInitDataBindings())); + + + javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "applyDataBinding", + compiler.getApplyDataBinding().toString() + JAXXCompiler.getLineSeparator() + "processDataBinding($binding);", + new JavaArgument("String", "$binding")) + ); + + javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", "removeDataBinding", + compiler.getRemoveDataBinding().toString(), new JavaArgument("String", "$binding")) + ); + + javaFile.addMethod(createProcessDataBindingMethod(compiler, superclassIsJAXXObject)); + + addEventHandlers(compiler, javaFile); + + /*//TODO : move this to jaxx-compiler-swing generator + if (ClassDescriptorLoader.getClassDescriptor("jaxx.runtime.swing.Application").isAssignableFrom(root.getObjectClass()) && !compiler.isMainDeclared()) { + // TODO: check for existing main method first + javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC | Modifier.STATIC, "void", "main", + "SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });", + new JavaArgument("String[]", "arg")) + ); + }*/ + + } + + + /*---------------------------------------------------------------------------------*/ + /*-- Create fields ----------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + protected JavaField createJAXXObjectDescriptorField(JAXXCompiler compiler, JavaFile javaFile) { + try { + JAXXObjectDescriptor descriptor = compiler.getJAXXObjectDescriptor(); + String data = Base64Coder.serialize(descriptor, true); + /*ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + ObjectOutputStream out = new ObjectOutputStream(new GZIPOutputStream(buffer)); + out.writeObject(descriptor); + out.close(); + // the use of the weird deprecated constructor is deliberate -- we need to store the data as a String + // in the compiled class file, since byte array initialization is horribly inefficient compared to + // String initialization. So we store the bytes in the String, and we quite explicitly want a 1:1 + // mapping between bytes and chars, with the high byte of the char set to zero. We can then safely + // reconstitute the original byte[] at a later date. This is unquestionably an abuse of the String + // type, but if we could efficiently store a byte[] we wouldn't have to do this. + String data = new String(buffer.toByteArray(), 0);*/ + + int sizeLimit = 65000; // constant strings are limited to 64K, and I'm not brave enough to push right up to the limit + if (data.length() < sizeLimit) { + return JavaField.newField(Modifier.PRIVATE | Modifier.STATIC, "java.lang.String", "$jaxxObjectDescriptor", TypeManager.getJavaCode(data)); + } else { + StringBuffer initializer = new StringBuffer(); + for (int i = 0; i < data.length(); i += sizeLimit) { + String name = "$jaxxObjectDescriptor" + i; + javaFile.addField(new JavaField(Modifier.PRIVATE | Modifier.STATIC, "java.lang.String", name, + TypeManager.getJavaCode(data.substring(i, Math.min(i + sizeLimit, data.length()))))); + if (initializer.length() > 0) { + initializer.append(" + "); + } + initializer.append("String.valueOf(").append(name).append(")"); + } + return JavaField.newField(Modifier.PRIVATE | Modifier.STATIC, "java.lang.String", "$jaxxObjectDescriptor", initializer.toString()); + } + } catch (IOException e) { + throw new RuntimeException("Internal error: can't-happen error", e); + } + } + + /*---------------------------------------------------------------------------------*/ + /*-- Create methods ---------------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + protected void addPropertyChangeSupport(CompiledObject root, JavaFile javaFile) { + ClassDescriptor currentClass = root.getObjectClass(); + MethodDescriptor firePropertyChange = null; + while (firePropertyChange == null && currentClass != null) { + try { + firePropertyChange = currentClass.getDeclaredMethodDescriptor("firePropertyChange", ClassDescriptorLoader.getClassDescriptor(String.class), + ClassDescriptorLoader.getClassDescriptor(Object.class), + ClassDescriptorLoader.getClassDescriptor(Object.class)); + + } + catch (NoSuchMethodException e) { + currentClass = currentClass.getSuperclass(); + } + } + + int modifiers = firePropertyChange != null ? firePropertyChange.getModifiers() : 0; + if (Modifier.isPublic(modifiers)) { + // we have all the support we need + } + if (Modifier.isProtected(modifiers)) { + // there is property change support but the firePropertyChange method is protected + javaFile.addMethod(FIRE_PROPERTY_CHANGE_METHOD); + } else { + // either no support at all or firePropertyChange isn't accessible + javaFile.addField(PROPERTY_CHANGE_SUPPORT_FIELD); + javaFile.addMethod(GET_PROPERTY_CHANGE_SUPPORT_METHOD); + javaFile.addMethod(ADD_PROPERTY_CHANGE_SUPPORT_METHOD); + javaFile.addMethod(ADD_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD); + javaFile.addMethod(REMOVE_PROPERTY_CHANGE_SUPPORT_METHOD); + javaFile.addMethod(REMOVE_PROPERTY_CHANGE_SUPPORT_NAMED_METHOD); + javaFile.addMethod(FIRE_PROPERTY_CHANGE_NAMED_METHOD); + } + } + + protected void addEventHandlers(JAXXCompiler compiler, JavaFile javaFile) { + for (Map.Entry<String, Map<ClassDescriptor, List<EventHandler>>> e1 : compiler.getEventHandlers().entrySet()) { + // outer loop is iterating over different objects (well, technically, different Java expressions) + for (Map.Entry<ClassDescriptor, List<EventHandler>> e2 : e1.getValue().entrySet()) { + // iterate over different types of listeners for this particular object (MouseListener, ComponentListener, etc.) + for (EventHandler handler : e2.getValue()) { + // iterate over individual event handlers of a single type + String methodName = compiler.getEventHandlerMethodName(handler); + MethodDescriptor listenerMethod = handler.getListenerMethod(); + if (listenerMethod.getParameterTypes().length != 1) { + throw new CompilerException("Expected event handler " + listenerMethod.getName() + " of class " + handler.getListenerClass() + " to have exactly one argument"); + } + javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC, "void", methodName, handler.getJavaCode(), + new JavaArgument(JAXXCompiler.getCanonicalName(listenerMethod.getParameterTypes()[0]), "event"))); + } + } + } + } + + protected JavaMethod createConstructor(JAXXCompiler compiler, String className, boolean superclassIsJAXXObject) throws CompilerException { + StringBuffer code = new StringBuffer(); + String constructorParams = compiler.getRootObject().getConstructorParams(); + if (constructorParams != null) { + code.append(" super(").append(constructorParams).append(");").append(JAXXCompiler.getLineSeparator()); + } else { + if (superclassIsJAXXObject) { + code.append(" super();").append(JAXXCompiler.getLineSeparator()); + } + } + code.append("$initialize();"); + code.append(JAXXCompiler.getLineSeparator()); + return JavaMethod.newMethod(Modifier.PUBLIC, null, className, code.toString()); + } + + protected JavaMethod createConstructorWithInitialContext(JAXXCompiler compiler, String className, boolean superclassIsJAXXObject) throws CompilerException { + StringBuffer code = new StringBuffer(); + String constructorParams = compiler.getRootObject().getConstructorParams(); + if (constructorParams != null) { + code.append(" super(").append(constructorParams).append(");").append(JAXXCompiler.getLineSeparator()); + } else { + if (superclassIsJAXXObject) { + code.append(" super(parentContext);").append(JAXXCompiler.getLineSeparator()); + } + } + if (!superclassIsJAXXObject) { + code.append("if (parentContext instanceof jaxx.runtime.JAXXInitialContext) {"); + code.append(JAXXCompiler.getLineSeparator()); + code.append(" ((jaxx.runtime.JAXXInitialContext)parentContext).to(this);"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("} else {"); + code.append(JAXXCompiler.getLineSeparator()); + code.append(" setContextValue(parentContext);"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("}"); + code.append(JAXXCompiler.getLineSeparator()); + } + code.append("$initialize();"); + code.append(JAXXCompiler.getLineSeparator()); + return JavaMethod.newMethod(Modifier.PUBLIC, null, className, code.toString(), new JavaArgument("jaxx.runtime.JAXXContext", "parentContext")); + } + + public JavaMethod createInitializer(JAXXCompiler compiler) throws CompilerException { + StringBuffer code = new StringBuffer(); + CompiledObject root = compiler.getRootObject(); + code.append("if (allComponentsCreated) {"); + code.append(JAXXCompiler.getLineSeparator()); + code.append(" return;"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("}"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("$objectMap.put(").append(TypeManager.getJavaCode(root.getId())).append(", this);"); + code.append(JAXXCompiler.getLineSeparator()); + + Iterator<CompiledObject> i = compiler.getObjectCreationOrder(); + boolean lastWasMethodCall = false; + while (i.hasNext()) { + CompiledObject object = i.next(); + if (object != root && !object.isOverride()) { + if (compiler.inlineCreation(object)) { + if (lastWasMethodCall) { + lastWasMethodCall = false; + code.append(JAXXCompiler.getLineSeparator()); + } + code.append(getCreationCode(compiler, object)); + code.append(JAXXCompiler.getLineSeparator()); + } else { + code.append(object.getCreationMethodName()).append("();"); + code.append(JAXXCompiler.getLineSeparator()); + lastWasMethodCall = true; + } + } + } + String rootCode = root.getInitializationCode(compiler); + if (rootCode != null && rootCode.length() > 0) { + code.append(rootCode); + code.append(JAXXCompiler.getLineSeparator()); + } + code.append(JAXXCompiler.getLineSeparator()); + if (compiler.getInitializer().length() > 0) { + code.append(compiler.getInitializer()); + code.append(JAXXCompiler.getLineSeparator()); + } + code.append("$completeSetup();"); + code.append(JAXXCompiler.getLineSeparator()); + return JavaMethod.newMethod(Modifier.PRIVATE, "void", "$initialize", code.toString()); + } + + + protected JavaMethod createCompleteSetupMethod(JAXXCompiler compiler, JavaFile javaFile, StringBuffer initDataBindings) { + StringBuffer code = new StringBuffer(); + code.append("allComponentsCreated = true;"); + code.append(JAXXCompiler.getLineSeparator()); + for (CompiledObject object : compiler.getObjects().values()) { + //TC - 20081017 only generate the method if not empty ? + if (object.getId().startsWith("$")) { + code.append(object.getAdditionCode()).append(JAXXCompiler.getLineSeparator()); + } else { + String additionCode = object.getAdditionCode(); + if (additionCode.length() > 0) { + code.append(object.getAdditionMethodName()).append("();").append(JAXXCompiler.getLineSeparator()); + additionCode = "if (!allComponentsCreated) {" + JAXXCompiler.getLineSeparator() + " return;" + JAXXCompiler.getLineSeparator() + "}" + JAXXCompiler.getLineSeparator() + additionCode; + javaFile.addMethod(JavaMethod.newMethod(Modifier.PROTECTED, "void", object.getAdditionMethodName(), additionCode)); + } + } + //code.append(getLineSeparator()); + } + + code.append(initDataBindings); + + if (compiler.getLateInitializer().length() > 0) { + code.append(compiler.getLateInitializer()); + code.append(JAXXCompiler.getLineSeparator()); + } + + return JavaMethod.newMethod(Modifier.PRIVATE, "void", "$completeSetup", code.toString()); + } + + protected JavaMethod createProcessDataBindingMethod(JAXXCompiler compiler, boolean superclassIsJAXXObject) { + StringBuffer code = new StringBuffer(); + //boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(compiler.getRootObject().getObjectClass()); + // the force parameter forces the update to happen even if it is already in activeBindings. This + // is used on superclass invocations b/c by the time the call gets to the superclass, it is already + // marked active and would otherwise be skipped + if (compiler.getProcessDataBinding().length() > 0) { + code.append(" if (!$force && $activeBindings.contains($dest)) { "); + code.append(JAXXCompiler.getLineSeparator()); + code.append(" return;"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("}"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("$activeBindings.add($dest);"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("try {"); + code.append(JAXXCompiler.getLineSeparator()); + if (compiler.getProcessDataBinding().length() > 0) { + code.append(compiler.getProcessDataBinding().toString()); + //code.append(JAXXCompiler.getLineSeparator()); + } + if (superclassIsJAXXObject) { + code.append(" else {"); + code.append(JAXXCompiler.getLineSeparator()); + code.append(" super.processDataBinding($dest, true);"); + code.append(JAXXCompiler.getLineSeparator()); + code.append(" }"); + code.append(JAXXCompiler.getLineSeparator()); + } + code.append("} finally {"); + code.append(JAXXCompiler.getLineSeparator()); + code.append(" $activeBindings.remove($dest);"); + code.append(JAXXCompiler.getLineSeparator()); + code.append("}"); + code.append(JAXXCompiler.getLineSeparator()); + } else if (superclassIsJAXXObject) { + code.append("super.processDataBinding($dest, true);"); + code.append(JAXXCompiler.getLineSeparator()); + } + return JavaMethod.newMethod(Modifier.PUBLIC, "void", "processDataBinding", code.toString(), + new JavaArgument("String", "$dest"), new JavaArgument("boolean", "$force") + ); + } + + /*---------------------------------------------------------------------------------*/ + /*-- Create methods code ----------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + protected String getCreationCode(JAXXCompiler compiler, CompiledObject object) throws CompilerException { + if (object instanceof ScriptInitializer) { + return object.getInitializationCode(compiler); + } + StringBuffer result = new StringBuffer(); + result.append(object.getId()); + result.append(" = "); + if (object.isJavaBean() && object.getJavaBeanInitCode() != null) { + result.append(object.getJavaBeanInitCode()).append(";"); + } else { + String constructorParams = object.getConstructorParams(); + if (constructorParams != null) { + //TC - 20081017 compiledObject can have generics + result.append(" new ").append(JAXXCompiler.getCanonicalName(object)).append("(").append(constructorParams).append(");"); + //result.append("(").append(getCanonicalName(object.getObjectClass())).append(") new ").append(getCanonicalName(object.getObjectClass())).append("(").append(constructorParams).append(");"); + } else { + //TC - 20081017 compiledObject can have generics + result.append("new ").append(JAXXCompiler.getCanonicalName(object)).append("();"); + } + } + result.append(JAXXCompiler.getLineSeparator()); + String initCode = object.getInitializationCode(compiler); + if (initCode != null && initCode.length() > 0) { + result.append(initCode); + } + result.append("$objectMap.put(").append(TypeManager.getJavaCode(object.getId())).append(", ").append(object.getId()).append(");"); + + return result.toString(); + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaArgument.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaArgument.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaArgument.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaArgument.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,86 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +/** + * Represents an argument to a <code>JavaMethod</code>. + * + * @see JavaMethod + */ +public class JavaArgument { + private String name; + private String type; + private boolean isFinal; + + + /** + * Creates a new <code>JavaArgument</code> with the specified name and type. For example, the method <code>main()</code> + * might have a <code>JavaArgument</code> with a name of <code>"arg"</code> and a type of <code>"java.lang.String[]"</code>. + * + * @param type the argument's type, as it would appear in Java source code + * @param name the argument's name + */ + public JavaArgument(String type, String name) { + this(type, name, false); + } + + + /** + * Creates a new <code>JavaArgument</code> with the specified name, type, and finality. For example, the method <code>main()</code> + * might have a <code>JavaArgument</code> with a name of <code>"arg"</code> and a type of <code>"java.lang.String[]"</code>. The + * <code>isFinal</code> parameter allows the presence of the <code>final</code> keyword on the argument to be controlled. + * + * @param type the argument's type, as it would appear in Java source code + * @param name the argument's name + * @param isFinal <code>true</code> if the argument should be marked final + */ + public JavaArgument(String type, String name, boolean isFinal) { + this.type = type; + this.name = name; + this.isFinal = isFinal; + } + + + /** + * Returns the argument's name. + * + * @return the name of the argument + */ + public String getName() { + return name; + } + + + /** + * Returns the argument's type as it would be represented in Java source code. + * + * @return the argument's type + */ + public String getType() { + return type; + } + + + /** + * Returns <code>true</code> if the <code>final</code> keyword should appear before the argument. + * + * @return <code>true</code> if the argument is final + */ + public boolean isFinal() { + return isFinal; + } + + + /** + * Returns the Java source code for this argument. + * + * @return the Java source code for this argument + */ + @Override + public String toString() { + String result = type + ' ' + name; + return isFinal ? "final " + result : result; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaField.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaField.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaField.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaField.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,187 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import java.lang.reflect.Modifier; +import java.util.Comparator; + +/** + * Represents a field in a Java source file being generated for output. <code>JavaFields</code> are created + * and added to a {@link JavaFile}, which can then output Java source code. + */ +public class JavaField implements Comparable<JavaField> { + + private int modifiers; + private String type; + private String name; + private String initializer; + + + /** + * Constructs a new <code>JavaField</code>. The <code>modifiers</code> parameter is a bit mask of the + * constants from {@link java.lang.reflect.Modifier}, and the <code>type</code> of the field should be + * represented as it would appear in Java source code. + * + * @param modifiers the modifier keywords that should appear as part of the field's declaration + * @param type the type of the field as it would appear in Java source code + * @param name the field's name + */ + public JavaField(int modifiers, String type, String name) { + this(modifiers, type, name, null); + } + + + /** + * Constructs a new <code>JavaField</code>. The <code>modifiers</code> parameter is a bit mask of the + * constants from <code>java.lang.reflect.Modifier</code>, and the <code>type</code> of the field should be + * represented as it would appear in Java source code. The <code>initializer</code> is the initial + * value of the field as it would appear in Java source code, or <code>null</code> to leave it at the + * default value. + * + * @param modifiers the modifier keywords that should appear as part of the field's declaration + * @param type the type of the field as it would appear in Java source code + * @param name the field's name + * @param initializer the initial value of the field, as it would appear in Java source code + */ + public JavaField(int modifiers, String type, String name, String initializer) { + this.modifiers = modifiers; + this.type = type; + this.name = name; + this.initializer = initializer; + } + + + /** + * Returns a bit mask describing the modifier keywords which should appear as part of this field's + * declaration. See <code>java.lang.reflect.Modifier</code> for more information on decoding this + * field. + * + * @return the modifier bit mask + */ + public int getModifiers() { + return modifiers; + } + + + /** + * Returns the field's name. + * + * @return the field's name + */ + public String getName() { + return name; + } + + + /** + * Returns the field's type, as it would be represented in Java source code. + * + * @return the field's type + */ + public String getType() { + return type; + } + + + /** + * Returns the Java source code for this field. + * + * @param lineSeparator line separator + * @return the Java source code for this field + */ + public String toString(String lineSeparator) { + StringBuffer result = new StringBuffer(); + result.append(JavaFile.getModifiersText(modifiers)); + result.append(type).append(' ').append(name); + if (initializer != null) { + result.append(" = ").append(initializer); + } + result.append(';').append(lineSeparator); + return result.toString(); + } + + public int compareTo(JavaField o) { + return COMPARATOR.compare(this, o); + } + + public static final Comparator<JavaField> COMPARATOR = new Comparator<JavaField>() { + + public int compare(JavaField o1, JavaField o2) { + + int result; + if ((result = compareStatic(o1, o2)) != 0) { + return result; + } + + // data sources must be on the last after all other fields + if ((result = compareDataSource(o1, o2)) != 0) { + return result; + } + + // same static + if ((result = compareVisibility(o1, o2)) != 0) { + return result; + } + // same visibility, test name + return o1.name.compareTo(o2.name); + } + + public int compareStatic(JavaField o1, JavaField o2) { + // first comparator modifiers : static always before none static + if (Modifier.isStatic(o1.modifiers) && !Modifier.isStatic(o2.modifiers)) { + return -1; + } + if (!Modifier.isStatic(o1.modifiers) && Modifier.isStatic(o2.modifiers)) { + return 1; + } + return 0; + } + + public int compareDataSource(JavaField o1, JavaField o2) { + // first comparator modifiers : static always before none static + if (o1.name.startsWith("$DataSource") && !o2.name.startsWith("$DataSource")) { + return 1; + } + if (!o1.name.startsWith("$DataSource") && o2.name.startsWith("$DataSource")) { + return -1; + } + return 0; + } + + public int compareVisibility(JavaField o1, JavaField o2) { + // first comparator modifiers : static always before none static + if (!Modifier.isPublic(o1.modifiers) && Modifier.isPublic(o2.modifiers)) { + return 1; + } + + if (Modifier.isPublic(o1.modifiers) && !Modifier.isPublic(o2.modifiers)) { + return -1; + } + + if (Modifier.isProtected(o1.modifiers) && !Modifier.isProtected(o2.modifiers)) { + return -1; + } + if (!Modifier.isProtected(o1.modifiers) && Modifier.isProtected(o2.modifiers)) { + return 1; + } + + if (Modifier.isPrivate(o1.modifiers) && !Modifier.isPrivate(o2.modifiers)) { + return -1; + } + if (!Modifier.isPrivate(o1.modifiers) && Modifier.isPrivate(o2.modifiers)) { + return 1; + } + return 0; + } + }; + + public static JavaField newField(int modifiers, String returnType, String name) { + return newField(modifiers, returnType, name, null); + } + + public static JavaField newField(int modifiers, String returnType, String name, String initializer) { + return new JavaField(modifiers, returnType, name, initializer); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaFile.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaFile.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaFile.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaFile.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,327 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.compiler.JavaMethod.MethodOrder; + +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EnumMap; +import java.util.List; +import java.util.Map.Entry; + +/** + * A Java source file being generated for output. Once the class is completely initialized, use the + * {@link #toString} method to generate source code for it. + */ +public class JavaFile { + + protected static final String GETTER_PATTERN = "return %1$s;"; + + protected static final String BOOLEAN_GETTER_PATTERN = "return %1$s !=null && %1$s;"; + + protected static final String SETTER_PATTERN = "%1$s oldValue = this.%2$s;\nthis.%2$s = newValue;\nfirePropertyChange(\"%2$s\", oldValue, newValue);"; + + private int modifiers; + private String className; + private List<String> imports = new ArrayList<String>(); + private List<JavaField> fields = new ArrayList<JavaField>(); + private List<JavaMethod> methods = new ArrayList<JavaMethod>(); + private List<JavaFile> innerClasses = new ArrayList<JavaFile>(); + private String superClass; + private List<String> interfaces; + private StringBuffer rawBodyCode = new StringBuffer(); + private boolean superclassIsJAXXObject; + + + public JavaFile() { + } + + + public JavaFile(int modifiers, String className, String superClass) { + this(modifiers, className, superClass, null); + } + + + public JavaFile(int modifiers, String className, String superClass, List<String> interfaces) { + this.modifiers = modifiers; + this.className = className; + this.superClass = superClass; + this.interfaces = interfaces; + } + + + public void addImport(String importString) { + imports.add(importString); + } + + public void addImport(Class importString) { + imports.add(importString.getName()); + } + + + public String[] getImports() { + return imports.toArray(new String[imports.size()]); + } + + + public int getModifiers() { + return modifiers; + } + + + public void setModifiers(int modifiers) { + this.modifiers = modifiers; + } + + + public String getClassName() { + return className; + } + + + public void setClassName(String className) { + this.className = className; + } + + + public String getSuperClass() { + return superClass; + } + + + public void setSuperClass(String superClass) { + this.superClass = superClass; + } + + + public List<String> getInterfaces() { + if (interfaces == null) { + interfaces = new ArrayList<String>(); + } + return interfaces; + } + + + public void setInterfaces(List<String> interfaces) { + this.interfaces = interfaces; + } + + + public void addMethod(JavaMethod method) { + methods.add(method); + } + + + public JavaMethod[] getMethods() { + return methods.toArray(new JavaMethod[methods.size()]); + } + + public void addField(JavaField field) { + addField(field, false); + } + + public void addField(JavaField field, boolean javaBean) { + addSimpleField(field); + String id = field.getName(); + String capitalizedName = org.apache.commons.lang.StringUtils.capitalize(id); + // add getter file + String content = String.format(GETTER_PATTERN, id); + addMethod(new JavaMethod( + Modifier.isProtected(field.getModifiers()) ? Modifier.PUBLIC : Modifier.PROTECTED, + field.getType(), "get" + capitalizedName, null, null, content)); + + if (javaBean) { + // add full javabean support + if (Boolean.class.getName().equals(field.getType())) { + content = String.format(BOOLEAN_GETTER_PATTERN, id); + addMethod(new JavaMethod(Modifier.PUBLIC, field.getType(), "is" + capitalizedName, null, null, content)); + } + content = String.format(SETTER_PATTERN, field.getType(), id); + JavaArgument arg = new JavaArgument(field.getType(), "newValue"); + addMethod(new JavaMethod(Modifier.PUBLIC, "void", "set" + capitalizedName, new JavaArgument[]{arg}, null, content)); + } + } + + public void addSimpleField(JavaField field) { + fields.add(field); + } + + + public JavaField[] getFields() { + return fields.toArray(new JavaField[fields.size()]); + } + + + public static String addIndentation(String source, int indentation, String lineSeparator) { + return indent(source, indentation, false, lineSeparator); + } + + + public static String setIndentation(String source, int indentation, String lineSeparator) { + return indent(source, indentation, true, lineSeparator); + } + + + public static String indent(String source, int indentation, boolean trim, String lineSeparator) { + if (trim) { + source = source.trim(); + } + char[] spaces = new char[indentation]; + Arrays.fill(spaces, ' '); + StringBuffer result = new StringBuffer(); + String[] lines = source.split(System.getProperty("line.separator") + "|\n"); + for (int i = 0; i < lines.length; i++) { + if (i > 0) { + result.append(lineSeparator); + } + result.append(spaces); + result.append(trim ? lines[i].trim() : lines[i]); + } + return result.toString(); + } + + + public void addBodyCode(String bodyCode) { + rawBodyCode.append(bodyCode); + } + + + public String getClassBody(String lineSeparator) { + StringBuffer result = new StringBuffer(); + if (fields.size() > 0) { + java.util.Collections.sort(fields); // sort fields + + for (JavaField field : fields) { + result.append(addIndentation(field.toString(lineSeparator), 4, lineSeparator)); + result.append(lineSeparator); + } + + result.append(lineSeparator); + } + + if (rawBodyCode.length() > 0) { + result.append(addIndentation("/* begin raw body code */\n", 4, lineSeparator)); + String s = rawBodyCode.toString(); + if (!s.startsWith(lineSeparator)) { + result.append(lineSeparator); + } + result.append(addIndentation(s, 4, lineSeparator)); + result.append(lineSeparator); + result.append(addIndentation("/* end raw body code */", 4, lineSeparator)); + result.append(lineSeparator); + } + + for (JavaFile innerClass : innerClasses) { + result.append(addIndentation(innerClass.toString(), 4, lineSeparator)); + result.append(lineSeparator).append(lineSeparator); + } + + /* + java.util.Collections.sort(methods); // sort methods + + for (JavaMethod method : methods) { + result.append(addIndentation(method.toString(), 4)); + result.append(lineSeparator); + result.append(lineSeparator); + } + */ + + EnumMap<MethodOrder, List<JavaMethod>> map = JavaMethod.getSortedMethods(methods); + for (Entry<MethodOrder, List<JavaMethod>> entry : map.entrySet()) { + List<JavaMethod> list = entry.getValue(); + entry.getKey().generate(result, list, lineSeparator); + list.clear(); + } + map.clear(); + + return result.toString(); + } + + + public String getClassDefinition(String lineSeparator) { + StringBuffer result = new StringBuffer(); + result.append(getModifiersText(modifiers)); + result.append("class "); + result.append(className.substring(className.lastIndexOf(".") + 1)); + result.append(" extends "); + result.append(superClass); + if (interfaces != null && !interfaces.isEmpty()) { + result.append(" implements ").append(interfaces.get(0)); + for (int i = 1; i < interfaces.size(); i++) { + /*if (i > 0) { + result.append(", "); + }*/ + result.append(", ").append(interfaces.get(i)); + } + } + result.append(" {"); + result.append(lineSeparator); + result.append(getClassBody(lineSeparator)); + result.append("}"); + return result.toString(); + } + + + public static String getModifiersText(int modifiers) { + if (modifiers == 0) { + return ""; + } else { + return Modifier.toString(modifiers) + ' '; + } + } + + + /** + * Returns the Java source code for this class. + * + * @param lineSeparator line separator + * @return a complete Java file for this class + */ + public String toString(String lineSeparator) { + StringBuffer result = new StringBuffer(); + if (className.indexOf(".") != -1) { + result.append("package ").append(className.substring(0, className.lastIndexOf("."))).append(";"); + result.append(lineSeparator); + result.append(lineSeparator); + } + + if (imports.size() > 0) { + for (String anImport : imports) { + result.append("import "); + result.append(anImport); + result.append(';'); + result.append(lineSeparator); + } + result.append(lineSeparator); + } + + result.append(getClassDefinition(lineSeparator)); + return result.toString(); + } + + public void addInterface(String canonicalName) { + if (interfaces == null || !interfaces.contains(canonicalName)) { + getInterfaces().add(canonicalName); + } + } + + public void addInterfaces(List<String> canonicalNames) { + for (String canonicalName : canonicalNames) { + if (interfaces == null || !interfaces.contains(canonicalName)) { + getInterfaces().add(canonicalName); + } + } + } + + public boolean isSuperclassIsJAXXObject() { + return superclassIsJAXXObject; + } + + public void setSuperclassIsJAXXObject(boolean superclassIsJAXXObject) { + this.superclassIsJAXXObject = superclassIsJAXXObject; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaMethod.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JavaMethod.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaMethod.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/JavaMethod.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,499 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.EnumMap; +import java.util.EnumSet; +import java.util.Iterator; +import java.util.List; + +/** + * Represents a method in a Java source file being generated for output. <code>JavaMethods</code> are created + * and added to a {@link JavaFile}, which can then output Java source code. In addition to normal methods, a + * <code>JavaMethod</code> can represent a constructor -- constructors should be named after their containing + * classes and have a return type of <code>null</code>. + */ +public class JavaMethod implements Comparable<JavaMethod> { + private int modifiers; + private String returnType; + private String name; + private JavaArgument[] arguments; + private String[] exceptions; + private StringBuffer bodyCode; + + + /** + * Constructs a new no-argument <code>JavaMethod</code> which throws no checked exceptions. The + * <code>modifiers</code> parameter is a bit mask of the constants from {@link java.lang.reflect.Modifier}, + * and the <code>returnType</code> of the method should be represented as it would appear in Java source + * code (<code>null</code> for a constructor). The method body is initially empty. + * + * @param modifiers the modifier keywords that should appear as part of the method's declaration + * @param returnType the return type of the method as it would appear in Java source code + * @param name the method's name + * @see #appendBodyCode + */ + //public JavaMethod(int modifiers, String returnType, String name) { + // this(modifiers, returnType, name, null); + //} + + + /** + * Constructs a new <code>JavaMethod</code> which throws no checked exceptions. The <code>modifiers</code> + * parameter is a bit mask of the constants from {@link java.lang.reflect.Modifier}, and the + * <code>returnType</code> of the method should be represented as it would appear in Java source code + * (<code>null</code> for a constructor). The method body is initially empty. + * + * @param modifiers the modifier keywords that should appear as part of the method's declaration + * @param returnType the return type of the method as it would appear in Java source code + * @param name the method's name + * @param arguments the method's arguments + * @see #appendBodyCode + */ + //public JavaMethod(int modifiers, String returnType, String name, JavaArgument[] arguments) { + // this(modifiers, returnType, name, arguments, null); + //} + + + /** + * Constructs a new <code>JavaMethod</code>. The <code>modifiers</code> parameter is a bit mask of the + * constants from {@link java.lang.reflect.Modifier}, and the <code>returnType</code> and <code>exceptions</code> + * of the method should be represented as they would appear in Java source code (<code>null</code> for a + * constructor). The method body is initially empty. + * + * @param modifiers the modifier keywords that should appear as part of the method's declaration + * @param returnType the return type of the method as it would appear in Java source code + * @param name the method's name + * @param arguments the method's arguments + * @param exceptions a list of exceptions the methods can throw, as they would be represented in Java source code + * @see #appendBodyCode + */ + //public JavaMethod(int modifiers, String returnType, String name, JavaArgument[] arguments, String[] exceptions) { + // this(modifiers, returnType, name, arguments, exceptions, null); + //} + + + /** + * Constructs a new <code>JavaMethod</code> containing the specified body code. The <code>modifiers</code> parameter + * is a bit mask of the constants from {@link java.lang.reflect.Modifier}, and the <code>returnType</code> and + * <code>exceptions</code> of the method should be represented as they would appear in Java source code (<code>null</code> + * for a constructor). The method body is initially empty. + * + * @param modifiers the modifier keywords that should appear as part of the method's declaration + * @param returnType the return type of the method as it would appear in Java source code + * @param name the method's name + * @param arguments the method's arguments + * @param exceptions a list of exceptions the methods can throw, as they would be represented in Java source code + * @param bodyCode Java source code which should appear in the method body + */ + public JavaMethod(int modifiers, String returnType, String name, JavaArgument[] arguments, String[] exceptions, String bodyCode) { + this.modifiers = modifiers; + this.returnType = returnType; + this.name = name; + this.arguments = arguments; + this.exceptions = exceptions; + this.bodyCode = new StringBuffer(bodyCode != null ? bodyCode : ""); + } + + + /** + * Returns a bit mask describing the modifier keywords which should appear as part of this method's + * declaration. See <code>java.lang.reflect.Modifier</code> for more information on decoding this + * field. + * + * @return the modifier bit mask + */ + public int getModifiers() { + return modifiers; + } + + + /** + * Returns the method's return type, as it would be represented in Java source code. + * + * @return the method's return type + */ + public String getReturnType() { + return returnType; + } + + + /** + * Returns the method's name. + * + * @return the method's name + */ + public String getName() { + return name; + } + + + /** + * Returns a list of the method's arguments. + * + * @return the method's arguments + */ + public JavaArgument[] getArguments() { + return arguments; + } + + + /** + * Returns a list of exceptions the method can throw. + * + * @return the method's exceptions + */ + public String[] getExceptions() { + return exceptions; + } + + + /** + * Returns the Java source code for the method's body. + * + * @return the method's body code + */ + public String getBodyCode() { + return bodyCode.toString(); + } + + + /** + * Appends additional code to the method's body. + * + * @param extraCode Java source code to append to the method's body + * @param lineSeparator line separator + */ + public void appendBodyCode(String extraCode, String lineSeparator) { + if (extraCode.length() == 0) { + return; + } + if (bodyCode.length() > 0 && !bodyCode.toString().endsWith(lineSeparator)) { + bodyCode.append(lineSeparator); + } + bodyCode.append(extraCode); + } + + + /** + * Returns the Java source code for this method. + * + * @param lineSeparator line separator + * @return the Java source code for this method + */ + public String toString(String lineSeparator) { + StringBuffer result = new StringBuffer(); + result.append(JavaFile.getModifiersText(modifiers)); + if (returnType != null) { + result.append(returnType); + result.append(' '); + } + result.append(name); + result.append('('); + if (arguments != null) { + for (int i = 0; i < arguments.length; i++) { + if (i > 0) { + result.append(", "); + } + result.append(arguments[i].toString()); + } + } + result.append(") {"); + result.append(lineSeparator); + if (bodyCode != null) { + String formattedBodyCode = JavaFile.addIndentation(bodyCode.toString().trim(), 4, lineSeparator); + if (formattedBodyCode.length() > 0) { + result.append(formattedBodyCode); + result.append(lineSeparator); + } + } + result.append("}"); + return result.toString(); + } + + public int compareTo(JavaMethod o) { + return COMPARATOR.compare(this, o); + } + + public static JavaMethod newMethod(int modifiers, String returnType, String name, String initializer, String[] exceptions, JavaArgument... arguments) { + return new JavaMethod(modifiers, returnType, name, arguments, exceptions, initializer); + } + + public static JavaMethod newMethod(int modifiers, String returnType, String name, String initializer, JavaArgument... arguments) { + return newMethod(modifiers, returnType, name, initializer, new String[0], arguments); + } + + public enum MethodOrder { + + statics(Modifier.STATIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Statics methods --------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + }, + + constructors(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Constructors -----------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return method.returnType == null; + } + }, + + JAXXObject(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- JAXXObject implementation ----------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + private List<String> methods = Arrays.asList("applyDataBinding", "firePropertyChange", "getObjectById", "get$objectMap", "processDataBinding", "removeDataBinding"); + + public boolean accept(JavaMethod method) { + return methods.contains(method.name); + } + }, + + JAXXContext(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- JAXXContext implementation ---------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + private List<String> methods = Arrays.asList("getContextValue", "getDelegateContext", "getParentContainer", "removeContextValue", "setContextValue"); + public boolean accept(JavaMethod method) { + return methods.contains(method.name); + } + }, + + JAXXValidation(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- JAXXValidation implementation ------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + private List<String> methods = Arrays.asList("getValidator", "getValidatorIds"); + + public boolean accept(JavaMethod method) { + return methods.contains(method.name); + } + }, + + events(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Event methods ----------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("do") && method.name.indexOf("__") > -1); + } + }, + + publicGetters(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- public acessor methods -------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("get") || method.name.startsWith("is")); + } + }, + + publicSetters(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- public mutator methods -------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("set")); + } + }, + + otherPublic(Modifier.PUBLIC, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- public mutator methods -------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + @Override + public boolean accept(int mod) { + return super.accept(mod) && !Modifier.isStatic(mod); + } + }, + + protectedGetters(Modifier.PROTECTED, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- protected acessors methods ---------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return (method.name.startsWith("get") || method.name.startsWith("is")); + } + }, + + createMethod(Modifier.PROTECTED | Modifier.PRIVATE, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- ui creation methods ----------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + public boolean accept(JavaMethod method) { + return method.name.startsWith("create") || method.name.startsWith("add") || + method.name.equals("$completeSetup") || + method.name.equals("$initialize"); + } + }, + + protecteds(Modifier.PROTECTED, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Other protected methods ------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + }, + + packageLocal(0, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Package methods --------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + @Override + public boolean accept(int mod) { + return !Modifier.isStatic(mod) && !Modifier.isPublic(mod) && !Modifier.isProtected(mod); + }}, + + privates(Modifier.PRIVATE, "/*---------------------------------------------------------------------------------*/\n" + + "/*-- Private methods --------------------------------------------------------------*/\n" + + "/*---------------------------------------------------------------------------------*/") { + }; + + private final String header; + + private int modifier; + + MethodOrder(int modifier, String header) { + this.header = header; + this.modifier = modifier; + } + + public String getHeader() { + return header; + } + + public boolean accept(JavaMethod method) { + return true; + } + + public boolean accept(int mod) { + return (mod & modifier) != 0; + } + + public boolean accept(int mod, JavaMethod method) { + return accept(mod) && accept(method); + } + + public static MethodOrder valueOf(JavaMethod method, int scope) { + for (MethodOrder o : values()) { + if (o.accept(scope, method)) { + return o; + } + } + throw new IllegalArgumentException("could not find a " + MethodOrder.class + " for method " + method); + } + + public void generate(StringBuffer buffer, List<JavaMethod> methods, String lineSeparator) { + if (methods.isEmpty()) { + return; + } + buffer.append(JavaFile.addIndentation(header, 4, lineSeparator)); + buffer.append(lineSeparator).append(lineSeparator); + for (JavaMethod method : methods) { + buffer.append(JavaFile.addIndentation(method.toString(lineSeparator), 4, lineSeparator)); + buffer.append(lineSeparator).append(lineSeparator); + } + } + } + + public static EnumMap<MethodOrder, List<JavaMethod>> getSortedMethods(List<JavaMethod> methods) { + + EnumMap<MethodOrder, List<JavaMethod>> result = new EnumMap<MethodOrder, List<JavaMethod>>(MethodOrder.class); + for (MethodOrder methodOrder : MethodOrder.values()) { + result.put(methodOrder, new ArrayList<JavaMethod>()); + } + + EnumSet<MethodOrder> allConstants = EnumSet.allOf(MethodOrder.class); + List<JavaMethod> allMethods = new ArrayList<JavaMethod>(methods); + int[] scopes = new int[]{Modifier.STATIC, Modifier.PUBLIC, Modifier.PROTECTED, Modifier.PRIVATE}; + for (int scope : scopes) { + EnumSet<MethodOrder> constants = getMethodOrderScope(allConstants, scope); + + Iterator<JavaMethod> itMethods = allMethods.iterator(); + while (itMethods.hasNext()) { + JavaMethod method = itMethods.next(); + for (MethodOrder constant : constants) { + if (constant.accept(method.getModifiers(), method)) { + result.get(constant).add(method); + itMethods.remove(); + break; + } + } + } + constants.clear(); + } + + if (!allMethods.isEmpty()) { + throw new IllegalArgumentException("could not find a " + MethodOrder.class + " for method " + allMethods); + } + + for (MethodOrder methodOrder : MethodOrder.values()) { + // sort methods + java.util.Collections.sort(result.get(methodOrder)); + } + return result; + } + + public static EnumSet<MethodOrder> getMethodOrderScope(EnumSet<MethodOrder> allConstants, int scope) { + EnumSet<MethodOrder> constants = EnumSet.noneOf(MethodOrder.class); + for (MethodOrder order : allConstants) { + if (order.accept(scope)) { + constants.add(order); + } + } + return constants; + } + + public static final Comparator<JavaMethod> COMPARATOR = new Comparator<JavaMethod>() { + + public int compare(JavaMethod o1, JavaMethod o2) { + + /*int result; + if ((result = compareStatic(o1, o2)) != 0) { + return result; + } + if ((result = compareConstructor(o1, o2)) != 0) { + return result; + } + if ((result = compareVisibility(o1, o2)) != 0) { + return result; + }*/ + return o1.name.compareTo(o2.name); + } + + public int compareStatic(JavaMethod o1, JavaMethod o2) { + if (Modifier.isStatic(o1.modifiers) && !Modifier.isStatic(o2.modifiers)) { + return -1; + } + if (!Modifier.isStatic(o1.modifiers) && Modifier.isStatic(o2.modifiers)) { + return 1; + } + return 0; + } + + public int compareConstructor(JavaMethod o1, JavaMethod o2) { + if (o1.returnType == null && o2.returnType != null) { + return -1; + } + if (o1.returnType != null && o2.returnType == null) { + return 1; + } + return 0; + } + + public int compareVisibility(JavaMethod o1, JavaMethod o2) { + if (Modifier.isPublic(o1.modifiers) && !Modifier.isPublic(o2.modifiers)) { + return -1; + } + if (!Modifier.isPublic(o1.modifiers) && Modifier.isPublic(o2.modifiers)) { + return 1; + } + if (Modifier.isProtected(o1.modifiers) && !Modifier.isProtected(o2.modifiers)) { + return -1; + } + if (!Modifier.isProtected(o1.modifiers) && Modifier.isProtected(o2.modifiers)) { + return 1; + } + if (Modifier.isPrivate(o1.modifiers) && !Modifier.isPrivate(o2.modifiers)) { + return -1; + } + if (!Modifier.isPrivate(o1.modifiers) && Modifier.isPrivate(o2.modifiers)) { + return 1; + } + return 0; + } + }; +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptInitializer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/ScriptInitializer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptInitializer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptInitializer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,20 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.reflect.ClassDescriptorLoader; + +/** + * A dummy CompiledObject which serves to initialize scripted field. This is handled by + * a CompiledObject rather than (say) simply inlining the initialization code in order to + * ensure that the field is initialized in document order. + */ +public class ScriptInitializer extends CompiledObject { + public ScriptInitializer(String initializer, JAXXCompiler compiler) { + super(compiler.getAutoId(ClassDescriptorLoader.getClassDescriptor(ScriptInitializer.class)), + ClassDescriptorLoader.getClassDescriptor(ScriptInitializer.class), compiler, false); + appendInitializationCode(initializer); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptManager.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/ScriptManager.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptManager.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/ScriptManager.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,336 @@ +package jaxx.compiler; + +import jaxx.CompilerException; +import jaxx.parser.JavaParser; +import jaxx.parser.JavaParserTreeConstants; +import jaxx.parser.SimpleNode; +import jaxx.reflect.FieldDescriptor; +import jaxx.reflect.MethodDescriptor; +import jaxx.tags.TagManager; + +import java.io.StringReader; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class ScriptManager { + private JAXXCompiler compiler; + + + ScriptManager(JAXXCompiler compiler) { + this.compiler = compiler; + } + + + /** + * Strips unnecessary curly braces from around the script, generating a warning if they are found. + * + * @param script script to trim + * @return the trimed script + */ + public String trimScript(String script) { + script = script.trim(); + if (script.startsWith("{") && script.endsWith("}")) { + compiler.reportWarning("curly braces are unnecessary for script '" + script + "'"); + script = script.substring(1, script.length() - 1); + } + return script; + } + + + public void checkParse(String script) throws CompilerException { + script = trimScript(script); + JavaParser p = new JavaParser(new StringReader(script)); + while (!p.Line()) { + // ??? + } + } + + + public String preprocessScript(String script) throws CompilerException { + script = trimScript(script); + StringBuffer result = new StringBuffer(); + JavaParser p = new JavaParser(new StringReader(script)); + //JavaParser p = new JavaParser(new StringReader(script + ";")); + while (!p.Line()) { + SimpleNode node = p.popNode(); + if (node != null) { + preprocessScriptNode(node, false); + result.append(node.getText()); + } + } + return result.toString(); + } + + + /** + * Scans through a compound symbol (foo.bar.baz) to identify and compile the JAXX class it refers to, if any. + * + * @param symbol symbol to scan + */ + private void scanCompoundSymbol(String symbol) { + String[] tokens = symbol.split("\\."); + StringBuffer currentSymbol = new StringBuffer(); + for (String token : tokens) { + if (currentSymbol.length() > 0) + currentSymbol.append('.'); + currentSymbol.append(token.trim()); + + String contextClass = TagManager.resolveClassName(currentSymbol.toString(), compiler); + if (contextClass != null) { + compiler.addDependencyClass(contextClass); + } + } + } + + + private void preprocessScriptNode(SimpleNode node, boolean staticContext) throws CompilerException { + // identify static methods and initializers -- we can't fire events statically + if (node.getId() == JavaParserTreeConstants.JJTMETHODDECLARATION) { + if (node.getParent().getChild(0).getText().indexOf("static") != -1) { + staticContext = true; + } + } else if (node.getId() == JavaParserTreeConstants.JJTINITIALIZER) + if (node.getText().trim().startsWith("static")) { + staticContext = true; + } + + int count = node.jjtGetNumChildren(); + for (int i = 0; i < count; i++) { + preprocessScriptNode(node.getChild(i), staticContext); + } + + int id = node.getId(); + if (id == JavaParserTreeConstants.JJTNAME || id == JavaParserTreeConstants.JJTCLASSORINTERFACETYPE) { + scanCompoundSymbol(node.getText()); + } + if (!staticContext) { + String lhs = null; + if (id == JavaParserTreeConstants.JJTASSIGNMENTEXPRESSION || (id == JavaParserTreeConstants.JJTPOSTFIXEXPRESSION && node.jjtGetNumChildren() == 2)) { + lhs = ((SimpleNode) node.jjtGetChild(0)).getText().trim(); + } + else + if (id == JavaParserTreeConstants.JJTPREINCREMENTEXPRESSION || id == JavaParserTreeConstants.JJTPREDECREMENTEXPRESSION) { + lhs = ((SimpleNode) node.jjtGetChild(0)).getText().trim(); + } + if (lhs != null) { + FieldDescriptor[] fields = compiler.getScriptFields(); + for (FieldDescriptor field : fields) { + if (field.getName().equals(lhs)) { + //lhs.substring(lhs.lastIndexOf(".") + 1); + node.firstToken.image = "jaxx.runtime.Util.assignment(" + node.firstToken.image; + String outputClassName = compiler.getOutputClassName(); + node.lastToken.image = node.lastToken.image + ", \"" + lhs + "\", " + outputClassName + ".this)"; + } + } + } + } + } + + + /** + * Examines a Line to determine its real type. As all tokens returned by the parser are Lines, and + * they are just a tiny wrapper around the real node, this method strips off the wrapper layers to identify + * the real type of a node. + * + * @param line line to scan + * @return the line type + */ + private int getLineType(SimpleNode line) { + if (line.jjtGetNumChildren() == 1) { + SimpleNode node = line.getChild(0); + if (node.getId() == JavaParserTreeConstants.JJTBLOCKSTATEMENT) { + if (node.jjtGetNumChildren() == 1) { + return node.getChild(0).getId(); + } + } else + if (node.getId() == JavaParserTreeConstants.JJTCLASSORINTERFACEBODYDECLARATION) { + int id = node.getChild(0).getId(); + if (id == JavaParserTreeConstants.JJTMODIFIERS) { + return node.getChild(1).getId(); + } + if (id == JavaParserTreeConstants.JJTINITIALIZER) { + return id; + } + } + return node.getId(); + } + return JavaParserTreeConstants.JJTLINE; // generic value implying that it's okay to put into the initializer block + } + + + private SimpleNode findExplicitConstructorInvocation(SimpleNode parent) { + if (parent.getId() == JavaParserTreeConstants.JJTEXPLICITCONSTRUCTORINVOCATION) { + return parent; + } + + int count = parent.jjtGetNumChildren(); + for (int i = 0; i < count; i++) { + SimpleNode result = findExplicitConstructorInvocation(parent.getChild(i)); + if (result != null) { + return result; + } + } + return null; + } + + + private void processConstructor(String modifiers, SimpleNode node) { + assert node.getId() == JavaParserTreeConstants.JJTCONSTRUCTORDECLARATION : "expected node to be ConstructorDeclaration, found " + JavaParserTreeConstants.jjtNodeName[node.getId()] + " instead"; + assert node.getChild(0).getId() == JavaParserTreeConstants.JJTFORMALPARAMETERS : "expected node 0 to be FormalParameters, found " + JavaParserTreeConstants.jjtNodeName[node.getChild(1).getId()] + " instead"; + String code = ""; + if (node.getChild(0).jjtGetNumChildren() == 0) { + compiler.reportError("The default no-argument constructor may not be redefined"); + } + else { + SimpleNode explicitConstructorInvocation = findExplicitConstructorInvocation(node); + if (explicitConstructorInvocation == null || explicitConstructorInvocation.getText().trim().startsWith("super(")) { + code = "$initialize();" + JAXXCompiler.getLineSeparator(); + if (explicitConstructorInvocation == null) { + node.getChild(1).firstToken.image = node.getChild(1).firstToken.image; + } + else { + explicitConstructorInvocation.lastToken.image += code; + } + } + } + + compiler.appendBodyCode(modifiers + " "+ node.getText().substring(0,node.getText().length()-1) + code + "}"); + //compiler.bodyCode.append(";\n"); + } + + + private void scanScriptNode(SimpleNode node) throws CompilerException { + int nodeType = getLineType(node); + if (nodeType == JavaParserTreeConstants.JJTIMPORTDECLARATION) { // have to handle imports early so the preprocessing takes them into account + String text = node.getChild(0).getText().trim(); + if (text.startsWith("import")) { + text = text.substring("import".length()).trim(); + } + if (text.endsWith(";")) { + text = text.substring(0, text.length() - 1); + } + compiler.addImport(text); + } + + preprocessScriptNode(node, false); + + if (nodeType == JavaParserTreeConstants.JJTIMPORTDECLARATION) { + // do nothing, already handled above + } else if (nodeType == JavaParserTreeConstants.JJTMETHODDECLARATION) { + String returnType = null; + String name = null; + List<String> parameterTypes = new ArrayList<String>(); + //List<String> parameterNames = new ArrayList<String>(); + SimpleNode methodDeclaration = node.getChild(0).getChild(1); + assert methodDeclaration.getId() == JavaParserTreeConstants.JJTMETHODDECLARATION; + for (int i = 0; i < methodDeclaration.jjtGetNumChildren(); i++) { + SimpleNode child = methodDeclaration.getChild(i); + int type = child.getId(); + if (type == JavaParserTreeConstants.JJTRESULTTYPE) { + String rawReturnType = child.getText().trim(); + returnType = TagManager.resolveClassName(rawReturnType, compiler); + // FIXME: this check fails for inner classes defined in this file + //if (returnType == null) + // throw new CompilerException("could not find class '" + rawReturnType + "'"); + } else + if (type == JavaParserTreeConstants.JJTMETHODDECLARATOR) { + name = child.firstToken.image.trim(); + SimpleNode formalParameters = child.getChild(0); + assert formalParameters.getId() == JavaParserTreeConstants.JJTFORMALPARAMETERS; + for (int j = 0; j < formalParameters.jjtGetNumChildren(); j++) + { + SimpleNode parameter = formalParameters.getChild(j); + String rawParameterType = parameter.getChild(1).getText().trim().replaceAll("\\.\\.\\.", "[]"); + String parameterType = TagManager.resolveClassName(rawParameterType, compiler); + // FIXME: this check fails for inner classes defined in this file + //if (parameterType == null) + // throw new CompilerException("could not find class '" + rawParameterType + "'"); + parameterTypes.add(parameterType); + //parameterNames.add(parameter.getChild(2).getText().trim()); + } + } + } + compiler.appendBodyCode(node.getText()); + //compiler.bodyCode.append(";\n"); + compiler.addScriptMethod(new MethodDescriptor(name, Modifier.PUBLIC, returnType, parameterTypes.toArray(new String[parameterTypes.size()]), compiler.getClassLoader())); + } else + if (nodeType == JavaParserTreeConstants.JJTCLASSORINTERFACEDECLARATION || + nodeType == JavaParserTreeConstants.JJTINITIALIZER) { + String str = node.getText().trim(); + if (str.endsWith(";")) { + str+=";"; + } + compiler.appendBodyCode(str); + //compiler.bodyCode.append(";\n"); + } else + if (nodeType == JavaParserTreeConstants.JJTCONSTRUCTORDECLARATION) { + processConstructor(node.getChild(0).getChild(0).getText(), node.getChild(0).getChild(1)); + } else + if (nodeType == JavaParserTreeConstants.JJTLOCALVARIABLEDECLARATION || nodeType == JavaParserTreeConstants.JJTFIELDDECLARATION) { + // the "local" variable declarations in this expression aren't actually local -- they are flagged local + // just because there isn't an enclosing class scope visible to the parser. "Real" local variable + // declarations won't show up here, because they will be buried inside of methods. + String text = node.getText().trim(); + if (!text.endsWith(";")) { + text+=";"; + } + String declaration = text; + int equals = text.indexOf("="); + if (equals != -1) { + declaration = declaration.substring(0, equals); + } + declaration = declaration.trim(); + String[] declarationTokens = declaration.split("\\s"); + boolean isFinal = Arrays.asList(declarationTokens).contains("final"); + boolean isStatic = Arrays.asList(declarationTokens).contains("static"); + String name = declarationTokens[declarationTokens.length - 1]; + if (name.endsWith(";")) { + name = name.substring(0, name.length() - 1).trim(); + } + String className = declarationTokens[declarationTokens.length - 2]; + String type = TagManager.resolveClassName(className, compiler); + compiler.addScriptField(new FieldDescriptor(name, Modifier.PUBLIC, type, compiler.getClassLoader())); // TODO: determine the actual modifiers + if (equals != -1 && !isFinal && !isStatic) { // declare the field in the class body, but wait to actually initialize it + //compiler.bodyCode.append(text.substring(0, equals).trim()); + compiler.appendBodyCode(text.substring(0, equals).trim() + ";"); + String initializer = text.substring(equals + 1).trim(); + if (type.endsWith("[]")) { + initializer = "new " + type + " " + initializer; + } + final String finalInitializer = name + " = " + initializer; + compiler.registerInitializer(new Runnable() { + public void run() { + compiler.registerCompiledObject(new ScriptInitializer(finalInitializer, compiler)); + } + }); + } else { + compiler.appendBodyCode(text); + } + compiler.appendBodyCode("\n"); + //compiler.bodyCode.append(";\n"); + } else { + String text = node.getText().trim(); + if (text.length() > 0) { + if (!text.endsWith(";")) { + text += ";"; + } + compiler.appendInitializerCode(text); + //compiler.initializer.append(";\n"); + } + } + } + + + public void registerScript(String script) throws CompilerException { + JavaParser p = new JavaParser(new StringReader(script)); + //JavaParser p = new JavaParser(new StringReader(script + ";")); + while (!p.Line()) { + SimpleNode node = p.popNode(); + if (node != null) { + scanScriptNode(node); + } + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/SymbolTable.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/SymbolTable.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/SymbolTable.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/compiler/SymbolTable.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,56 @@ +package jaxx.compiler; + +import jaxx.reflect.FieldDescriptor; +import jaxx.reflect.MethodDescriptor; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** Symbol table constructed during the first pass of compilation. */ +public class SymbolTable { + + private String superclass; + + // maps ID strings to class names -- we can't map directly to CompiledObjects, because we + // can't create those until after the first pass + private Map<String, String> ids = new HashMap<String, String>(); + + private List<FieldDescriptor> scriptFields = new ArrayList<FieldDescriptor>(); + + private List<MethodDescriptor> scriptMethods = new ArrayList<MethodDescriptor>(); + + + /** @return the fully-qualified name of the superclass of the class described by this symbol table. */ + public String getSuperclassName() { + return superclass; + } + + + public void setSuperclassName(String superclass) { + this.superclass = superclass; + } + + + /** + * @return a map of IDs to class names. Each entry in the map corresponds to a class tag with an + * <code>id</code> attribute. The <code>id</code> is the key, and the fully-qualified class name + * of the tag is the value. + */ + public Map<String, String> getClassTagIds() { + return ids; + } + + + /** @return a list of <code>FieldDescriptors</code> for fields defined in <script> tags. */ + public List<FieldDescriptor> getScriptFields() { + return scriptFields; + } + + + /** @return a list of <code>MethodDescriptors</code> for methods defined in <script> tags. */ + public List<MethodDescriptor> getScriptMethods() { + return scriptMethods; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jj (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/CSS.jj) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jj (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jj 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,587 @@ +/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. .\CSS.jj */ +/*@egen*//* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ + +// I would love to have used an existing CSS parser, but all of the ones I could +// find are licensed under the LGPL. As JAXX is BSD licensed and I'm not a big +// fan of the LGPL, unfortunately that won't work. +options { + STATIC = false; + JDK_VERSION = "1.4"; +} + +PARSER_BEGIN(CSSParser) +package jaxx.css; + +public class CSSParser/*@bgen(jjtree)*/implements CSSParserTreeConstants/*@egen*/ {/*@bgen(jjtree)*/ + protected JJTCSSParserState jjtree = new JJTCSSParserState(); + +/*@egen*/ + public SimpleNode popNode() { + if ( jjtree.nodeArity() > 0) // number of child nodes + return (SimpleNode)jjtree.popNode(); + else + return null; + } + + void jjtreeOpenNodeScope(Node n) { + ((SimpleNode) n).firstToken = getToken(1); + } + + void jjtreeCloseNodeScope(Node n) { + ((SimpleNode) n).lastToken = getToken(0); + } + + public static void main(String args[]) { + System.out.println("Reading from standard input..."); + CSSParser css = new CSSParser(System.in); + try { + SimpleNode n = css.Stylesheet(); + n.dump(""); + System.out.println("Thank you."); + } catch (Exception e) { + System.out.println("Oops."); + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } +} + +PARSER_END(CSSParser) + + +<DEFAULT, IN_RULE> SKIP : +{ + " " +| "\t" +| "\n" +| "\r" +| <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")> +| <"/*" (~["*"])* "*" (~["/"] (~["*"])* "*")* "/"> +} + +<*> TOKEN : /* LITERALS */ +{ + <DECIMAL_LITERAL: <INTEGER_LITERAL> ("." <INTEGER_LITERAL>)?> +| + <#INTEGER_LITERAL: (["0"-"9"])+> +} + +<DEFAULT, IN_RULE> TOKEN : /* IDENTIFIER */ +{ + <IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)*> +| + <#LETTER: ["_", "-", "a"-"z", "A"-"Z"]> +| + <#DIGIT: ["0"-"9"]> +} + +<IN_PSEUDOCLASS> TOKEN : /* PSEUDOCLASS_IDENTIFIER */ +{ + <PSEUDOCLASS_IDENTIFIER: <IDENTIFIER>> : DEFAULT +} + +<DEFAULT> TOKEN: /* COLON */ +{ + <PSEUDOCLASS_COLON: ":"> : IN_PSEUDOCLASS +} + +<IN_RULE> TOKEN: /* COLON_IN_RULE */ +{ + <COLON: ":"> +} + +<*> TOKEN: /* SEMICOLON */ +{ + <SEMICOLON: ";"> +} + +TOKEN : /* LEFT BRACE */ +{ + <LEFT_BRACE: "{"> : IN_RULE +} + +<IN_RULE> TOKEN : /* RIGHT BRACE */ +{ + <RIGHT_BRACE: "}"> : DEFAULT +} + +<IN_RULE> TOKEN : /* JAVA_CODE_RULE START */ +{ + <JAVA_CODE_START: <LEFT_BRACE>> : JAVA_CODE_RULE +} + +<JAVA_CODE_RULE> TOKEN : /* JAVA_CODE_RULE */ +{ + <JAVA_CODE: (~["}"])+ > +} + +<JAVA_CODE_RULE> TOKEN : /* JAVA_CODE_RULE END */ +{ + <JAVA_CODE_END: <RIGHT_BRACE>> : IN_RULE +} + + +<IN_PSEUDOCLASS> TOKEN : /* PROGRAMMATIC_PSEUDOCLASS */ +{ + <PROGRAMMATIC_PSEUDOCLASS: "{" (~["}"])+ "}"> : DEFAULT +} + +<IN_RULE> TOKEN : /* STRINGS */ +{ + <STRING: "\"" (~["\"", "\\", "\n", "\r"])* "\""> +} + +<IN_RULE> TOKEN : /* COLORS */ +{ + <HEXCOLOR: "#" <HEXDIGIT> <HEXDIGIT> <HEXDIGIT> (<HEXDIGIT> <HEXDIGIT> <HEXDIGIT>)?> +| + <#HEXDIGIT: ["0"-"9", "a"-"f", "A"-"F"]> +} + + +<IN_RULE> TOKEN : /* EMS */ +{ + <EMS: <DECIMAL_LITERAL> "em"> +} + + +<IN_RULE> TOKEN : /* EXS */ +{ + <EXS: <DECIMAL_LITERAL> "ex"> +} + + +<IN_RULE> TOKEN : /* LENGTH */ +{ + <LENGTH: <DECIMAL_LITERAL> ("pt" | "mm" | "cm" | "pc" | "in")> +} + + +SimpleNode Stylesheet() : {/*@bgen(jjtree) Stylesheet */ + SimpleNode jjtn000 = new SimpleNode(JJTSTYLESHEET); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Stylesheet */ + try { +/*@egen*/ + (Rule())*/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ + { return jjtn000; }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Rule() : {/*@bgen(jjtree) Rule */ + SimpleNode jjtn000 = new SimpleNode(JJTRULE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Rule */ + try { +/*@egen*/ + Selectors() + <LEFT_BRACE> Declaration() (";" (Declaration())?)* <RIGHT_BRACE>/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Selectors() : {/*@bgen(jjtree) Selectors */ + SimpleNode jjtn000 = new SimpleNode(JJTSELECTORS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Selectors */ + try { +/*@egen*/ + Selector() ("," Selector())*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Selector() : {/*@bgen(jjtree) Selector */ + SimpleNode jjtn000 = new SimpleNode(JJTSELECTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Selector */ + try { +/*@egen*/ + JavaClass() (Id())? (Class())? (PseudoClass())? +| + Id() (Class())? (PseudoClass())? +| + Class() (PseudoClass())? +| + PseudoClass()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void JavaClass() : {/*@bgen(jjtree) JavaClass */ + SimpleNode jjtn000 = new SimpleNode(JJTJAVACLASS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) JavaClass */ + try { +/*@egen*/ + <IDENTIFIER> | "*"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Id() : {/*@bgen(jjtree) Id */ + SimpleNode jjtn000 = new SimpleNode(JJTID); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Id */ + try { +/*@egen*/ + "#" <IDENTIFIER>/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Class() : {/*@bgen(jjtree) Class */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Class */ + try { +/*@egen*/ + "." <IDENTIFIER>/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void PseudoClass() : {/*@bgen(jjtree) PseudoClass */ + SimpleNode jjtn000 = new SimpleNode(JJTPSEUDOCLASS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PseudoClass */ + try { +/*@egen*/ + <PSEUDOCLASS_COLON> (<PSEUDOCLASS_IDENTIFIER> | <PROGRAMMATIC_PSEUDOCLASS>) (AnimationProperties())?/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void AnimationProperties() : {/*@bgen(jjtree) AnimationProperties */ + SimpleNode jjtn000 = new SimpleNode(JJTANIMATIONPROPERTIES); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AnimationProperties */ + try { +/*@egen*/ + "[" AnimationProperty() ("," AnimationProperty())* "]"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void AnimationProperty() : {/*@bgen(jjtree) AnimationProperty */ + SimpleNode jjtn000 = new SimpleNode(JJTANIMATIONPROPERTY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AnimationProperty */ + try { +/*@egen*/ + <IDENTIFIER> "=" <DECIMAL_LITERAL> (<IDENTIFIER>)?/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Declaration() : {/*@bgen(jjtree) Declaration */ + SimpleNode jjtn000 = new SimpleNode(JJTDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Declaration */ + try { +/*@egen*/ + Property() <COLON> Expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Property() : {/*@bgen(jjtree) Property */ + SimpleNode jjtn000 = new SimpleNode(JJTPROPERTY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Property */ + try { +/*@egen*/ + <IDENTIFIER>/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Expression() : {/*@bgen(jjtree) Expression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Expression */ + try { +/*@egen*/ + (<DECIMAL_LITERAL> | <STRING> | <IDENTIFIER> | <HEXCOLOR> | <EMS> | <EXS> | <LENGTH> | + JavaCode())/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void JavaCode() : {/*@bgen(jjtree) JavaCode */ + SimpleNode jjtn000 = new SimpleNode(JJTJAVACODE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) JavaCode */ + try { +/*@egen*/ + <JAVA_CODE_START> <JAVA_CODE> <JAVA_CODE_END>/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void Identifier() : {/*@bgen(jjtree) Identifier */ + SimpleNode jjtn000 = new SimpleNode(JJTIDENTIFIER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Identifier */ + try { +/*@egen*/ + <IDENTIFIER>/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jjt (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/CSS.jjt) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jjt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSS.jjt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,256 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ + +// I would love to have used an existing CSS parser, but all of the ones I could +// find are licensed under the LGPL. As JAXX is BSD licensed and I'm not a big +// fan of the LGPL, unfortunately that won't work. +options { + STATIC = false; + JDK_VERSION = "1.4"; + NODE_SCOPE_HOOK = true; +} + +PARSER_BEGIN(CSSParser) +package jaxx.css; + +public class CSSParser { + public SimpleNode popNode() { + if ( jjtree.nodeArity() > 0) // number of child nodes + return (SimpleNode)jjtree.popNode(); + else + return null; + } + + void jjtreeOpenNodeScope(Node n) { + ((SimpleNode) n).firstToken = getToken(1); + } + + void jjtreeCloseNodeScope(Node n) { + ((SimpleNode) n).lastToken = getToken(0); + } + + public static void main(String args[]) { + System.out.println("Reading from standard input..."); + CSSParser css = new CSSParser(System.in); + try { + SimpleNode n = css.Stylesheet(); + n.dump(""); + System.out.println("Thank you."); + } catch (Exception e) { + System.out.println("Oops."); + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } +} + +PARSER_END(CSSParser) + + +<DEFAULT, IN_RULE> SKIP : +{ + " " +| "\t" +| "\n" +| "\r" +| <"//" (~["\n","\r"])* ("\n"|"\r"|"\r\n")> +| <"/*" (~["*"])* "*" (~["/"] (~["*"])* "*")* "/"> +} + +<*> TOKEN : /* LITERALS */ +{ + <DECIMAL_LITERAL: <INTEGER_LITERAL> ("." <INTEGER_LITERAL>)?> +| + <#INTEGER_LITERAL: (["0"-"9"])+> +} + +<DEFAULT, IN_RULE> TOKEN : /* IDENTIFIER */ +{ + <IDENTIFIER: <LETTER> (<LETTER>|<DIGIT>)*> +| + <#LETTER: ["_", "-", "a"-"z", "A"-"Z"]> +| + <#DIGIT: ["0"-"9"]> +} + +<IN_PSEUDOCLASS> TOKEN : /* PSEUDOCLASS_IDENTIFIER */ +{ + <PSEUDOCLASS_IDENTIFIER: <IDENTIFIER>> : DEFAULT +} + +<DEFAULT> TOKEN: /* COLON */ +{ + <PSEUDOCLASS_COLON: ":"> : IN_PSEUDOCLASS +} + +<IN_RULE> TOKEN: /* COLON_IN_RULE */ +{ + <COLON: ":"> +} + +<*> TOKEN: /* SEMICOLON */ +{ + <SEMICOLON: ";"> +} + +TOKEN : /* LEFT BRACE */ +{ + <LEFT_BRACE: "{"> : IN_RULE +} + +<IN_RULE> TOKEN : /* RIGHT BRACE */ +{ + <RIGHT_BRACE: "}"> : DEFAULT +} + +<IN_RULE> TOKEN : /* JAVA_CODE_RULE START */ +{ + <JAVA_CODE_START: <LEFT_BRACE>> : JAVA_CODE_RULE +} + +<JAVA_CODE_RULE> TOKEN : /* JAVA_CODE_RULE */ +{ + <JAVA_CODE: (~["}"])+ > +} + +<JAVA_CODE_RULE> TOKEN : /* JAVA_CODE_RULE END */ +{ + <JAVA_CODE_END: <RIGHT_BRACE>> : IN_RULE +} + + +<IN_PSEUDOCLASS> TOKEN : /* PROGRAMMATIC_PSEUDOCLASS */ +{ + <PROGRAMMATIC_PSEUDOCLASS: "{" (~["}"])+ "}"> : DEFAULT +} + +<IN_RULE> TOKEN : /* STRINGS */ +{ + <STRING: "\"" (~["\"", "\\", "\n", "\r"])* "\""> +} + +<IN_RULE> TOKEN : /* COLORS */ +{ + <HEXCOLOR: "#" <HEXDIGIT> <HEXDIGIT> <HEXDIGIT> (<HEXDIGIT> <HEXDIGIT> <HEXDIGIT>)?> +| + <#HEXDIGIT: ["0"-"9", "a"-"f", "A"-"F"]> +} + + +<IN_RULE> TOKEN : /* EMS */ +{ + <EMS: <DECIMAL_LITERAL> "em"> +} + + +<IN_RULE> TOKEN : /* EXS */ +{ + <EXS: <DECIMAL_LITERAL> "ex"> +} + + +<IN_RULE> TOKEN : /* LENGTH */ +{ + <LENGTH: <DECIMAL_LITERAL> ("pt" | "mm" | "cm" | "pc" | "in")> +} + + +SimpleNode Stylesheet() : {} +{ + (Rule())* + { return jjtThis; } +} + + +void Rule() : {} +{ + Selectors() + <LEFT_BRACE> Declaration() (";" (Declaration())?)* <RIGHT_BRACE> +} + + +void Selectors() : {} +{ + Selector() ("," Selector())* +} + + +void Selector() : {} +{ + JavaClass() (Id())? (Class())? (PseudoClass())? +| + Id() (Class())? (PseudoClass())? +| + Class() (PseudoClass())? +| + PseudoClass() +} + + +void JavaClass() : {} +{ + <IDENTIFIER> | "*" +} + + +void Id() : {} +{ + "#" <IDENTIFIER> +} + + +void Class() : {} +{ + "." <IDENTIFIER> +} + + +void PseudoClass() : {} +{ + <PSEUDOCLASS_COLON> (<PSEUDOCLASS_IDENTIFIER> | <PROGRAMMATIC_PSEUDOCLASS>) (AnimationProperties())? +} + + +void AnimationProperties() : {} +{ + "[" AnimationProperty() ("," AnimationProperty())* "]" +} + + +void AnimationProperty() : {} +{ + <IDENTIFIER> "=" <DECIMAL_LITERAL> (<IDENTIFIER>)? +} + + +void Declaration() : {} +{ + Property() <COLON> Expression() +} + + +void Property() : {} +{ + <IDENTIFIER> +} + + +void Expression() : {} +{ + (<DECIMAL_LITERAL> | <STRING> | <IDENTIFIER> | <HEXCOLOR> | <EMS> | <EXS> | <LENGTH> | + JavaCode()) +} + + +void JavaCode() : {} +{ + <JAVA_CODE_START> <JAVA_CODE> <JAVA_CODE_END> +} + + +void Identifier() : {} +{ + <IDENTIFIER> +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParser.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/CSSParser.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParser.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParser.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,799 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. CSSParser.java */ +package jaxx.css; + +public class CSSParser/*@bgen(jjtree)*/ implements CSSParserTreeConstants, CSSParserConstants {/*@bgen(jjtree)*/ + protected JJTCSSParserState jjtree = new JJTCSSParserState(); + + public SimpleNode popNode() { + if (jjtree.nodeArity() > 0) // number of child nodes + return (SimpleNode) jjtree.popNode(); + else + return null; + } + + void jjtreeOpenNodeScope(Node n) { + ((SimpleNode) n).firstToken = getToken(1); + } + + void jjtreeCloseNodeScope(Node n) { + ((SimpleNode) n).lastToken = getToken(0); + } + + public static void main(String args[]) { + System.out.println("Reading from standard input..."); + CSSParser css = new CSSParser(System.in); + try { + SimpleNode n = css.Stylesheet(); + n.dump(""); + System.out.println("Thank you."); + } catch (Exception e) { + System.out.println("Oops."); + System.out.println(e.getMessage()); + e.printStackTrace(); + } + } + + final public SimpleNode Stylesheet() throws ParseException { + /*@bgen(jjtree) Stylesheet */ + SimpleNode jjtn000 = new SimpleNode(JJTSTYLESHEET); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + label_1: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + case PSEUDOCLASS_COLON: + case 29: + case 30: + case 31: + ; + break; + default: + jj_la1[0] = jj_gen; + break label_1; + } + Rule(); + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return jjtn000; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + throw new Error("Missing return statement in function"); + } + + final public void Rule() throws ParseException { + /*@bgen(jjtree) Rule */ + SimpleNode jjtn000 = new SimpleNode(JJTRULE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Selectors(); + jj_consume_token(LEFT_BRACE); + Declaration(); + label_2: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case SEMICOLON: + ; + break; + default: + jj_la1[1] = jj_gen; + break label_2; + } + jj_consume_token(SEMICOLON); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + Declaration(); + break; + default: + jj_la1[2] = jj_gen; + ; + } + } + jj_consume_token(RIGHT_BRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Selectors() throws ParseException { + /*@bgen(jjtree) Selectors */ + SimpleNode jjtn000 = new SimpleNode(JJTSELECTORS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Selector(); + label_3: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 28: + ; + break; + default: + jj_la1[3] = jj_gen; + break label_3; + } + jj_consume_token(28); + Selector(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Selector() throws ParseException { + /*@bgen(jjtree) Selector */ + SimpleNode jjtn000 = new SimpleNode(JJTSELECTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + case 29: + JavaClass(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 30: + Id(); + break; + default: + jj_la1[4] = jj_gen; + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 31: + Class(); + break; + default: + jj_la1[5] = jj_gen; + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PSEUDOCLASS_COLON: + PseudoClass(); + break; + default: + jj_la1[6] = jj_gen; + ; + } + break; + case 30: + Id(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 31: + Class(); + break; + default: + jj_la1[7] = jj_gen; + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PSEUDOCLASS_COLON: + PseudoClass(); + break; + default: + jj_la1[8] = jj_gen; + ; + } + break; + case 31: + Class(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PSEUDOCLASS_COLON: + PseudoClass(); + break; + default: + jj_la1[9] = jj_gen; + ; + } + break; + case PSEUDOCLASS_COLON: + PseudoClass(); + break; + default: + jj_la1[10] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void JavaClass() throws ParseException { + /*@bgen(jjtree) JavaClass */ + SimpleNode jjtn000 = new SimpleNode(JJTJAVACLASS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + jj_consume_token(IDENTIFIER); + break; + case 29: + jj_consume_token(29); + break; + default: + jj_la1[11] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Id() throws ParseException { + /*@bgen(jjtree) Id */ + SimpleNode jjtn000 = new SimpleNode(JJTID); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(30); + jj_consume_token(IDENTIFIER); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Class() throws ParseException { + /*@bgen(jjtree) Class */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(31); + jj_consume_token(IDENTIFIER); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PseudoClass() throws ParseException { + /*@bgen(jjtree) PseudoClass */ + SimpleNode jjtn000 = new SimpleNode(JJTPSEUDOCLASS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(PSEUDOCLASS_COLON); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PSEUDOCLASS_IDENTIFIER: + jj_consume_token(PSEUDOCLASS_IDENTIFIER); + break; + case PROGRAMMATIC_PSEUDOCLASS: + jj_consume_token(PROGRAMMATIC_PSEUDOCLASS); + break; + default: + jj_la1[12] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 32: + AnimationProperties(); + break; + default: + jj_la1[13] = jj_gen; + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AnimationProperties() throws ParseException { + /*@bgen(jjtree) AnimationProperties */ + SimpleNode jjtn000 = new SimpleNode(JJTANIMATIONPROPERTIES); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(32); + AnimationProperty(); + label_4: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 28: + ; + break; + default: + jj_la1[14] = jj_gen; + break label_4; + } + jj_consume_token(28); + AnimationProperty(); + } + jj_consume_token(33); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AnimationProperty() throws ParseException { + /*@bgen(jjtree) AnimationProperty */ + SimpleNode jjtn000 = new SimpleNode(JJTANIMATIONPROPERTY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + jj_consume_token(34); + jj_consume_token(DECIMAL_LITERAL); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + jj_consume_token(IDENTIFIER); + break; + default: + jj_la1[15] = jj_gen; + ; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Declaration() throws ParseException { + /*@bgen(jjtree) Declaration */ + SimpleNode jjtn000 = new SimpleNode(JJTDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Property(); + jj_consume_token(COLON); + Expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Property() throws ParseException { + /*@bgen(jjtree) Property */ + SimpleNode jjtn000 = new SimpleNode(JJTPROPERTY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Expression() throws ParseException { + /*@bgen(jjtree) Expression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case DECIMAL_LITERAL: + jj_consume_token(DECIMAL_LITERAL); + break; + case STRING: + jj_consume_token(STRING); + break; + case IDENTIFIER: + jj_consume_token(IDENTIFIER); + break; + case HEXCOLOR: + jj_consume_token(HEXCOLOR); + break; + case EMS: + jj_consume_token(EMS); + break; + case EXS: + jj_consume_token(EXS); + break; + case LENGTH: + jj_consume_token(LENGTH); + break; + case JAVA_CODE_START: + JavaCode(); + break; + default: + jj_la1[16] = jj_gen; + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void JavaCode() throws ParseException { + /*@bgen(jjtree) JavaCode */ + SimpleNode jjtn000 = new SimpleNode(JJTJAVACODE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(JAVA_CODE_START); + jj_consume_token(JAVA_CODE); + jj_consume_token(JAVA_CODE_END); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Identifier() throws ParseException { + /*@bgen(jjtree) Identifier */ + SimpleNode jjtn000 = new SimpleNode(JJTIDENTIFIER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + public CSSParserTokenManager token_source; + SimpleCharStream jj_input_stream; + public Token token, jj_nt; + private int jj_ntk; + private int jj_gen; + final private int[] jj_la1 = new int[17]; + static private int[] jj_la1_0; + static private int[] jj_la1_1; + + static { + jj_la1_0(); + jj_la1_1(); + } + + private static void jj_la1_0() { + jj_la1_0 = new int[]{0xe0002200, 0x8000, 0x200, 0x10000000, 0x40000000, 0x80000000, 0x2000, 0x80000000, 0x2000, 0x2000, 0xe0002200, 0x20000200, 0x201000, 0x0, 0x10000000, 0x200, 0xec40280,}; + } + + private static void jj_la1_1() { + jj_la1_1 = new int[]{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0, 0x0,}; + } + + public CSSParser(java.io.InputStream stream) { + this(stream, null); + } + + public CSSParser(java.io.InputStream stream, String encoding) { + try { + jj_input_stream = new SimpleCharStream(stream, encoding, 1, 1); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + token_source = new CSSParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 17; i++) jj_la1[i] = -1; + } + + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + + public void ReInit(java.io.InputStream stream, String encoding) { + try { + jj_input_stream.ReInit(stream, encoding, 1, 1); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 17; i++) jj_la1[i] = -1; + } + + public CSSParser(java.io.Reader stream) { + jj_input_stream = new SimpleCharStream(stream, 1, 1); + token_source = new CSSParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 17; i++) jj_la1[i] = -1; + } + + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 17; i++) jj_la1[i] = -1; + } + + public CSSParser(CSSParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jj_gen = 0; + for (int i = 0; i < 17; i++) jj_la1[i] = -1; + } + + public void ReInit(CSSParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + jj_gen = 0; + for (int i = 0; i < 17; i++) jj_la1[i] = -1; + } + + final private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + jj_gen++; + return token; + } + token = oldToken; + jj_kind = kind; + throw generateParseException(); + } + + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + jj_gen++; + return token; + } + + final public Token getToken(int index) { + Token t = token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + final private int jj_ntk() { + if ((jj_nt = token.next) == null) + return (jj_ntk = (token.next = token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + private java.util.Vector jj_expentries = new java.util.Vector(); + private int[] jj_expentry; + private int jj_kind = -1; + + public ParseException generateParseException() { + Token errortok = token.next; + int line = errortok.beginLine, column = errortok.beginColumn; + String mess = (errortok.kind == 0) ? tokenImage[0] : errortok.image; + return new ParseException("Parse error. Encountered: " + mess, line, column); + } + + final public void enable_tracing() { + } + + final public void disable_tracing() { + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserConstants.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/CSSParserConstants.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserConstants.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserConstants.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,72 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. CSSParserConstants.java */ +package jaxx.css; + +public interface CSSParserConstants { + + int EOF = 0; + int DECIMAL_LITERAL = 7; + int INTEGER_LITERAL = 8; + int IDENTIFIER = 9; + int LETTER = 10; + int DIGIT = 11; + int PSEUDOCLASS_IDENTIFIER = 12; + int PSEUDOCLASS_COLON = 13; + int COLON = 14; + int SEMICOLON = 15; + int LEFT_BRACE = 16; + int RIGHT_BRACE = 17; + int JAVA_CODE_START = 18; + int JAVA_CODE = 19; + int JAVA_CODE_END = 20; + int PROGRAMMATIC_PSEUDOCLASS = 21; + int STRING = 22; + int HEXCOLOR = 23; + int HEXDIGIT = 24; + int EMS = 25; + int EXS = 26; + int LENGTH = 27; + + int DEFAULT = 0; + int IN_RULE = 1; + int JAVA_CODE_RULE = 2; + int IN_PSEUDOCLASS = 3; + + String[] tokenImage = { + "<EOF>", + "\" \"", + "\"\\t\"", + "\"\\n\"", + "\"\\r\"", + "<token of kind 5>", + "<token of kind 6>", + "<DECIMAL_LITERAL>", + "<INTEGER_LITERAL>", + "<IDENTIFIER>", + "<LETTER>", + "<DIGIT>", + "<PSEUDOCLASS_IDENTIFIER>", + "\":\"", + "\":\"", + "\";\"", + "\"{\"", + "\"}\"", + "<JAVA_CODE_START>", + "<JAVA_CODE>", + "<JAVA_CODE_END>", + "<PROGRAMMATIC_PSEUDOCLASS>", + "<STRING>", + "<HEXCOLOR>", + "<HEXDIGIT>", + "<EMS>", + "<EXS>", + "<LENGTH>", + "\",\"", + "\"*\"", + "\"#\"", + "\".\"", + "\"[\"", + "\"]\"", + "\"=\"", + }; + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTokenManager.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/CSSParserTokenManager.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTokenManager.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTokenManager.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,1152 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. CSSParserTokenManager.java */ +package jaxx.css; + +public class CSSParserTokenManager implements CSSParserConstants { + public java.io.PrintStream debugStream = System.out; + + public void setDebugStream(java.io.PrintStream ds) { + debugStream = ds; + } + + private int jjStopStringLiteralDfa_0(int pos, long active0) { + switch (pos) { + default: + return -1; + } + } + + private int jjStartNfa_0(int pos, long active0) { + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0), pos + 1); + } + + private int jjStopAtPos(int pos, int kind) { + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; + } + + private int jjStartNfaWithStates_0(int pos, int kind, int state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return pos + 1; + } + return jjMoveNfa_0(state, pos + 1); + } + + private int jjMoveStringLiteralDfa0_0() { + switch (curChar) { + case 35: + return jjStopAtPos(0, 30); + case 42: + return jjStopAtPos(0, 29); + case 44: + return jjStopAtPos(0, 28); + case 46: + return jjStopAtPos(0, 31); + case 58: + return jjStopAtPos(0, 13); + case 59: + return jjStopAtPos(0, 15); + case 61: + return jjStopAtPos(0, 34); + case 91: + return jjStopAtPos(0, 32); + case 93: + return jjStopAtPos(0, 33); + case 123: + return jjStopAtPos(0, 16); + default: + return jjMoveNfa_0(3, 0); + } + } + + private void jjCheckNAdd(int state) { + if (jjrounds[state] != jjround) { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } + } + + private void jjAddStates(int start, int end) { + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); + } + + private void jjCheckNAddTwoStates(int state1, int state2) { + jjCheckNAdd(state1); + jjCheckNAdd(state2); + } + + private void jjCheckNAddStates(int start, int end) { + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); + } + + private void jjCheckNAddStates(int start) { + jjCheckNAdd(jjnextStates[start]); + jjCheckNAdd(jjnextStates[start + 1]); + } + + static final long[] jjbitVec0 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL + }; + + private int jjMoveNfa_0(int startState, int curPos) { + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 17; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (; ;) { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) { + long l = 1L << curChar; + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 3: + if ((0x3ff000000000000L & l) != 0L) { + if (kind > 7) + kind = 7; + jjCheckNAddTwoStates(0, 1); + } else if (curChar == 47) + jjAddStates(0, 1); + else if (curChar == 45) { + if (kind > 9) + kind = 9; + jjCheckNAdd(4); + } + break; + case 0: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAddTwoStates(0, 1); + break; + case 1: + if (curChar == 46) + jjCheckNAdd(2); + break; + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAdd(2); + break; + case 4: + if ((0x3ff200000000000L & l) == 0L) + break; + if (kind > 9) + kind = 9; + jjCheckNAdd(4); + break; + case 5: + if (curChar == 47) + jjAddStates(0, 1); + break; + case 6: + if (curChar == 47) + jjCheckNAddStates(2, 4); + break; + case 7: + if ((0xffffffffffffdbffL & l) != 0L) + jjCheckNAddStates(2, 4); + break; + case 8: + if ((0x2400L & l) != 0L && kind > 5) + kind = 5; + break; + case 9: + if (curChar == 10 && kind > 5) + kind = 5; + break; + case 10: + if (curChar == 13) + jjstateSet[jjnewStateCnt++] = 9; + break; + case 11: + if (curChar == 42) + jjCheckNAddTwoStates(12, 13); + break; + case 12: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddTwoStates(12, 13); + break; + case 13: + if (curChar == 42) + jjAddStates(5, 6); + break; + case 14: + if ((0xffff7fffffffffffL & l) != 0L) + jjCheckNAddTwoStates(15, 13); + break; + case 15: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddTwoStates(15, 13); + break; + case 16: + if (curChar == 47 && kind > 6) + kind = 6; + break; + default: + break; + } + } while (i != startsAt); + } else if (curChar < 128) { + long l = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 3: + case 4: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 9) + kind = 9; + jjCheckNAdd(4); + break; + case 7: + jjAddStates(2, 4); + break; + case 12: + jjCheckNAddTwoStates(12, 13); + break; + case 14: + case 15: + jjCheckNAddTwoStates(15, 13); + break; + default: + break; + } + } while (i != startsAt); + } else { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 7: + if ((jjbitVec0[i2] & l2) != 0L) + jjAddStates(2, 4); + break; + case 12: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddTwoStates(12, 13); + break; + case 14: + case 15: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddTwoStates(15, 13); + break; + default: + break; + } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 17 - (jjnewStateCnt = startsAt))) + return curPos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return curPos; + } + } + } + + private int jjStopStringLiteralDfa_3(int pos, long active0) { + switch (pos) { + default: + return -1; + } + } + + private int jjStartNfa_3(int pos, long active0) { + return jjMoveNfa_3(jjStopStringLiteralDfa_3(pos, active0), pos + 1); + } + + private int jjStartNfaWithStates_3(int pos, int kind, int state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return pos + 1; + } + return jjMoveNfa_3(state, pos + 1); + } + + private int jjMoveStringLiteralDfa0_3() { + switch (curChar) { + case 59: + return jjStopAtPos(0, 15); + default: + return jjMoveNfa_3(3, 0); + } + } + + private int jjMoveNfa_3(int startState, int curPos) { + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 8; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (; ;) { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) { + long l = 1L << curChar; + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 3: + if ((0x3ff000000000000L & l) != 0L) { + if (kind > 7) + kind = 7; + jjCheckNAddTwoStates(0, 1); + } else if (curChar == 45) { + if (kind > 12) + kind = 12; + jjCheckNAdd(4); + } + break; + case 0: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAddTwoStates(0, 1); + break; + case 1: + if (curChar == 46) + jjCheckNAdd(2); + break; + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAdd(2); + break; + case 4: + if ((0x3ff200000000000L & l) == 0L) + break; + if (kind > 12) + kind = 12; + jjCheckNAdd(4); + break; + case 6: + jjAddStates(7, 8); + break; + default: + break; + } + } while (i != startsAt); + } else if (curChar < 128) { + long l = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 3: + if ((0x7fffffe87fffffeL & l) != 0L) { + if (kind > 12) + kind = 12; + jjCheckNAdd(4); + } else if (curChar == 123) + jjCheckNAdd(6); + break; + case 4: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 12) + kind = 12; + jjCheckNAdd(4); + break; + case 5: + if (curChar == 123) + jjCheckNAdd(6); + break; + case 6: + if ((0xdfffffffffffffffL & l) != 0L) + jjCheckNAddTwoStates(6, 7); + break; + case 7: + if (curChar == 125) + kind = 21; + break; + default: + break; + } + } while (i != startsAt); + } else { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 6: + if ((jjbitVec0[i2] & l2) != 0L) + jjAddStates(7, 8); + break; + default: + break; + } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 8 - (jjnewStateCnt = startsAt))) + return curPos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return curPos; + } + } + } + + private int jjStopStringLiteralDfa_1(int pos, long active0) { + switch (pos) { + default: + return -1; + } + } + + private int jjStartNfa_1(int pos, long active0) { + return jjMoveNfa_1(jjStopStringLiteralDfa_1(pos, active0), pos + 1); + } + + private int jjStartNfaWithStates_1(int pos, int kind, int state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return pos + 1; + } + return jjMoveNfa_1(state, pos + 1); + } + + private int jjMoveStringLiteralDfa0_1() { + switch (curChar) { + case 58: + return jjStopAtPos(0, 14); + case 59: + return jjStopAtPos(0, 15); + case 125: + return jjStopAtPos(0, 17); + default: + return jjMoveNfa_1(0, 0); + } + } + + private int jjMoveNfa_1(int startState, int curPos) { + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 50; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (; ;) { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) { + long l = 1L << curChar; + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 0: + if ((0x3ff000000000000L & l) != 0L) { + if (kind > 7) + kind = 7; + jjCheckNAddStates(9, 22); + } else if (curChar == 47) + jjAddStates(23, 24); + else if (curChar == 35) + jjstateSet[jjnewStateCnt++] = 7; + else if (curChar == 34) + jjCheckNAddTwoStates(4, 5); + else if (curChar == 45) { + if (kind > 9) + kind = 9; + jjCheckNAdd(1); + } + break; + case 1: + if ((0x3ff200000000000L & l) == 0L) + break; + if (kind > 9) + kind = 9; + jjCheckNAdd(1); + break; + case 3: + if (curChar == 34) + jjCheckNAddTwoStates(4, 5); + break; + case 4: + if ((0xfffffffbffffdbffL & l) != 0L) + jjCheckNAddTwoStates(4, 5); + break; + case 5: + if (curChar == 34 && kind > 22) + kind = 22; + break; + case 6: + if (curChar == 35) + jjstateSet[jjnewStateCnt++] = 7; + break; + case 7: + if ((0x3ff000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 8; + break; + case 8: + if ((0x3ff000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 9; + break; + case 9: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 23) + kind = 23; + jjstateSet[jjnewStateCnt++] = 10; + break; + case 10: + if ((0x3ff000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 11; + break; + case 11: + if ((0x3ff000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 12; + break; + case 12: + if ((0x3ff000000000000L & l) != 0L && kind > 23) + kind = 23; + break; + case 13: + if (curChar == 47) + jjAddStates(23, 24); + break; + case 14: + if (curChar == 47) + jjCheckNAddStates(25, 27); + break; + case 15: + if ((0xffffffffffffdbffL & l) != 0L) + jjCheckNAddStates(25, 27); + break; + case 16: + if ((0x2400L & l) != 0L && kind > 5) + kind = 5; + break; + case 17: + if (curChar == 10 && kind > 5) + kind = 5; + break; + case 18: + if (curChar == 13) + jjstateSet[jjnewStateCnt++] = 17; + break; + case 19: + if (curChar == 42) + jjCheckNAddTwoStates(20, 21); + break; + case 20: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddTwoStates(20, 21); + break; + case 21: + if (curChar == 42) + jjAddStates(28, 29); + break; + case 22: + if ((0xffff7fffffffffffL & l) != 0L) + jjCheckNAddTwoStates(23, 21); + break; + case 23: + if ((0xfffffbffffffffffL & l) != 0L) + jjCheckNAddTwoStates(23, 21); + break; + case 24: + if (curChar == 47 && kind > 6) + kind = 6; + break; + case 25: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAddStates(9, 22); + break; + case 26: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAddTwoStates(26, 27); + break; + case 27: + if (curChar == 46) + jjCheckNAdd(28); + break; + case 28: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAdd(28); + break; + case 29: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(30, 32); + break; + case 30: + if (curChar == 46) + jjCheckNAdd(31); + break; + case 31: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(31, 33); + break; + case 34: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(33, 35); + break; + case 35: + if (curChar == 46) + jjCheckNAdd(36); + break; + case 36: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(36, 38); + break; + case 39: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(36, 41); + break; + case 40: + if (curChar == 46) + jjCheckNAdd(41); + break; + case 41: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(42, 46); + break; + default: + break; + } + } while (i != startsAt); + } else if (curChar < 128) { + long l = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 0: + if ((0x7fffffe87fffffeL & l) != 0L) { + if (kind > 9) + kind = 9; + jjCheckNAdd(1); + } else if (curChar == 123) { + if (kind > 18) + kind = 18; + } + break; + case 1: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 9) + kind = 9; + jjCheckNAdd(1); + break; + case 2: + if (curChar == 123 && kind > 18) + kind = 18; + break; + case 4: + if ((0xffffffffefffffffL & l) != 0L) + jjAddStates(47, 48); + break; + case 7: + if ((0x7e0000007eL & l) != 0L) + jjstateSet[jjnewStateCnt++] = 8; + break; + case 8: + if ((0x7e0000007eL & l) != 0L) + jjstateSet[jjnewStateCnt++] = 9; + break; + case 9: + if ((0x7e0000007eL & l) == 0L) + break; + if (kind > 23) + kind = 23; + jjstateSet[jjnewStateCnt++] = 10; + break; + case 10: + if ((0x7e0000007eL & l) != 0L) + jjstateSet[jjnewStateCnt++] = 11; + break; + case 11: + if ((0x7e0000007eL & l) != 0L) + jjstateSet[jjnewStateCnt++] = 12; + break; + case 12: + if ((0x7e0000007eL & l) != 0L && kind > 23) + kind = 23; + break; + case 15: + jjAddStates(25, 27); + break; + case 20: + jjCheckNAddTwoStates(20, 21); + break; + case 22: + case 23: + jjCheckNAddTwoStates(23, 21); + break; + case 32: + if (curChar == 109 && kind > 25) + kind = 25; + break; + case 33: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 32; + break; + case 37: + if (curChar == 120 && kind > 26) + kind = 26; + break; + case 38: + if (curChar == 101) + jjstateSet[jjnewStateCnt++] = 37; + break; + case 42: + if (curChar == 109 && kind > 27) + kind = 27; + break; + case 43: + if (curChar == 109) + jjCheckNAdd(42); + break; + case 44: + if (curChar == 99) + jjCheckNAdd(42); + break; + case 45: + if (curChar == 110 && kind > 27) + kind = 27; + break; + case 46: + if (curChar == 105) + jjstateSet[jjnewStateCnt++] = 45; + break; + case 47: + if (curChar == 112) + jjAddStates(49, 50); + break; + case 48: + if (curChar == 116 && kind > 27) + kind = 27; + break; + case 49: + if (curChar == 99 && kind > 27) + kind = 27; + break; + default: + break; + } + } while (i != startsAt); + } else { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 4: + if ((jjbitVec0[i2] & l2) != 0L) + jjAddStates(47, 48); + break; + case 15: + if ((jjbitVec0[i2] & l2) != 0L) + jjAddStates(25, 27); + break; + case 20: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddTwoStates(20, 21); + break; + case 22: + case 23: + if ((jjbitVec0[i2] & l2) != 0L) + jjCheckNAddTwoStates(23, 21); + break; + default: + break; + } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 50 - (jjnewStateCnt = startsAt))) + return curPos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return curPos; + } + } + } + + private int jjStopStringLiteralDfa_2(int pos, long active0) { + switch (pos) { + default: + return -1; + } + } + + private int jjStartNfa_2(int pos, long active0) { + return jjMoveNfa_2(jjStopStringLiteralDfa_2(pos, active0), pos + 1); + } + + private int jjStartNfaWithStates_2(int pos, int kind, int state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return pos + 1; + } + return jjMoveNfa_2(state, pos + 1); + } + + private int jjMoveStringLiteralDfa0_2() { + switch (curChar) { + case 59: + return jjStartNfaWithStates_2(0, 15, 3); + default: + return jjMoveNfa_2(4, 0); + } + } + + private int jjMoveNfa_2(int startState, int curPos) { + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 5; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (; ;) { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) { + long l = 1L << curChar; + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 4: + if (kind > 19) + kind = 19; + jjCheckNAdd(3); + if ((0x3ff000000000000L & l) != 0L) { + if (kind > 7) + kind = 7; + jjCheckNAddTwoStates(0, 1); + } + break; + case 0: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAddTwoStates(0, 1); + break; + case 1: + if (curChar == 46) + jjCheckNAdd(2); + break; + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 7) + kind = 7; + jjCheckNAdd(2); + break; + case 3: + if (kind > 19) + kind = 19; + jjCheckNAdd(3); + break; + default: + break; + } + } while (i != startsAt); + } else if (curChar < 128) { + long l = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 4: + if ((0xdfffffffffffffffL & l) != 0L) { + if (kind > 19) + kind = 19; + jjCheckNAdd(3); + } else if (curChar == 125) { + if (kind > 20) + kind = 20; + } + break; + case 3: + if ((0xdfffffffffffffffL & l) == 0L) + break; + kind = 19; + jjCheckNAdd(3); + break; + default: + break; + } + } while (i != startsAt); + } else { + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 4: + case 3: + if ((jjbitVec0[i2] & l2) == 0L) + break; + if (kind > 19) + kind = 19; + jjCheckNAdd(3); + break; + default: + break; + } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 5 - (jjnewStateCnt = startsAt))) + return curPos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return curPos; + } + } + } + + static final int[] jjnextStates = { + 6, 11, 7, 8, 10, 14, 16, 6, 7, 26, 27, 29, 30, 33, 34, 35, + 38, 39, 40, 43, 44, 46, 47, 14, 19, 15, 16, 18, 22, 24, 29, 30, + 33, 34, 35, 38, 39, 40, 43, 44, 46, 47, 41, 43, 44, 46, 47, 4, + 5, 48, 49, + }; + public static final String[] jjstrLiteralImages = { + "", null, null, null, null, null, null, null, null, null, null, null, null, + "\72", "\72", "\73", "\173", "\175", null, null, null, null, null, null, null, null, + null, null, "\54", "\52", "\43", "\56", "\133", "\135", "\75",}; + public static final String[] lexStateNames = { + "DEFAULT", + "IN_RULE", + "JAVA_CODE_RULE", + "IN_PSEUDOCLASS", + }; + public static final int[] jjnewLexState = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 3, -1, -1, 1, 0, 2, -1, 1, 0, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + static final long[] jjtoToken = { + 0x7fefff281L, + }; + static final long[] jjtoSkip = { + 0x7eL, + }; + protected SimpleCharStream input_stream; + private final int[] jjrounds = new int[50]; + private final int[] jjstateSet = new int[100]; + protected char curChar; + + public CSSParserTokenManager(SimpleCharStream stream) { + if (SimpleCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; + } + + public CSSParserTokenManager(SimpleCharStream stream, int lexState) { + this(stream); + SwitchTo(lexState); + } + + public void ReInit(SimpleCharStream stream) { + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); + } + + private void ReInitRounds() { + int i; + jjround = 0x80000001; + for (i = 50; i-- > 0;) + jjrounds[i] = 0x80000000; + } + + public void ReInit(SimpleCharStream stream, int lexState) { + ReInit(stream); + SwitchTo(lexState); + } + + public void SwitchTo(int lexState) { + if (lexState >= 4 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; + } + + protected Token jjFillToken() { + Token t = Token.newToken(jjmatchedKind); + t.kind = jjmatchedKind; + String im = jjstrLiteralImages[jjmatchedKind]; + t.image = (im == null) ? input_stream.GetImage() : im; + t.beginLine = input_stream.getBeginLine(); + t.beginColumn = input_stream.getBeginColumn(); + t.endLine = input_stream.getEndLine(); + t.endColumn = input_stream.getEndColumn(); + return t; + } + + int curLexState = 0; + int defaultLexState = 0; + int jjnewStateCnt; + int jjround; + int jjmatchedPos; + int jjmatchedKind; + + public Token getNextToken() { + int kind; + Token specialToken = null; + Token matchedToken; + int curPos = 0; + + EOFLoop: + for (; ;) { + try { + curChar = input_stream.BeginToken(); + } + catch (java.io.IOException e) { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + return matchedToken; + } + + switch (curLexState) { + case 0: + try { + input_stream.backup(0); + while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L) + curChar = input_stream.BeginToken(); + } + catch (java.io.IOException e1) { + continue EOFLoop; + } + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + break; + case 1: + try { + input_stream.backup(0); + while (curChar <= 32 && (0x100002600L & (1L << curChar)) != 0L) + curChar = input_stream.BeginToken(); + } + catch (java.io.IOException e1) { + continue EOFLoop; + } + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_1(); + break; + case 2: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_2(); + break; + case 3: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_3(); + break; + } + if (jjmatchedKind != 0x7fffffff) { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) { + matchedToken = jjFillToken(); + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + return matchedToken; + } else { + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + continue EOFLoop; + } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { + input_stream.readChar(); + input_stream.backup(1); + } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTreeConstants.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/CSSParserTreeConstants.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTreeConstants.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/CSSParserTreeConstants.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,40 @@ +/* Generated By:JJTree: Do not edit this line. .\CSSParserTreeConstants.java */ + +package jaxx.css; + +public interface CSSParserTreeConstants { + public int JJTSTYLESHEET = 0; + public int JJTRULE = 1; + public int JJTSELECTORS = 2; + public int JJTSELECTOR = 3; + public int JJTJAVACLASS = 4; + public int JJTID = 5; + public int JJTCLASS = 6; + public int JJTPSEUDOCLASS = 7; + public int JJTANIMATIONPROPERTIES = 8; + public int JJTANIMATIONPROPERTY = 9; + public int JJTDECLARATION = 10; + public int JJTPROPERTY = 11; + public int JJTEXPRESSION = 12; + public int JJTJAVACODE = 13; + public int JJTIDENTIFIER = 14; + + + public String[] jjtNodeName = { + "Stylesheet", + "Rule", + "Selectors", + "Selector", + "JavaClass", + "Id", + "Class", + "PseudoClass", + "AnimationProperties", + "AnimationProperty", + "Declaration", + "Property", + "Expression", + "JavaCode", + "Identifier", + }; +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/JJTCSSParserState.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/JJTCSSParserState.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/JJTCSSParserState.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/JJTCSSParserState.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,123 @@ +/* Generated By:JJTree: Do not edit this line. .\JJTCSSParserState.java */ + +package jaxx.css; + +class JJTCSSParserState { + private java.util.Stack<Node> nodes; + private java.util.Stack<Integer> marks; + + private int sp; // number of nodes on stack + private int mk; // current mark + private boolean node_created; + + JJTCSSParserState() { + nodes = new java.util.Stack<Node>(); + marks = new java.util.Stack<Integer>(); + sp = 0; + mk = 0; + } + + /* Determines whether the current node was actually closed and + pushed. This should only be called in the final user action of a + node scope. */ + boolean nodeCreated() { + return node_created; + } + + /* Call this to reinitialize the node stack. It is called +automatically by the parser's ReInit() method. */ + void reset() { + nodes.removeAllElements(); + marks.removeAllElements(); + sp = 0; + mk = 0; + } + + /* Returns the root node of the AST. It only makes sense to call +this after a successful parse. */ + Node rootNode() { + return nodes.elementAt(0); + } + + /* Pushes a node on to the stack. */ + void pushNode(Node n) { + nodes.push(n); + ++sp; + } + + /* Returns the node on the top of the stack, and remove it from the + stack. */ + Node popNode() { + if (--sp < mk) { + mk = marks.pop(); + } + return nodes.pop(); + } + + /* Returns the node currently on the top of the stack. */ + Node peekNode() { + return nodes.peek(); + } + + /* Returns the number of children on the stack in the current node + scope. */ + int nodeArity() { + return sp - mk; + } + + + void clearNodeScope(Node n) { + while (sp > mk) { + popNode(); + } + mk = marks.pop(); + } + + + void openNodeScope(Node n) { + marks.push(mk); + mk = sp; + n.jjtOpen(); + } + + + /* A definite node is constructed from a specified number of +children. That number of nodes are popped from the stack and +made the children of the definite node. Then the definite node +is pushed on to the stack. */ + void closeNodeScope(Node n, int num) { + mk = marks.pop(); + while (num-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, num); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } + + + /* A conditional node is constructed if its condition is true. All +the nodes that have been pushed since the node was opened are +made children of the the conditional node, which is then pushed +on to the stack. If the condition is false the node is not +constructed and they are left on the stack. */ + void closeNodeScope(Node n, boolean condition) { + if (condition) { + int a = nodeArity(); + mk = marks.pop(); + while (a-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, a); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } else { + mk = marks.pop(); + node_created = false; + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Node.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Node.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Node.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Node.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,51 @@ +/* Generated By:JJTree: Do not edit this line. Node.java */ + +package jaxx.css; + +/* All AST nodes must implement this interface. It provides basic + machinery for constructing the parent and child relationships + between nodes. */ + +public interface Node { + + /** + * This method is called after the node has been made the current + * node. It indicates that child nodes can now be added to it. + */ + public void jjtOpen(); + + /** + * This method is called after all the child nodes have been + * added. + */ + public void jjtClose(); + + /** + * This pair of methods are used to inform the node of its + * parent. + * + * @param n node + */ + public void jjtSetParent(Node n); + + public Node jjtGetParent(); + + /** + * This method tells the node to add its argument to the node's + * list of children. + * + * @param n node + * @param i pos + */ + public void jjtAddChild(Node n, int i); + + /** + * @param i pos + * @return a child node. The children are numbered + * from zero, left to right. + */ + public Node jjtGetChild(int i); + + /** @return the number of children the node has. */ + public int jjtGetNumChildren(); +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/ParseException.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/ParseException.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/ParseException.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/ParseException.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,20 @@ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */ +package jaxx.css; + +public class ParseException extends jaxx.parser.ParseException { + private static final long serialVersionUID = 229575674880359031L; + + public ParseException() { + super(); + } + + + public ParseException(String message) { + super(message); + } + + + public ParseException(String message, int line, int column) { + super(message, line, column); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleCharStream.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/SimpleCharStream.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleCharStream.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleCharStream.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,398 @@ +/* Generated By:JavaCC: Do not edit this line. SimpleCharStream.java Version 4.0 */ +package jaxx.css; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (without unicode processing). + */ + +public class SimpleCharStream { + public static final boolean staticFlag = false; + int bufsize; + int available; + int tokenBegin; + public int bufpos = -1; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { + tabSize = i; + } + + protected int getTabSize(int i) { + return tabSize; + } + + + protected void ExpandBuff(boolean wrapAround) { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try { + if (wrapAround) { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, + bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos += (bufsize - tokenBegin)); + } else { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + maxNextCharInd = (bufpos -= tokenBegin); + } + } + catch (Throwable t) { + throw new Error(t.getMessage()); + } + + + bufsize += 2048; + available = bufsize; + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException { + if (maxNextCharInd == available) { + if (available == bufsize) { + if (tokenBegin > 2048) { + bufpos = maxNextCharInd = 0; + available = tokenBegin; + } else if (tokenBegin < 0) + bufpos = maxNextCharInd = 0; + else + ExpandBuff(false); + } else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + int i; + try { + if ((i = inputStream.read(buffer, maxNextCharInd, + available - maxNextCharInd)) == -1) { + inputStream.close(); + throw new java.io.IOException(); + } else + maxNextCharInd += i; + } + catch (java.io.IOException e) { + --bufpos; + backup(0); + if (tokenBegin == -1) + tokenBegin = bufpos; + throw e; + } + } + + public char BeginToken() throws java.io.IOException { + tokenBegin = -1; + char c = readChar(); + tokenBegin = bufpos; + + return c; + } + + protected void UpdateLineColumn(char c) { + column++; + + if (prevCharIsLF) { + prevCharIsLF = false; + line += (column = 1); + } else if (prevCharIsCR) { + prevCharIsCR = false; + if (c == '\n') { + prevCharIsLF = true; + } else + line += (column = 1); + } + + switch (c) { + case '\r': + prevCharIsCR = true; + break; + case '\n': + prevCharIsLF = true; + break; + case '\t': + column--; + column += (tabSize - (column % tabSize)); + break; + default: + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + + public char readChar() throws java.io.IOException { + if (inBuf > 0) { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + if (++bufpos >= maxNextCharInd) + FillBuff(); + + char c = buffer[bufpos]; + + UpdateLineColumn(c); + return (c); + } + + /** + * @return ??? + * @see #getEndColumn + * @deprecated + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + /** + * @return ??? + * @see #getEndLine + * @deprecated + */ + + public int getLine() { + return bufline[bufpos]; + } + + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + public int getEndLine() { + return bufline[bufpos]; + } + + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + public int getBeginLine() { + return bufline[tokenBegin]; + } + + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + + public SimpleCharStream(java.io.Reader dstream, int startline, + int startcolumn) { + this(dstream, startline, startcolumn, 4096); + } + + public SimpleCharStream(java.io.Reader dstream) { + this(dstream, 1, 1, 4096); + } + + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn, int buffersize) { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + bufpos = -1; + } + + public void ReInit(java.io.Reader dstream, int startline, + int startcolumn) { + ReInit(dstream, startline, startcolumn, 4096); + } + + public void ReInit(java.io.Reader dstream) { + ReInit(dstream, 1, 1, 4096); + } + + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + public SimpleCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException { + this(dstream, encoding, startline, startcolumn, 4096); + } + + public SimpleCharStream(java.io.InputStream dstream, int startline, + int startcolumn) { + this(dstream, startline, startcolumn, 4096); + } + + public SimpleCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException { + this(dstream, encoding, 1, 1, 4096); + } + + public SimpleCharStream(java.io.InputStream dstream) { + this(dstream, 1, 1, 4096); + } + + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException { + ReInit(dstream, encoding, 1, 1, 4096); + } + + public void ReInit(java.io.InputStream dstream) { + ReInit(dstream, 1, 1, 4096); + } + + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) { + ReInit(dstream, startline, startcolumn, 4096); + } + + public String GetImage() { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + public char[] GetSuffix(int len) { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + public void Done() { + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + * + * @param newLine ? + * @param newCol ? + */ + public void adjustBeginLineColumn(int newLine, int newCol) { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) { + len = bufpos - tokenBegin + inBuf + 1; + } else { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k; + int nextColDiff, columnDiff = 0; + + while (i < len && + bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleNode.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/SimpleNode.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleNode.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/SimpleNode.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,122 @@ +/* Generated By:JJTree: Do not edit this line. SimpleNode.java */ + +package jaxx.css; + +public class SimpleNode implements Node { + protected Node parent; + protected Node[] children; + protected int id; + protected CSSParser parser; + public Token firstToken; + public Token lastToken; + + + public SimpleNode(int i) { + id = i; + } + + public SimpleNode(CSSParser p, int i) { + this(i); + parser = p; + } + + + public int getId() { + return id; + } + + public void jjtOpen() { + } + + public void jjtClose() { + } + + public void jjtSetParent(Node n) { + parent = n; + } + + public Node jjtGetParent() { + return parent; + } + + public SimpleNode getParent() { + return (SimpleNode) parent; + } + + public void jjtAddChild(Node n, int i) { + if (children == null) { + children = new Node[i + 1]; + } else if (i >= children.length) { + Node c[] = new Node[i + 1]; + System.arraycopy(children, 0, c, 0, children.length); + children = c; + } + children[i] = n; + } + + public Node jjtGetChild(int i) { + return children[i]; + } + + public SimpleNode getChild(int i) { + return (SimpleNode) children[i]; + } + + public int jjtGetNumChildren() { + return (children == null) ? 0 : children.length; + } + + /* You can override these two methods in subclasses of SimpleNode to +customize the way the node appears when the tree is dumped. If +your output uses more than one line you should override +toString(String), otherwise overriding toString() is probably all +you need to do. */ + + @Override + public String toString() { + return getClass().getName() + "[" + getText() + "]"; + } + + public String toString(String prefix) { + return prefix + toString(); + } + + /* Override this method if you want to customize how the node dumps + out its children. */ + + public void dump(String prefix) { + System.out.println(toString(prefix)); + if (children != null) { + for (Node aChildren : children) { + SimpleNode n = (SimpleNode) aChildren; + if (n != null) { + n.dump(prefix + " "); + } + } + } + } + + private void appendSpecialTokens(StringBuffer s, Token st) { + if (st != null) { + appendSpecialTokens(s, st.specialToken); + s.append(st.image); + } + } + + + /** @return the text of the tokens comprising this node. */ + public String getText() { + StringBuffer text = new StringBuffer(); + Token t = firstToken; + while (t != null) { + appendSpecialTokens(text, t.specialToken); + text.append(t.image); + if (t == lastToken) + break; + t = t.next; + } + + return text.toString(); + } +} + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/StylesheetHelper.java (from rev 1097, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/StylesheetHelper.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/StylesheetHelper.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/StylesheetHelper.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,563 @@ +package jaxx.css; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.DataBinding; +import jaxx.compiler.DataSource; +import jaxx.compiler.JAXXCompiler; +import jaxx.parser.JavaParser; +import jaxx.parser.JavaParserTreeConstants; +import jaxx.parser.SimpleNode; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.MethodDescriptor; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.TagManager; +import jaxx.types.TypeManager; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.StringReader; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +/** + * A helper class to compute {@link Stylesheet}, {@link Rule} and {@link Selector} + * and extract all the compiler logic from this class. + * <p/> + * In that way we can make the compiler as a single module and a runtime as another module. + * + * @author chemit + */ +public class StylesheetHelper { + + public static void applyTo(CompiledObject object, JAXXCompiler compiler, Stylesheet stylesheet, Stylesheet overrides) throws CompilerException { + Map<String, String> overriddenProperties; + if (overrides != null) { + overriddenProperties = getApplicableProperties(overrides, object); + //overriddenProperties = overrides.getApplicableProperties(s,object); + } else { + overriddenProperties = null; + } + + Map<String, String> properties = getApplicableProperties(stylesheet, object); + if (properties != null) { + if (overriddenProperties != null) { + properties.keySet().removeAll(overriddenProperties.keySet()); + } + DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + for (Map.Entry<String, String> e : properties.entrySet()) { + String value = e.getValue(); + if (value.equals(Rule.INLINE_ATTRIBUTE) || value.equals(Rule.DATA_BINDING)) { + continue; + } + handler.setAttribute(object, e.getKey(), e.getValue(), false, compiler); + } + } + + Rule[] pseudoClasses = getApplicablePseudoClasses(stylesheet, object); + if (pseudoClasses != null) { + Map<String, Map<String, String>> combinedPseudoClasses = new LinkedHashMap<String, Map<String, String>>(); + for (Rule pseudoClass1 : pseudoClasses) { + Selector[] selectors = pseudoClass1.getSelectors(); + for (Selector selector : selectors) { + if (appliesTo(selector, object) == Selector.PSEUDOCLASS_APPLIES) { + properties = pseudoClass1.getProperties(); + String pseudoClass = selector.getPseudoClass(); + // TODO: overrides by downstream pseudoclasses are not handled + Map<String, String> combinedProperties = combinedPseudoClasses.get(pseudoClass); + if (combinedProperties == null) { + combinedProperties = new HashMap<String, String>(); + combinedPseudoClasses.put(pseudoClass, combinedProperties); + } + combinedProperties.putAll(properties); + } + } + } + + int count = 0; + for (Map.Entry<String, Map<String, String>> e : combinedPseudoClasses.entrySet()) { + applyPseudoClass(e.getKey(), e.getValue(), object, compiler, count++); + } + } + } + + /** + * Replaces all references to the variable "object" with the actual object ID. + * + * @param code ? + * @param id ? + * @return ? + * @throws jaxx.CompilerException ? + */ + public static String replaceObjectReferences(String code, String id) throws CompilerException { + JavaParser p = new JavaParser(new StringReader(code + ";")); + p.Expression(); + jaxx.parser.SimpleNode node = p.popNode(); + scanNode(node, id); + return node.getText(); + } + + public static void scanNode(SimpleNode node, String id) { + if (node.getId() == JavaParserTreeConstants.JJTNAME) { + String name = node.getText(); + if (name.equals("object") || (name.indexOf(".") != -1 && name.substring(0, name.indexOf(".")).trim().equals("object"))) { + node.firstToken.image = id; + } + } else { + int count = node.jjtGetNumChildren(); + for (int i = 0; i < count; i++) { + scanNode(node.getChild(i), id); + } + } + } + + public static void compilePseudoClassAdd(String pseudoClass, CompiledObject object, String propertyCode, JAXXCompiler compiler) throws CompilerException { + + if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".add"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + pseudoClass + ") { " + propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");"); + return; + } + + MouseEventEnum constant = MouseEventEnum.valueOf(pseudoClass); + + String property = null; + switch (constant) { + case mousedown: + property = "mousePressed"; + break; + case mouseout: + property = "mouseExited"; + break; + case mouseover: + property = "mouseEntered"; + break; + case mouseup: + property = "mouseReleased"; + break; + } + + ClassDescriptor mouseListenerDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseListener.class); + ClassDescriptor mouseEventDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseEvent.class); + + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", mouseListenerDescriptor); + MethodDescriptor methodDescriptor = mouseListenerDescriptor.getMethodDescriptor(property, mouseEventDescriptor); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, methodDescriptor, propertyCode, compiler); + + } catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + + /*if (pseudoClass.equals("mouseover")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseEntered", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseout")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseExited", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + compiler.appendInitDataBindings("{" + propertyCode + "}"); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseout pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mousedown")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mousePressed", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mousedown pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseup")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".add", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseReleased", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + compiler.appendInitDataBindings("{" + propertyCode + "}"); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseup pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".add"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + pseudoClass + ") { "+ propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding("+ destCode + ");"); + } else + throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass);*/ + } + + public static void compilePseudoClassRemove(String pseudoClass, CompiledObject object, String propertyCode, JAXXCompiler compiler) throws CompilerException { + if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".remove"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + invert(pseudoClass) + ") { " + propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");"); + return; + } + + MouseEventEnum constant = MouseEventEnum.valueOf(pseudoClass); + + String property = null; + switch (constant) { + case mousedown: + property = "mousePressed"; + break; + case mouseout: + property = "mouseReleased"; + break; + case mouseover: + property = "mouseExited"; + break; + case mouseup: + property = "mousePressed"; + break; + } + + ClassDescriptor mouseListenerDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseListener.class); + ClassDescriptor mouseEventDescriptor = ClassDescriptorLoader.getClassDescriptor(MouseEvent.class); + + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", mouseListenerDescriptor); + MethodDescriptor methodDescriptor = mouseListenerDescriptor.getMethodDescriptor(property, mouseEventDescriptor); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, methodDescriptor, propertyCode, compiler); + + } catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + + /*if (pseudoClass.equals("mouseover")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseExited", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseover pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseout")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseEntered", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseout pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mousedown")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseReleased", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mousedown pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.equals("mouseup")) { + try { + MethodDescriptor addMouseListener = object.getObjectClass().getMethodDescriptor("addMouseListener", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseListener.class)}); + object.addEventHandler("style." + pseudoClass + ".remove", addMouseListener, + ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mousePressed", + new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}), + propertyCode, compiler); + } + catch (NoSuchMethodException e) { + compiler.reportError("mouseup pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)"); + } + } else if (pseudoClass.startsWith("{")) { + pseudoClass = pseudoClass.substring(1, pseudoClass.length() - 1).trim(); + pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode()); + String dest = object.getId() + ".style." + pseudoClass + ".remove"; + String destCode = TypeManager.getJavaCode(dest); + if (compiler.haveProcessDataBinding()) { + compiler.appendProcessDataBinding("else "); + } + compiler.appendProcessDataBinding("if ($dest.equals(" + destCode + ")) { if (" + invert(pseudoClass) + ") { " + propertyCode + "} }"); + new DataSource(dest, pseudoClass, compiler).compile("new jaxx.runtime.DataBindingListener(" + compiler.getRootObject().getJavaCode() + ", " + destCode + ")"); + compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");"); + } else { + throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass); + }*/ + } + + public static String invert(String javaCode) { + javaCode = javaCode.trim(); + return javaCode.startsWith("!") ? javaCode.substring(1) : "!(" + javaCode + ")"; + } + + public static String unwrap(ClassDescriptor type, String valueCode) { + if (type == ClassDescriptorLoader.getClassDescriptor(boolean.class)) { + return "((java.lang.Boolean) " + valueCode + ").booleanValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(byte.class)) { + return "((java.lang.Byte) " + valueCode + ").byteValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(short.class)) { + return "((java.lang.Short) " + valueCode + ").shortValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(int.class)) { + return "((java.lang.Integer) " + valueCode + ").intValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(long.class)) { + return "((java.lang.Long) " + valueCode + ").longValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(float.class)) { + return "((java.lang.Float) " + valueCode + ").floatValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(double.class)) { + return "((java.lang.Double) " + valueCode + ").doubleValue()"; + } else if (type == ClassDescriptorLoader.getClassDescriptor(char.class)) { + return "((java.lang.Character) " + valueCode + ").charValue()"; + } else { + return valueCode; + } + } + + public static void applyPseudoClass(String pseudoClass, Map<String, String> properties, + CompiledObject object, JAXXCompiler compiler, int priority) throws CompilerException { + if (pseudoClass.indexOf("[") != -1) { + pseudoClass = pseudoClass.substring(0, pseudoClass.indexOf("[")); + } + final StringBuffer buffer = new StringBuffer(); + /*CompiledObject bufferObject = new CompiledObject(object.getId(), object.getJavaCode(), object.getObjectClass(), compiler, true) { + public void appendInitializationCode(String code) { + buffer.append(code); + } + public void registerDataBinding(String src, String property, String assignment, JAXXCompiler compiler) throws CompilerException { + buffer.append(assignment); + } + };*/ + + DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + boolean valueDeclared = false; + for (Map.Entry<String, String> e : properties.entrySet()) { + String property = e.getKey(); + ClassDescriptor type = handler.getPropertyType(object, property, compiler); + String dataBinding = compiler.processDataBindings(e.getValue(), type); + String valueCode; + if (dataBinding != null) { + valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; + new DataBinding(dataBinding, object.getId() + "." + property + "." + priority, handler.getSetPropertyCode(object.getJavaCode(), + property, "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBinding, compiler), compiler).compile(false); + } else { + try { + Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; + valueCode = TypeManager.getJavaCode(TypeManager.convertFromString(e.getValue(), typeClass)); + } + catch (ClassNotFoundException ex) { + compiler.reportError("could not find class " + type.getName()); + return; + } + } + if (!valueDeclared) { + buffer.append("java.lang.Object "); + valueDeclared = true; + } + buffer.append("value = jaxx.runtime.css.Pseudoclasses.applyProperty(").append(compiler.getOutputClassName()).append(".this, ").append(object.getJavaCode()).append(", ").append(TypeManager.getJavaCode(property)).append(", ").append(valueCode).append(", jaxx.runtime.css.Pseudoclasses.wrap(").append(handler.getGetPropertyCode(object.getJavaCode(), property, compiler)).append("), ").append(priority).append(");").append(JAXXCompiler.getLineSeparator()); + buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {").append(JAXXCompiler.getLineSeparator()); + String unwrappedValue = unwrap(type, "value"); + buffer.append(" ").append(handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompiler.getCanonicalName(type) + + ") " + unwrappedValue, compiler)).append(JAXXCompiler.getLineSeparator()); + buffer.append("}").append(JAXXCompiler.getLineSeparator()); + } + + if (pseudoClass.equals("focused")) { + pseudoClass = "{ object.hasFocus() }"; + } else if (pseudoClass.equals("unfocused")) { + pseudoClass = "{ !object.hasFocus() }"; + } else if (pseudoClass.equals("enabled")) { + pseudoClass = "{ object.isEnabled() }"; + } else if (pseudoClass.equals("disabled")) { + pseudoClass = "{ !object.isEnabled() }"; + } else if (pseudoClass.equals("selected")) { + pseudoClass = "{ object.isSelected() }"; + } else if (pseudoClass.equals("deselected")) { + pseudoClass = "{ !object.isSelected() }"; + } + + compilePseudoClassAdd(pseudoClass, object, buffer.toString(), compiler); + + buffer.setLength(0); + valueDeclared = false; + for (Map.Entry<String, String> e : properties.entrySet()) { + String property = e.getKey(); + ClassDescriptor type = handler.getPropertyType(object, property, compiler); + String dataBinding = compiler.processDataBindings(e.getValue(), type); + String valueCode; + if (dataBinding != null) { + valueCode = "new jaxx.runtime.css.DataBinding(" + TypeManager.getJavaCode(object.getId() + "." + property + "." + priority) + ")"; + new DataBinding(dataBinding, object.getId() + "." + property + "." + priority, handler.getSetPropertyCode(object.getJavaCode(), + property, "(" + JAXXCompiler.getCanonicalName(type) + ") " + dataBinding, compiler), compiler).compile(false); + } else { + try { + Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; + valueCode = TypeManager.getJavaCode(TypeManager.convertFromString(e.getValue(), typeClass)); + } + catch (ClassNotFoundException ex) { + compiler.reportError("could not find class " + type.getName()); + return; + } + } + if (!valueDeclared) { + buffer.append("java.lang.Object "); + valueDeclared = true; + } + buffer.append("value = jaxx.runtime.css.Pseudoclasses.removeProperty(").append(compiler.getOutputClassName()).append(".this, ").append(object.getJavaCode()).append(", ").append(TypeManager.getJavaCode(property)).append(", ").append(valueCode).append(", jaxx.runtime.css.Pseudoclasses.wrap(").append(handler.getGetPropertyCode(object.getJavaCode(), property, compiler)).append("), ").append(priority).append(");").append(JAXXCompiler.getLineSeparator()); + buffer.append("if (!(value instanceof jaxx.runtime.css.DataBinding)) {").append(JAXXCompiler.getLineSeparator()); + String unwrappedValue = unwrap(type, "value"); + buffer.append(" ").append(handler.getSetPropertyCode(object.getJavaCode(), property, "(" + JAXXCompiler.getCanonicalName(type) + + ") " + unwrappedValue, compiler)).append(JAXXCompiler.getLineSeparator()); + buffer.append("}").append(JAXXCompiler.getLineSeparator()); + } + compilePseudoClassRemove(pseudoClass, object, buffer.toString(), compiler); + } + + public static Map<String, String> getApplicableProperties(Stylesheet s, CompiledObject object) throws CompilerException { + DefaultObjectHandler handler = TagManager.getTagHandler(object.getObjectClass()); + Map<String, String> result = null; + for (Rule rule : s.getRules()) { + int apply = appliesTo(rule, object); + if (apply == Selector.ALWAYS_APPLIES || apply == Selector.ALWAYS_APPLIES_INHERIT_ONLY) { + if (result == null) { + result = new HashMap<String, String>(); + } + for (Map.Entry<String, String> entry : rule.getProperties().entrySet()) { + String property = entry.getKey(); + if (apply == Selector.ALWAYS_APPLIES || handler.isPropertyInherited(property)) { + result.put(property, entry.getValue()); + } + } + } + } + return result; + } + + public static Rule[] getApplicablePseudoClasses(Stylesheet s, CompiledObject object) throws CompilerException { + List<Rule> result = null; + for (Rule rule : s.getRules()) { + if (appliesTo(rule, object) == Selector.PSEUDOCLASS_APPLIES) { + if (result == null) { + result = new ArrayList<Rule>(); + } + result.add(rule); + } + } + return result != null ? result.toArray(new Rule[result.size()]) : null; + } + + public static Rule inlineAttribute(CompiledObject object, String propertyName, boolean dataBinding) { + Map<String, String> properties = new HashMap<String, String>(); + properties.put(propertyName, dataBinding ? Rule.DATA_BINDING : Rule.INLINE_ATTRIBUTE); + return new Rule(new Selector[]{new Selector(null, null, null, object.getId(), true)}, properties); + } + + public static int appliesTo(Rule rule, CompiledObject object) throws CompilerException { + int appliesTo = Selector.NEVER_APPLIES; + for (Selector selector : rule.getSelectors()) { + appliesTo = Math.max(appliesTo(selector, object), appliesTo); + if (appliesTo == Selector.ALWAYS_APPLIES || appliesTo == Selector.ALWAYS_APPLIES_INHERIT_ONLY) { + break; + } + } + return appliesTo; + } + + public static int appliesTo(Selector selector, CompiledObject object) { + boolean inheritOnly = false; + CompiledObject parent = object; + String javaClassName = selector.getJavaClassName(); + String styleClass = selector.getStyleClass(); + String pseudoClass = selector.getPseudoClass(); + String id = selector.getId(); + + while (parent != null) { + boolean classMatch = (javaClassName == null); + if (!classMatch) { + ClassDescriptor javaClass = parent.getObjectClass(); + do { + String name = javaClass.getName(); + if (name.equals(javaClassName) || name.substring(name.lastIndexOf(".") + 1).equals(javaClassName)) { + classMatch = true; + break; + } + javaClass = javaClass.getSuperclass(); + } + while (javaClass != null); + } + + boolean styleClassMatch = (styleClass == null || styleClass.equals(parent.getStyleClass())); + + String objectId = parent.getId(); + objectId = objectId.substring(objectId.lastIndexOf(".") + 1); + boolean idMatch = (id == null || (' ' + objectId + ' ').indexOf(' ' + id + ' ') > -1); + + if (classMatch && styleClassMatch && idMatch) { + if (pseudoClass != null) { + return inheritOnly ? Selector.PSEUDOCLASS_APPLIES_INHERIT_ONLY : Selector.PSEUDOCLASS_APPLIES; + } else { + return inheritOnly ? Selector.ALWAYS_APPLIES_INHERIT_ONLY : Selector.ALWAYS_APPLIES; + } + } + + parent = parent.getParent(); + inheritOnly = true; + } + return Selector.NEVER_APPLIES; + } + + public enum MouseEventEnum { + mouseover, + mouseout, + mousedown, + mouseup + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Token.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Token.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Token.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/Token.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,76 @@ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */ +package jaxx.css; + +/** Describes the input token stream. */ + +public class Token { + + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** + * beginLine and beginColumn describe the position of the first character + * of this token; endLine and endColumn describe the position of the + * last character of this token. + */ + public int beginLine, beginColumn, endLine, endColumn; + + /** The string image of the token. */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** Returns the image. */ + public String toString() { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simlpy add something like : + * <p/> + * case MyParserConstants.ID : return new IDToken(); + * <p/> + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use it in your lexical actions. + * + * @param ofKind kind of token + * @return the new token + */ + public static Token newToken(int ofKind) { + switch (ofKind) { + default: + return new Token(); + } + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/TokenMgrError.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/TokenMgrError.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/TokenMgrError.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/css/TokenMgrError.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,126 @@ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */ +package jaxx.css; + +public class TokenMgrError extends Error { + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** Lexical error occured. */ + static final int LEXICAL_ERROR = 0; + + /** An attempt wass made to create a second instance of a static token manager. */ + static final int STATIC_LEXER_ERROR = 1; + + /** Tried to change to an invalid lexical state. */ + static final int INVALID_LEXICAL_STATE = 2; + + /** Detected (and bailed out of) an infinite loop in the token manager. */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + private static final long serialVersionUID = -4308847190164230336L; + + /** + * Replaces unprintable characters by their espaced (or unicode escaped) + * equivalents in the given string + * + * @param str text to espace + * @return the espaced text + */ + protected static String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) { + case 0: + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u").append(s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + } + } + return retval.toString(); + } + + /** + * @param EOFSeen : indicates if EOF caused the lexicl error + * @param lexState : lexical state in which this error occured + * @param errorLine : line number when the error occured + * @param errorColumn : column number when the error occured + * @param errorAfter : prefix that was seen before this error occured + * @param curChar : the offending character + * Note: You can customize the lexical error message by modifying this method. + * @return a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return ("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int) curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * <p/> + * "Internal Error : Please file a bug report .... " + * <p/> + * from this method for such cases in the release version of your parser. + */ + @Override + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + public TokenMgrError() { + } + + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/introspection/JAXXBeanDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,14 @@ +package jaxx.introspection; + +import jaxx.reflect.ClassDescriptor; + +/** + * Mirrors the class <code>java.beans.BeanDescriptor</code>. JAXX uses its own introspector rather than the built-in + * <code>java.beans.Introspector</code> so that it can introspect {@link jaxx.reflect.ClassDescriptor}, + * not just <code>java.lang.Class</code>. + */ +public class JAXXBeanDescriptor extends JAXXFeatureDescriptor { + public JAXXBeanDescriptor(ClassDescriptor beanClass) { + super(beanClass, beanClass.getName()); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanInfo.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/introspection/JAXXBeanInfo.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanInfo.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXBeanInfo.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,36 @@ +package jaxx.introspection; + +/** + * Mirrors the class <code>java.beans.BeanInfo</code>. JAXX uses its own introspector rather than the built-in + * <code>java.beans.Introspector</code> so that it can introspect {@link jaxx.reflect.ClassDescriptor}, + * not just <code>java.lang.Class</code>. + */ +public class JAXXBeanInfo { + private JAXXBeanDescriptor beanDescriptor; + private JAXXPropertyDescriptor[] propertyDescriptors; + private JAXXEventSetDescriptor[] eventSetDescriptors; + + + public JAXXBeanInfo(JAXXBeanDescriptor beanDescriptor, + JAXXPropertyDescriptor[] propertyDescriptors, + JAXXEventSetDescriptor[] eventSetDescriptors) { + this.beanDescriptor = beanDescriptor; + this.propertyDescriptors = propertyDescriptors; + this.eventSetDescriptors = eventSetDescriptors; + } + + + public JAXXBeanDescriptor getJAXXBeanDescriptor() { + return beanDescriptor; + } + + + public JAXXPropertyDescriptor[] getJAXXPropertyDescriptors() { + return propertyDescriptors; + } + + + public JAXXEventSetDescriptor[] getJAXXEventSetDescriptors() { + return eventSetDescriptors; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXEventSetDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/introspection/JAXXEventSetDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXEventSetDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXEventSetDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,39 @@ +package jaxx.introspection; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.MethodDescriptor; + +/** + * Mirrors the class <code>java.beans.EventSetDescriptor</code>. JAXX uses its own introspector rather than the built-in + * <code>java.beans.Introspector</code> so that it can introspect {@link jaxx.reflect.ClassDescriptor}, + * not just <code>java.lang.Class</code>. + */ +public class JAXXEventSetDescriptor extends JAXXFeatureDescriptor { + private MethodDescriptor addListenerMethod; + private MethodDescriptor removeListenerMethod; + private MethodDescriptor[] listenerMethods; + + + public JAXXEventSetDescriptor(ClassDescriptor classDescriptor, String name, MethodDescriptor addListenerMethod, + MethodDescriptor removeListenerMethod, MethodDescriptor[] listenerMethods) { + super(classDescriptor, name); + this.addListenerMethod = addListenerMethod; + this.removeListenerMethod = removeListenerMethod; + this.listenerMethods = listenerMethods; + } + + + public MethodDescriptor getAddListenerMethod() { + return addListenerMethod; + } + + + public MethodDescriptor getRemoveListenerMethod() { + return removeListenerMethod; + } + + + public MethodDescriptor[] getListenerMethods() { + return listenerMethods; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXFeatureDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/introspection/JAXXFeatureDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXFeatureDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXFeatureDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,55 @@ +package jaxx.introspection; + +import jaxx.reflect.ClassDescriptor; + +import java.util.HashMap; +import java.util.Map; + +/** + * Mirrors the class <code>java.beans.FeatureDescriptor</code>. JAXX uses its own introspector rather than the built-in + * <code>java.beans.Introspector</code> so that it can introspect {@link jaxx.reflect.ClassDescriptor}, + * not just <code>java.lang.Class</code>. + */ +public class JAXXFeatureDescriptor { + private String name; + private Map<String, Object> values; + private ClassDescriptor classDescriptor; + + + JAXXFeatureDescriptor(ClassDescriptor classDescriptor, String name) { + if (name == null || classDescriptor == null) + throw new NullPointerException(); + this.name = name; + this.classDescriptor = classDescriptor; + } + + + public String getName() { + return name; + } + + + public ClassDescriptor getClassDescriptor() { + return classDescriptor; + } + + + public Object getValue(String key) { + return values != null ? values.get(key) : null; + } + + + public void setValue(String key, Object value) { + if (values == null) + values = new HashMap<String, Object>(); + values.put(key, value); + } + + + public static String capitalize(String name) { + if (name.length() == 0) + return name; + else + return Character.toUpperCase(name.charAt(0)) + name.substring(1); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXIntrospector.java (from rev 1098, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/introspection/JAXXIntrospector.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXIntrospector.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXIntrospector.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,176 @@ +package jaxx.introspection; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.MethodDescriptor; + +import java.beans.BeanDescriptor; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyChangeListener; +import java.beans.PropertyDescriptor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Enumeration; +import java.util.EventListener; +import java.util.HashMap; +import java.util.Map; + +/** + * Performs introspection on a <code>ClassDescriptor</code>. Ideally, I could just have copied Sun's Introspector + * and changed a few things, but the licensing terms are incompatible. This implementation is incomplete -- it only + * bothers to report info that JAXX actually checks. It also relaxes some of Introspector's rules a bit, but I + * don't believe it results in any meaningful incompatibilities. + * <p/> + * JAXX uses its own introspector rather than the built-in + * <code>java.beans.Introspector</code> so that it can introspect {@link jaxx.reflect.ClassDescriptor}, + * not just <code>java.lang.Class</code>. + */ +public class JAXXIntrospector { + private ClassDescriptor classDescriptor; + private Map<String, JAXXPropertyDescriptor> propertyDescriptors = new HashMap<String, JAXXPropertyDescriptor>(); + private Map<String, JAXXEventSetDescriptor> eventSetDescriptors = new HashMap<String, JAXXEventSetDescriptor>(); + + private JAXXIntrospector(ClassDescriptor classDescriptor) { + this.classDescriptor = classDescriptor; + } + + + /** + * Returns the <code>JAXXBeanInfo</code> for a given class. + * + * @param classDescriptor the class to introspect + * @return the <code>JAXXBeanInfo</code> for the bean class + * @throws IntrospectionException if an error occurs + */ + public static JAXXBeanInfo getJAXXBeanInfo(ClassDescriptor classDescriptor) throws IntrospectionException { + JAXXIntrospector introspector = new JAXXIntrospector(classDescriptor); + return introspector.createBeanInfo(); + } + + + private JAXXBeanInfo createBeanInfo() { + ClassDescriptor explicitInfoClass = classDescriptor; + BeanInfo explicitBeanInfo = null; + while (explicitInfoClass != null) { + explicitBeanInfo = getExplicitBeanInfo(explicitInfoClass); + if (explicitBeanInfo != null) + break; + explicitInfoClass = explicitInfoClass.getSuperclass(); + } + + if (explicitBeanInfo != null) { + PropertyDescriptor[] explicitProperties = explicitBeanInfo.getPropertyDescriptors(); + for (PropertyDescriptor explicitProperty : explicitProperties) { + Class type = explicitProperty.getPropertyType(); + Method readMethod = explicitProperty.getReadMethod(); + Method writeMethod = explicitProperty.getWriteMethod(); + try { + ClassDescriptor typeDescriptor = ClassDescriptorLoader.getClassDescriptor(type.getName(), type.getClassLoader()); + JAXXPropertyDescriptor propertyDescriptor = new JAXXPropertyDescriptor(classDescriptor, explicitProperty.getName(), + readMethod != null ? classDescriptor.getMethodDescriptor(readMethod.getName()) : null, + writeMethod != null ? classDescriptor.getMethodDescriptor(writeMethod.getName(), typeDescriptor) : null); + propertyDescriptor.setBound(explicitProperty.isBound()); + Enumeration<String> attributeNames = explicitProperty.attributeNames(); + while (attributeNames.hasMoreElements()) { + String name = attributeNames.nextElement(); + propertyDescriptor.setValue(name, explicitProperty.getValue(name)); + } + propertyDescriptors.put(propertyDescriptor.getName(), propertyDescriptor); + } + catch (ClassNotFoundException e) { + throw new RuntimeException("Internal error: Could not find ClassDescriptor corresponding to Java " + type, e); + } + catch (NoSuchMethodException e) { + throw new RuntimeException("Internal error: Could not find expected MethodDescriptor in " + classDescriptor, e); + } + } + } + + // if the class broadcasts PropertyChangeEvent, assume all properties are bound (java.beans.Introspector + // does the same) + boolean propertyChangeSource; + try { + classDescriptor.getMethodDescriptor("addPropertyChangeListener", ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)); + propertyChangeSource = true; + } + catch (NoSuchMethodException e) { + propertyChangeSource = false; + } + + MethodDescriptor[] methods = classDescriptor.getMethodDescriptors(); + for (MethodDescriptor method : methods) { + String name = method.getName(); + if (name.startsWith("get") && name.length() > 3 && Character.isUpperCase(name.charAt(3)) && method.getParameterTypes().length == 0) { + String propertyName = Introspector.decapitalize(name.substring(3)); + if (!propertyDescriptors.containsKey(propertyName)) + propertyDescriptors.put(propertyName, new JAXXPropertyDescriptor(classDescriptor, propertyName, method, null, propertyChangeSource)); + } else + if (name.startsWith("is") && name.length() > 2 && Character.isUpperCase(name.charAt(2)) && method.getParameterTypes().length == 0) { + String propertyName = Introspector.decapitalize(name.substring(2)); + if (!propertyDescriptors.containsKey(propertyName)) + propertyDescriptors.put(propertyName, new JAXXPropertyDescriptor(classDescriptor, propertyName, method, null, propertyChangeSource)); + } else + if (name.startsWith("set") && name.length() > 3 && Character.isUpperCase(name.charAt(3)) && method.getParameterTypes().length == 1) { + String propertyName = Introspector.decapitalize(name.substring(3)); + if (!propertyDescriptors.containsKey(propertyName)) + propertyDescriptors.put(propertyName, new JAXXPropertyDescriptor(classDescriptor, propertyName, null, method, propertyChangeSource)); + } else + if (name.startsWith("add") && name.length() > 3 && Character.isUpperCase(name.charAt(3))) { + ClassDescriptor[] parameters = method.getParameterTypes(); + if (parameters.length != 1 || !ClassDescriptorLoader.getClassDescriptor(EventListener.class).isAssignableFrom(parameters[0])) + continue; // not an event listener method + try { + String eventSetName = method.getName().substring(3); + MethodDescriptor remove = classDescriptor.getMethodDescriptor("remove" + eventSetName, parameters); + eventSetDescriptors.put(eventSetName, new JAXXEventSetDescriptor(classDescriptor, eventSetName, method, remove, parameters[0].getMethodDescriptors())); + } + catch (NoSuchMethodException e) { + // no matching remove method, not a valid event + } + } + } + + JAXXBeanDescriptor beanDescriptor = new JAXXBeanDescriptor(classDescriptor); + if (explicitBeanInfo != null) { + BeanDescriptor explicitBeanDescriptor = explicitBeanInfo.getBeanDescriptor(); + if (explicitBeanDescriptor != null) { + Enumeration/*<String>*/ attributeNames = explicitBeanDescriptor.attributeNames(); + while (attributeNames.hasMoreElements()) { + String name = (String) attributeNames.nextElement(); + beanDescriptor.setValue(name, explicitBeanDescriptor.getValue(name)); + } + } + } + + return new JAXXBeanInfo(beanDescriptor, + propertyDescriptors.values().toArray(new JAXXPropertyDescriptor[propertyDescriptors.size()]), + eventSetDescriptors.values().toArray(new JAXXEventSetDescriptor[eventSetDescriptors.size()])); + } + + + private static BeanInfo getExplicitBeanInfo(ClassDescriptor classDescriptor) { + try { + Class beanClass = Class.forName(classDescriptor.getName(), true, classDescriptor.getClassLoader()); // see if there is a class by that name in this package + Method findExplicitBeanInfo = Introspector.class.getDeclaredMethod("findExplicitBeanInfo", new Class[]{Class.class}); + findExplicitBeanInfo.setAccessible(true); + return (BeanInfo) findExplicitBeanInfo.invoke(null, beanClass); + } + catch (ClassNotFoundException e) { + return null; // happens for uncompiled classes + } + catch (NoClassDefFoundError e) { + return null; // wrong case, etc. + } + catch (NoSuchMethodException e) { + throw new RuntimeException("Error: could not find method 'findExplicitBeanInfo' in java.beans.Introspector. You are most likely running a version of Java against which JAXX has not been tested."); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXPropertyDescriptor.java (from rev 1098, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/introspection/JAXXPropertyDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXPropertyDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/introspection/JAXXPropertyDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,96 @@ +package jaxx.introspection; + +import jaxx.CompilerException; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.MethodDescriptor; + +/** + * Mirrors the class <code>java.beans.PropertyDescriptor</code>. JAXX uses its own introspector rather than the built-in + * <code>java.beans.Introspector</code> so that it can introspect {@link jaxx.reflect.ClassDescriptor}, + * not just <code>java.lang.Class</code>. + */ +public class JAXXPropertyDescriptor extends JAXXFeatureDescriptor { + private ClassDescriptor propertyType; + private MethodDescriptor readMethod; + private MethodDescriptor writeMethod; + private boolean bound; + + public JAXXPropertyDescriptor(ClassDescriptor classDescriptor, String propertyName) { + this(classDescriptor, propertyName, null, null); + } + + + public JAXXPropertyDescriptor(ClassDescriptor classDescriptor, String propertyName, + MethodDescriptor readMethod, MethodDescriptor writeMethod) { + this(classDescriptor, propertyName, readMethod, writeMethod, false); + } + + + public JAXXPropertyDescriptor(ClassDescriptor classDescriptor, String propertyName, + MethodDescriptor readMethod, MethodDescriptor writeMethod, + boolean bound) { + super(classDescriptor, propertyName); + this.readMethod = readMethod; + this.writeMethod = writeMethod; + this.bound = bound; + } + + + public MethodDescriptor getReadMethodDescriptor() { + if (readMethod == null) { + try { + readMethod = getClassDescriptor().getMethodDescriptor("get" + capitalize(getName())); + } + catch (NoSuchMethodException e) { + try { + readMethod = getClassDescriptor().getMethodDescriptor("is" + capitalize(getName())); + } + catch (NoSuchMethodException e2) { + } + } + } + return readMethod; + } + + + public MethodDescriptor getWriteMethodDescriptor() { + if (writeMethod == null) { + try { + String methodName = "set" + capitalize(getName()); + MethodDescriptor read = getReadMethodDescriptor(); + if (read != null) { + writeMethod = getClassDescriptor().getMethodDescriptor(methodName, read.getReturnType()); + } else { + throw new CompilerException("Internal error: requesting 'set' method for property of unknown type: '" + getName() + "' (in " + getClassDescriptor() + ")"); + } + } + catch (NoSuchMethodException e) { + } + } + return writeMethod; + } + + + public ClassDescriptor getPropertyType() { + if (propertyType == null) { + MethodDescriptor read = getReadMethodDescriptor(); + if (read != null) + propertyType = read.getReturnType(); + else { + MethodDescriptor write = getWriteMethodDescriptor(); + propertyType = write.getParameterTypes()[0]; + } + } + return propertyType; + } + + + public boolean isBound() { + return bound; + } + + + public void setBound(boolean bound) { + this.bound = bound; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JJTJavaParserState.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/JJTJavaParserState.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JJTJavaParserState.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JJTJavaParserState.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,123 @@ +/* Generated By:JJTree: Do not edit this line. .\JJTJavaParserState.java */ + +package jaxx.parser; + +class JJTJavaParserState { + private java.util.Stack<Node> nodes; + private java.util.Stack<Integer> marks; + + private int sp; // number of nodes on stack + private int mk; // current mark + private boolean node_created; + + JJTJavaParserState() { + nodes = new java.util.Stack<Node>(); + marks = new java.util.Stack<Integer>(); + sp = 0; + mk = 0; + } + + /* Determines whether the current node was actually closed and + pushed. This should only be called in the final user action of a + node scope. */ + boolean nodeCreated() { + return node_created; + } + + /* Call this to reinitialize the node stack. It is called +automatically by the parser's ReInit() method. */ + void reset() { + nodes.removeAllElements(); + marks.removeAllElements(); + sp = 0; + mk = 0; + } + + /* Returns the root node of the AST. It only makes sense to call +this after a successful parse. */ + Node rootNode() { + return nodes.elementAt(0); + } + + /* Pushes a node on to the stack. */ + void pushNode(Node n) { + nodes.push(n); + ++sp; + } + + /* Returns the node on the top of the stack, and remove it from the + stack. */ + Node popNode() { + if (--sp < mk) { + mk = marks.pop(); + } + return nodes.pop(); + } + + /* Returns the node currently on the top of the stack. */ + Node peekNode() { + return nodes.peek(); + } + + /* Returns the number of children on the stack in the current node + scope. */ + int nodeArity() { + return sp - mk; + } + + + void clearNodeScope(Node n) { + while (sp > mk) { + popNode(); + } + mk = marks.pop(); + } + + + void openNodeScope(Node n) { + marks.push(mk); + mk = sp; + n.jjtOpen(); + } + + + /* A definite node is constructed from a specified number of +children. That number of nodes are popped from the stack and +made the children of the definite node. Then the definite node +is pushed on to the stack. */ + void closeNodeScope(Node n, int num) { + mk = marks.pop(); + while (num-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, num); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } + + + /* A conditional node is constructed if its condition is true. All +the nodes that have been pushed since the node was opened are +made children of the the conditional node, which is then pushed +on to the stack. If the condition is false the node is not +constructed and they are left on the stack. */ + void closeNodeScope(Node n, boolean condition) { + if (condition) { + int a = nodeArity(); + mk = marks.pop(); + while (a-- > 0) { + Node c = popNode(); + c.jjtSetParent(n); + n.jjtAddChild(c, a); + } + n.jjtClose(); + pushNode(n); + node_created = true; + } else { + mk = marks.pop(); + node_created = false; + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jj (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/Java1.5.jj) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jj (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jj 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,5125 @@ +/*@bgen(jjtree) Generated By:JJTree: Do not edit this line. ./Java1.5.jj */ +/*@egen*/ +/* + * Copyright \u00a9 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * California 95054, U.S.A. All rights reserved. Sun Microsystems, Inc. has + * intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, + * these intellectual property rights may include one or more of the U.S. + * patents listed at http://www.sun.com/patents and one or more additional + * patents or pending patent applications in the U.S. and in other countries. + * U.S. Government Rights - Commercial software. Government users are subject + * to the Sun Microsystems, Inc. standard license agreement and applicable + * provisions of the FAR and its supplements. Use is subject to license terms. + * Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered + * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. This + * product is covered and controlled by U.S. Export Control laws and may be + * subject to the export or import laws in other countries. Nuclear, missile, + * chemical biological weapons or nuclear maritime end uses or end users, + * whether direct or indirect, are strictly prohibited. Export or reexport + * to countries subject to U.S. embargo or to entities identified on U.S. + * export exclusion lists, including, but not limited to, the denied persons + * and specially designated nationals lists is strictly prohibited. + */ + +// Slightly modified version of javacc's reference 1.5 grammar, tweaked for +// usage with JAXX. There are two main areas of changes: several new +// nonterminals were added to make identifying certain constructs easier, +// and the Line nonterminal was added to support JAXX's script tags. +// Several of the new changes are inefficient and require excess lookahead, +// but at this point I'd rather have inefficiency than risk breaking it during +// attempted optimizations. + +options { + JAVA_UNICODE_ESCAPE = true; + ERROR_REPORTING = false; + STATIC = false; + JDK_VERSION = "1.4"; +} + +PARSER_BEGIN(JavaParser) +package jaxx.parser; + +import java.io.*; + +/** + * Grammar to parse Java version 1.5 + * @author Sreenivasa Viswanadha - Simplified and enhanced for 1.5 + */ +public class JavaParser/*@bgen(jjtree)*/implements JavaParserTreeConstants/*@egen*/ +{/*@bgen(jjtree)*/ + protected JJTJavaParserState jjtree = new JJTJavaParserState(); + +/*@egen*/ + /** + * Class to hold modifiers. + */ + static public final class ModifierSet + { + /* Definitions of the bits in the modifiers field. */ + public static final int PUBLIC = 0x0001; + public static final int PROTECTED = 0x0002; + public static final int PRIVATE = 0x0004; + public static final int ABSTRACT = 0x0008; + public static final int STATIC = 0x0010; + public static final int FINAL = 0x0020; + public static final int SYNCHRONIZED = 0x0040; + public static final int NATIVE = 0x0080; + public static final int TRANSIENT = 0x0100; + public static final int VOLATILE = 0x0200; + public static final int STRICTFP = 0x1000; + + /** A set of accessors that indicate whether the specified modifier + is in the set. */ + + public boolean isPublic(int modifiers) + { + return (modifiers & PUBLIC) != 0; + } + + public boolean isProtected(int modifiers) + { + return (modifiers & PROTECTED) != 0; + } + + public boolean isPrivate(int modifiers) + { + return (modifiers & PRIVATE) != 0; + } + + public boolean isStatic(int modifiers) + { + return (modifiers & STATIC) != 0; + } + + public boolean isAbstract(int modifiers) + { + return (modifiers & ABSTRACT) != 0; + } + + public boolean isFinal(int modifiers) + { + return (modifiers & FINAL) != 0; + } + + public boolean isNative(int modifiers) + { + return (modifiers & NATIVE) != 0; + } + + public boolean isStrictfp(int modifiers) + { + return (modifiers & STRICTFP) != 0; + } + + public boolean isSynchronized(int modifiers) + { + return (modifiers & SYNCHRONIZED) != 0; + } + + public boolean isTransient(int modifiers) + { + return (modifiers & TRANSIENT) != 0; + } + + public boolean isVolatile(int modifiers) + { + return (modifiers & VOLATILE) != 0; + } + + /** + * Removes the given modifier. + */ + static int removeModifier(int modifiers, int mod) + { + return modifiers & ~mod; + } + } + + public JavaParser(String fileName) + { + this(System.in); + try { ReInit(new FileInputStream(new File(fileName))); } + catch(Exception e) { e.printStackTrace(); } + } + + void jjtreeOpenNodeScope(Node n) { + ((SimpleNode) n).firstToken = getToken(1); + } + + void jjtreeCloseNodeScope(Node n) { + ((SimpleNode) n).lastToken = getToken(0); + } + + public SimpleNode popNode() + { + if ( jjtree.nodeArity() > 0) // number of child nodes + return (SimpleNode)jjtree.popNode(); + else + return null; + } + public static void main(String args[]) { + JavaParser parser; + if (args.length == 0) { + System.out.println("Java Parser Version 1.1: Reading from standard input . . ."); + parser = new JavaParser(System.in); + } else if (args.length == 1) { + System.out.println("Java Parser Version 1.1: Reading from file " + args[0] + " . . ."); + try { + parser = new JavaParser(new java.io.FileInputStream(args[0])); + } catch (java.io.FileNotFoundException e) { + System.out.println("Java Parser Version 1.1: File " + args[0] + " not found."); + return; + } + } else { + System.out.println("Java Parser Version 1.1: Usage is one of:"); + System.out.println(" java JavaParser < inputfile"); + System.out.println("OR"); + System.out.println(" java JavaParser inputfile"); + return; + } + try { + parser.CompilationUnit(); + System.out.println("Java Parser Version 1.1: Java program parsed successfully."); + } catch (ParseException e) { + System.out.println(e.getMessage()); + System.out.println("Java Parser Version 1.1: Encountered errors during parse."); + } + } + +} + +PARSER_END(JavaParser) + +/* COMMENTS */ + +MORE : +{ + <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT +| + "/*" : IN_MULTI_LINE_COMMENT +} + +SPECIAL_TOKEN: +{ + <WHITE_SPACE: ([" ", "\n", "\r", "\t", "\f"])+> +} + +SPECIAL_TOKEN : +{ + <SINGLE_LINE_COMMENT: "//" (~["\n", "\r"])* ("\n" | "\r" | "\r\n")?> +} + +<IN_FORMAL_COMMENT> +SPECIAL_TOKEN : +{ + <FORMAL_COMMENT: "*/" > : DEFAULT +} + +<IN_MULTI_LINE_COMMENT> +SPECIAL_TOKEN : +{ + <MULTI_LINE_COMMENT: "*/" > : DEFAULT +} + +<IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT> +MORE : +{ + < ~[] > +} + +/* RESERVED WORDS AND LITERALS */ + +TOKEN : +{ + < ABSTRACT: "abstract" > +| < ASSERT: "assert" > +| < BOOLEAN: "boolean" > +| < BREAK: "break" > +| < BYTE: "byte" > +| < CASE: "case" > +| < CATCH: "catch" > +| < CHAR: "char" > +| < CLASS: "class" > +| < CONST: "const" > +| < CONTINUE: "continue" > +| < _DEFAULT: "default" > +| < DO: "do" > +| < DOUBLE: "double" > +| < ELSE: "else" > +| < ENUM: "enum" > +| < EXTENDS: "extends" > +| < FALSE: "false" > +| < FINAL: "final" > +| < FINALLY: "finally" > +| < FLOAT: "float" > +| < FOR: "for" > +| < GOTO: "goto" > +| < IF: "if" > +| < IMPLEMENTS: "implements" > +| < IMPORT: "import" > +| < INSTANCEOF: "instanceof" > +| < INT: "int" > +| < INTERFACE: "interface" > +| < LONG: "long" > +| < NATIVE: "native" > +| < NEW: "new" > +| < NULL: "null" > +| < PACKAGE: "package"> +| < PRIVATE: "private" > +| < PROTECTED: "protected" > +| < PUBLIC: "public" > +| < RETURN: "return" > +| < SHORT: "short" > +| < STATIC: "static" > +| < STRICTFP: "strictfp" > +| < SUPER: "super" > +| < SWITCH: "switch" > +| < SYNCHRONIZED: "synchronized" > +| < THIS: "this" > +| < THROW: "throw" > +| < THROWS: "throws" > +| < TRANSIENT: "transient" > +| < TRUE: "true" > +| < TRY: "try" > +| < VOID: "void" > +| < VOLATILE: "volatile" > +| < WHILE: "while" > +} + +/* LITERALS */ + +TOKEN : +{ + < INTEGER_LITERAL: + <DECIMAL_LITERAL> (["l","L"])? + | <HEX_LITERAL> (["l","L"])? + | <OCTAL_LITERAL> (["l","L"])? + > +| + < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > +| + < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > +| + < #OCTAL_LITERAL: "0" (["0"-"7"])* > +| + < FLOATING_POINT_LITERAL: + <DECIMAL_FLOATING_POINT_LITERAL> + | <HEXADECIMAL_FLOATING_POINT_LITERAL> + > +| + < #DECIMAL_FLOATING_POINT_LITERAL: + (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])? + | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])? + | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])? + | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"] + > +| + < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > +| + < #HEXADECIMAL_FLOATING_POINT_LITERAL: + "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])? + | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])? + > +| + < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ > +| + < CHARACTER_LITERAL: + "'" + ( (~["'","\\","\n","\r"]) + | ("\\" + ( ["n","t","b","r","f","\\","'","\""] + | ["0"-"7"] ( ["0"-"7"] )? + | ["0"-"3"] ["0"-"7"] ["0"-"7"] + ) + ) + ) + "'" + > +| + < STRING_LITERAL: + "\"" + ( (~["\"","\\","\n","\r"]) + | ("\\" + ( ["n","t","b","r","f","\\","'","\""] + | ["0"-"7"] ( ["0"-"7"] )? + | ["0"-"3"] ["0"-"7"] ["0"-"7"] + ) + ) + )* + "\"" + > +} + +/* IDENTIFIERS */ + +TOKEN : +{ + < IDENTIFIER: <LETTER> (<PART_LETTER>)* > +| + < #LETTER: + [ // all chars for which Character.isIdentifierStart is true + "$", + "A"-"Z", + "_", + "a"-"z", + "\u00a2"-"\u00a5", + "\u00aa", + "\u00b5", + "\u00ba", + "\u00c0"-"\u00d6", + "\u00d8"-"\u00f6", + "\u00f8"-"\u021f", + "\u0222"-"\u0233", + "\u0250"-"\u02ad", + "\u02b0"-"\u02b8", + "\u02bb"-"\u02c1", + "\u02d0"-"\u02d1", + "\u02e0"-"\u02e4", + "\u02ee", + "\u037a", + "\u0386", + "\u0388"-"\u038a", + "\u038c", + "\u038e"-"\u03a1", + "\u03a3"-"\u03ce", + "\u03d0"-"\u03d7", + "\u03da"-"\u03f3", + "\u0400"-"\u0481", + "\u048c"-"\u04c4", + "\u04c7"-"\u04c8", + "\u04cb"-"\u04cc", + "\u04d0"-"\u04f5", + "\u04f8"-"\u04f9", + "\u0531"-"\u0556", + "\u0559", + "\u0561"-"\u0587", + "\u05d0"-"\u05ea", + "\u05f0"-"\u05f2", + "\u0621"-"\u063a", + "\u0640"-"\u064a", + "\u0671"-"\u06d3", + "\u06d5", + "\u06e5"-"\u06e6", + "\u06fa"-"\u06fc", + "\u0710", + "\u0712"-"\u072c", + "\u0780"-"\u07a5", + "\u0905"-"\u0939", + "\u093d", + "\u0950", + "\u0958"-"\u0961", + "\u0985"-"\u098c", + "\u098f"-"\u0990", + "\u0993"-"\u09a8", + "\u09aa"-"\u09b0", + "\u09b2", + "\u09b6"-"\u09b9", + "\u09dc"-"\u09dd", + "\u09df"-"\u09e1", + "\u09f0"-"\u09f3", + "\u0a05"-"\u0a0a", + "\u0a0f"-"\u0a10", + "\u0a13"-"\u0a28", + "\u0a2a"-"\u0a30", + "\u0a32"-"\u0a33", + "\u0a35"-"\u0a36", + "\u0a38"-"\u0a39", + "\u0a59"-"\u0a5c", + "\u0a5e", + "\u0a72"-"\u0a74", + "\u0a85"-"\u0a8b", + "\u0a8d", + "\u0a8f"-"\u0a91", + "\u0a93"-"\u0aa8", + "\u0aaa"-"\u0ab0", + "\u0ab2"-"\u0ab3", + "\u0ab5"-"\u0ab9", + "\u0abd", + "\u0ad0", + "\u0ae0", + "\u0b05"-"\u0b0c", + "\u0b0f"-"\u0b10", + "\u0b13"-"\u0b28", + "\u0b2a"-"\u0b30", + "\u0b32"-"\u0b33", + "\u0b36"-"\u0b39", + "\u0b3d", + "\u0b5c"-"\u0b5d", + "\u0b5f"-"\u0b61", + "\u0b85"-"\u0b8a", + "\u0b8e"-"\u0b90", + "\u0b92"-"\u0b95", + "\u0b99"-"\u0b9a", + "\u0b9c", + "\u0b9e"-"\u0b9f", + "\u0ba3"-"\u0ba4", + "\u0ba8"-"\u0baa", + "\u0bae"-"\u0bb5", + "\u0bb7"-"\u0bb9", + "\u0c05"-"\u0c0c", + "\u0c0e"-"\u0c10", + "\u0c12"-"\u0c28", + "\u0c2a"-"\u0c33", + "\u0c35"-"\u0c39", + "\u0c60"-"\u0c61", + "\u0c85"-"\u0c8c", + "\u0c8e"-"\u0c90", + "\u0c92"-"\u0ca8", + "\u0caa"-"\u0cb3", + "\u0cb5"-"\u0cb9", + "\u0cde", + "\u0ce0"-"\u0ce1", + "\u0d05"-"\u0d0c", + "\u0d0e"-"\u0d10", + "\u0d12"-"\u0d28", + "\u0d2a"-"\u0d39", + "\u0d60"-"\u0d61", + "\u0d85"-"\u0d96", + "\u0d9a"-"\u0db1", + "\u0db3"-"\u0dbb", + "\u0dbd", + "\u0dc0"-"\u0dc6", + "\u0e01"-"\u0e30", + "\u0e32"-"\u0e33", + "\u0e3f"-"\u0e46", + "\u0e81"-"\u0e82", + "\u0e84", + "\u0e87"-"\u0e88", + "\u0e8a", + "\u0e8d", + "\u0e94"-"\u0e97", + "\u0e99"-"\u0e9f", + "\u0ea1"-"\u0ea3", + "\u0ea5", + "\u0ea7", + "\u0eaa"-"\u0eab", + "\u0ead"-"\u0eb0", + "\u0eb2"-"\u0eb3", + "\u0ebd", + "\u0ec0"-"\u0ec4", + "\u0ec6", + "\u0edc"-"\u0edd", + "\u0f00", + "\u0f40"-"\u0f47", + "\u0f49"-"\u0f6a", + "\u0f88"-"\u0f8b", + "\u1000"-"\u1021", + "\u1023"-"\u1027", + "\u1029"-"\u102a", + "\u1050"-"\u1055", + "\u10a0"-"\u10c5", + "\u10d0"-"\u10f6", + "\u1100"-"\u1159", + "\u115f"-"\u11a2", + "\u11a8"-"\u11f9", + "\u1200"-"\u1206", + "\u1208"-"\u1246", + "\u1248", + "\u124a"-"\u124d", + "\u1250"-"\u1256", + "\u1258", + "\u125a"-"\u125d", + "\u1260"-"\u1286", + "\u1288", + "\u128a"-"\u128d", + "\u1290"-"\u12ae", + "\u12b0", + "\u12b2"-"\u12b5", + "\u12b8"-"\u12be", + "\u12c0", + "\u12c2"-"\u12c5", + "\u12c8"-"\u12ce", + "\u12d0"-"\u12d6", + "\u12d8"-"\u12ee", + "\u12f0"-"\u130e", + "\u1310", + "\u1312"-"\u1315", + "\u1318"-"\u131e", + "\u1320"-"\u1346", + "\u1348"-"\u135a", + "\u13a0"-"\u13f4", + "\u1401"-"\u166c", + "\u166f"-"\u1676", + "\u1681"-"\u169a", + "\u16a0"-"\u16ea", + "\u1780"-"\u17b3", + "\u17db", + "\u1820"-"\u1877", + "\u1880"-"\u18a8", + "\u1e00"-"\u1e9b", + "\u1ea0"-"\u1ef9", + "\u1f00"-"\u1f15", + "\u1f18"-"\u1f1d", + "\u1f20"-"\u1f45", + "\u1f48"-"\u1f4d", + "\u1f50"-"\u1f57", + "\u1f59", + "\u1f5b", + "\u1f5d", + "\u1f5f"-"\u1f7d", + "\u1f80"-"\u1fb4", + "\u1fb6"-"\u1fbc", + "\u1fbe", + "\u1fc2"-"\u1fc4", + "\u1fc6"-"\u1fcc", + "\u1fd0"-"\u1fd3", + "\u1fd6"-"\u1fdb", + "\u1fe0"-"\u1fec", + "\u1ff2"-"\u1ff4", + "\u1ff6"-"\u1ffc", + "\u203f"-"\u2040", + "\u207f", + "\u20a0"-"\u20af", + "\u2102", + "\u2107", + "\u210a"-"\u2113", + "\u2115", + "\u2119"-"\u211d", + "\u2124", + "\u2126", + "\u2128", + "\u212a"-"\u212d", + "\u212f"-"\u2131", + "\u2133"-"\u2139", + "\u2160"-"\u2183", + "\u3005"-"\u3007", + "\u3021"-"\u3029", + "\u3031"-"\u3035", + "\u3038"-"\u303a", + "\u3041"-"\u3094", + "\u309d"-"\u309e", + "\u30a1"-"\u30fe", + "\u3105"-"\u312c", + "\u3131"-"\u318e", + "\u31a0"-"\u31b7", + "\u3400"-"\u4db5", + "\u4e00"-"\u9fa5", + "\ua000"-"\ua48c", + "\uac00"-"\ud7a3", + "\uf900"-"\ufa2d", + "\ufb00"-"\ufb06", + "\ufb13"-"\ufb17", + "\ufb1d", + "\ufb1f"-"\ufb28", + "\ufb2a"-"\ufb36", + "\ufb38"-"\ufb3c", + "\ufb3e", + "\ufb40"-"\ufb41", + "\ufb43"-"\ufb44", + "\ufb46"-"\ufbb1", + "\ufbd3"-"\ufd3d", + "\ufd50"-"\ufd8f", + "\ufd92"-"\ufdc7", + "\ufdf0"-"\ufdfb", + "\ufe33"-"\ufe34", + "\ufe4d"-"\ufe4f", + "\ufe69", + "\ufe70"-"\ufe72", + "\ufe74", + "\ufe76"-"\ufefc", + "\uff04", + "\uff21"-"\uff3a", + "\uff3f", + "\uff41"-"\uff5a", + "\uff65"-"\uffbe", + "\uffc2"-"\uffc7", + "\uffca"-"\uffcf", + "\uffd2"-"\uffd7", + "\uffda"-"\uffdc", + "\uffe0"-"\uffe1", + "\uffe5"-"\uffe6" + ] + > +| + < #PART_LETTER: + [ // all chars for which Character.isIdentifierPart is true + "\u0000"-"\u0008", + "\u000e"-"\u001b", + "$", + "0"-"9", + "A"-"Z", + "_", + "a"-"z", + "\u007f"-"\u009f", + "\u00a2"-"\u00a5", + "\u00aa", + "\u00b5", + "\u00ba", + "\u00c0"-"\u00d6", + "\u00d8"-"\u00f6", + "\u00f8"-"\u021f", + "\u0222"-"\u0233", + "\u0250"-"\u02ad", + "\u02b0"-"\u02b8", + "\u02bb"-"\u02c1", + "\u02d0"-"\u02d1", + "\u02e0"-"\u02e4", + "\u02ee", + "\u0300"-"\u034e", + "\u0360"-"\u0362", + "\u037a", + "\u0386", + "\u0388"-"\u038a", + "\u038c", + "\u038e"-"\u03a1", + "\u03a3"-"\u03ce", + "\u03d0"-"\u03d7", + "\u03da"-"\u03f3", + "\u0400"-"\u0481", + "\u0483"-"\u0486", + "\u048c"-"\u04c4", + "\u04c7"-"\u04c8", + "\u04cb"-"\u04cc", + "\u04d0"-"\u04f5", + "\u04f8"-"\u04f9", + "\u0531"-"\u0556", + "\u0559", + "\u0561"-"\u0587", + "\u0591"-"\u05a1", + "\u05a3"-"\u05b9", + "\u05bb"-"\u05bd", + "\u05bf", + "\u05c1"-"\u05c2", + "\u05c4", + "\u05d0"-"\u05ea", + "\u05f0"-"\u05f2", + "\u0621"-"\u063a", + "\u0640"-"\u0655", + "\u0660"-"\u0669", + "\u0670"-"\u06d3", + "\u06d5"-"\u06dc", + "\u06df"-"\u06e8", + "\u06ea"-"\u06ed", + "\u06f0"-"\u06fc", + "\u070f"-"\u072c", + "\u0730"-"\u074a", + "\u0780"-"\u07b0", + "\u0901"-"\u0903", + "\u0905"-"\u0939", + "\u093c"-"\u094d", + "\u0950"-"\u0954", + "\u0958"-"\u0963", + "\u0966"-"\u096f", + "\u0981"-"\u0983", + "\u0985"-"\u098c", + "\u098f"-"\u0990", + "\u0993"-"\u09a8", + "\u09aa"-"\u09b0", + "\u09b2", + "\u09b6"-"\u09b9", + "\u09bc", + "\u09be"-"\u09c4", + "\u09c7"-"\u09c8", + "\u09cb"-"\u09cd", + "\u09d7", + "\u09dc"-"\u09dd", + "\u09df"-"\u09e3", + "\u09e6"-"\u09f3", + "\u0a02", + "\u0a05"-"\u0a0a", + "\u0a0f"-"\u0a10", + "\u0a13"-"\u0a28", + "\u0a2a"-"\u0a30", + "\u0a32"-"\u0a33", + "\u0a35"-"\u0a36", + "\u0a38"-"\u0a39", + "\u0a3c", + "\u0a3e"-"\u0a42", + "\u0a47"-"\u0a48", + "\u0a4b"-"\u0a4d", + "\u0a59"-"\u0a5c", + "\u0a5e", + "\u0a66"-"\u0a74", + "\u0a81"-"\u0a83", + "\u0a85"-"\u0a8b", + "\u0a8d", + "\u0a8f"-"\u0a91", + "\u0a93"-"\u0aa8", + "\u0aaa"-"\u0ab0", + "\u0ab2"-"\u0ab3", + "\u0ab5"-"\u0ab9", + "\u0abc"-"\u0ac5", + "\u0ac7"-"\u0ac9", + "\u0acb"-"\u0acd", + "\u0ad0", + "\u0ae0", + "\u0ae6"-"\u0aef", + "\u0b01"-"\u0b03", + "\u0b05"-"\u0b0c", + "\u0b0f"-"\u0b10", + "\u0b13"-"\u0b28", + "\u0b2a"-"\u0b30", + "\u0b32"-"\u0b33", + "\u0b36"-"\u0b39", + "\u0b3c"-"\u0b43", + "\u0b47"-"\u0b48", + "\u0b4b"-"\u0b4d", + "\u0b56"-"\u0b57", + "\u0b5c"-"\u0b5d", + "\u0b5f"-"\u0b61", + "\u0b66"-"\u0b6f", + "\u0b82"-"\u0b83", + "\u0b85"-"\u0b8a", + "\u0b8e"-"\u0b90", + "\u0b92"-"\u0b95", + "\u0b99"-"\u0b9a", + "\u0b9c", + "\u0b9e"-"\u0b9f", + "\u0ba3"-"\u0ba4", + "\u0ba8"-"\u0baa", + "\u0bae"-"\u0bb5", + "\u0bb7"-"\u0bb9", + "\u0bbe"-"\u0bc2", + "\u0bc6"-"\u0bc8", + "\u0bca"-"\u0bcd", + "\u0bd7", + "\u0be7"-"\u0bef", + "\u0c01"-"\u0c03", + "\u0c05"-"\u0c0c", + "\u0c0e"-"\u0c10", + "\u0c12"-"\u0c28", + "\u0c2a"-"\u0c33", + "\u0c35"-"\u0c39", + "\u0c3e"-"\u0c44", + "\u0c46"-"\u0c48", + "\u0c4a"-"\u0c4d", + "\u0c55"-"\u0c56", + "\u0c60"-"\u0c61", + "\u0c66"-"\u0c6f", + "\u0c82"-"\u0c83", + "\u0c85"-"\u0c8c", + "\u0c8e"-"\u0c90", + "\u0c92"-"\u0ca8", + "\u0caa"-"\u0cb3", + "\u0cb5"-"\u0cb9", + "\u0cbe"-"\u0cc4", + "\u0cc6"-"\u0cc8", + "\u0cca"-"\u0ccd", + "\u0cd5"-"\u0cd6", + "\u0cde", + "\u0ce0"-"\u0ce1", + "\u0ce6"-"\u0cef", + "\u0d02"-"\u0d03", + "\u0d05"-"\u0d0c", + "\u0d0e"-"\u0d10", + "\u0d12"-"\u0d28", + "\u0d2a"-"\u0d39", + "\u0d3e"-"\u0d43", + "\u0d46"-"\u0d48", + "\u0d4a"-"\u0d4d", + "\u0d57", + "\u0d60"-"\u0d61", + "\u0d66"-"\u0d6f", + "\u0d82"-"\u0d83", + "\u0d85"-"\u0d96", + "\u0d9a"-"\u0db1", + "\u0db3"-"\u0dbb", + "\u0dbd", + "\u0dc0"-"\u0dc6", + "\u0dca", + "\u0dcf"-"\u0dd4", + "\u0dd6", + "\u0dd8"-"\u0ddf", + "\u0df2"-"\u0df3", + "\u0e01"-"\u0e3a", + "\u0e3f"-"\u0e4e", + "\u0e50"-"\u0e59", + "\u0e81"-"\u0e82", + "\u0e84", + "\u0e87"-"\u0e88", + "\u0e8a", + "\u0e8d", + "\u0e94"-"\u0e97", + "\u0e99"-"\u0e9f", + "\u0ea1"-"\u0ea3", + "\u0ea5", + "\u0ea7", + "\u0eaa"-"\u0eab", + "\u0ead"-"\u0eb9", + "\u0ebb"-"\u0ebd", + "\u0ec0"-"\u0ec4", + "\u0ec6", + "\u0ec8"-"\u0ecd", + "\u0ed0"-"\u0ed9", + "\u0edc"-"\u0edd", + "\u0f00", + "\u0f18"-"\u0f19", + "\u0f20"-"\u0f29", + "\u0f35", + "\u0f37", + "\u0f39", + "\u0f3e"-"\u0f47", + "\u0f49"-"\u0f6a", + "\u0f71"-"\u0f84", + "\u0f86"-"\u0f8b", + "\u0f90"-"\u0f97", + "\u0f99"-"\u0fbc", + "\u0fc6", + "\u1000"-"\u1021", + "\u1023"-"\u1027", + "\u1029"-"\u102a", + "\u102c"-"\u1032", + "\u1036"-"\u1039", + "\u1040"-"\u1049", + "\u1050"-"\u1059", + "\u10a0"-"\u10c5", + "\u10d0"-"\u10f6", + "\u1100"-"\u1159", + "\u115f"-"\u11a2", + "\u11a8"-"\u11f9", + "\u1200"-"\u1206", + "\u1208"-"\u1246", + "\u1248", + "\u124a"-"\u124d", + "\u1250"-"\u1256", + "\u1258", + "\u125a"-"\u125d", + "\u1260"-"\u1286", + "\u1288", + "\u128a"-"\u128d", + "\u1290"-"\u12ae", + "\u12b0", + "\u12b2"-"\u12b5", + "\u12b8"-"\u12be", + "\u12c0", + "\u12c2"-"\u12c5", + "\u12c8"-"\u12ce", + "\u12d0"-"\u12d6", + "\u12d8"-"\u12ee", + "\u12f0"-"\u130e", + "\u1310", + "\u1312"-"\u1315", + "\u1318"-"\u131e", + "\u1320"-"\u1346", + "\u1348"-"\u135a", + "\u1369"-"\u1371", + "\u13a0"-"\u13f4", + "\u1401"-"\u166c", + "\u166f"-"\u1676", + "\u1681"-"\u169a", + "\u16a0"-"\u16ea", + "\u1780"-"\u17d3", + "\u17db", + "\u17e0"-"\u17e9", + "\u180b"-"\u180e", + "\u1810"-"\u1819", + "\u1820"-"\u1877", + "\u1880"-"\u18a9", + "\u1e00"-"\u1e9b", + "\u1ea0"-"\u1ef9", + "\u1f00"-"\u1f15", + "\u1f18"-"\u1f1d", + "\u1f20"-"\u1f45", + "\u1f48"-"\u1f4d", + "\u1f50"-"\u1f57", + "\u1f59", + "\u1f5b", + "\u1f5d", + "\u1f5f"-"\u1f7d", + "\u1f80"-"\u1fb4", + "\u1fb6"-"\u1fbc", + "\u1fbe", + "\u1fc2"-"\u1fc4", + "\u1fc6"-"\u1fcc", + "\u1fd0"-"\u1fd3", + "\u1fd6"-"\u1fdb", + "\u1fe0"-"\u1fec", + "\u1ff2"-"\u1ff4", + "\u1ff6"-"\u1ffc", + "\u200c"-"\u200f", + "\u202a"-"\u202e", + "\u203f"-"\u2040", + "\u206a"-"\u206f", + "\u207f", + "\u20a0"-"\u20af", + "\u20d0"-"\u20dc", + "\u20e1", + "\u2102", + "\u2107", + "\u210a"-"\u2113", + "\u2115", + "\u2119"-"\u211d", + "\u2124", + "\u2126", + "\u2128", + "\u212a"-"\u212d", + "\u212f"-"\u2131", + "\u2133"-"\u2139", + "\u2160"-"\u2183", + "\u3005"-"\u3007", + "\u3021"-"\u302f", + "\u3031"-"\u3035", + "\u3038"-"\u303a", + "\u3041"-"\u3094", + "\u3099"-"\u309a", + "\u309d"-"\u309e", + "\u30a1"-"\u30fe", + "\u3105"-"\u312c", + "\u3131"-"\u318e", + "\u31a0"-"\u31b7", + "\u3400"-"\u4db5", + "\u4e00"-"\u9fa5", + "\ua000"-"\ua48c", + "\uac00"-"\ud7a3", + "\uf900"-"\ufa2d", + "\ufb00"-"\ufb06", + "\ufb13"-"\ufb17", + "\ufb1d"-"\ufb28", + "\ufb2a"-"\ufb36", + "\ufb38"-"\ufb3c", + "\ufb3e", + "\ufb40"-"\ufb41", + "\ufb43"-"\ufb44", + "\ufb46"-"\ufbb1", + "\ufbd3"-"\ufd3d", + "\ufd50"-"\ufd8f", + "\ufd92"-"\ufdc7", + "\ufdf0"-"\ufdfb", + "\ufe20"-"\ufe23", + "\ufe33"-"\ufe34", + "\ufe4d"-"\ufe4f", + "\ufe69", + "\ufe70"-"\ufe72", + "\ufe74", + "\ufe76"-"\ufefc", + "\ufeff", + "\uff04", + "\uff10"-"\uff19", + "\uff21"-"\uff3a", + "\uff3f", + "\uff41"-"\uff5a", + "\uff65"-"\uffbe", + "\uffc2"-"\uffc7", + "\uffca"-"\uffcf", + "\uffd2"-"\uffd7", + "\uffda"-"\uffdc", + "\uffe0"-"\uffe1", + "\uffe5"-"\uffe6", + "\ufff9"-"\ufffb" + ] + > +} + +/* SEPARATORS */ + +TOKEN : +{ + < LPAREN: "(" > +| < RPAREN: ")" > +| < LBRACE: "{" > +| < RBRACE: "}" > +| < LBRACKET: "[" > +| < RBRACKET: "]" > +| < SEMICOLON: ";" > +| < COMMA: "," > +| < DOT: "." > +| < AT: "@" > +} + +/* OPERATORS */ + +TOKEN : +{ + < ASSIGN: "=" > +| < LT: "<" > +| < BANG: "!" > +| < TILDE: "~" > +| < HOOK: "?" > +| < COLON: ":" > +| < EQ: "==" > +| < LE: "<=" > +| < GE: ">=" > +| < NE: "!=" > +| < SC_OR: "||" > +| < SC_AND: "&&" > +| < INCR: "++" > +| < DECR: "--" > +| < PLUS: "+" > +| < MINUS: "-" > +| < STAR: "*" > +| < SLASH: "/" > +| < BIT_AND: "&" > +| < BIT_OR: "|" > +| < XOR: "^" > +| < REM: "%" > +| < LSHIFT: "<<" > +| < PLUSASSIGN: "+=" > +| < MINUSASSIGN: "-=" > +| < STARASSIGN: "*=" > +| < SLASHASSIGN: "/=" > +| < ANDASSIGN: "&=" > +| < ORASSIGN: "|=" > +| < XORASSIGN: "^=" > +| < REMASSIGN: "%=" > +| < LSHIFTASSIGN: "<<=" > +| < RSIGNEDSHIFTASSIGN: ">>=" > +| < RUNSIGNEDSHIFTASSIGN: ">>>=" > +| < ELLIPSIS: "..." > +} + +/* >'s need special attention due to generics syntax. */ +TOKEN : +{ + < RUNSIGNEDSHIFT: ">>>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT; + input_stream.backup(2); + matchedToken.image = ">"; + } +| < RSIGNEDSHIFT: ">>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RSIGNEDSHIFT; + input_stream.backup(1); + matchedToken.image = ">"; + } +| < GT: ">" > +} + +boolean Line() : +{/*@bgen(jjtree) Line */ + SimpleNode jjtn000 = new SimpleNode(JJTLINE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/ + int modifiers; +} +{/*@bgen(jjtree) Line */ + try { +/*@egen*/ + <EOF>/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ { + return true; + } +| + LOOKAHEAD(BlockStatement()) + BlockStatement()/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ { + return false; + } +| + LOOKAHEAD(Modifiers() [ TypeParameters() ] [ ResultType() ] <IDENTIFIER> FormalParameters() [ "throws" NameList() ] "{") + ClassOrInterfaceBodyDeclaration(false)/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ { + return false; + } +| + LOOKAHEAD(ClassOrInterfaceBodyDeclaration(false)) + ClassOrInterfaceBodyDeclaration(false)/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ { + return false; + } +| + LOOKAHEAD(Expression()) + Expression()/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ { + return false; + } +| + ImportDeclaration()/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ { + return false; + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +/***************************************** + * THE JAVA LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ + +/* + * Program structuring syntax follows. + */ + +void CompilationUnit(): +{/*@bgen(jjtree) CompilationUnit */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPILATIONUNIT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) CompilationUnit */ + try { +/*@egen*/ + [ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ] + ( ImportDeclaration() )* + ( TypeDeclaration() )* + ( < "\u001a" > )? + ( <STUFF_TO_IGNORE: ~[]> )? + <EOF>/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PackageDeclaration(): +{/*@bgen(jjtree) PackageDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTPACKAGEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PackageDeclaration */ + try { +/*@egen*/ + Modifiers() "package" Name() ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ImportDeclaration(): +{/*@bgen(jjtree) ImportDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTIMPORTDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ImportDeclaration */ + try { +/*@egen*/ + "import" [ "static" ] Name() [ "." "*" ] ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +/* + * Modifiers. We match all modifiers in a single rule to reduce the chances of + * syntax errors for simple modifier mistakes. It will also enable us to give + * better error messages. + */ + +int Modifiers(): +{/*@bgen(jjtree) Modifiers */ + SimpleNode jjtn000 = new SimpleNode(JJTMODIFIERS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/ + int modifiers = 0; +} +{/*@bgen(jjtree) Modifiers */ + try { +/*@egen*/ + ( + LOOKAHEAD(2) + ( + "public" { modifiers |= ModifierSet.PUBLIC; } + | + "static" { modifiers |= ModifierSet.STATIC; } + | + "protected" { modifiers |= ModifierSet.PROTECTED; } + | + "private" { modifiers |= ModifierSet.PRIVATE; } + | + "final" { modifiers |= ModifierSet.FINAL; } + | + "abstract" { modifiers |= ModifierSet.ABSTRACT; } + | + "synchronized" { modifiers |= ModifierSet.SYNCHRONIZED; } + | + "native" { modifiers |= ModifierSet.NATIVE; } + | + "transient" { modifiers |= ModifierSet.TRANSIENT; } + | + "volatile" { modifiers |= ModifierSet.VOLATILE; } + | + "strictfp" { modifiers |= ModifierSet.STRICTFP; } + | + Annotation() + ) + )*/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ + + { + return modifiers; + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +/* + * Declaration syntax follows. + */ +void TypeDeclaration(): +{/*@bgen(jjtree) TypeDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/ + int modifiers; +} +{/*@bgen(jjtree) TypeDeclaration */ + try { +/*@egen*/ + ";" +| + modifiers = Modifiers() + ( + ClassOrInterfaceDeclaration(modifiers) + | + EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void ClassOrInterfaceDeclaration(int modifiers): +{/*@bgen(jjtree) ClassOrInterfaceDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/ + boolean isInterface = false; +} +{/*@bgen(jjtree) ClassOrInterfaceDeclaration */ + try { +/*@egen*/ + ( "class" | "interface" { isInterface = true; } ) + <IDENTIFIER> + [ TypeParameters() ] + [ ExtendsList(isInterface) ] + [ ImplementsList(isInterface) ] + ClassOrInterfaceBody(isInterface)/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ExtendsList(boolean isInterface): +{/*@bgen(jjtree) ExtendsList */ + SimpleNode jjtn000 = new SimpleNode(JJTEXTENDSLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/ + boolean extendsMoreThanOne = false; +} +{/*@bgen(jjtree) ExtendsList */ + try { +/*@egen*/ + "extends" ClassOrInterfaceType() + ( "," ClassOrInterfaceType() { extendsMoreThanOne = true; } )*/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ + { + if (extendsMoreThanOne && !isInterface) + throw new ParseException("A class cannot extend more than one other class"); + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ImplementsList(boolean isInterface): +{/*@bgen(jjtree) ImplementsList */ + SimpleNode jjtn000 = new SimpleNode(JJTIMPLEMENTSLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ImplementsList */ + try { +/*@egen*/ + "implements" ClassOrInterfaceType() + ( "," ClassOrInterfaceType() )*/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ + { + if (isInterface) + throw new ParseException("An interface cannot implement other interfaces"); + }/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void EnumDeclaration(int modifiers): +{/*@bgen(jjtree) EnumDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) EnumDeclaration */ + try { +/*@egen*/ + "enum" <IDENTIFIER> + [ ImplementsList(false) ] + EnumBody()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void EnumBody(): +{/*@bgen(jjtree) EnumBody */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMBODY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) EnumBody */ + try { +/*@egen*/ + "{" + [ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ] + [ "," ] + [ ";" ( ClassOrInterfaceBodyDeclaration(false) )* ] + "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void EnumConstant(): +{/*@bgen(jjtree) EnumConstant */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMCONSTANT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) EnumConstant */ + try { +/*@egen*/ + Modifiers() <IDENTIFIER> [ Arguments() ] [ ClassOrInterfaceBody(false) ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void TypeParameters(): +{/*@bgen(jjtree) TypeParameters */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEPARAMETERS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) TypeParameters */ + try { +/*@egen*/ + "<" TypeParameter() ( "," TypeParameter() )* ">"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void TypeParameter(): +{/*@bgen(jjtree) TypeParameter */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEPARAMETER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) TypeParameter */ + try { +/*@egen*/ + <IDENTIFIER> [ TypeBound() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void TypeBound(): +{/*@bgen(jjtree) TypeBound */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEBOUND); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) TypeBound */ + try { +/*@egen*/ + "extends" ClassOrInterfaceType() ( "&" ClassOrInterfaceType() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ClassOrInterfaceBody(boolean isInterface): +{/*@bgen(jjtree) ClassOrInterfaceBody */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACEBODY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ClassOrInterfaceBody */ + try { +/*@egen*/ + "{" ( ClassOrInterfaceBodyDeclaration(isInterface) )* "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ClassOrInterfaceBodyDeclaration(boolean isInterface): +{/*@bgen(jjtree) ClassOrInterfaceBodyDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACEBODYDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/ + boolean isNestedInterface = false; + int modifiers; +} +{/*@bgen(jjtree) ClassOrInterfaceBodyDeclaration */ + try { +/*@egen*/ + LOOKAHEAD(2) + Initializer()/*@bgen(jjtree)*/ + { + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + } +/*@egen*/ + { + if (isInterface) + throw new ParseException("An interface cannot have initializers"); + } +| + modifiers = Modifiers() // Just get all the modifiers out of the way. If you want to do + // more checks, pass the modifiers down to the member + ( + ClassOrInterfaceDeclaration(modifiers) + | + EnumDeclaration(modifiers) + | + LOOKAHEAD( [ TypeParameters() ] <IDENTIFIER> "(" ) + ConstructorDeclaration() + | + LOOKAHEAD( Type() <IDENTIFIER> ( "[" "]" )* ( "," | "=" | ";" ) ) + FieldDeclaration(modifiers) + | + MethodDeclaration(modifiers) + ) +| + ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void FieldDeclaration(int modifiers): +{/*@bgen(jjtree) FieldDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTFIELDDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) FieldDeclaration */ + try { +/*@egen*/ + // Modifiers are already matched in the caller + Type() VariableDeclarator() ( "," VariableDeclarator() )* ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void VariableDeclarator(): +{/*@bgen(jjtree) VariableDeclarator */ + SimpleNode jjtn000 = new SimpleNode(JJTVARIABLEDECLARATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) VariableDeclarator */ + try { +/*@egen*/ + VariableDeclaratorId() [ "=" VariableInitializer() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void VariableDeclaratorId(): +{/*@bgen(jjtree) VariableDeclaratorId */ + SimpleNode jjtn000 = new SimpleNode(JJTVARIABLEDECLARATORID); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) VariableDeclaratorId */ + try { +/*@egen*/ + <IDENTIFIER> ( "[" "]" )*/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void VariableInitializer(): +{/*@bgen(jjtree) VariableInitializer */ + SimpleNode jjtn000 = new SimpleNode(JJTVARIABLEINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) VariableInitializer */ + try { +/*@egen*/ + ArrayInitializer() +| + Expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ArrayInitializer(): +{/*@bgen(jjtree) ArrayInitializer */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAYINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ArrayInitializer */ + try { +/*@egen*/ + "{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MethodDeclaration(int modifiers): +{/*@bgen(jjtree) MethodDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTMETHODDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MethodDeclaration */ + try { +/*@egen*/ + // Modifiers already matched in the caller! + [ TypeParameters() ] + ResultType() + MethodDeclarator() [ "throws" NameList() ] + ( Block() | ";" )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MethodDeclarator(): +{/*@bgen(jjtree) MethodDeclarator */ + SimpleNode jjtn000 = new SimpleNode(JJTMETHODDECLARATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MethodDeclarator */ + try { +/*@egen*/ + <IDENTIFIER> FormalParameters() ( "[" "]" )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void FormalParameters(): +{/*@bgen(jjtree) FormalParameters */ + SimpleNode jjtn000 = new SimpleNode(JJTFORMALPARAMETERS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) FormalParameters */ + try { +/*@egen*/ + "(" [ FormalParameter() ( "," FormalParameter() )* ] ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void FormalParameter(): +{/*@bgen(jjtree) FormalParameter */ + SimpleNode jjtn000 = new SimpleNode(JJTFORMALPARAMETER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) FormalParameter */ + try { +/*@egen*/ + Modifiers() Type() [ "..." ] VariableDeclaratorId()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ConstructorDeclaration(): +{/*@bgen(jjtree) ConstructorDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCONSTRUCTORDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ConstructorDeclaration */ + try { +/*@egen*/ + [ TypeParameters() ] + // Modifiers matched in the caller + <IDENTIFIER> FormalParameters() [ "throws" NameList() ] + "{" + [ LOOKAHEAD(ExplicitConstructorInvocation()) + ExplicitConstructorInvocation() + ] + ( BlockStatement() )* + "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ExplicitConstructorInvocation(): +{/*@bgen(jjtree) ExplicitConstructorInvocation */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPLICITCONSTRUCTORINVOCATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ExplicitConstructorInvocation */ + try { +/*@egen*/ + ( <IDENTIFIER> "." )* [ LOOKAHEAD(2) "this" "." ] + [ TypeArguments() ] ("this"|"super") Arguments() ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void Initializer(): +{/*@bgen(jjtree) Initializer */ + SimpleNode jjtn000 = new SimpleNode(JJTINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Initializer */ + try { +/*@egen*/ + [ "static" ] Block()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +/* + * Type, name and expression syntax follows. + */ + +void Type(): +{/*@bgen(jjtree) Type */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Type */ + try { +/*@egen*/ + LOOKAHEAD(2) ReferenceType() + | + PrimitiveType()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ReferenceType(): +{/*@bgen(jjtree) ReferenceType */ + SimpleNode jjtn000 = new SimpleNode(JJTREFERENCETYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ReferenceType */ + try { +/*@egen*/ + PrimitiveType() ( LOOKAHEAD(2) "[" "]" )+ + | + ( ClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ClassOrInterfaceType(): +{/*@bgen(jjtree) ClassOrInterfaceType */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACETYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ClassOrInterfaceType */ + try { +/*@egen*/ + <IDENTIFIER> [ LOOKAHEAD(2) TypeArguments() ] + ( LOOKAHEAD(2) "." <IDENTIFIER> [ LOOKAHEAD(2) TypeArguments() ] )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void TypeArguments(): +{/*@bgen(jjtree) TypeArguments */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) TypeArguments */ + try { +/*@egen*/ + "<" TypeArgument() ( "," TypeArgument() )* ">"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void TypeArgument(): +{/*@bgen(jjtree) TypeArgument */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) TypeArgument */ + try { +/*@egen*/ + ReferenceType() + | + "?" [ WildcardBounds() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void WildcardBounds(): +{/*@bgen(jjtree) WildcardBounds */ + SimpleNode jjtn000 = new SimpleNode(JJTWILDCARDBOUNDS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) WildcardBounds */ + try { +/*@egen*/ + "extends" ReferenceType() + | + "super" ReferenceType()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +void PrimitiveType(): +{/*@bgen(jjtree) PrimitiveType */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMITIVETYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PrimitiveType */ + try { +/*@egen*/ + "boolean" +| + "char" +| + "byte" +| + "short" +| + "int" +| + "long" +| + "float" +| + "double"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ResultType(): +{/*@bgen(jjtree) ResultType */ + SimpleNode jjtn000 = new SimpleNode(JJTRESULTTYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ResultType */ + try { +/*@egen*/ + "void" +| + Type()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void Name(): +/* + * A lookahead of 2 is required below since "Name" can be followed + * by a ".*" when used in the context of an "ImportDeclaration". + */ +{/*@bgen(jjtree) Name */ + SimpleNode jjtn000 = new SimpleNode(JJTNAME); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Name */ + try { +/*@egen*/ + <IDENTIFIER> + ( LOOKAHEAD(2) "." <IDENTIFIER> + )*/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void NameList(): +{/*@bgen(jjtree) NameList */ + SimpleNode jjtn000 = new SimpleNode(JJTNAMELIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) NameList */ + try { +/*@egen*/ + Name() ( "," Name() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +/* + * Expression syntax follows. + */ + +void Expression(): +/* + * This expansion has been written this way instead of: + * Assignment() | ConditionalExpression() + * for performance reasons. + * However, it is a weakening of the grammar for it allows the LHS of + * assignments to be any conditional expression whereas it can only be + * a primary expression. Consider adding a semantic predicate to work + * around this. + */ +{/*@bgen(jjtree) Expression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Expression */ + try { +/*@egen*/ + ConditionalExpression() + [ + LOOKAHEAD(2) + AssignmentOperator() Expression() + ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AssignmentOperator(): +{/*@bgen(jjtree) AssignmentOperator */ + SimpleNode jjtn000 = new SimpleNode(JJTASSIGNMENTOPERATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AssignmentOperator */ + try { +/*@egen*/ + "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|="/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AssignmentExpression(): +{/*@bgen(jjtree) AssignmentExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTASSIGNMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AssignmentExpression */ + try { +/*@egen*/ + PrimaryExpression() AssignmentOperator() Expression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ConditionalExpression(): +{/*@bgen(jjtree) ConditionalExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONALEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ConditionalExpression */ + try { +/*@egen*/ + ConditionalOrExpression() [ "?" Expression() ":" Expression() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ConditionalOrExpression(): +{/*@bgen(jjtree) ConditionalOrExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONALOREXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ConditionalOrExpression */ + try { +/*@egen*/ + ConditionalAndExpression() ( "||" ConditionalAndExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ConditionalAndExpression(): +{/*@bgen(jjtree) ConditionalAndExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONALANDEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ConditionalAndExpression */ + try { +/*@egen*/ + InclusiveOrExpression() ( "&&" InclusiveOrExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void InclusiveOrExpression(): +{/*@bgen(jjtree) InclusiveOrExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTINCLUSIVEOREXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) InclusiveOrExpression */ + try { +/*@egen*/ + ExclusiveOrExpression() ( "|" ExclusiveOrExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ExclusiveOrExpression(): +{/*@bgen(jjtree) ExclusiveOrExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXCLUSIVEOREXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ExclusiveOrExpression */ + try { +/*@egen*/ + AndExpression() ( "^" AndExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AndExpression(): +{/*@bgen(jjtree) AndExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTANDEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AndExpression */ + try { +/*@egen*/ + EqualityExpression() ( "&" EqualityExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void EqualityExpression(): +{/*@bgen(jjtree) EqualityExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTEQUALITYEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) EqualityExpression */ + try { +/*@egen*/ + InstanceOfExpression() ( ( "==" | "!=" ) InstanceOfExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void InstanceOfExpression(): +{/*@bgen(jjtree) InstanceOfExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTINSTANCEOFEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) InstanceOfExpression */ + try { +/*@egen*/ + RelationalExpression() [ "instanceof" Type() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void RelationalExpression(): +{/*@bgen(jjtree) RelationalExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTRELATIONALEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) RelationalExpression */ + try { +/*@egen*/ + ShiftExpression() ( ( "<" | ">" | "<=" | ">=" ) ShiftExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ShiftExpression(): +{/*@bgen(jjtree) ShiftExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTSHIFTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ShiftExpression */ + try { +/*@egen*/ + AdditiveExpression() ( ( "<<" | RSIGNEDSHIFT() | RUNSIGNEDSHIFT() ) AdditiveExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AdditiveExpression(): +{/*@bgen(jjtree) AdditiveExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTADDITIVEEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AdditiveExpression */ + try { +/*@egen*/ + MultiplicativeExpression() ( ( "+" | "-" ) MultiplicativeExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MultiplicativeExpression(): +{/*@bgen(jjtree) MultiplicativeExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTMULTIPLICATIVEEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MultiplicativeExpression */ + try { +/*@egen*/ + UnaryExpression() ( ( "*" | "/" | "%" ) UnaryExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void UnaryExpression(): +{/*@bgen(jjtree) UnaryExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTUNARYEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) UnaryExpression */ + try { +/*@egen*/ + ( "+" | "-" ) UnaryExpression() +| + PreIncrementExpression() +| + PreDecrementExpression() +| + UnaryExpressionNotPlusMinus()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PreIncrementExpression(): +{/*@bgen(jjtree) PreIncrementExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPREINCREMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PreIncrementExpression */ + try { +/*@egen*/ + "++" PrimaryExpression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PreDecrementExpression(): +{/*@bgen(jjtree) PreDecrementExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPREDECREMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PreDecrementExpression */ + try { +/*@egen*/ + "--" PrimaryExpression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void UnaryExpressionNotPlusMinus(): +{/*@bgen(jjtree) UnaryExpressionNotPlusMinus */ + SimpleNode jjtn000 = new SimpleNode(JJTUNARYEXPRESSIONNOTPLUSMINUS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) UnaryExpressionNotPlusMinus */ + try { +/*@egen*/ + ( "~" | "!" ) UnaryExpression() +| + LOOKAHEAD( CastLookahead() ) + CastExpression() +| + PostfixExpression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +// This production is to determine lookahead only. The LOOKAHEAD specifications +// below are not used, but they are there just to indicate that we know about +// this. +void CastLookahead(): +{/*@bgen(jjtree) CastLookahead */ + SimpleNode jjtn000 = new SimpleNode(JJTCASTLOOKAHEAD); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) CastLookahead */ + try { +/*@egen*/ + LOOKAHEAD(2) + "(" PrimitiveType() +| + LOOKAHEAD("(" Type() "[") + "(" Type() "[" "]" +| + "(" Type() ")" ( "~" | "!" | "(" | <IDENTIFIER> | "this" | "super" | "new" | Literal() )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PostfixExpression(): +{/*@bgen(jjtree) PostfixExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPOSTFIXEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PostfixExpression */ + try { +/*@egen*/ + PrimaryExpression() [ PostfixOperator() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PostfixOperator(): +{/*@bgen(jjtree) PostfixOperator */ + SimpleNode jjtn000 = new SimpleNode(JJTPOSTFIXOPERATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PostfixOperator */ + try { +/*@egen*/ + "++" | "--"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void CastExpression(): +{/*@bgen(jjtree) CastExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCASTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) CastExpression */ + try { +/*@egen*/ + LOOKAHEAD("(" PrimitiveType()) + "(" Type() ")" UnaryExpression() +| + "(" Type() ")" UnaryExpressionNotPlusMinus()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PrimaryExpression(): +{/*@bgen(jjtree) PrimaryExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARYEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PrimaryExpression */ + try { +/*@egen*/ + PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MemberSelector(): +{/*@bgen(jjtree) MemberSelector */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERSELECTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MemberSelector */ + try { +/*@egen*/ + "." TypeArguments() <IDENTIFIER>/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PrimaryPrefix(): +{/*@bgen(jjtree) PrimaryPrefix */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARYPREFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PrimaryPrefix */ + try { +/*@egen*/ + Literal() +| + LOOKAHEAD( ( <IDENTIFIER> "." )* "this" ) + ( <IDENTIFIER> "." )* + "this" +| + "super" "." <IDENTIFIER> +| + "(" Expression() ")" +| + AllocationExpression() +| + LOOKAHEAD( ResultType() "." "class" ) + ResultType() "." "class" +| + Name()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void PrimarySuffix(): +{/*@bgen(jjtree) PrimarySuffix */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARYSUFFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) PrimarySuffix */ + try { +/*@egen*/ + LOOKAHEAD("." "super" ".") + "." "super" +| + LOOKAHEAD("." "this") + "." "this" +| + LOOKAHEAD(2) + "." AllocationExpression() +| + LOOKAHEAD(3) + MemberSelector() +| + "[" Expression() "]" +| + "." <IDENTIFIER> +| + Arguments()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void Literal(): +{/*@bgen(jjtree) Literal */ + SimpleNode jjtn000 = new SimpleNode(JJTLITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Literal */ + try { +/*@egen*/ + <INTEGER_LITERAL> +| + <FLOATING_POINT_LITERAL> +| + <CHARACTER_LITERAL> +| + <STRING_LITERAL> +| + BooleanLiteral() +| + NullLiteral()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void BooleanLiteral(): +{/*@bgen(jjtree) BooleanLiteral */ + SimpleNode jjtn000 = new SimpleNode(JJTBOOLEANLITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) BooleanLiteral */ + try { +/*@egen*/ + "true" +| + "false"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void NullLiteral(): +{/*@bgen(jjtree) NullLiteral */ + SimpleNode jjtn000 = new SimpleNode(JJTNULLLITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) NullLiteral */ + try { +/*@egen*/ + "null"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void Arguments(): +{/*@bgen(jjtree) Arguments */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Arguments */ + try { +/*@egen*/ + "(" [ ArgumentList() ] ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ArgumentList(): +{/*@bgen(jjtree) ArgumentList */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENTLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ArgumentList */ + try { +/*@egen*/ + Expression() ( "," Expression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AllocationExpression(): +{/*@bgen(jjtree) AllocationExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTALLOCATIONEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AllocationExpression */ + try { +/*@egen*/ + LOOKAHEAD(2) + "new" PrimitiveType() ArrayDimsAndInits() +| + "new" ClassOrInterfaceType() [ TypeArguments() ] + ( + ArrayDimsAndInits() + | + Arguments() [ ClassOrInterfaceBody(false) ] + )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +/* + * The third LOOKAHEAD specification below is to parse to PrimarySuffix + * if there is an expression between the "[...]". + */ +void ArrayDimsAndInits(): +{/*@bgen(jjtree) ArrayDimsAndInits */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAYDIMSANDINITS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ArrayDimsAndInits */ + try { +/*@egen*/ + LOOKAHEAD(2) + ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "[" "]" )* +| + ( "[" "]" )+ ArrayInitializer()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +/* + * Statement syntax follows. + */ + +void Statement(): +{/*@bgen(jjtree) Statement */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Statement */ + try { +/*@egen*/ + LOOKAHEAD(2) + LabeledStatement() +| + AssertStatement() +| + Block() +| + EmptyStatement() +| + StatementExpression() ";" +| + SwitchStatement() +| + IfStatement() +| + WhileStatement() +| + DoStatement() +| + ForStatement() +| + BreakStatement() +| + ContinueStatement() +| + ReturnStatement() +| + ThrowStatement() +| + SynchronizedStatement() +| + TryStatement()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AssertStatement(): +{/*@bgen(jjtree) AssertStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTASSERTSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AssertStatement */ + try { +/*@egen*/ + "assert" Expression() [ ":" Expression() ] ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void LabeledStatement(): +{/*@bgen(jjtree) LabeledStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTLABELEDSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) LabeledStatement */ + try { +/*@egen*/ + <IDENTIFIER> ":" Statement()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void Block(): +{/*@bgen(jjtree) Block */ + SimpleNode jjtn000 = new SimpleNode(JJTBLOCK); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Block */ + try { +/*@egen*/ + "{" ( BlockStatement() )* "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void BlockStatement(): +{/*@bgen(jjtree) BlockStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTBLOCKSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) BlockStatement */ + try { +/*@egen*/ + LOOKAHEAD( Modifiers() Type() <IDENTIFIER> ) + LocalVariableDeclaration() ";" +| + Statement() +| + ClassOrInterfaceDeclaration(0)/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void LocalVariableDeclaration(): +{/*@bgen(jjtree) LocalVariableDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTLOCALVARIABLEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) LocalVariableDeclaration */ + try { +/*@egen*/ + Modifiers() Type() VariableDeclarator() ( "," VariableDeclarator() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void EmptyStatement(): +{/*@bgen(jjtree) EmptyStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTEMPTYSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) EmptyStatement */ + try { +/*@egen*/ + ";"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void StatementExpression(): +{/*@bgen(jjtree) StatementExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) StatementExpression */ + try { +/*@egen*/ + PreIncrementExpression() +| + PreDecrementExpression() +| + LOOKAHEAD(PrimaryExpression() AssignmentOperator()) + AssignmentExpression() +| + PostfixExpression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void SwitchStatement(): +{/*@bgen(jjtree) SwitchStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTSWITCHSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) SwitchStatement */ + try { +/*@egen*/ + "switch" "(" Expression() ")" "{" + ( SwitchLabel() ( BlockStatement() )* )* + "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void SwitchLabel(): +{/*@bgen(jjtree) SwitchLabel */ + SimpleNode jjtn000 = new SimpleNode(JJTSWITCHLABEL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) SwitchLabel */ + try { +/*@egen*/ + "case" Expression() ":" +| + "default" ":"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void IfStatement(): +/* + * The disambiguating algorithm of JavaCC automatically binds dangling + * else's to the innermost if statement. The LOOKAHEAD specification + * is to tell JavaCC that we know what we are doing. + */ +{/*@bgen(jjtree) IfStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTIFSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) IfStatement */ + try { +/*@egen*/ + "if" "(" Expression() ")" Statement() [ LOOKAHEAD(1) "else" Statement() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void WhileStatement(): +{/*@bgen(jjtree) WhileStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTWHILESTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) WhileStatement */ + try { +/*@egen*/ + "while" "(" Expression() ")" Statement()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void DoStatement(): +{/*@bgen(jjtree) DoStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTDOSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) DoStatement */ + try { +/*@egen*/ + "do" Statement() "while" "(" Expression() ")" ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ForStatement(): +{/*@bgen(jjtree) ForStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTFORSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ForStatement */ + try { +/*@egen*/ + "for" "(" + + ( + LOOKAHEAD(Modifiers() Type() <IDENTIFIER> ":") + Modifiers() Type() <IDENTIFIER> ":" Expression() + | + [ ForInit() ] ";" [ Expression() ] ";" [ ForUpdate() ] + ) + + ")" Statement()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ForInit(): +{/*@bgen(jjtree) ForInit */ + SimpleNode jjtn000 = new SimpleNode(JJTFORINIT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ForInit */ + try { +/*@egen*/ + LOOKAHEAD( Modifiers() Type() <IDENTIFIER> ) + LocalVariableDeclaration() +| + StatementExpressionList()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void StatementExpressionList(): +{/*@bgen(jjtree) StatementExpressionList */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENTEXPRESSIONLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) StatementExpressionList */ + try { +/*@egen*/ + StatementExpression() ( "," StatementExpression() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ForUpdate(): +{/*@bgen(jjtree) ForUpdate */ + SimpleNode jjtn000 = new SimpleNode(JJTFORUPDATE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ForUpdate */ + try { +/*@egen*/ + StatementExpressionList()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void BreakStatement(): +{/*@bgen(jjtree) BreakStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTBREAKSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) BreakStatement */ + try { +/*@egen*/ + "break" [ <IDENTIFIER> ] ";"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ContinueStatement(): +{/*@bgen(jjtree) ContinueStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTCONTINUESTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ContinueStatement */ + try { +/*@egen*/ + "continue" [ <IDENTIFIER> ] ";"/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ReturnStatement(): +{/*@bgen(jjtree) ReturnStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTRETURNSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ReturnStatement */ + try { +/*@egen*/ + "return" [ Expression() ] ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void ThrowStatement(): +{/*@bgen(jjtree) ThrowStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTTHROWSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) ThrowStatement */ + try { +/*@egen*/ + "throw" Expression() ";"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void SynchronizedStatement(): +{/*@bgen(jjtree) SynchronizedStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTSYNCHRONIZEDSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) SynchronizedStatement */ + try { +/*@egen*/ + "synchronized" "(" Expression() ")" Block()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void TryStatement(): +/* + * Semantic check required here to make sure that at least one + * finally/catch is present. + */ +{/*@bgen(jjtree) TryStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTTRYSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) TryStatement */ + try { +/*@egen*/ + "try" Block() + ( "catch" "(" FormalParameter() ")" Block() )* + [ "finally" Block() ]/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +/* We use productions to match >>>, >> and > so that we can keep the + * type declaration syntax with generics clean + */ + +void RUNSIGNEDSHIFT(): +{/*@bgen(jjtree) RUNSIGNEDSHIFT */ + SimpleNode jjtn000 = new SimpleNode(JJTRUNSIGNEDSHIFT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) RUNSIGNEDSHIFT */ + try { +/*@egen*/ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT} ) + ">" ">" ">" + )/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void RSIGNEDSHIFT(): +{/*@bgen(jjtree) RSIGNEDSHIFT */ + SimpleNode jjtn000 = new SimpleNode(JJTRSIGNEDSHIFT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) RSIGNEDSHIFT */ + try { +/*@egen*/ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RSIGNEDSHIFT} ) + ">" ">" + )/*@bgen(jjtree)*/ + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +/* Annotation syntax follows. */ + +void Annotation(): +{/*@bgen(jjtree) Annotation */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) Annotation */ + try { +/*@egen*/ + LOOKAHEAD( "@" Name() "(" ( <IDENTIFIER> "=" | ")" )) + NormalAnnotation() + | + LOOKAHEAD( "@" Name() "(" ) + SingleMemberAnnotation() + | + MarkerAnnotation()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void NormalAnnotation(): +{/*@bgen(jjtree) NormalAnnotation */ + SimpleNode jjtn000 = new SimpleNode(JJTNORMALANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) NormalAnnotation */ + try { +/*@egen*/ + "@" Name() "(" [ MemberValuePairs() ] ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MarkerAnnotation(): +{/*@bgen(jjtree) MarkerAnnotation */ + SimpleNode jjtn000 = new SimpleNode(JJTMARKERANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MarkerAnnotation */ + try { +/*@egen*/ + "@" Name()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void SingleMemberAnnotation(): +{/*@bgen(jjtree) SingleMemberAnnotation */ + SimpleNode jjtn000 = new SimpleNode(JJTSINGLEMEMBERANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) SingleMemberAnnotation */ + try { +/*@egen*/ + "@" Name() "(" MemberValue() ")"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MemberValuePairs(): +{/*@bgen(jjtree) MemberValuePairs */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUEPAIRS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MemberValuePairs */ + try { +/*@egen*/ + MemberValuePair() ( "," MemberValuePair() )*/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MemberValuePair(): +{/*@bgen(jjtree) MemberValuePair */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUEPAIR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MemberValuePair */ + try { +/*@egen*/ + <IDENTIFIER> "=" MemberValue()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MemberValue(): +{/*@bgen(jjtree) MemberValue */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MemberValue */ + try { +/*@egen*/ + Annotation() + | + MemberValueArrayInitializer() + | + ConditionalExpression()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void MemberValueArrayInitializer(): +{/*@bgen(jjtree) MemberValueArrayInitializer */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUEARRAYINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) MemberValueArrayInitializer */ + try { +/*@egen*/ + "{" MemberValue() ( LOOKAHEAD(2) "," MemberValue() )* [ "," ] "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + + +/* Annotation Types. */ + +void AnnotationTypeDeclaration(int modifiers): +{/*@bgen(jjtree) AnnotationTypeDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATIONTYPEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AnnotationTypeDeclaration */ + try { +/*@egen*/ + "@" "interface" <IDENTIFIER> AnnotationTypeBody()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AnnotationTypeBody(): +{/*@bgen(jjtree) AnnotationTypeBody */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATIONTYPEBODY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) AnnotationTypeBody */ + try { +/*@egen*/ + "{" ( AnnotationTypeMemberDeclaration() )* "}"/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void AnnotationTypeMemberDeclaration(): +{/*@bgen(jjtree) AnnotationTypeMemberDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATIONTYPEMEMBERDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/ + int modifiers; +} +{/*@bgen(jjtree) AnnotationTypeMemberDeclaration */ + try { +/*@egen*/ + modifiers = Modifiers() + ( + LOOKAHEAD(Type() <IDENTIFIER> "(") + Type() <IDENTIFIER> "(" ")" [ DefaultValue() ] ";" + | + ClassOrInterfaceDeclaration(modifiers) + | + EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + | + FieldDeclaration(modifiers) + ) + | + ( ";" )/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} + +void DefaultValue(): +{/*@bgen(jjtree) DefaultValue */ + SimpleNode jjtn000 = new SimpleNode(JJTDEFAULTVALUE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); +/*@egen*/} +{/*@bgen(jjtree) DefaultValue */ + try { +/*@egen*/ + "default" MemberValue()/*@bgen(jjtree)*/ + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + throw (RuntimeException)jjte000; + } + if (jjte000 instanceof ParseException) { + throw (ParseException)jjte000; + } + throw (Error)jjte000; + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } +/*@egen*/ +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jjt (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/Java1.5.jjt) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jjt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Java1.5.jjt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2150 @@ + +/* + * Copyright © 2002 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * California 95054, U.S.A. All rights reserved. Sun Microsystems, Inc. has + * intellectual property rights relating to technology embodied in the product + * that is described in this document. In particular, and without limitation, + * these intellectual property rights may include one or more of the U.S. + * patents listed at http://www.sun.com/patents and one or more additional + * patents or pending patent applications in the U.S. and in other countries. + * U.S. Government Rights - Commercial software. Government users are subject + * to the Sun Microsystems, Inc. standard license agreement and applicable + * provisions of the FAR and its supplements. Use is subject to license terms. + * Sun, Sun Microsystems, the Sun logo and Java are trademarks or registered + * trademarks of Sun Microsystems, Inc. in the U.S. and other countries. This + * product is covered and controlled by U.S. Export Control laws and may be + * subject to the export or import laws in other countries. Nuclear, missile, + * chemical biological weapons or nuclear maritime end uses or end users, + * whether direct or indirect, are strictly prohibited. Export or reexport + * to countries subject to U.S. embargo or to entities identified on U.S. + * export exclusion lists, including, but not limited to, the denied persons + * and specially designated nationals lists is strictly prohibited. + */ + +// Slightly modified version of javacc's reference 1.5 grammar, tweaked for +// usage with JAXX. There are two main areas of changes: several new +// nonterminals were added to make identifying certain constructs easier, +// and the Line nonterminal was added to support JAXX's script tags. +// Several of the new changes are inefficient and require excess lookahead, +// but at this point I'd rather have inefficiency than risk breaking it during +// attempted optimizations. + +options { + JAVA_UNICODE_ESCAPE = true; + ERROR_REPORTING = false; + STATIC = false; + JDK_VERSION = "1.4"; + NODE_SCOPE_HOOK=true; +} + +PARSER_BEGIN(JavaParser) +package jaxx.parser; + +import java.io.*; + +/** + * Grammar to parse Java version 1.5 + * @author Sreenivasa Viswanadha - Simplified and enhanced for 1.5 + */ +public class JavaParser +{ + /** + * Class to hold modifiers. + */ + static public final class ModifierSet + { + /* Definitions of the bits in the modifiers field. */ + public static final int PUBLIC = 0x0001; + public static final int PROTECTED = 0x0002; + public static final int PRIVATE = 0x0004; + public static final int ABSTRACT = 0x0008; + public static final int STATIC = 0x0010; + public static final int FINAL = 0x0020; + public static final int SYNCHRONIZED = 0x0040; + public static final int NATIVE = 0x0080; + public static final int TRANSIENT = 0x0100; + public static final int VOLATILE = 0x0200; + public static final int STRICTFP = 0x1000; + + /** A set of accessors that indicate whether the specified modifier + is in the set. */ + + public boolean isPublic(int modifiers) + { + return (modifiers & PUBLIC) != 0; + } + + public boolean isProtected(int modifiers) + { + return (modifiers & PROTECTED) != 0; + } + + public boolean isPrivate(int modifiers) + { + return (modifiers & PRIVATE) != 0; + } + + public boolean isStatic(int modifiers) + { + return (modifiers & STATIC) != 0; + } + + public boolean isAbstract(int modifiers) + { + return (modifiers & ABSTRACT) != 0; + } + + public boolean isFinal(int modifiers) + { + return (modifiers & FINAL) != 0; + } + + public boolean isNative(int modifiers) + { + return (modifiers & NATIVE) != 0; + } + + public boolean isStrictfp(int modifiers) + { + return (modifiers & STRICTFP) != 0; + } + + public boolean isSynchronized(int modifiers) + { + return (modifiers & SYNCHRONIZED) != 0; + } + + public boolean isTransient(int modifiers) + { + return (modifiers & TRANSIENT) != 0; + } + + public boolean isVolatile(int modifiers) + { + return (modifiers & VOLATILE) != 0; + } + + /** + * Removes the given modifier. + */ + static int removeModifier(int modifiers, int mod) + { + return modifiers & ~mod; + } + } + + public JavaParser(String fileName) + { + this(System.in); + try { ReInit(new FileInputStream(new File(fileName))); } + catch(Exception e) { e.printStackTrace(); } + } + + void jjtreeOpenNodeScope(Node n) { + ((SimpleNode) n).firstToken = getToken(1); + } + + void jjtreeCloseNodeScope(Node n) { + ((SimpleNode) n).lastToken = getToken(0); + } + + public SimpleNode popNode() + { + if ( jjtree.nodeArity() > 0) // number of child nodes + return (SimpleNode)jjtree.popNode(); + else + return null; + } + public static void main(String args[]) { + JavaParser parser; + if (args.length == 0) { + System.out.println("Java Parser Version 1.1: Reading from standard input . . ."); + parser = new JavaParser(System.in); + } else if (args.length == 1) { + System.out.println("Java Parser Version 1.1: Reading from file " + args[0] + " . . ."); + try { + parser = new JavaParser(new java.io.FileInputStream(args[0])); + } catch (java.io.FileNotFoundException e) { + System.out.println("Java Parser Version 1.1: File " + args[0] + " not found."); + return; + } + } else { + System.out.println("Java Parser Version 1.1: Usage is one of:"); + System.out.println(" java JavaParser < inputfile"); + System.out.println("OR"); + System.out.println(" java JavaParser inputfile"); + return; + } + try { + parser.CompilationUnit(); + System.out.println("Java Parser Version 1.1: Java program parsed successfully."); + } catch (ParseException e) { + System.out.println(e.getMessage()); + System.out.println("Java Parser Version 1.1: Encountered errors during parse."); + } + } + +} + +PARSER_END(JavaParser) + +/* COMMENTS */ + +MORE : +{ + <"/**" ~["/"]> { input_stream.backup(1); } : IN_FORMAL_COMMENT +| + "/*" : IN_MULTI_LINE_COMMENT +} + +SPECIAL_TOKEN: +{ + <WHITE_SPACE: ([" ", "\n", "\r", "\t", "\f"])+> +} + +SPECIAL_TOKEN : +{ + <SINGLE_LINE_COMMENT: "//" (~["\n", "\r"])* ("\n" | "\r" | "\r\n")?> +} + +<IN_FORMAL_COMMENT> +SPECIAL_TOKEN : +{ + <FORMAL_COMMENT: "*/" > : DEFAULT +} + +<IN_MULTI_LINE_COMMENT> +SPECIAL_TOKEN : +{ + <MULTI_LINE_COMMENT: "*/" > : DEFAULT +} + +<IN_FORMAL_COMMENT,IN_MULTI_LINE_COMMENT> +MORE : +{ + < ~[] > +} + +/* RESERVED WORDS AND LITERALS */ + +TOKEN : +{ + < ABSTRACT: "abstract" > +| < ASSERT: "assert" > +| < BOOLEAN: "boolean" > +| < BREAK: "break" > +| < BYTE: "byte" > +| < CASE: "case" > +| < CATCH: "catch" > +| < CHAR: "char" > +| < CLASS: "class" > +| < CONST: "const" > +| < CONTINUE: "continue" > +| < _DEFAULT: "default" > +| < DO: "do" > +| < DOUBLE: "double" > +| < ELSE: "else" > +| < ENUM: "enum" > +| < EXTENDS: "extends" > +| < FALSE: "false" > +| < FINAL: "final" > +| < FINALLY: "finally" > +| < FLOAT: "float" > +| < FOR: "for" > +| < GOTO: "goto" > +| < IF: "if" > +| < IMPLEMENTS: "implements" > +| < IMPORT: "import" > +| < INSTANCEOF: "instanceof" > +| < INT: "int" > +| < INTERFACE: "interface" > +| < LONG: "long" > +| < NATIVE: "native" > +| < NEW: "new" > +| < NULL: "null" > +| < PACKAGE: "package"> +| < PRIVATE: "private" > +| < PROTECTED: "protected" > +| < PUBLIC: "public" > +| < RETURN: "return" > +| < SHORT: "short" > +| < STATIC: "static" > +| < STRICTFP: "strictfp" > +| < SUPER: "super" > +| < SWITCH: "switch" > +| < SYNCHRONIZED: "synchronized" > +| < THIS: "this" > +| < THROW: "throw" > +| < THROWS: "throws" > +| < TRANSIENT: "transient" > +| < TRUE: "true" > +| < TRY: "try" > +| < VOID: "void" > +| < VOLATILE: "volatile" > +| < WHILE: "while" > +} + +/* LITERALS */ + +TOKEN : +{ + < INTEGER_LITERAL: + <DECIMAL_LITERAL> (["l","L"])? + | <HEX_LITERAL> (["l","L"])? + | <OCTAL_LITERAL> (["l","L"])? + > +| + < #DECIMAL_LITERAL: ["1"-"9"] (["0"-"9"])* > +| + < #HEX_LITERAL: "0" ["x","X"] (["0"-"9","a"-"f","A"-"F"])+ > +| + < #OCTAL_LITERAL: "0" (["0"-"7"])* > +| + < FLOATING_POINT_LITERAL: + <DECIMAL_FLOATING_POINT_LITERAL> + | <HEXADECIMAL_FLOATING_POINT_LITERAL> + > +| + < #DECIMAL_FLOATING_POINT_LITERAL: + (["0"-"9"])+ "." (["0"-"9"])* (<DECIMAL_EXPONENT>)? (["f","F","d","D"])? + | "." (["0"-"9"])+ (<DECIMAL_EXPONENT>)? (["f","F","d","D"])? + | (["0"-"9"])+ <DECIMAL_EXPONENT> (["f","F","d","D"])? + | (["0"-"9"])+ (<DECIMAL_EXPONENT>)? ["f","F","d","D"] + > +| + < #DECIMAL_EXPONENT: ["e","E"] (["+","-"])? (["0"-"9"])+ > +| + < #HEXADECIMAL_FLOATING_POINT_LITERAL: + "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])+ (".")? <HEXADECIMAL_EXPONENT> (["f","F","d","D"])? + | "0" ["x", "X"] (["0"-"9","a"-"f","A"-"F"])* "." (["0"-"9","a"-"f","A"-"F"])+ <HEXADECIMAL_EXPONENT> (["f","F","d","D"])? + > +| + < #HEXADECIMAL_EXPONENT: ["p","P"] (["+","-"])? (["0"-"9"])+ > +| + < CHARACTER_LITERAL: + "'" + ( (~["'","\\","\n","\r"]) + | ("\\" + ( ["n","t","b","r","f","\\","'","\""] + | ["0"-"7"] ( ["0"-"7"] )? + | ["0"-"3"] ["0"-"7"] ["0"-"7"] + ) + ) + ) + "'" + > +| + < STRING_LITERAL: + "\"" + ( (~["\"","\\","\n","\r"]) + | ("\\" + ( ["n","t","b","r","f","\\","'","\""] + | ["0"-"7"] ( ["0"-"7"] )? + | ["0"-"3"] ["0"-"7"] ["0"-"7"] + ) + ) + )* + "\"" + > +} + +/* IDENTIFIERS */ + +TOKEN : +{ + < IDENTIFIER: <LETTER> (<PART_LETTER>)* > +| + < #LETTER: + [ // all chars for which Character.isIdentifierStart is true + "$", + "A"-"Z", + "_", + "a"-"z", + "\u00a2"-"\u00a5", + "\u00aa", + "\u00b5", + "\u00ba", + "\u00c0"-"\u00d6", + "\u00d8"-"\u00f6", + "\u00f8"-"\u021f", + "\u0222"-"\u0233", + "\u0250"-"\u02ad", + "\u02b0"-"\u02b8", + "\u02bb"-"\u02c1", + "\u02d0"-"\u02d1", + "\u02e0"-"\u02e4", + "\u02ee", + "\u037a", + "\u0386", + "\u0388"-"\u038a", + "\u038c", + "\u038e"-"\u03a1", + "\u03a3"-"\u03ce", + "\u03d0"-"\u03d7", + "\u03da"-"\u03f3", + "\u0400"-"\u0481", + "\u048c"-"\u04c4", + "\u04c7"-"\u04c8", + "\u04cb"-"\u04cc", + "\u04d0"-"\u04f5", + "\u04f8"-"\u04f9", + "\u0531"-"\u0556", + "\u0559", + "\u0561"-"\u0587", + "\u05d0"-"\u05ea", + "\u05f0"-"\u05f2", + "\u0621"-"\u063a", + "\u0640"-"\u064a", + "\u0671"-"\u06d3", + "\u06d5", + "\u06e5"-"\u06e6", + "\u06fa"-"\u06fc", + "\u0710", + "\u0712"-"\u072c", + "\u0780"-"\u07a5", + "\u0905"-"\u0939", + "\u093d", + "\u0950", + "\u0958"-"\u0961", + "\u0985"-"\u098c", + "\u098f"-"\u0990", + "\u0993"-"\u09a8", + "\u09aa"-"\u09b0", + "\u09b2", + "\u09b6"-"\u09b9", + "\u09dc"-"\u09dd", + "\u09df"-"\u09e1", + "\u09f0"-"\u09f3", + "\u0a05"-"\u0a0a", + "\u0a0f"-"\u0a10", + "\u0a13"-"\u0a28", + "\u0a2a"-"\u0a30", + "\u0a32"-"\u0a33", + "\u0a35"-"\u0a36", + "\u0a38"-"\u0a39", + "\u0a59"-"\u0a5c", + "\u0a5e", + "\u0a72"-"\u0a74", + "\u0a85"-"\u0a8b", + "\u0a8d", + "\u0a8f"-"\u0a91", + "\u0a93"-"\u0aa8", + "\u0aaa"-"\u0ab0", + "\u0ab2"-"\u0ab3", + "\u0ab5"-"\u0ab9", + "\u0abd", + "\u0ad0", + "\u0ae0", + "\u0b05"-"\u0b0c", + "\u0b0f"-"\u0b10", + "\u0b13"-"\u0b28", + "\u0b2a"-"\u0b30", + "\u0b32"-"\u0b33", + "\u0b36"-"\u0b39", + "\u0b3d", + "\u0b5c"-"\u0b5d", + "\u0b5f"-"\u0b61", + "\u0b85"-"\u0b8a", + "\u0b8e"-"\u0b90", + "\u0b92"-"\u0b95", + "\u0b99"-"\u0b9a", + "\u0b9c", + "\u0b9e"-"\u0b9f", + "\u0ba3"-"\u0ba4", + "\u0ba8"-"\u0baa", + "\u0bae"-"\u0bb5", + "\u0bb7"-"\u0bb9", + "\u0c05"-"\u0c0c", + "\u0c0e"-"\u0c10", + "\u0c12"-"\u0c28", + "\u0c2a"-"\u0c33", + "\u0c35"-"\u0c39", + "\u0c60"-"\u0c61", + "\u0c85"-"\u0c8c", + "\u0c8e"-"\u0c90", + "\u0c92"-"\u0ca8", + "\u0caa"-"\u0cb3", + "\u0cb5"-"\u0cb9", + "\u0cde", + "\u0ce0"-"\u0ce1", + "\u0d05"-"\u0d0c", + "\u0d0e"-"\u0d10", + "\u0d12"-"\u0d28", + "\u0d2a"-"\u0d39", + "\u0d60"-"\u0d61", + "\u0d85"-"\u0d96", + "\u0d9a"-"\u0db1", + "\u0db3"-"\u0dbb", + "\u0dbd", + "\u0dc0"-"\u0dc6", + "\u0e01"-"\u0e30", + "\u0e32"-"\u0e33", + "\u0e3f"-"\u0e46", + "\u0e81"-"\u0e82", + "\u0e84", + "\u0e87"-"\u0e88", + "\u0e8a", + "\u0e8d", + "\u0e94"-"\u0e97", + "\u0e99"-"\u0e9f", + "\u0ea1"-"\u0ea3", + "\u0ea5", + "\u0ea7", + "\u0eaa"-"\u0eab", + "\u0ead"-"\u0eb0", + "\u0eb2"-"\u0eb3", + "\u0ebd", + "\u0ec0"-"\u0ec4", + "\u0ec6", + "\u0edc"-"\u0edd", + "\u0f00", + "\u0f40"-"\u0f47", + "\u0f49"-"\u0f6a", + "\u0f88"-"\u0f8b", + "\u1000"-"\u1021", + "\u1023"-"\u1027", + "\u1029"-"\u102a", + "\u1050"-"\u1055", + "\u10a0"-"\u10c5", + "\u10d0"-"\u10f6", + "\u1100"-"\u1159", + "\u115f"-"\u11a2", + "\u11a8"-"\u11f9", + "\u1200"-"\u1206", + "\u1208"-"\u1246", + "\u1248", + "\u124a"-"\u124d", + "\u1250"-"\u1256", + "\u1258", + "\u125a"-"\u125d", + "\u1260"-"\u1286", + "\u1288", + "\u128a"-"\u128d", + "\u1290"-"\u12ae", + "\u12b0", + "\u12b2"-"\u12b5", + "\u12b8"-"\u12be", + "\u12c0", + "\u12c2"-"\u12c5", + "\u12c8"-"\u12ce", + "\u12d0"-"\u12d6", + "\u12d8"-"\u12ee", + "\u12f0"-"\u130e", + "\u1310", + "\u1312"-"\u1315", + "\u1318"-"\u131e", + "\u1320"-"\u1346", + "\u1348"-"\u135a", + "\u13a0"-"\u13f4", + "\u1401"-"\u166c", + "\u166f"-"\u1676", + "\u1681"-"\u169a", + "\u16a0"-"\u16ea", + "\u1780"-"\u17b3", + "\u17db", + "\u1820"-"\u1877", + "\u1880"-"\u18a8", + "\u1e00"-"\u1e9b", + "\u1ea0"-"\u1ef9", + "\u1f00"-"\u1f15", + "\u1f18"-"\u1f1d", + "\u1f20"-"\u1f45", + "\u1f48"-"\u1f4d", + "\u1f50"-"\u1f57", + "\u1f59", + "\u1f5b", + "\u1f5d", + "\u1f5f"-"\u1f7d", + "\u1f80"-"\u1fb4", + "\u1fb6"-"\u1fbc", + "\u1fbe", + "\u1fc2"-"\u1fc4", + "\u1fc6"-"\u1fcc", + "\u1fd0"-"\u1fd3", + "\u1fd6"-"\u1fdb", + "\u1fe0"-"\u1fec", + "\u1ff2"-"\u1ff4", + "\u1ff6"-"\u1ffc", + "\u203f"-"\u2040", + "\u207f", + "\u20a0"-"\u20af", + "\u2102", + "\u2107", + "\u210a"-"\u2113", + "\u2115", + "\u2119"-"\u211d", + "\u2124", + "\u2126", + "\u2128", + "\u212a"-"\u212d", + "\u212f"-"\u2131", + "\u2133"-"\u2139", + "\u2160"-"\u2183", + "\u3005"-"\u3007", + "\u3021"-"\u3029", + "\u3031"-"\u3035", + "\u3038"-"\u303a", + "\u3041"-"\u3094", + "\u309d"-"\u309e", + "\u30a1"-"\u30fe", + "\u3105"-"\u312c", + "\u3131"-"\u318e", + "\u31a0"-"\u31b7", + "\u3400"-"\u4db5", + "\u4e00"-"\u9fa5", + "\ua000"-"\ua48c", + "\uac00"-"\ud7a3", + "\uf900"-"\ufa2d", + "\ufb00"-"\ufb06", + "\ufb13"-"\ufb17", + "\ufb1d", + "\ufb1f"-"\ufb28", + "\ufb2a"-"\ufb36", + "\ufb38"-"\ufb3c", + "\ufb3e", + "\ufb40"-"\ufb41", + "\ufb43"-"\ufb44", + "\ufb46"-"\ufbb1", + "\ufbd3"-"\ufd3d", + "\ufd50"-"\ufd8f", + "\ufd92"-"\ufdc7", + "\ufdf0"-"\ufdfb", + "\ufe33"-"\ufe34", + "\ufe4d"-"\ufe4f", + "\ufe69", + "\ufe70"-"\ufe72", + "\ufe74", + "\ufe76"-"\ufefc", + "\uff04", + "\uff21"-"\uff3a", + "\uff3f", + "\uff41"-"\uff5a", + "\uff65"-"\uffbe", + "\uffc2"-"\uffc7", + "\uffca"-"\uffcf", + "\uffd2"-"\uffd7", + "\uffda"-"\uffdc", + "\uffe0"-"\uffe1", + "\uffe5"-"\uffe6" + ] + > +| + < #PART_LETTER: + [ // all chars for which Character.isIdentifierPart is true + "\u0000"-"\u0008", + "\u000e"-"\u001b", + "$", + "0"-"9", + "A"-"Z", + "_", + "a"-"z", + "\u007f"-"\u009f", + "\u00a2"-"\u00a5", + "\u00aa", + "\u00b5", + "\u00ba", + "\u00c0"-"\u00d6", + "\u00d8"-"\u00f6", + "\u00f8"-"\u021f", + "\u0222"-"\u0233", + "\u0250"-"\u02ad", + "\u02b0"-"\u02b8", + "\u02bb"-"\u02c1", + "\u02d0"-"\u02d1", + "\u02e0"-"\u02e4", + "\u02ee", + "\u0300"-"\u034e", + "\u0360"-"\u0362", + "\u037a", + "\u0386", + "\u0388"-"\u038a", + "\u038c", + "\u038e"-"\u03a1", + "\u03a3"-"\u03ce", + "\u03d0"-"\u03d7", + "\u03da"-"\u03f3", + "\u0400"-"\u0481", + "\u0483"-"\u0486", + "\u048c"-"\u04c4", + "\u04c7"-"\u04c8", + "\u04cb"-"\u04cc", + "\u04d0"-"\u04f5", + "\u04f8"-"\u04f9", + "\u0531"-"\u0556", + "\u0559", + "\u0561"-"\u0587", + "\u0591"-"\u05a1", + "\u05a3"-"\u05b9", + "\u05bb"-"\u05bd", + "\u05bf", + "\u05c1"-"\u05c2", + "\u05c4", + "\u05d0"-"\u05ea", + "\u05f0"-"\u05f2", + "\u0621"-"\u063a", + "\u0640"-"\u0655", + "\u0660"-"\u0669", + "\u0670"-"\u06d3", + "\u06d5"-"\u06dc", + "\u06df"-"\u06e8", + "\u06ea"-"\u06ed", + "\u06f0"-"\u06fc", + "\u070f"-"\u072c", + "\u0730"-"\u074a", + "\u0780"-"\u07b0", + "\u0901"-"\u0903", + "\u0905"-"\u0939", + "\u093c"-"\u094d", + "\u0950"-"\u0954", + "\u0958"-"\u0963", + "\u0966"-"\u096f", + "\u0981"-"\u0983", + "\u0985"-"\u098c", + "\u098f"-"\u0990", + "\u0993"-"\u09a8", + "\u09aa"-"\u09b0", + "\u09b2", + "\u09b6"-"\u09b9", + "\u09bc", + "\u09be"-"\u09c4", + "\u09c7"-"\u09c8", + "\u09cb"-"\u09cd", + "\u09d7", + "\u09dc"-"\u09dd", + "\u09df"-"\u09e3", + "\u09e6"-"\u09f3", + "\u0a02", + "\u0a05"-"\u0a0a", + "\u0a0f"-"\u0a10", + "\u0a13"-"\u0a28", + "\u0a2a"-"\u0a30", + "\u0a32"-"\u0a33", + "\u0a35"-"\u0a36", + "\u0a38"-"\u0a39", + "\u0a3c", + "\u0a3e"-"\u0a42", + "\u0a47"-"\u0a48", + "\u0a4b"-"\u0a4d", + "\u0a59"-"\u0a5c", + "\u0a5e", + "\u0a66"-"\u0a74", + "\u0a81"-"\u0a83", + "\u0a85"-"\u0a8b", + "\u0a8d", + "\u0a8f"-"\u0a91", + "\u0a93"-"\u0aa8", + "\u0aaa"-"\u0ab0", + "\u0ab2"-"\u0ab3", + "\u0ab5"-"\u0ab9", + "\u0abc"-"\u0ac5", + "\u0ac7"-"\u0ac9", + "\u0acb"-"\u0acd", + "\u0ad0", + "\u0ae0", + "\u0ae6"-"\u0aef", + "\u0b01"-"\u0b03", + "\u0b05"-"\u0b0c", + "\u0b0f"-"\u0b10", + "\u0b13"-"\u0b28", + "\u0b2a"-"\u0b30", + "\u0b32"-"\u0b33", + "\u0b36"-"\u0b39", + "\u0b3c"-"\u0b43", + "\u0b47"-"\u0b48", + "\u0b4b"-"\u0b4d", + "\u0b56"-"\u0b57", + "\u0b5c"-"\u0b5d", + "\u0b5f"-"\u0b61", + "\u0b66"-"\u0b6f", + "\u0b82"-"\u0b83", + "\u0b85"-"\u0b8a", + "\u0b8e"-"\u0b90", + "\u0b92"-"\u0b95", + "\u0b99"-"\u0b9a", + "\u0b9c", + "\u0b9e"-"\u0b9f", + "\u0ba3"-"\u0ba4", + "\u0ba8"-"\u0baa", + "\u0bae"-"\u0bb5", + "\u0bb7"-"\u0bb9", + "\u0bbe"-"\u0bc2", + "\u0bc6"-"\u0bc8", + "\u0bca"-"\u0bcd", + "\u0bd7", + "\u0be7"-"\u0bef", + "\u0c01"-"\u0c03", + "\u0c05"-"\u0c0c", + "\u0c0e"-"\u0c10", + "\u0c12"-"\u0c28", + "\u0c2a"-"\u0c33", + "\u0c35"-"\u0c39", + "\u0c3e"-"\u0c44", + "\u0c46"-"\u0c48", + "\u0c4a"-"\u0c4d", + "\u0c55"-"\u0c56", + "\u0c60"-"\u0c61", + "\u0c66"-"\u0c6f", + "\u0c82"-"\u0c83", + "\u0c85"-"\u0c8c", + "\u0c8e"-"\u0c90", + "\u0c92"-"\u0ca8", + "\u0caa"-"\u0cb3", + "\u0cb5"-"\u0cb9", + "\u0cbe"-"\u0cc4", + "\u0cc6"-"\u0cc8", + "\u0cca"-"\u0ccd", + "\u0cd5"-"\u0cd6", + "\u0cde", + "\u0ce0"-"\u0ce1", + "\u0ce6"-"\u0cef", + "\u0d02"-"\u0d03", + "\u0d05"-"\u0d0c", + "\u0d0e"-"\u0d10", + "\u0d12"-"\u0d28", + "\u0d2a"-"\u0d39", + "\u0d3e"-"\u0d43", + "\u0d46"-"\u0d48", + "\u0d4a"-"\u0d4d", + "\u0d57", + "\u0d60"-"\u0d61", + "\u0d66"-"\u0d6f", + "\u0d82"-"\u0d83", + "\u0d85"-"\u0d96", + "\u0d9a"-"\u0db1", + "\u0db3"-"\u0dbb", + "\u0dbd", + "\u0dc0"-"\u0dc6", + "\u0dca", + "\u0dcf"-"\u0dd4", + "\u0dd6", + "\u0dd8"-"\u0ddf", + "\u0df2"-"\u0df3", + "\u0e01"-"\u0e3a", + "\u0e3f"-"\u0e4e", + "\u0e50"-"\u0e59", + "\u0e81"-"\u0e82", + "\u0e84", + "\u0e87"-"\u0e88", + "\u0e8a", + "\u0e8d", + "\u0e94"-"\u0e97", + "\u0e99"-"\u0e9f", + "\u0ea1"-"\u0ea3", + "\u0ea5", + "\u0ea7", + "\u0eaa"-"\u0eab", + "\u0ead"-"\u0eb9", + "\u0ebb"-"\u0ebd", + "\u0ec0"-"\u0ec4", + "\u0ec6", + "\u0ec8"-"\u0ecd", + "\u0ed0"-"\u0ed9", + "\u0edc"-"\u0edd", + "\u0f00", + "\u0f18"-"\u0f19", + "\u0f20"-"\u0f29", + "\u0f35", + "\u0f37", + "\u0f39", + "\u0f3e"-"\u0f47", + "\u0f49"-"\u0f6a", + "\u0f71"-"\u0f84", + "\u0f86"-"\u0f8b", + "\u0f90"-"\u0f97", + "\u0f99"-"\u0fbc", + "\u0fc6", + "\u1000"-"\u1021", + "\u1023"-"\u1027", + "\u1029"-"\u102a", + "\u102c"-"\u1032", + "\u1036"-"\u1039", + "\u1040"-"\u1049", + "\u1050"-"\u1059", + "\u10a0"-"\u10c5", + "\u10d0"-"\u10f6", + "\u1100"-"\u1159", + "\u115f"-"\u11a2", + "\u11a8"-"\u11f9", + "\u1200"-"\u1206", + "\u1208"-"\u1246", + "\u1248", + "\u124a"-"\u124d", + "\u1250"-"\u1256", + "\u1258", + "\u125a"-"\u125d", + "\u1260"-"\u1286", + "\u1288", + "\u128a"-"\u128d", + "\u1290"-"\u12ae", + "\u12b0", + "\u12b2"-"\u12b5", + "\u12b8"-"\u12be", + "\u12c0", + "\u12c2"-"\u12c5", + "\u12c8"-"\u12ce", + "\u12d0"-"\u12d6", + "\u12d8"-"\u12ee", + "\u12f0"-"\u130e", + "\u1310", + "\u1312"-"\u1315", + "\u1318"-"\u131e", + "\u1320"-"\u1346", + "\u1348"-"\u135a", + "\u1369"-"\u1371", + "\u13a0"-"\u13f4", + "\u1401"-"\u166c", + "\u166f"-"\u1676", + "\u1681"-"\u169a", + "\u16a0"-"\u16ea", + "\u1780"-"\u17d3", + "\u17db", + "\u17e0"-"\u17e9", + "\u180b"-"\u180e", + "\u1810"-"\u1819", + "\u1820"-"\u1877", + "\u1880"-"\u18a9", + "\u1e00"-"\u1e9b", + "\u1ea0"-"\u1ef9", + "\u1f00"-"\u1f15", + "\u1f18"-"\u1f1d", + "\u1f20"-"\u1f45", + "\u1f48"-"\u1f4d", + "\u1f50"-"\u1f57", + "\u1f59", + "\u1f5b", + "\u1f5d", + "\u1f5f"-"\u1f7d", + "\u1f80"-"\u1fb4", + "\u1fb6"-"\u1fbc", + "\u1fbe", + "\u1fc2"-"\u1fc4", + "\u1fc6"-"\u1fcc", + "\u1fd0"-"\u1fd3", + "\u1fd6"-"\u1fdb", + "\u1fe0"-"\u1fec", + "\u1ff2"-"\u1ff4", + "\u1ff6"-"\u1ffc", + "\u200c"-"\u200f", + "\u202a"-"\u202e", + "\u203f"-"\u2040", + "\u206a"-"\u206f", + "\u207f", + "\u20a0"-"\u20af", + "\u20d0"-"\u20dc", + "\u20e1", + "\u2102", + "\u2107", + "\u210a"-"\u2113", + "\u2115", + "\u2119"-"\u211d", + "\u2124", + "\u2126", + "\u2128", + "\u212a"-"\u212d", + "\u212f"-"\u2131", + "\u2133"-"\u2139", + "\u2160"-"\u2183", + "\u3005"-"\u3007", + "\u3021"-"\u302f", + "\u3031"-"\u3035", + "\u3038"-"\u303a", + "\u3041"-"\u3094", + "\u3099"-"\u309a", + "\u309d"-"\u309e", + "\u30a1"-"\u30fe", + "\u3105"-"\u312c", + "\u3131"-"\u318e", + "\u31a0"-"\u31b7", + "\u3400"-"\u4db5", + "\u4e00"-"\u9fa5", + "\ua000"-"\ua48c", + "\uac00"-"\ud7a3", + "\uf900"-"\ufa2d", + "\ufb00"-"\ufb06", + "\ufb13"-"\ufb17", + "\ufb1d"-"\ufb28", + "\ufb2a"-"\ufb36", + "\ufb38"-"\ufb3c", + "\ufb3e", + "\ufb40"-"\ufb41", + "\ufb43"-"\ufb44", + "\ufb46"-"\ufbb1", + "\ufbd3"-"\ufd3d", + "\ufd50"-"\ufd8f", + "\ufd92"-"\ufdc7", + "\ufdf0"-"\ufdfb", + "\ufe20"-"\ufe23", + "\ufe33"-"\ufe34", + "\ufe4d"-"\ufe4f", + "\ufe69", + "\ufe70"-"\ufe72", + "\ufe74", + "\ufe76"-"\ufefc", + "\ufeff", + "\uff04", + "\uff10"-"\uff19", + "\uff21"-"\uff3a", + "\uff3f", + "\uff41"-"\uff5a", + "\uff65"-"\uffbe", + "\uffc2"-"\uffc7", + "\uffca"-"\uffcf", + "\uffd2"-"\uffd7", + "\uffda"-"\uffdc", + "\uffe0"-"\uffe1", + "\uffe5"-"\uffe6", + "\ufff9"-"\ufffb" + ] + > +} + +/* SEPARATORS */ + +TOKEN : +{ + < LPAREN: "(" > +| < RPAREN: ")" > +| < LBRACE: "{" > +| < RBRACE: "}" > +| < LBRACKET: "[" > +| < RBRACKET: "]" > +| < SEMICOLON: ";" > +| < COMMA: "," > +| < DOT: "." > +| < AT: "@" > +} + +/* OPERATORS */ + +TOKEN : +{ + < ASSIGN: "=" > +| < LT: "<" > +| < BANG: "!" > +| < TILDE: "~" > +| < HOOK: "?" > +| < COLON: ":" > +| < EQ: "==" > +| < LE: "<=" > +| < GE: ">=" > +| < NE: "!=" > +| < SC_OR: "||" > +| < SC_AND: "&&" > +| < INCR: "++" > +| < DECR: "--" > +| < PLUS: "+" > +| < MINUS: "-" > +| < STAR: "*" > +| < SLASH: "/" > +| < BIT_AND: "&" > +| < BIT_OR: "|" > +| < XOR: "^" > +| < REM: "%" > +| < LSHIFT: "<<" > +| < PLUSASSIGN: "+=" > +| < MINUSASSIGN: "-=" > +| < STARASSIGN: "*=" > +| < SLASHASSIGN: "/=" > +| < ANDASSIGN: "&=" > +| < ORASSIGN: "|=" > +| < XORASSIGN: "^=" > +| < REMASSIGN: "%=" > +| < LSHIFTASSIGN: "<<=" > +| < RSIGNEDSHIFTASSIGN: ">>=" > +| < RUNSIGNEDSHIFTASSIGN: ">>>=" > +| < ELLIPSIS: "..." > +} + +/* >'s need special attention due to generics syntax. */ +TOKEN : +{ + < RUNSIGNEDSHIFT: ">>>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RUNSIGNEDSHIFT; + input_stream.backup(2); + matchedToken.image = ">"; + } +| < RSIGNEDSHIFT: ">>" > + { + matchedToken.kind = GT; + ((Token.GTToken)matchedToken).realKind = RSIGNEDSHIFT; + input_stream.backup(1); + matchedToken.image = ">"; + } +| < GT: ">" > +} + +boolean Line() : +{ + int modifiers; +} +{ + <EOF> { + return true; + } +| + LOOKAHEAD(BlockStatement()) + BlockStatement() { + return false; + } +| + LOOKAHEAD(Modifiers() [ TypeParameters() ] [ ResultType() ] <IDENTIFIER> FormalParameters() [ "throws" NameList() ] "{") + ClassOrInterfaceBodyDeclaration(false) { + return false; + } +| + LOOKAHEAD(ClassOrInterfaceBodyDeclaration(false)) + ClassOrInterfaceBodyDeclaration(false) { + return false; + } +| + LOOKAHEAD(Expression()) + Expression() { + return false; + } +| + ImportDeclaration() { + return false; + } +} + +/***************************************** + * THE JAVA LANGUAGE GRAMMAR STARTS HERE * + *****************************************/ + +/* + * Program structuring syntax follows. + */ + +void CompilationUnit(): +{} +{ + [ LOOKAHEAD( ( Annotation() )* "package" ) PackageDeclaration() ] + ( ImportDeclaration() )* + ( TypeDeclaration() )* + ( < "\u001a" > )? + ( <STUFF_TO_IGNORE: ~[]> )? + <EOF> +} + +void PackageDeclaration(): +{} +{ + Modifiers() "package" Name() ";" +} + +void ImportDeclaration(): +{} +{ + "import" [ "static" ] Name() [ "." "*" ] ";" +} + +/* + * Modifiers. We match all modifiers in a single rule to reduce the chances of + * syntax errors for simple modifier mistakes. It will also enable us to give + * better error messages. + */ + +int Modifiers(): +{ + int modifiers = 0; +} +{ + ( + LOOKAHEAD(2) + ( + "public" { modifiers |= ModifierSet.PUBLIC; } + | + "static" { modifiers |= ModifierSet.STATIC; } + | + "protected" { modifiers |= ModifierSet.PROTECTED; } + | + "private" { modifiers |= ModifierSet.PRIVATE; } + | + "final" { modifiers |= ModifierSet.FINAL; } + | + "abstract" { modifiers |= ModifierSet.ABSTRACT; } + | + "synchronized" { modifiers |= ModifierSet.SYNCHRONIZED; } + | + "native" { modifiers |= ModifierSet.NATIVE; } + | + "transient" { modifiers |= ModifierSet.TRANSIENT; } + | + "volatile" { modifiers |= ModifierSet.VOLATILE; } + | + "strictfp" { modifiers |= ModifierSet.STRICTFP; } + | + Annotation() + ) + )* + + { + return modifiers; + } +} + +/* + * Declaration syntax follows. + */ +void TypeDeclaration(): +{ + int modifiers; +} +{ + ";" +| + modifiers = Modifiers() + ( + ClassOrInterfaceDeclaration(modifiers) + | + EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + ) +} + + +void ClassOrInterfaceDeclaration(int modifiers): +{ + boolean isInterface = false; +} +{ + ( "class" | "interface" { isInterface = true; } ) + <IDENTIFIER> + [ TypeParameters() ] + [ ExtendsList(isInterface) ] + [ ImplementsList(isInterface) ] + ClassOrInterfaceBody(isInterface) +} + +void ExtendsList(boolean isInterface): +{ + boolean extendsMoreThanOne = false; +} +{ + "extends" ClassOrInterfaceType() + ( "," ClassOrInterfaceType() { extendsMoreThanOne = true; } )* + { + if (extendsMoreThanOne && !isInterface) + throw new ParseException("A class cannot extend more than one other class"); + } +} + +void ImplementsList(boolean isInterface): +{} +{ + "implements" ClassOrInterfaceType() + ( "," ClassOrInterfaceType() )* + { + if (isInterface) + throw new ParseException("An interface cannot implement other interfaces"); + } +} + +void EnumDeclaration(int modifiers): +{} +{ + "enum" <IDENTIFIER> + [ ImplementsList(false) ] + EnumBody() +} + +void EnumBody(): +{} +{ + "{" + [ EnumConstant() ( LOOKAHEAD(2) "," EnumConstant() )* ] + [ "," ] + [ ";" ( ClassOrInterfaceBodyDeclaration(false) )* ] + "}" +} + +void EnumConstant(): +{} +{ + Modifiers() <IDENTIFIER> [ Arguments() ] [ ClassOrInterfaceBody(false) ] +} + +void TypeParameters(): +{} +{ + "<" TypeParameter() ( "," TypeParameter() )* ">" +} + +void TypeParameter(): +{} +{ + <IDENTIFIER> [ TypeBound() ] +} + +void TypeBound(): +{} +{ + "extends" ClassOrInterfaceType() ( "&" ClassOrInterfaceType() )* +} + +void ClassOrInterfaceBody(boolean isInterface): +{} +{ + "{" ( ClassOrInterfaceBodyDeclaration(isInterface) )* "}" +} + +void ClassOrInterfaceBodyDeclaration(boolean isInterface): +{ + boolean isNestedInterface = false; + int modifiers; +} +{ + LOOKAHEAD(2) + Initializer() + { + if (isInterface) + throw new ParseException("An interface cannot have initializers"); + } +| + modifiers = Modifiers() // Just get all the modifiers out of the way. If you want to do + // more checks, pass the modifiers down to the member + ( + ClassOrInterfaceDeclaration(modifiers) + | + EnumDeclaration(modifiers) + | + LOOKAHEAD( [ TypeParameters() ] <IDENTIFIER> "(" ) + ConstructorDeclaration() + | + LOOKAHEAD( Type() <IDENTIFIER> ( "[" "]" )* ( "," | "=" | ";" ) ) + FieldDeclaration(modifiers) + | + MethodDeclaration(modifiers) + ) +| + ";" +} + +void FieldDeclaration(int modifiers): +{} +{ + // Modifiers are already matched in the caller + Type() VariableDeclarator() ( "," VariableDeclarator() )* ";" +} + +void VariableDeclarator(): +{} +{ + VariableDeclaratorId() [ "=" VariableInitializer() ] +} + +void VariableDeclaratorId(): +{} +{ + <IDENTIFIER> ( "[" "]" )* +} + +void VariableInitializer(): +{} +{ + ArrayInitializer() +| + Expression() +} + +void ArrayInitializer(): +{} +{ + "{" [ VariableInitializer() ( LOOKAHEAD(2) "," VariableInitializer() )* ] [ "," ] "}" +} + +void MethodDeclaration(int modifiers): +{} +{ + // Modifiers already matched in the caller! + [ TypeParameters() ] + ResultType() + MethodDeclarator() [ "throws" NameList() ] + ( Block() | ";" ) +} + +void MethodDeclarator(): +{} +{ + <IDENTIFIER> FormalParameters() ( "[" "]" )* +} + +void FormalParameters(): +{} +{ + "(" [ FormalParameter() ( "," FormalParameter() )* ] ")" +} + +void FormalParameter(): +{} +{ + Modifiers() Type() [ "..." ] VariableDeclaratorId() +} + +void ConstructorDeclaration(): +{} +{ + [ TypeParameters() ] + // Modifiers matched in the caller + <IDENTIFIER> FormalParameters() [ "throws" NameList() ] + "{" + [ LOOKAHEAD(ExplicitConstructorInvocation()) + ExplicitConstructorInvocation() + ] + ( BlockStatement() )* + "}" +} + +void ExplicitConstructorInvocation(): +{} +{ + ( <IDENTIFIER> "." )* [ LOOKAHEAD(2) "this" "." ] + [ TypeArguments() ] ("this"|"super") Arguments() ";" +} + +void Initializer(): +{} +{ + [ "static" ] Block() +} + + +/* + * Type, name and expression syntax follows. + */ + +void Type(): +{} +{ + LOOKAHEAD(2) ReferenceType() + | + PrimitiveType() +} + +void ReferenceType(): +{} +{ + PrimitiveType() ( LOOKAHEAD(2) "[" "]" )+ + | + ( ClassOrInterfaceType() ) ( LOOKAHEAD(2) "[" "]" )* +} + +void ClassOrInterfaceType(): +{} +{ + <IDENTIFIER> [ LOOKAHEAD(2) TypeArguments() ] + ( LOOKAHEAD(2) "." <IDENTIFIER> [ LOOKAHEAD(2) TypeArguments() ] )* +} + +void TypeArguments(): +{} +{ + "<" TypeArgument() ( "," TypeArgument() )* ">" +} + +void TypeArgument(): +{} +{ + ReferenceType() + | + "?" [ WildcardBounds() ] +} + +void WildcardBounds(): +{} +{ + "extends" ReferenceType() + | + "super" ReferenceType() +} + + +void PrimitiveType(): +{} +{ + "boolean" +| + "char" +| + "byte" +| + "short" +| + "int" +| + "long" +| + "float" +| + "double" +} + +void ResultType(): +{} +{ + "void" +| + Type() +} + +void Name(): +/* + * A lookahead of 2 is required below since "Name" can be followed + * by a ".*" when used in the context of an "ImportDeclaration". + */ +{} +{ + <IDENTIFIER> + ( LOOKAHEAD(2) "." <IDENTIFIER> + )* +} + +void NameList(): +{} +{ + Name() ( "," Name() )* +} + + +/* + * Expression syntax follows. + */ + +void Expression(): +/* + * This expansion has been written this way instead of: + * Assignment() | ConditionalExpression() + * for performance reasons. + * However, it is a weakening of the grammar for it allows the LHS of + * assignments to be any conditional expression whereas it can only be + * a primary expression. Consider adding a semantic predicate to work + * around this. + */ +{} +{ + ConditionalExpression() + [ + LOOKAHEAD(2) + AssignmentOperator() Expression() + ] +} + +void AssignmentOperator(): +{} +{ + "=" | "*=" | "/=" | "%=" | "+=" | "-=" | "<<=" | ">>=" | ">>>=" | "&=" | "^=" | "|=" +} + +void AssignmentExpression(): +{} +{ + PrimaryExpression() AssignmentOperator() Expression() +} + +void ConditionalExpression(): +{} +{ + ConditionalOrExpression() [ "?" Expression() ":" Expression() ] +} + +void ConditionalOrExpression(): +{} +{ + ConditionalAndExpression() ( "||" ConditionalAndExpression() )* +} + +void ConditionalAndExpression(): +{} +{ + InclusiveOrExpression() ( "&&" InclusiveOrExpression() )* +} + +void InclusiveOrExpression(): +{} +{ + ExclusiveOrExpression() ( "|" ExclusiveOrExpression() )* +} + +void ExclusiveOrExpression(): +{} +{ + AndExpression() ( "^" AndExpression() )* +} + +void AndExpression(): +{} +{ + EqualityExpression() ( "&" EqualityExpression() )* +} + +void EqualityExpression(): +{} +{ + InstanceOfExpression() ( ( "==" | "!=" ) InstanceOfExpression() )* +} + +void InstanceOfExpression(): +{} +{ + RelationalExpression() [ "instanceof" Type() ] +} + +void RelationalExpression(): +{} +{ + ShiftExpression() ( ( "<" | ">" | "<=" | ">=" ) ShiftExpression() )* +} + +void ShiftExpression(): +{} +{ + AdditiveExpression() ( ( "<<" | RSIGNEDSHIFT() | RUNSIGNEDSHIFT() ) AdditiveExpression() )* +} + +void AdditiveExpression(): +{} +{ + MultiplicativeExpression() ( ( "+" | "-" ) MultiplicativeExpression() )* +} + +void MultiplicativeExpression(): +{} +{ + UnaryExpression() ( ( "*" | "/" | "%" ) UnaryExpression() )* +} + +void UnaryExpression(): +{} +{ + ( "+" | "-" ) UnaryExpression() +| + PreIncrementExpression() +| + PreDecrementExpression() +| + UnaryExpressionNotPlusMinus() +} + +void PreIncrementExpression(): +{} +{ + "++" PrimaryExpression() +} + +void PreDecrementExpression(): +{} +{ + "--" PrimaryExpression() +} + +void UnaryExpressionNotPlusMinus(): +{} +{ + ( "~" | "!" ) UnaryExpression() +| + LOOKAHEAD( CastLookahead() ) + CastExpression() +| + PostfixExpression() +} + +// This production is to determine lookahead only. The LOOKAHEAD specifications +// below are not used, but they are there just to indicate that we know about +// this. +void CastLookahead(): +{} +{ + LOOKAHEAD(2) + "(" PrimitiveType() +| + LOOKAHEAD("(" Type() "[") + "(" Type() "[" "]" +| + "(" Type() ")" ( "~" | "!" | "(" | <IDENTIFIER> | "this" | "super" | "new" | Literal() ) +} + +void PostfixExpression(): +{} +{ + PrimaryExpression() [ PostfixOperator() ] +} + +void PostfixOperator(): +{} +{ + "++" | "--" +} + +void CastExpression(): +{} +{ + LOOKAHEAD("(" PrimitiveType()) + "(" Type() ")" UnaryExpression() +| + "(" Type() ")" UnaryExpressionNotPlusMinus() +} + +void PrimaryExpression(): +{} +{ + PrimaryPrefix() ( LOOKAHEAD(2) PrimarySuffix() )* +} + +void MemberSelector(): +{} +{ + "." TypeArguments() <IDENTIFIER> +} + +void PrimaryPrefix(): +{} +{ + Literal() +| + LOOKAHEAD( ( <IDENTIFIER> "." )* "this" ) + ( <IDENTIFIER> "." )* + "this" +| + "super" "." <IDENTIFIER> +| + "(" Expression() ")" +| + AllocationExpression() +| + LOOKAHEAD( ResultType() "." "class" ) + ResultType() "." "class" +| + Name() +} + +void PrimarySuffix(): +{} +{ + LOOKAHEAD("." "super" ".") + "." "super" +| + LOOKAHEAD("." "this") + "." "this" +| + LOOKAHEAD(2) + "." AllocationExpression() +| + LOOKAHEAD(3) + MemberSelector() +| + "[" Expression() "]" +| + "." <IDENTIFIER> +| + Arguments() +} + +void Literal(): +{} +{ + <INTEGER_LITERAL> +| + <FLOATING_POINT_LITERAL> +| + <CHARACTER_LITERAL> +| + <STRING_LITERAL> +| + BooleanLiteral() +| + NullLiteral() +} + +void BooleanLiteral(): +{} +{ + "true" +| + "false" +} + +void NullLiteral(): +{} +{ + "null" +} + +void Arguments(): +{} +{ + "(" [ ArgumentList() ] ")" +} + +void ArgumentList(): +{} +{ + Expression() ( "," Expression() )* +} + +void AllocationExpression(): +{} +{ + LOOKAHEAD(2) + "new" PrimitiveType() ArrayDimsAndInits() +| + "new" ClassOrInterfaceType() [ TypeArguments() ] + ( + ArrayDimsAndInits() + | + Arguments() [ ClassOrInterfaceBody(false) ] + ) +} + +/* + * The third LOOKAHEAD specification below is to parse to PrimarySuffix + * if there is an expression between the "[...]". + */ +void ArrayDimsAndInits(): +{} +{ + LOOKAHEAD(2) + ( LOOKAHEAD(2) "[" Expression() "]" )+ ( LOOKAHEAD(2) "[" "]" )* +| + ( "[" "]" )+ ArrayInitializer() +} + + +/* + * Statement syntax follows. + */ + +void Statement(): +{} +{ + LOOKAHEAD(2) + LabeledStatement() +| + AssertStatement() +| + Block() +| + EmptyStatement() +| + StatementExpression() ";" +| + SwitchStatement() +| + IfStatement() +| + WhileStatement() +| + DoStatement() +| + ForStatement() +| + BreakStatement() +| + ContinueStatement() +| + ReturnStatement() +| + ThrowStatement() +| + SynchronizedStatement() +| + TryStatement() +} + +void AssertStatement(): +{} +{ + "assert" Expression() [ ":" Expression() ] ";" +} + +void LabeledStatement(): +{} +{ + <IDENTIFIER> ":" Statement() +} + +void Block(): +{} +{ + "{" ( BlockStatement() )* "}" +} + +void BlockStatement(): +{} +{ + LOOKAHEAD( Modifiers() Type() <IDENTIFIER> ) + LocalVariableDeclaration() ";" +| + Statement() +| + ClassOrInterfaceDeclaration(0) +} + +void LocalVariableDeclaration(): +{} +{ + Modifiers() Type() VariableDeclarator() ( "," VariableDeclarator() )* +} + +void EmptyStatement(): +{} +{ + ";" +} + +void StatementExpression(): +{} +{ + PreIncrementExpression() +| + PreDecrementExpression() +| + LOOKAHEAD(PrimaryExpression() AssignmentOperator()) + AssignmentExpression() +| + PostfixExpression() +} + +void SwitchStatement(): +{} +{ + "switch" "(" Expression() ")" "{" + ( SwitchLabel() ( BlockStatement() )* )* + "}" +} + +void SwitchLabel(): +{} +{ + "case" Expression() ":" +| + "default" ":" +} + +void IfStatement(): +/* + * The disambiguating algorithm of JavaCC automatically binds dangling + * else's to the innermost if statement. The LOOKAHEAD specification + * is to tell JavaCC that we know what we are doing. + */ +{} +{ + "if" "(" Expression() ")" Statement() [ LOOKAHEAD(1) "else" Statement() ] +} + +void WhileStatement(): +{} +{ + "while" "(" Expression() ")" Statement() +} + +void DoStatement(): +{} +{ + "do" Statement() "while" "(" Expression() ")" ";" +} + +void ForStatement(): +{} +{ + "for" "(" + + ( + LOOKAHEAD(Modifiers() Type() <IDENTIFIER> ":") + Modifiers() Type() <IDENTIFIER> ":" Expression() + | + [ ForInit() ] ";" [ Expression() ] ";" [ ForUpdate() ] + ) + + ")" Statement() +} + +void ForInit(): +{} +{ + LOOKAHEAD( Modifiers() Type() <IDENTIFIER> ) + LocalVariableDeclaration() +| + StatementExpressionList() +} + +void StatementExpressionList(): +{} +{ + StatementExpression() ( "," StatementExpression() )* +} + +void ForUpdate(): +{} +{ + StatementExpressionList() +} + +void BreakStatement(): +{} +{ + "break" [ <IDENTIFIER> ] ";" +} + +void ContinueStatement(): +{} +{ + "continue" [ <IDENTIFIER> ] ";" +} + +void ReturnStatement(): +{} +{ + "return" [ Expression() ] ";" +} + +void ThrowStatement(): +{} +{ + "throw" Expression() ";" +} + +void SynchronizedStatement(): +{} +{ + "synchronized" "(" Expression() ")" Block() +} + +void TryStatement(): +/* + * Semantic check required here to make sure that at least one + * finally/catch is present. + */ +{} +{ + "try" Block() + ( "catch" "(" FormalParameter() ")" Block() )* + [ "finally" Block() ] +} + +/* We use productions to match >>>, >> and > so that we can keep the + * type declaration syntax with generics clean + */ + +void RUNSIGNEDSHIFT(): +{} +{ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RUNSIGNEDSHIFT} ) + ">" ">" ">" + ) +} + +void RSIGNEDSHIFT(): +{} +{ + ( LOOKAHEAD({ getToken(1).kind == GT && + ((Token.GTToken)getToken(1)).realKind == RSIGNEDSHIFT} ) + ">" ">" + ) +} + +/* Annotation syntax follows. */ + +void Annotation(): +{} +{ + LOOKAHEAD( "@" Name() "(" ( <IDENTIFIER> "=" | ")" )) + NormalAnnotation() + | + LOOKAHEAD( "@" Name() "(" ) + SingleMemberAnnotation() + | + MarkerAnnotation() +} + +void NormalAnnotation(): +{} +{ + "@" Name() "(" [ MemberValuePairs() ] ")" +} + +void MarkerAnnotation(): +{} +{ + "@" Name() +} + +void SingleMemberAnnotation(): +{} +{ + "@" Name() "(" MemberValue() ")" +} + +void MemberValuePairs(): +{} +{ + MemberValuePair() ( "," MemberValuePair() )* +} + +void MemberValuePair(): +{} +{ + <IDENTIFIER> "=" MemberValue() +} + +void MemberValue(): +{} +{ + Annotation() + | + MemberValueArrayInitializer() + | + ConditionalExpression() +} + +void MemberValueArrayInitializer(): +{} +{ + "{" MemberValue() ( LOOKAHEAD(2) "," MemberValue() )* [ "," ] "}" +} + + +/* Annotation Types. */ + +void AnnotationTypeDeclaration(int modifiers): +{} +{ + "@" "interface" <IDENTIFIER> AnnotationTypeBody() +} + +void AnnotationTypeBody(): +{} +{ + "{" ( AnnotationTypeMemberDeclaration() )* "}" +} + +void AnnotationTypeMemberDeclaration(): +{ + int modifiers; +} +{ + modifiers = Modifiers() + ( + LOOKAHEAD(Type() <IDENTIFIER> "(") + Type() <IDENTIFIER> "(" ")" [ DefaultValue() ] ";" + | + ClassOrInterfaceDeclaration(modifiers) + | + EnumDeclaration(modifiers) + | + AnnotationTypeDeclaration(modifiers) + | + FieldDeclaration(modifiers) + ) + | + ( ";" ) +} + +void DefaultValue(): +{} +{ + "default" MemberValue() +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaCharStream.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/JavaCharStream.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaCharStream.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaCharStream.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,530 @@ +/* Generated By:JavaCC: Do not edit this line. JavaCharStream.java Version 4.0 */ +package jaxx.parser; + +/** + * An implementation of interface CharStream, where the stream is assumed to + * contain only ASCII characters (with java-like unicode escape processing). + */ + +public class JavaCharStream { + public static final boolean staticFlag = false; + + static int hexval(char c) throws java.io.IOException { + switch (c) { + case '0': + return 0; + case '1': + return 1; + case '2': + return 2; + case '3': + return 3; + case '4': + return 4; + case '5': + return 5; + case '6': + return 6; + case '7': + return 7; + case '8': + return 8; + case '9': + return 9; + + case 'a': + case 'A': + return 10; + case 'b': + case 'B': + return 11; + case 'c': + case 'C': + return 12; + case 'd': + case 'D': + return 13; + case 'e': + case 'E': + return 14; + case 'f': + case 'F': + return 15; + } + + throw new java.io.IOException(); // Should never come here + } + + public int bufpos = -1; + int bufsize; + int available; + int tokenBegin; + protected int bufline[]; + protected int bufcolumn[]; + + protected int column = 0; + protected int line = 1; + + protected boolean prevCharIsCR = false; + protected boolean prevCharIsLF = false; + + protected java.io.Reader inputStream; + + protected char[] nextCharBuf; + protected char[] buffer; + protected int maxNextCharInd = 0; + protected int nextCharInd = -1; + protected int inBuf = 0; + protected int tabSize = 8; + + protected void setTabSize(int i) { + tabSize = i; + } + + protected int getTabSize(int i) { + return tabSize; + } + + protected void ExpandBuff(boolean wrapAround) { + char[] newbuffer = new char[bufsize + 2048]; + int newbufline[] = new int[bufsize + 2048]; + int newbufcolumn[] = new int[bufsize + 2048]; + + try { + if (wrapAround) { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + System.arraycopy(buffer, 0, newbuffer, + bufsize - tokenBegin, bufpos); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + System.arraycopy(bufline, 0, newbufline, bufsize - tokenBegin, bufpos); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + System.arraycopy(bufcolumn, 0, newbufcolumn, bufsize - tokenBegin, bufpos); + bufcolumn = newbufcolumn; + + bufpos += (bufsize - tokenBegin); + } else { + System.arraycopy(buffer, tokenBegin, newbuffer, 0, bufsize - tokenBegin); + buffer = newbuffer; + + System.arraycopy(bufline, tokenBegin, newbufline, 0, bufsize - tokenBegin); + bufline = newbufline; + + System.arraycopy(bufcolumn, tokenBegin, newbufcolumn, 0, bufsize - tokenBegin); + bufcolumn = newbufcolumn; + + bufpos -= tokenBegin; + } + } + catch (Throwable t) { + throw new Error(t.getMessage()); + } + + available = (bufsize += 2048); + tokenBegin = 0; + } + + protected void FillBuff() throws java.io.IOException { + int i; + if (maxNextCharInd == 4096) + maxNextCharInd = nextCharInd = 0; + + try { + if ((i = inputStream.read(nextCharBuf, maxNextCharInd, + 4096 - maxNextCharInd)) == -1) { + inputStream.close(); + throw new java.io.IOException(); + } else { + maxNextCharInd += i; + } + } + catch (java.io.IOException e) { + if (bufpos != 0) { + --bufpos; + backup(0); + } else { + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + throw e; + } + } + + protected char ReadByte() throws java.io.IOException { + if (++nextCharInd >= maxNextCharInd) + FillBuff(); + + return nextCharBuf[nextCharInd]; + } + + public char BeginToken() throws java.io.IOException { + if (inBuf > 0) { + --inBuf; + + if (++bufpos == bufsize) { + bufpos = 0; + } + + tokenBegin = bufpos; + return buffer[bufpos]; + } + + tokenBegin = 0; + bufpos = -1; + + return readChar(); + } + + protected void AdjustBuffSize() { + if (available == bufsize) { + if (tokenBegin > 2048) { + bufpos = 0; + available = tokenBegin; + } else + ExpandBuff(false); + } else if (available > tokenBegin) + available = bufsize; + else if ((tokenBegin - available) < 2048) + ExpandBuff(true); + else + available = tokenBegin; + } + + protected void UpdateLineColumn(char c) { + column++; + + if (prevCharIsLF) { + prevCharIsLF = false; + line += (column = 1); + } else if (prevCharIsCR) { + prevCharIsCR = false; + if (c == '\n') { + prevCharIsLF = true; + } else + line += (column = 1); + } + + switch (c) { + case '\r': + prevCharIsCR = true; + break; + case '\n': + prevCharIsLF = true; + break; + case '\t': + column--; + column += (tabSize - (column % tabSize)); + break; + default: + break; + } + + bufline[bufpos] = line; + bufcolumn[bufpos] = column; + } + + public char readChar() throws java.io.IOException { + if (inBuf > 0) { + --inBuf; + + if (++bufpos == bufsize) + bufpos = 0; + + return buffer[bufpos]; + } + + char c; + + if (++bufpos == available) + AdjustBuffSize(); + + if ((buffer[bufpos] = c = ReadByte()) == '\\') { + UpdateLineColumn(c); + + int backSlashCnt = 1; + + for (; ;) // Read all the backslashes + { + if (++bufpos == available) + AdjustBuffSize(); + + try { + if ((buffer[bufpos] = c = ReadByte()) != '\\') { + UpdateLineColumn(c); + // found a non-backslash char. + if ((c == 'u') && ((backSlashCnt & 1) == 1)) { + if (--bufpos < 0) + bufpos = bufsize - 1; + + break; + } + + backup(backSlashCnt); + return '\\'; + } + } + catch (java.io.IOException e) { + if (backSlashCnt > 1) + backup(backSlashCnt); + + return '\\'; + } + + UpdateLineColumn(c); + backSlashCnt++; + } + + // Here, we have seen an odd number of backslash's followed by a 'u' + try { + while ((c = ReadByte()) == 'u') + ++column; + + buffer[bufpos] = c = (char) (hexval(c) << 12 | + hexval(ReadByte()) << 8 | + hexval(ReadByte()) << 4 | + hexval(ReadByte())); + + column += 4; + } + catch (java.io.IOException e) { + throw new Error("Invalid escape character at line " + line + + " column " + column + "."); + } + + if (backSlashCnt == 1) + return c; + else { + backup(backSlashCnt - 1); + return '\\'; + } + } else { + UpdateLineColumn(c); + return (c); + } + } + + /** + * @return column index + * @see #getEndColumn + * @deprecated + */ + + public int getColumn() { + return bufcolumn[bufpos]; + } + + /** + * @return line type ??? + * @see #getEndLine + * @deprecated + */ + + public int getLine() { + return bufline[bufpos]; + } + + public int getEndColumn() { + return bufcolumn[bufpos]; + } + + public int getEndLine() { + return bufline[bufpos]; + } + + public int getBeginColumn() { + return bufcolumn[tokenBegin]; + } + + public int getBeginLine() { + return bufline[tokenBegin]; + } + + public void backup(int amount) { + + inBuf += amount; + if ((bufpos -= amount) < 0) + bufpos += bufsize; + } + + public JavaCharStream(java.io.Reader dstream, + int startline, int startcolumn, int buffersize) { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + nextCharBuf = new char[4096]; + } + + public JavaCharStream(java.io.Reader dstream, + int startline, int startcolumn) { + this(dstream, startline, startcolumn, 4096); + } + + public JavaCharStream(java.io.Reader dstream) { + this(dstream, 1, 1, 4096); + } + + public void ReInit(java.io.Reader dstream, + int startline, int startcolumn, int buffersize) { + inputStream = dstream; + line = startline; + column = startcolumn - 1; + + if (buffer == null || buffersize != buffer.length) { + available = bufsize = buffersize; + buffer = new char[buffersize]; + bufline = new int[buffersize]; + bufcolumn = new int[buffersize]; + nextCharBuf = new char[4096]; + } + prevCharIsLF = prevCharIsCR = false; + tokenBegin = inBuf = maxNextCharInd = 0; + nextCharInd = bufpos = -1; + } + + public void ReInit(java.io.Reader dstream, + int startline, int startcolumn) { + ReInit(dstream, startline, startcolumn, 4096); + } + + public void ReInit(java.io.Reader dstream) { + ReInit(dstream, 1, 1, 4096); + } + + public JavaCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException { + this(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + public JavaCharStream(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) { + this(new java.io.InputStreamReader(dstream), startline, startcolumn, 4096); + } + + public JavaCharStream(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException { + this(dstream, encoding, startline, startcolumn, 4096); + } + + public JavaCharStream(java.io.InputStream dstream, int startline, + int startcolumn) { + this(dstream, startline, startcolumn, 4096); + } + + public JavaCharStream(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException { + this(dstream, encoding, 1, 1, 4096); + } + + public JavaCharStream(java.io.InputStream dstream) { + this(dstream, 1, 1, 4096); + } + + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn, int buffersize) throws java.io.UnsupportedEncodingException { + ReInit(encoding == null ? new java.io.InputStreamReader(dstream) : new java.io.InputStreamReader(dstream, encoding), startline, startcolumn, buffersize); + } + + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn, int buffersize) { + ReInit(new java.io.InputStreamReader(dstream), startline, startcolumn, buffersize); + } + + public void ReInit(java.io.InputStream dstream, String encoding, int startline, + int startcolumn) throws java.io.UnsupportedEncodingException { + ReInit(dstream, encoding, startline, startcolumn, 4096); + } + + public void ReInit(java.io.InputStream dstream, int startline, + int startcolumn) { + ReInit(dstream, startline, startcolumn, 4096); + } + + public void ReInit(java.io.InputStream dstream, String encoding) throws java.io.UnsupportedEncodingException { + ReInit(dstream, encoding, 1, 1, 4096); + } + + public void ReInit(java.io.InputStream dstream) { + ReInit(dstream, 1, 1, 4096); + } + + public String GetImage() { + if (bufpos >= tokenBegin) + return new String(buffer, tokenBegin, bufpos - tokenBegin + 1); + else + return new String(buffer, tokenBegin, bufsize - tokenBegin) + + new String(buffer, 0, bufpos + 1); + } + + public char[] GetSuffix(int len) { + char[] ret = new char[len]; + + if ((bufpos + 1) >= len) + System.arraycopy(buffer, bufpos - len + 1, ret, 0, len); + else { + System.arraycopy(buffer, bufsize - (len - bufpos - 1), ret, 0, + len - bufpos - 1); + System.arraycopy(buffer, 0, ret, len - bufpos - 1, bufpos + 1); + } + + return ret; + } + + public void Done() { + nextCharBuf = null; + buffer = null; + bufline = null; + bufcolumn = null; + } + + /** + * Method to adjust line and column numbers for the start of a token. + * + * @param newLine line number ? + * @param newCol column number ? + */ + public void adjustBeginLineColumn(int newLine, int newCol) { + int start = tokenBegin; + int len; + + if (bufpos >= tokenBegin) { + len = bufpos - tokenBegin + inBuf + 1; + } else { + len = bufsize - tokenBegin + bufpos + 1 + inBuf; + } + + int i = 0, j = 0, k; + int nextColDiff, columnDiff = 0; + + while (i < len && + bufline[j = start % bufsize] == bufline[k = ++start % bufsize]) { + bufline[j] = newLine; + nextColDiff = columnDiff + bufcolumn[k] - bufcolumn[j]; + bufcolumn[j] = newCol + columnDiff; + columnDiff = nextColDiff; + i++; + } + + if (i < len) { + bufline[j] = newLine++; + bufcolumn[j] = newCol + columnDiff; + + while (i++ < len) { + if (bufline[j = start % bufsize] != bufline[++start % bufsize]) + bufline[j] = newLine++; + else + bufline[j] = newLine; + } + } + + line = bufline[j]; + column = bufcolumn[j]; + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParser.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/JavaParser.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParser.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParser.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,10048 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. JavaParser.java */ +package jaxx.parser; + +import java.io.File; +import java.io.FileInputStream; + +/** + * Grammar to parse Java version 1.5 + * + * @author Sreenivasa Viswanadha - Simplified and enhanced for 1.5 + */ +public class JavaParser/*@bgen(jjtree)*/ implements JavaParserTreeConstants, JavaParserConstants {/*@bgen(jjtree)*/ + protected JJTJavaParserState jjtree = new JJTJavaParserState(); + + /** Class to hold modifiers. */ + static public final class ModifierSet { + /* Definitions of the bits in the modifiers field. */ + public static final int PUBLIC = 0x0001; + public static final int PROTECTED = 0x0002; + public static final int PRIVATE = 0x0004; + public static final int ABSTRACT = 0x0008; + public static final int STATIC = 0x0010; + public static final int FINAL = 0x0020; + public static final int SYNCHRONIZED = 0x0040; + public static final int NATIVE = 0x0080; + public static final int TRANSIENT = 0x0100; + public static final int VOLATILE = 0x0200; + public static final int STRICTFP = 0x1000; + + /** + * A set of accessors that indicate whether the specified modifier + * is in the set. + */ + + public boolean isPublic(int modifiers) { + return (modifiers & PUBLIC) != 0; + } + + public boolean isProtected(int modifiers) { + return (modifiers & PROTECTED) != 0; + } + + public boolean isPrivate(int modifiers) { + return (modifiers & PRIVATE) != 0; + } + + public boolean isStatic(int modifiers) { + return (modifiers & STATIC) != 0; + } + + public boolean isAbstract(int modifiers) { + return (modifiers & ABSTRACT) != 0; + } + + public boolean isFinal(int modifiers) { + return (modifiers & FINAL) != 0; + } + + public boolean isNative(int modifiers) { + return (modifiers & NATIVE) != 0; + } + + public boolean isStrictfp(int modifiers) { + return (modifiers & STRICTFP) != 0; + } + + public boolean isSynchronized(int modifiers) { + return (modifiers & SYNCHRONIZED) != 0; + } + + public boolean isTransient(int modifiers) { + return (modifiers & TRANSIENT) != 0; + } + + public boolean isVolatile(int modifiers) { + return (modifiers & VOLATILE) != 0; + } + + /** Removes the given modifier. */ + static int removeModifier(int modifiers, int mod) { + return modifiers & ~mod; + } + } + + public JavaParser(String fileName) { + this(System.in); + try { + ReInit(new FileInputStream(new File(fileName))); + } + catch (Exception e) { + e.printStackTrace(); + } + } + + void jjtreeOpenNodeScope(Node n) { + ((SimpleNode) n).firstToken = getToken(1); + } + + void jjtreeCloseNodeScope(Node n) { + ((SimpleNode) n).lastToken = getToken(0); + } + + public SimpleNode popNode() { + if (jjtree.nodeArity() > 0) // number of child nodes + return (SimpleNode) jjtree.popNode(); + else + return null; + } + + public static void main(String args[]) { + JavaParser parser; + if (args.length == 0) { + System.out.println("Java Parser Version 1.1: Reading from standard input . . ."); + parser = new JavaParser(System.in); + } else if (args.length == 1) { + System.out.println("Java Parser Version 1.1: Reading from file " + args[0] + " . . ."); + try { + parser = new JavaParser(new java.io.FileInputStream(args[0])); + } catch (java.io.FileNotFoundException e) { + System.out.println("Java Parser Version 1.1: File " + args[0] + " not found."); + return; + } + } else { + System.out.println("Java Parser Version 1.1: Usage is one of:"); + System.out.println(" java JavaParser < inputfile"); + System.out.println("OR"); + System.out.println(" java JavaParser inputfile"); + return; + } + try { + parser.CompilationUnit(); + System.out.println("Java Parser Version 1.1: Java program parsed successfully."); + } catch (ParseException e) { + System.out.println(e.getMessage()); + System.out.println("Java Parser Version 1.1: Encountered errors during parse."); + } + } + + final public boolean Line() throws ParseException { + /*@bgen(jjtree) Line */ + SimpleNode jjtn000 = new SimpleNode(JJTLINE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + int modifiers; + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 0: + jj_consume_token(0); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return true; + } + break; + default: + if (jj_2_1(2147483647)) { + BlockStatement(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return false; + } + } else if (jj_2_2(2147483647)) { + ClassOrInterfaceBodyDeclaration(false); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return false; + } + } else if (jj_2_3(2147483647)) { + ClassOrInterfaceBodyDeclaration(false); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return false; + } + } else if (jj_2_4(2147483647)) { + Expression(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return false; + } + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IMPORT: + ImportDeclaration(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return false; + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + throw new Error("Missing return statement in function"); + } + + /** + * ************************************** + * THE JAVA LANGUAGE GRAMMAR STARTS HERE * + * *************************************** + */ + +/* + * Program structuring syntax follows. + */ + final public void CompilationUnit() throws ParseException { + /*@bgen(jjtree) CompilationUnit */ + SimpleNode jjtn000 = new SimpleNode(JJTCOMPILATIONUNIT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_5(2147483647)) { + PackageDeclaration(); + } else { + ; + } + label_1: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IMPORT: + ; + break; + default: + break label_1; + } + ImportDeclaration(); + } + label_2: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case CLASS: + case ENUM: + case FINAL: + case INTERFACE: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOLATILE: + case SEMICOLON: + case AT: + ; + break; + default: + break label_2; + } + TypeDeclaration(); + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case 123: + jj_consume_token(123); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case STUFF_TO_IGNORE: + jj_consume_token(STUFF_TO_IGNORE); + break; + default: + ; + } + jj_consume_token(0); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PackageDeclaration() throws ParseException { + /*@bgen(jjtree) PackageDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTPACKAGEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Modifiers(); + jj_consume_token(PACKAGE); + Name(); + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ImportDeclaration() throws ParseException { + /*@bgen(jjtree) ImportDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTIMPORTDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IMPORT); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case STATIC: + jj_consume_token(STATIC); + break; + default: + ; + } + Name(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case DOT: + jj_consume_token(DOT); + jj_consume_token(STAR); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* + * Modifiers. We match all modifiers in a single rule to reduce the chances of + * syntax errors for simple modifier mistakes. It will also enable us to give + * better error messages. + */ + final public int Modifiers() throws ParseException { + /*@bgen(jjtree) Modifiers */ + SimpleNode jjtn000 = new SimpleNode(JJTMODIFIERS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + int modifiers = 0; + try { + label_3: + while (true) { + if (jj_2_6(2)) { + ; + } else { + break label_3; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PUBLIC: + jj_consume_token(PUBLIC); + modifiers |= ModifierSet.PUBLIC; + break; + case STATIC: + jj_consume_token(STATIC); + modifiers |= ModifierSet.STATIC; + break; + case PROTECTED: + jj_consume_token(PROTECTED); + modifiers |= ModifierSet.PROTECTED; + break; + case PRIVATE: + jj_consume_token(PRIVATE); + modifiers |= ModifierSet.PRIVATE; + break; + case FINAL: + jj_consume_token(FINAL); + modifiers |= ModifierSet.FINAL; + break; + case ABSTRACT: + jj_consume_token(ABSTRACT); + modifiers |= ModifierSet.ABSTRACT; + break; + case SYNCHRONIZED: + jj_consume_token(SYNCHRONIZED); + modifiers |= ModifierSet.SYNCHRONIZED; + break; + case NATIVE: + jj_consume_token(NATIVE); + modifiers |= ModifierSet.NATIVE; + break; + case TRANSIENT: + jj_consume_token(TRANSIENT); + modifiers |= ModifierSet.TRANSIENT; + break; + case VOLATILE: + jj_consume_token(VOLATILE); + modifiers |= ModifierSet.VOLATILE; + break; + case STRICTFP: + jj_consume_token(STRICTFP); + modifiers |= ModifierSet.STRICTFP; + break; + case AT: + Annotation(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + { + if (true) return modifiers; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + throw new Error("Missing return statement in function"); + } + + /* + * Declaration syntax follows. + */ + final public void TypeDeclaration() throws ParseException { + /*@bgen(jjtree) TypeDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + int modifiers; + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case SEMICOLON: + jj_consume_token(SEMICOLON); + break; + case ABSTRACT: + case CLASS: + case ENUM: + case FINAL: + case INTERFACE: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOLATILE: + case AT: + modifiers = Modifiers(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case CLASS: + case INTERFACE: + ClassOrInterfaceDeclaration(modifiers); + break; + case ENUM: + EnumDeclaration(modifiers); + break; + case AT: + AnnotationTypeDeclaration(modifiers); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ClassOrInterfaceDeclaration(int modifiers) throws ParseException { + /*@bgen(jjtree) ClassOrInterfaceDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + boolean isInterface = false; + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case CLASS: + jj_consume_token(CLASS); + break; + case INTERFACE: + jj_consume_token(INTERFACE); + isInterface = true; + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + jj_consume_token(IDENTIFIER); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LT: + TypeParameters(); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case EXTENDS: + ExtendsList(isInterface); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IMPLEMENTS: + ImplementsList(isInterface); + break; + default: + ; + } + ClassOrInterfaceBody(isInterface); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ExtendsList(boolean isInterface) throws ParseException { + /*@bgen(jjtree) ExtendsList */ + SimpleNode jjtn000 = new SimpleNode(JJTEXTENDSLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + boolean extendsMoreThanOne = false; + try { + jj_consume_token(EXTENDS); + ClassOrInterfaceType(); + label_4: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_4; + } + jj_consume_token(COMMA); + ClassOrInterfaceType(); + extendsMoreThanOne = true; + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + if (extendsMoreThanOne && !isInterface) { + if (true) + throw new ParseException("A class cannot extend more than one other class"); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ImplementsList(boolean isInterface) throws ParseException { + /*@bgen(jjtree) ImplementsList */ + SimpleNode jjtn000 = new SimpleNode(JJTIMPLEMENTSLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IMPLEMENTS); + ClassOrInterfaceType(); + label_5: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_5; + } + jj_consume_token(COMMA); + ClassOrInterfaceType(); + } + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + if (isInterface) { + if (true) + throw new ParseException("An interface cannot implement other interfaces"); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void EnumDeclaration(int modifiers) throws ParseException { + /*@bgen(jjtree) EnumDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(ENUM); + jj_consume_token(IDENTIFIER); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IMPLEMENTS: + ImplementsList(false); + break; + default: + ; + } + EnumBody(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void EnumBody() throws ParseException { + /*@bgen(jjtree) EnumBody */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMBODY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LBRACE); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case FINAL: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOLATILE: + case IDENTIFIER: + case AT: + EnumConstant(); + label_6: + while (true) { + if (jj_2_7(2)) { + ; + } else { + break label_6; + } + jj_consume_token(COMMA); + EnumConstant(); + } + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + jj_consume_token(COMMA); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case SEMICOLON: + jj_consume_token(SEMICOLON); + label_7: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case CLASS: + case DOUBLE: + case ENUM: + case FINAL: + case FLOAT: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOID: + case VOLATILE: + case IDENTIFIER: + case LBRACE: + case SEMICOLON: + case AT: + case LT: + ; + break; + default: + break label_7; + } + ClassOrInterfaceBodyDeclaration(false); + } + break; + default: + ; + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void EnumConstant() throws ParseException { + /*@bgen(jjtree) EnumConstant */ + SimpleNode jjtn000 = new SimpleNode(JJTENUMCONSTANT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Modifiers(); + jj_consume_token(IDENTIFIER); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LPAREN: + Arguments(); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACE: + ClassOrInterfaceBody(false); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void TypeParameters() throws ParseException { + /*@bgen(jjtree) TypeParameters */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEPARAMETERS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LT); + TypeParameter(); + label_8: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_8; + } + jj_consume_token(COMMA); + TypeParameter(); + } + jj_consume_token(GT); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void TypeParameter() throws ParseException { + /*@bgen(jjtree) TypeParameter */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEPARAMETER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case EXTENDS: + TypeBound(); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void TypeBound() throws ParseException { + /*@bgen(jjtree) TypeBound */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEBOUND); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(EXTENDS); + ClassOrInterfaceType(); + label_9: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BIT_AND: + ; + break; + default: + break label_9; + } + jj_consume_token(BIT_AND); + ClassOrInterfaceType(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ClassOrInterfaceBody(boolean isInterface) throws ParseException { + /*@bgen(jjtree) ClassOrInterfaceBody */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACEBODY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LBRACE); + label_10: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case CLASS: + case DOUBLE: + case ENUM: + case FINAL: + case FLOAT: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOID: + case VOLATILE: + case IDENTIFIER: + case LBRACE: + case SEMICOLON: + case AT: + case LT: + ; + break; + default: + break label_10; + } + ClassOrInterfaceBodyDeclaration(isInterface); + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ClassOrInterfaceBodyDeclaration(boolean isInterface) throws ParseException { + /*@bgen(jjtree) ClassOrInterfaceBodyDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACEBODYDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + boolean isNestedInterface = false; + int modifiers; + try { + if (jj_2_10(2)) { + Initializer(); + jjtree.closeNodeScope(jjtn000, true); + jjtc000 = false; + jjtreeCloseNodeScope(jjtn000); + if (isInterface) { + if (true) + throw new ParseException("An interface cannot have initializers"); + } + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case CLASS: + case DOUBLE: + case ENUM: + case FINAL: + case FLOAT: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOID: + case VOLATILE: + case IDENTIFIER: + case AT: + case LT: + modifiers = Modifiers(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case CLASS: + case INTERFACE: + ClassOrInterfaceDeclaration(modifiers); + break; + case ENUM: + EnumDeclaration(modifiers); + break; + default: + if (jj_2_8(2147483647)) { + ConstructorDeclaration(); + } else if (jj_2_9(2147483647)) { + FieldDeclaration(modifiers); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FLOAT: + case INT: + case LONG: + case SHORT: + case VOID: + case IDENTIFIER: + case LT: + MethodDeclaration(modifiers); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } + break; + case SEMICOLON: + jj_consume_token(SEMICOLON); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void FieldDeclaration(int modifiers) throws ParseException { + /*@bgen(jjtree) FieldDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTFIELDDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Type(); + VariableDeclarator(); + label_11: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_11; + } + jj_consume_token(COMMA); + VariableDeclarator(); + } + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void VariableDeclarator() throws ParseException { + /*@bgen(jjtree) VariableDeclarator */ + SimpleNode jjtn000 = new SimpleNode(JJTVARIABLEDECLARATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + VariableDeclaratorId(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ASSIGN: + jj_consume_token(ASSIGN); + VariableInitializer(); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void VariableDeclaratorId() throws ParseException { + /*@bgen(jjtree) VariableDeclaratorId */ + SimpleNode jjtn000 = new SimpleNode(JJTVARIABLEDECLARATORID); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + label_12: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACKET: + ; + break; + default: + break label_12; + } + jj_consume_token(LBRACKET); + jj_consume_token(RBRACKET); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void VariableInitializer() throws ParseException { + /*@bgen(jjtree) VariableInitializer */ + SimpleNode jjtn000 = new SimpleNode(JJTVARIABLEINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACE: + ArrayInitializer(); + break; + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case BANG: + case TILDE: + case INCR: + case DECR: + case PLUS: + case MINUS: + Expression(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ArrayInitializer() throws ParseException { + /*@bgen(jjtree) ArrayInitializer */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAYINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LBRACE); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case LBRACE: + case BANG: + case TILDE: + case INCR: + case DECR: + case PLUS: + case MINUS: + VariableInitializer(); + label_13: + while (true) { + if (jj_2_11(2)) { + ; + } else { + break label_13; + } + jj_consume_token(COMMA); + VariableInitializer(); + } + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + jj_consume_token(COMMA); + break; + default: + ; + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MethodDeclaration(int modifiers) throws ParseException { + /*@bgen(jjtree) MethodDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTMETHODDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LT: + TypeParameters(); + break; + default: + ; + } + ResultType(); + MethodDeclarator(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case THROWS: + jj_consume_token(THROWS); + NameList(); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACE: + Block(); + break; + case SEMICOLON: + jj_consume_token(SEMICOLON); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MethodDeclarator() throws ParseException { + /*@bgen(jjtree) MethodDeclarator */ + SimpleNode jjtn000 = new SimpleNode(JJTMETHODDECLARATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + FormalParameters(); + label_14: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACKET: + ; + break; + default: + break label_14; + } + jj_consume_token(LBRACKET); + jj_consume_token(RBRACKET); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void FormalParameters() throws ParseException { + /*@bgen(jjtree) FormalParameters */ + SimpleNode jjtn000 = new SimpleNode(JJTFORMALPARAMETERS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LPAREN); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FINAL: + case FLOAT: + case INT: + case LONG: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOLATILE: + case IDENTIFIER: + case AT: + FormalParameter(); + label_15: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_15; + } + jj_consume_token(COMMA); + FormalParameter(); + } + break; + default: + ; + } + jj_consume_token(RPAREN); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void FormalParameter() throws ParseException { + /*@bgen(jjtree) FormalParameter */ + SimpleNode jjtn000 = new SimpleNode(JJTFORMALPARAMETER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Modifiers(); + Type(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ELLIPSIS: + jj_consume_token(ELLIPSIS); + break; + default: + ; + } + VariableDeclaratorId(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ConstructorDeclaration() throws ParseException { + /*@bgen(jjtree) ConstructorDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTCONSTRUCTORDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LT: + TypeParameters(); + break; + default: + ; + } + jj_consume_token(IDENTIFIER); + FormalParameters(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case THROWS: + jj_consume_token(THROWS); + NameList(); + break; + default: + ; + } + jj_consume_token(LBRACE); + if (jj_2_12(2147483647)) { + ExplicitConstructorInvocation(); + } else { + ; + } + label_16: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case ASSERT: + case BOOLEAN: + case BREAK: + case BYTE: + case CHAR: + case CLASS: + case CONTINUE: + case DO: + case DOUBLE: + case FALSE: + case FINAL: + case FLOAT: + case FOR: + case IF: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case NEW: + case NULL: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case RETURN: + case SHORT: + case STATIC: + case STRICTFP: + case SUPER: + case SWITCH: + case SYNCHRONIZED: + case THIS: + case THROW: + case TRANSIENT: + case TRUE: + case TRY: + case VOID: + case VOLATILE: + case WHILE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case LBRACE: + case SEMICOLON: + case AT: + case INCR: + case DECR: + ; + break; + default: + break label_16; + } + BlockStatement(); + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ExplicitConstructorInvocation() throws ParseException { + /*@bgen(jjtree) ExplicitConstructorInvocation */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPLICITCONSTRUCTORINVOCATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + label_17: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + ; + break; + default: + break label_17; + } + jj_consume_token(IDENTIFIER); + jj_consume_token(DOT); + } + if (jj_2_13(2)) { + jj_consume_token(THIS); + jj_consume_token(DOT); + } else { + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LT: + TypeArguments(); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case THIS: + jj_consume_token(THIS); + break; + case SUPER: + jj_consume_token(SUPER); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + Arguments(); + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Initializer() throws ParseException { + /*@bgen(jjtree) Initializer */ + SimpleNode jjtn000 = new SimpleNode(JJTINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case STATIC: + jj_consume_token(STATIC); + break; + default: + ; + } + Block(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* + * Type, name and expression syntax follows. + */ + final public void Type() throws ParseException { + /*@bgen(jjtree) Type */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_14(2)) { + ReferenceType(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FLOAT: + case INT: + case LONG: + case SHORT: + PrimitiveType(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ReferenceType() throws ParseException { + /*@bgen(jjtree) ReferenceType */ + SimpleNode jjtn000 = new SimpleNode(JJTREFERENCETYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FLOAT: + case INT: + case LONG: + case SHORT: + PrimitiveType(); + label_18: + while (true) { + jj_consume_token(LBRACKET); + jj_consume_token(RBRACKET); + if (jj_2_15(2)) { + ; + } else { + break label_18; + } + } + break; + case IDENTIFIER: + ClassOrInterfaceType(); + label_19: + while (true) { + if (jj_2_16(2)) { + ; + } else { + break label_19; + } + jj_consume_token(LBRACKET); + jj_consume_token(RBRACKET); + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ClassOrInterfaceType() throws ParseException { + /*@bgen(jjtree) ClassOrInterfaceType */ + SimpleNode jjtn000 = new SimpleNode(JJTCLASSORINTERFACETYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + if (jj_2_17(2)) { + TypeArguments(); + } else { + ; + } + label_20: + while (true) { + if (jj_2_18(2)) { + ; + } else { + break label_20; + } + jj_consume_token(DOT); + jj_consume_token(IDENTIFIER); + if (jj_2_19(2)) { + TypeArguments(); + } else { + ; + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void TypeArguments() throws ParseException { + /*@bgen(jjtree) TypeArguments */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LT); + TypeArgument(); + label_21: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_21; + } + jj_consume_token(COMMA); + TypeArgument(); + } + jj_consume_token(GT); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void TypeArgument() throws ParseException { + /*@bgen(jjtree) TypeArgument */ + SimpleNode jjtn000 = new SimpleNode(JJTTYPEARGUMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FLOAT: + case INT: + case LONG: + case SHORT: + case IDENTIFIER: + ReferenceType(); + break; + case HOOK: + jj_consume_token(HOOK); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case EXTENDS: + case SUPER: + WildcardBounds(); + break; + default: + ; + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void WildcardBounds() throws ParseException { + /*@bgen(jjtree) WildcardBounds */ + SimpleNode jjtn000 = new SimpleNode(JJTWILDCARDBOUNDS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case EXTENDS: + jj_consume_token(EXTENDS); + ReferenceType(); + break; + case SUPER: + jj_consume_token(SUPER); + ReferenceType(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PrimitiveType() throws ParseException { + /*@bgen(jjtree) PrimitiveType */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMITIVETYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + jj_consume_token(BOOLEAN); + break; + case CHAR: + jj_consume_token(CHAR); + break; + case BYTE: + jj_consume_token(BYTE); + break; + case SHORT: + jj_consume_token(SHORT); + break; + case INT: + jj_consume_token(INT); + break; + case LONG: + jj_consume_token(LONG); + break; + case FLOAT: + jj_consume_token(FLOAT); + break; + case DOUBLE: + jj_consume_token(DOUBLE); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ResultType() throws ParseException { + /*@bgen(jjtree) ResultType */ + SimpleNode jjtn000 = new SimpleNode(JJTRESULTTYPE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case VOID: + jj_consume_token(VOID); + break; + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FLOAT: + case INT: + case LONG: + case SHORT: + case IDENTIFIER: + Type(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Name() throws ParseException { + /*@bgen(jjtree) Name */ + SimpleNode jjtn000 = new SimpleNode(JJTNAME); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + label_22: + while (true) { + if (jj_2_20(2)) { + ; + } else { + break label_22; + } + jj_consume_token(DOT); + jj_consume_token(IDENTIFIER); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void NameList() throws ParseException { + /*@bgen(jjtree) NameList */ + SimpleNode jjtn000 = new SimpleNode(JJTNAMELIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Name(); + label_23: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_23; + } + jj_consume_token(COMMA); + Name(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* + * Expression syntax follows. + */ + final public void Expression() throws ParseException { + /*@bgen(jjtree) Expression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + ConditionalExpression(); + if (jj_2_21(2)) { + AssignmentOperator(); + Expression(); + } else { + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AssignmentOperator() throws ParseException { + /*@bgen(jjtree) AssignmentOperator */ + SimpleNode jjtn000 = new SimpleNode(JJTASSIGNMENTOPERATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ASSIGN: + jj_consume_token(ASSIGN); + break; + case STARASSIGN: + jj_consume_token(STARASSIGN); + break; + case SLASHASSIGN: + jj_consume_token(SLASHASSIGN); + break; + case REMASSIGN: + jj_consume_token(REMASSIGN); + break; + case PLUSASSIGN: + jj_consume_token(PLUSASSIGN); + break; + case MINUSASSIGN: + jj_consume_token(MINUSASSIGN); + break; + case LSHIFTASSIGN: + jj_consume_token(LSHIFTASSIGN); + break; + case RSIGNEDSHIFTASSIGN: + jj_consume_token(RSIGNEDSHIFTASSIGN); + break; + case RUNSIGNEDSHIFTASSIGN: + jj_consume_token(RUNSIGNEDSHIFTASSIGN); + break; + case ANDASSIGN: + jj_consume_token(ANDASSIGN); + break; + case XORASSIGN: + jj_consume_token(XORASSIGN); + break; + case ORASSIGN: + jj_consume_token(ORASSIGN); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AssignmentExpression() throws ParseException { + /*@bgen(jjtree) AssignmentExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTASSIGNMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + PrimaryExpression(); + AssignmentOperator(); + Expression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ConditionalExpression() throws ParseException { + /*@bgen(jjtree) ConditionalExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONALEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + ConditionalOrExpression(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case HOOK: + jj_consume_token(HOOK); + Expression(); + jj_consume_token(COLON); + Expression(); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ConditionalOrExpression() throws ParseException { + /*@bgen(jjtree) ConditionalOrExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONALOREXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + ConditionalAndExpression(); + label_24: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case SC_OR: + ; + break; + default: + break label_24; + } + jj_consume_token(SC_OR); + ConditionalAndExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ConditionalAndExpression() throws ParseException { + /*@bgen(jjtree) ConditionalAndExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCONDITIONALANDEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + InclusiveOrExpression(); + label_25: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case SC_AND: + ; + break; + default: + break label_25; + } + jj_consume_token(SC_AND); + InclusiveOrExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void InclusiveOrExpression() throws ParseException { + /*@bgen(jjtree) InclusiveOrExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTINCLUSIVEOREXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + ExclusiveOrExpression(); + label_26: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BIT_OR: + ; + break; + default: + break label_26; + } + jj_consume_token(BIT_OR); + ExclusiveOrExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ExclusiveOrExpression() throws ParseException { + /*@bgen(jjtree) ExclusiveOrExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTEXCLUSIVEOREXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + AndExpression(); + label_27: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case XOR: + ; + break; + default: + break label_27; + } + jj_consume_token(XOR); + AndExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AndExpression() throws ParseException { + /*@bgen(jjtree) AndExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTANDEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + EqualityExpression(); + label_28: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BIT_AND: + ; + break; + default: + break label_28; + } + jj_consume_token(BIT_AND); + EqualityExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void EqualityExpression() throws ParseException { + /*@bgen(jjtree) EqualityExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTEQUALITYEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + InstanceOfExpression(); + label_29: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case EQ: + case NE: + ; + break; + default: + break label_29; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case EQ: + jj_consume_token(EQ); + break; + case NE: + jj_consume_token(NE); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + InstanceOfExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void InstanceOfExpression() throws ParseException { + /*@bgen(jjtree) InstanceOfExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTINSTANCEOFEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + RelationalExpression(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case INSTANCEOF: + jj_consume_token(INSTANCEOF); + Type(); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void RelationalExpression() throws ParseException { + /*@bgen(jjtree) RelationalExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTRELATIONALEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + ShiftExpression(); + label_30: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LT: + case LE: + case GE: + case GT: + ; + break; + default: + break label_30; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LT: + jj_consume_token(LT); + break; + case GT: + jj_consume_token(GT); + break; + case LE: + jj_consume_token(LE); + break; + case GE: + jj_consume_token(GE); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + ShiftExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ShiftExpression() throws ParseException { + /*@bgen(jjtree) ShiftExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTSHIFTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + AdditiveExpression(); + label_31: + while (true) { + if (jj_2_22(1)) { + ; + } else { + break label_31; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LSHIFT: + jj_consume_token(LSHIFT); + break; + default: + if (jj_2_23(1)) { + RSIGNEDSHIFT(); + } else if (jj_2_24(1)) { + RUNSIGNEDSHIFT(); + } else { + jj_consume_token(-1); + throw new ParseException(); + } + } + AdditiveExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AdditiveExpression() throws ParseException { + /*@bgen(jjtree) AdditiveExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTADDITIVEEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + MultiplicativeExpression(); + label_32: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PLUS: + case MINUS: + ; + break; + default: + break label_32; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PLUS: + jj_consume_token(PLUS); + break; + case MINUS: + jj_consume_token(MINUS); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + MultiplicativeExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MultiplicativeExpression() throws ParseException { + /*@bgen(jjtree) MultiplicativeExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTMULTIPLICATIVEEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + UnaryExpression(); + label_33: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case STAR: + case SLASH: + case REM: + ; + break; + default: + break label_33; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case STAR: + jj_consume_token(STAR); + break; + case SLASH: + jj_consume_token(SLASH); + break; + case REM: + jj_consume_token(REM); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + UnaryExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void UnaryExpression() throws ParseException { + /*@bgen(jjtree) UnaryExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTUNARYEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PLUS: + case MINUS: + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case PLUS: + jj_consume_token(PLUS); + break; + case MINUS: + jj_consume_token(MINUS); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + UnaryExpression(); + break; + case INCR: + PreIncrementExpression(); + break; + case DECR: + PreDecrementExpression(); + break; + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case BANG: + case TILDE: + UnaryExpressionNotPlusMinus(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PreIncrementExpression() throws ParseException { + /*@bgen(jjtree) PreIncrementExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPREINCREMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(INCR); + PrimaryExpression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PreDecrementExpression() throws ParseException { + /*@bgen(jjtree) PreDecrementExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPREDECREMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(DECR); + PrimaryExpression(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void UnaryExpressionNotPlusMinus() throws ParseException { + /*@bgen(jjtree) UnaryExpressionNotPlusMinus */ + SimpleNode jjtn000 = new SimpleNode(JJTUNARYEXPRESSIONNOTPLUSMINUS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BANG: + case TILDE: + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case TILDE: + jj_consume_token(TILDE); + break; + case BANG: + jj_consume_token(BANG); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + UnaryExpression(); + break; + default: + if (jj_2_25(2147483647)) { + CastExpression(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + PostfixExpression(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + +// This production is to determine lookahead only. The LOOKAHEAD specifications +// below are not used, but they are there just to indicate that we know about + + // this. + final public void CastLookahead() throws ParseException { + /*@bgen(jjtree) CastLookahead */ + SimpleNode jjtn000 = new SimpleNode(JJTCASTLOOKAHEAD); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_26(2)) { + jj_consume_token(LPAREN); + PrimitiveType(); + } else if (jj_2_27(2147483647)) { + jj_consume_token(LPAREN); + Type(); + jj_consume_token(LBRACKET); + jj_consume_token(RBRACKET); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LPAREN: + jj_consume_token(LPAREN); + Type(); + jj_consume_token(RPAREN); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case TILDE: + jj_consume_token(TILDE); + break; + case BANG: + jj_consume_token(BANG); + break; + case LPAREN: + jj_consume_token(LPAREN); + break; + case IDENTIFIER: + jj_consume_token(IDENTIFIER); + break; + case THIS: + jj_consume_token(THIS); + break; + case SUPER: + jj_consume_token(SUPER); + break; + case NEW: + jj_consume_token(NEW); + break; + case FALSE: + case NULL: + case TRUE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + Literal(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PostfixExpression() throws ParseException { + /*@bgen(jjtree) PostfixExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPOSTFIXEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + PrimaryExpression(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case INCR: + case DECR: + PostfixOperator(); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PostfixOperator() throws ParseException { + /*@bgen(jjtree) PostfixOperator */ + SimpleNode jjtn000 = new SimpleNode(JJTPOSTFIXOPERATOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case INCR: + jj_consume_token(INCR); + break; + case DECR: + jj_consume_token(DECR); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void CastExpression() throws ParseException { + /*@bgen(jjtree) CastExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTCASTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_28(2147483647)) { + jj_consume_token(LPAREN); + Type(); + jj_consume_token(RPAREN); + UnaryExpression(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LPAREN: + jj_consume_token(LPAREN); + Type(); + jj_consume_token(RPAREN); + UnaryExpressionNotPlusMinus(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PrimaryExpression() throws ParseException { + /*@bgen(jjtree) PrimaryExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARYEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + PrimaryPrefix(); + label_34: + while (true) { + if (jj_2_29(2)) { + ; + } else { + break label_34; + } + PrimarySuffix(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MemberSelector() throws ParseException { + /*@bgen(jjtree) MemberSelector */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERSELECTOR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(DOT); + TypeArguments(); + jj_consume_token(IDENTIFIER); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PrimaryPrefix() throws ParseException { + /*@bgen(jjtree) PrimaryPrefix */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARYPREFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case FALSE: + case NULL: + case TRUE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + Literal(); + break; + default: + if (jj_2_30(2147483647)) { + label_35: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + ; + break; + default: + break label_35; + } + jj_consume_token(IDENTIFIER); + jj_consume_token(DOT); + } + jj_consume_token(THIS); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case SUPER: + jj_consume_token(SUPER); + jj_consume_token(DOT); + jj_consume_token(IDENTIFIER); + break; + case LPAREN: + jj_consume_token(LPAREN); + Expression(); + jj_consume_token(RPAREN); + break; + case NEW: + AllocationExpression(); + break; + default: + if (jj_2_31(2147483647)) { + ResultType(); + jj_consume_token(DOT); + jj_consume_token(CLASS); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + Name(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void PrimarySuffix() throws ParseException { + /*@bgen(jjtree) PrimarySuffix */ + SimpleNode jjtn000 = new SimpleNode(JJTPRIMARYSUFFIX); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_32(2147483647)) { + jj_consume_token(DOT); + jj_consume_token(SUPER); + } else if (jj_2_33(2147483647)) { + jj_consume_token(DOT); + jj_consume_token(THIS); + } else if (jj_2_34(2)) { + jj_consume_token(DOT); + AllocationExpression(); + } else if (jj_2_35(3)) { + MemberSelector(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACKET: + jj_consume_token(LBRACKET); + Expression(); + jj_consume_token(RBRACKET); + break; + case DOT: + jj_consume_token(DOT); + jj_consume_token(IDENTIFIER); + break; + case LPAREN: + Arguments(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Literal() throws ParseException { + /*@bgen(jjtree) Literal */ + SimpleNode jjtn000 = new SimpleNode(JJTLITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case INTEGER_LITERAL: + jj_consume_token(INTEGER_LITERAL); + break; + case FLOATING_POINT_LITERAL: + jj_consume_token(FLOATING_POINT_LITERAL); + break; + case CHARACTER_LITERAL: + jj_consume_token(CHARACTER_LITERAL); + break; + case STRING_LITERAL: + jj_consume_token(STRING_LITERAL); + break; + case FALSE: + case TRUE: + BooleanLiteral(); + break; + case NULL: + NullLiteral(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void BooleanLiteral() throws ParseException { + /*@bgen(jjtree) BooleanLiteral */ + SimpleNode jjtn000 = new SimpleNode(JJTBOOLEANLITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case TRUE: + jj_consume_token(TRUE); + break; + case FALSE: + jj_consume_token(FALSE); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void NullLiteral() throws ParseException { + /*@bgen(jjtree) NullLiteral */ + SimpleNode jjtn000 = new SimpleNode(JJTNULLLITERAL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(NULL); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Arguments() throws ParseException { + /*@bgen(jjtree) Arguments */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENTS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LPAREN); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case BANG: + case TILDE: + case INCR: + case DECR: + case PLUS: + case MINUS: + ArgumentList(); + break; + default: + ; + } + jj_consume_token(RPAREN); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ArgumentList() throws ParseException { + /*@bgen(jjtree) ArgumentList */ + SimpleNode jjtn000 = new SimpleNode(JJTARGUMENTLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Expression(); + label_36: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_36; + } + jj_consume_token(COMMA); + Expression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AllocationExpression() throws ParseException { + /*@bgen(jjtree) AllocationExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTALLOCATIONEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_36(2)) { + jj_consume_token(NEW); + PrimitiveType(); + ArrayDimsAndInits(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case NEW: + jj_consume_token(NEW); + ClassOrInterfaceType(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LT: + TypeArguments(); + break; + default: + ; + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACKET: + ArrayDimsAndInits(); + break; + case LPAREN: + Arguments(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACE: + ClassOrInterfaceBody(false); + break; + default: + ; + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* + * The third LOOKAHEAD specification below is to parse to PrimarySuffix + * if there is an expression between the "[...]". + */ + final public void ArrayDimsAndInits() throws ParseException { + /*@bgen(jjtree) ArrayDimsAndInits */ + SimpleNode jjtn000 = new SimpleNode(JJTARRAYDIMSANDINITS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_39(2)) { + label_37: + while (true) { + jj_consume_token(LBRACKET); + Expression(); + jj_consume_token(RBRACKET); + if (jj_2_37(2)) { + ; + } else { + break label_37; + } + } + label_38: + while (true) { + if (jj_2_38(2)) { + ; + } else { + break label_38; + } + jj_consume_token(LBRACKET); + jj_consume_token(RBRACKET); + } + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACKET: + label_39: + while (true) { + jj_consume_token(LBRACKET); + jj_consume_token(RBRACKET); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case LBRACKET: + ; + break; + default: + break label_39; + } + } + ArrayInitializer(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* + * Statement syntax follows. + */ + final public void Statement() throws ParseException { + /*@bgen(jjtree) Statement */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_40(2)) { + LabeledStatement(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ASSERT: + AssertStatement(); + break; + case LBRACE: + Block(); + break; + case SEMICOLON: + EmptyStatement(); + break; + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case INCR: + case DECR: + StatementExpression(); + jj_consume_token(SEMICOLON); + break; + case SWITCH: + SwitchStatement(); + break; + case IF: + IfStatement(); + break; + case WHILE: + WhileStatement(); + break; + case DO: + DoStatement(); + break; + case FOR: + ForStatement(); + break; + case BREAK: + BreakStatement(); + break; + case CONTINUE: + ContinueStatement(); + break; + case RETURN: + ReturnStatement(); + break; + case THROW: + ThrowStatement(); + break; + case SYNCHRONIZED: + SynchronizedStatement(); + break; + case TRY: + TryStatement(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AssertStatement() throws ParseException { + /*@bgen(jjtree) AssertStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTASSERTSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(ASSERT); + Expression(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COLON: + jj_consume_token(COLON); + Expression(); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void LabeledStatement() throws ParseException { + /*@bgen(jjtree) LabeledStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTLABELEDSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + jj_consume_token(COLON); + Statement(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void Block() throws ParseException { + /*@bgen(jjtree) Block */ + SimpleNode jjtn000 = new SimpleNode(JJTBLOCK); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LBRACE); + label_40: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case ASSERT: + case BOOLEAN: + case BREAK: + case BYTE: + case CHAR: + case CLASS: + case CONTINUE: + case DO: + case DOUBLE: + case FALSE: + case FINAL: + case FLOAT: + case FOR: + case IF: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case NEW: + case NULL: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case RETURN: + case SHORT: + case STATIC: + case STRICTFP: + case SUPER: + case SWITCH: + case SYNCHRONIZED: + case THIS: + case THROW: + case TRANSIENT: + case TRUE: + case TRY: + case VOID: + case VOLATILE: + case WHILE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case LBRACE: + case SEMICOLON: + case AT: + case INCR: + case DECR: + ; + break; + default: + break label_40; + } + BlockStatement(); + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void BlockStatement() throws ParseException { + /*@bgen(jjtree) BlockStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTBLOCKSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_41(2147483647)) { + LocalVariableDeclaration(); + jj_consume_token(SEMICOLON); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ASSERT: + case BOOLEAN: + case BREAK: + case BYTE: + case CHAR: + case CONTINUE: + case DO: + case DOUBLE: + case FALSE: + case FLOAT: + case FOR: + case IF: + case INT: + case LONG: + case NEW: + case NULL: + case RETURN: + case SHORT: + case SUPER: + case SWITCH: + case SYNCHRONIZED: + case THIS: + case THROW: + case TRUE: + case TRY: + case VOID: + case WHILE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case LBRACE: + case SEMICOLON: + case INCR: + case DECR: + Statement(); + break; + case CLASS: + case INTERFACE: + ClassOrInterfaceDeclaration(0); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void LocalVariableDeclaration() throws ParseException { + /*@bgen(jjtree) LocalVariableDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTLOCALVARIABLEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + Modifiers(); + Type(); + VariableDeclarator(); + label_41: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_41; + } + jj_consume_token(COMMA); + VariableDeclarator(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void EmptyStatement() throws ParseException { + /*@bgen(jjtree) EmptyStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTEMPTYSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(SEMICOLON); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void StatementExpression() throws ParseException { + /*@bgen(jjtree) StatementExpression */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENTEXPRESSION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case INCR: + PreIncrementExpression(); + break; + case DECR: + PreDecrementExpression(); + break; + default: + if (jj_2_42(2147483647)) { + AssignmentExpression(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + PostfixExpression(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void SwitchStatement() throws ParseException { + /*@bgen(jjtree) SwitchStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTSWITCHSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(SWITCH); + jj_consume_token(LPAREN); + Expression(); + jj_consume_token(RPAREN); + jj_consume_token(LBRACE); + label_42: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case CASE: + case _DEFAULT: + ; + break; + default: + break label_42; + } + SwitchLabel(); + label_43: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case ASSERT: + case BOOLEAN: + case BREAK: + case BYTE: + case CHAR: + case CLASS: + case CONTINUE: + case DO: + case DOUBLE: + case FALSE: + case FINAL: + case FLOAT: + case FOR: + case IF: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case NEW: + case NULL: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case RETURN: + case SHORT: + case STATIC: + case STRICTFP: + case SUPER: + case SWITCH: + case SYNCHRONIZED: + case THIS: + case THROW: + case TRANSIENT: + case TRUE: + case TRY: + case VOID: + case VOLATILE: + case WHILE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case LBRACE: + case SEMICOLON: + case AT: + case INCR: + case DECR: + ; + break; + default: + break label_43; + } + BlockStatement(); + } + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void SwitchLabel() throws ParseException { + /*@bgen(jjtree) SwitchLabel */ + SimpleNode jjtn000 = new SimpleNode(JJTSWITCHLABEL); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case CASE: + jj_consume_token(CASE); + Expression(); + jj_consume_token(COLON); + break; + case _DEFAULT: + jj_consume_token(_DEFAULT); + jj_consume_token(COLON); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void IfStatement() throws ParseException { + /*@bgen(jjtree) IfStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTIFSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IF); + jj_consume_token(LPAREN); + Expression(); + jj_consume_token(RPAREN); + Statement(); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ELSE: + jj_consume_token(ELSE); + Statement(); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void WhileStatement() throws ParseException { + /*@bgen(jjtree) WhileStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTWHILESTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(WHILE); + jj_consume_token(LPAREN); + Expression(); + jj_consume_token(RPAREN); + Statement(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void DoStatement() throws ParseException { + /*@bgen(jjtree) DoStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTDOSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(DO); + Statement(); + jj_consume_token(WHILE); + jj_consume_token(LPAREN); + Expression(); + jj_consume_token(RPAREN); + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ForStatement() throws ParseException { + /*@bgen(jjtree) ForStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTFORSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(FOR); + jj_consume_token(LPAREN); + if (jj_2_43(2147483647)) { + Modifiers(); + Type(); + jj_consume_token(IDENTIFIER); + jj_consume_token(COLON); + Expression(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FINAL: + case FLOAT: + case INT: + case LONG: + case NATIVE: + case NEW: + case NULL: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SUPER: + case SYNCHRONIZED: + case THIS: + case TRANSIENT: + case TRUE: + case VOID: + case VOLATILE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case SEMICOLON: + case AT: + case INCR: + case DECR: + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FINAL: + case FLOAT: + case INT: + case LONG: + case NATIVE: + case NEW: + case NULL: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SUPER: + case SYNCHRONIZED: + case THIS: + case TRANSIENT: + case TRUE: + case VOID: + case VOLATILE: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case AT: + case INCR: + case DECR: + ForInit(); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case BANG: + case TILDE: + case INCR: + case DECR: + case PLUS: + case MINUS: + Expression(); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case INCR: + case DECR: + ForUpdate(); + break; + default: + ; + } + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + jj_consume_token(RPAREN); + Statement(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ForInit() throws ParseException { + /*@bgen(jjtree) ForInit */ + SimpleNode jjtn000 = new SimpleNode(JJTFORINIT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_44(2147483647)) { + LocalVariableDeclaration(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case INCR: + case DECR: + StatementExpressionList(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void StatementExpressionList() throws ParseException { + /*@bgen(jjtree) StatementExpressionList */ + SimpleNode jjtn000 = new SimpleNode(JJTSTATEMENTEXPRESSIONLIST); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + StatementExpression(); + label_44: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_44; + } + jj_consume_token(COMMA); + StatementExpression(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ForUpdate() throws ParseException { + /*@bgen(jjtree) ForUpdate */ + SimpleNode jjtn000 = new SimpleNode(JJTFORUPDATE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + StatementExpressionList(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void BreakStatement() throws ParseException { + /*@bgen(jjtree) BreakStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTBREAKSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(BREAK); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + jj_consume_token(IDENTIFIER); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ContinueStatement() throws ParseException { + /*@bgen(jjtree) ContinueStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTCONTINUESTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(CONTINUE); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + jj_consume_token(IDENTIFIER); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ReturnStatement() throws ParseException { + /*@bgen(jjtree) ReturnStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTRETURNSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(RETURN); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case BANG: + case TILDE: + case INCR: + case DECR: + case PLUS: + case MINUS: + Expression(); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void ThrowStatement() throws ParseException { + /*@bgen(jjtree) ThrowStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTTHROWSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(THROW); + Expression(); + jj_consume_token(SEMICOLON); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void SynchronizedStatement() throws ParseException { + /*@bgen(jjtree) SynchronizedStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTSYNCHRONIZEDSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(SYNCHRONIZED); + jj_consume_token(LPAREN); + Expression(); + jj_consume_token(RPAREN); + Block(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void TryStatement() throws ParseException { + /*@bgen(jjtree) TryStatement */ + SimpleNode jjtn000 = new SimpleNode(JJTTRYSTATEMENT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(TRY); + Block(); + label_45: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case CATCH: + ; + break; + default: + break label_45; + } + jj_consume_token(CATCH); + jj_consume_token(LPAREN); + FormalParameter(); + jj_consume_token(RPAREN); + Block(); + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case FINALLY: + jj_consume_token(FINALLY); + Block(); + break; + default: + ; + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* We use productions to match >>>, >> and > so that we can keep the + * type declaration syntax with generics clean + */ + final public void RUNSIGNEDSHIFT() throws ParseException { + /*@bgen(jjtree) RUNSIGNEDSHIFT */ + SimpleNode jjtn000 = new SimpleNode(JJTRUNSIGNEDSHIFT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (getToken(1).kind == GT && + ((Token.GTToken) getToken(1)).realKind == RUNSIGNEDSHIFT) { + + } else { + jj_consume_token(-1); + throw new ParseException(); + } + jj_consume_token(GT); + jj_consume_token(GT); + jj_consume_token(GT); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void RSIGNEDSHIFT() throws ParseException { + /*@bgen(jjtree) RSIGNEDSHIFT */ + SimpleNode jjtn000 = new SimpleNode(JJTRSIGNEDSHIFT); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (getToken(1).kind == GT && + ((Token.GTToken) getToken(1)).realKind == RSIGNEDSHIFT) { + + } else { + jj_consume_token(-1); + throw new ParseException(); + } + jj_consume_token(GT); + jj_consume_token(GT); + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* Annotation syntax follows. */ + final public void Annotation() throws ParseException { + /*@bgen(jjtree) Annotation */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + if (jj_2_45(2147483647)) { + NormalAnnotation(); + } else if (jj_2_46(2147483647)) { + SingleMemberAnnotation(); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case AT: + MarkerAnnotation(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void NormalAnnotation() throws ParseException { + /*@bgen(jjtree) NormalAnnotation */ + SimpleNode jjtn000 = new SimpleNode(JJTNORMALANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(AT); + Name(); + jj_consume_token(LPAREN); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case IDENTIFIER: + MemberValuePairs(); + break; + default: + ; + } + jj_consume_token(RPAREN); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MarkerAnnotation() throws ParseException { + /*@bgen(jjtree) MarkerAnnotation */ + SimpleNode jjtn000 = new SimpleNode(JJTMARKERANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(AT); + Name(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void SingleMemberAnnotation() throws ParseException { + /*@bgen(jjtree) SingleMemberAnnotation */ + SimpleNode jjtn000 = new SimpleNode(JJTSINGLEMEMBERANNOTATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(AT); + Name(); + jj_consume_token(LPAREN); + MemberValue(); + jj_consume_token(RPAREN); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MemberValuePairs() throws ParseException { + /*@bgen(jjtree) MemberValuePairs */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUEPAIRS); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + MemberValuePair(); + label_46: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + ; + break; + default: + break label_46; + } + jj_consume_token(COMMA); + MemberValuePair(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MemberValuePair() throws ParseException { + /*@bgen(jjtree) MemberValuePair */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUEPAIR); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(IDENTIFIER); + jj_consume_token(ASSIGN); + MemberValue(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MemberValue() throws ParseException { + /*@bgen(jjtree) MemberValue */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case AT: + Annotation(); + break; + case LBRACE: + MemberValueArrayInitializer(); + break; + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FALSE: + case FLOAT: + case INT: + case LONG: + case NEW: + case NULL: + case SHORT: + case SUPER: + case THIS: + case TRUE: + case VOID: + case INTEGER_LITERAL: + case FLOATING_POINT_LITERAL: + case CHARACTER_LITERAL: + case STRING_LITERAL: + case IDENTIFIER: + case LPAREN: + case BANG: + case TILDE: + case INCR: + case DECR: + case PLUS: + case MINUS: + ConditionalExpression(); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void MemberValueArrayInitializer() throws ParseException { + /*@bgen(jjtree) MemberValueArrayInitializer */ + SimpleNode jjtn000 = new SimpleNode(JJTMEMBERVALUEARRAYINITIALIZER); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LBRACE); + MemberValue(); + label_47: + while (true) { + if (jj_2_47(2)) { + ; + } else { + break label_47; + } + jj_consume_token(COMMA); + MemberValue(); + } + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case COMMA: + jj_consume_token(COMMA); + break; + default: + ; + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + /* Annotation Types. */ + final public void AnnotationTypeDeclaration(int modifiers) throws ParseException { + /*@bgen(jjtree) AnnotationTypeDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATIONTYPEDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(AT); + jj_consume_token(INTERFACE); + jj_consume_token(IDENTIFIER); + AnnotationTypeBody(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AnnotationTypeBody() throws ParseException { + /*@bgen(jjtree) AnnotationTypeBody */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATIONTYPEBODY); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(LBRACE); + label_48: + while (true) { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case CLASS: + case DOUBLE: + case ENUM: + case FINAL: + case FLOAT: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOLATILE: + case IDENTIFIER: + case SEMICOLON: + case AT: + ; + break; + default: + break label_48; + } + AnnotationTypeMemberDeclaration(); + } + jj_consume_token(RBRACE); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void AnnotationTypeMemberDeclaration() throws ParseException { + /*@bgen(jjtree) AnnotationTypeMemberDeclaration */ + SimpleNode jjtn000 = new SimpleNode(JJTANNOTATIONTYPEMEMBERDECLARATION); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + int modifiers; + try { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case ABSTRACT: + case BOOLEAN: + case BYTE: + case CHAR: + case CLASS: + case DOUBLE: + case ENUM: + case FINAL: + case FLOAT: + case INT: + case INTERFACE: + case LONG: + case NATIVE: + case PRIVATE: + case PROTECTED: + case PUBLIC: + case SHORT: + case STATIC: + case STRICTFP: + case SYNCHRONIZED: + case TRANSIENT: + case VOLATILE: + case IDENTIFIER: + case AT: + modifiers = Modifiers(); + if (jj_2_48(2147483647)) { + Type(); + jj_consume_token(IDENTIFIER); + jj_consume_token(LPAREN); + jj_consume_token(RPAREN); + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case _DEFAULT: + DefaultValue(); + break; + default: + ; + } + jj_consume_token(SEMICOLON); + } else { + switch ((jj_ntk == -1) ? jj_ntk() : jj_ntk) { + case CLASS: + case INTERFACE: + ClassOrInterfaceDeclaration(modifiers); + break; + case ENUM: + EnumDeclaration(modifiers); + break; + case AT: + AnnotationTypeDeclaration(modifiers); + break; + case BOOLEAN: + case BYTE: + case CHAR: + case DOUBLE: + case FLOAT: + case INT: + case LONG: + case SHORT: + case IDENTIFIER: + FieldDeclaration(modifiers); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } + break; + case SEMICOLON: + jj_consume_token(SEMICOLON); + break; + default: + jj_consume_token(-1); + throw new ParseException(); + } + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final public void DefaultValue() throws ParseException { + /*@bgen(jjtree) DefaultValue */ + SimpleNode jjtn000 = new SimpleNode(JJTDEFAULTVALUE); + boolean jjtc000 = true; + jjtree.openNodeScope(jjtn000); + jjtreeOpenNodeScope(jjtn000); + try { + jj_consume_token(_DEFAULT); + MemberValue(); + } catch (Throwable jjte000) { + if (jjtc000) { + jjtree.clearNodeScope(jjtn000); + jjtc000 = false; + } else { + jjtree.popNode(); + } + if (jjte000 instanceof RuntimeException) { + { + if (true) throw (RuntimeException) jjte000; + } + } + if (jjte000 instanceof ParseException) { + { + if (true) throw (ParseException) jjte000; + } + } + { + if (true) throw (Error) jjte000; + } + } finally { + if (jjtc000) { + jjtree.closeNodeScope(jjtn000, true); + jjtreeCloseNodeScope(jjtn000); + } + } + } + + final private boolean jj_2_1(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_1(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_2(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_2(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_3(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_3(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_4(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_4(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_5(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_5(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_6(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_6(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_7(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_7(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_8(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_8(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_9(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_9(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_10(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_10(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_11(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_11(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_12(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_12(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_13(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_13(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_14(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_14(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_15(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_15(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_16(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_16(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_17(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_17(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_18(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_18(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_19(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_19(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_20(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_20(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_21(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_21(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_22(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_22(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_23(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_23(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_24(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_24(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_25(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_25(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_26(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_26(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_27(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_27(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_28(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_28(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_29(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_29(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_30(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_30(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_31(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_31(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_32(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_32(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_33(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_33(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_34(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_34(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_35(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_35(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_36(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_36(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_37(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_37(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_38(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_38(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_39(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_39(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_40(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_40(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_41(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_41(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_42(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_42(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_43(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_43(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_44(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_44(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_45(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_45(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_46(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_46(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_47(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_47(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_2_48(int xla) { + jj_la = xla; + jj_lastpos = jj_scanpos = token; + try { + return !jj_3_48(); + } + catch (LookaheadSuccess ls) { + return true; + } + } + + final private boolean jj_3R_56() { + if (jj_3R_101()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3_21()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_135() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_91()) return true; + return false; + } + + final private boolean jj_3R_99() { + if (jj_3R_91()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_135()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3_20() { + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(IDENTIFIER)) return true; + return false; + } + + final private boolean jj_3R_91() { + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_20()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_122() { + if (jj_3R_72()) return true; + return false; + } + + final private boolean jj_3R_86() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(58)) { + jj_scanpos = xsp; + if (jj_3R_122()) return true; + } + return false; + } + + final private boolean jj_3_19() { + if (jj_3R_78()) return true; + return false; + } + + final private boolean jj_3R_83() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(10)) { + jj_scanpos = xsp; + if (jj_scan_token(15)) { + jj_scanpos = xsp; + if (jj_scan_token(12)) { + jj_scanpos = xsp; + if (jj_scan_token(46)) { + jj_scanpos = xsp; + if (jj_scan_token(35)) { + jj_scanpos = xsp; + if (jj_scan_token(37)) { + jj_scanpos = xsp; + if (jj_scan_token(28)) { + jj_scanpos = xsp; + if (jj_scan_token(21)) return true; + } + } + } + } + } + } + } + return false; + } + + final private boolean jj_3R_194() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_112()) return true; + return false; + } + + final private boolean jj_3R_290() { + if (jj_scan_token(SUPER)) return true; + if (jj_3R_77()) return true; + return false; + } + + final private boolean jj_3_16() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_289() { + if (jj_scan_token(EXTENDS)) return true; + if (jj_3R_77()) return true; + return false; + } + + final private boolean jj_3R_277() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_289()) { + jj_scanpos = xsp; + if (jj_3R_290()) return true; + } + return false; + } + + final private boolean jj_3R_256() { + if (jj_3R_277()) return true; + return false; + } + + final private boolean jj_3R_151() { + if (jj_scan_token(HOOK)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_256()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3_17() { + if (jj_3R_78()) return true; + return false; + } + + final private boolean jj_3R_112() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_150()) { + jj_scanpos = xsp; + if (jj_3R_151()) return true; + } + return false; + } + + final private boolean jj_3R_150() { + if (jj_3R_77()) return true; + return false; + } + + final private boolean jj_3_15() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_78() { + if (jj_scan_token(LT)) return true; + if (jj_3R_112()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_194()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(GT)) return true; + return false; + } + + final private boolean jj_3_18() { + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3_19()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_149() { + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3_17()) jj_scanpos = xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_18()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_111() { + if (jj_3R_149()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_16()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_110() { + if (jj_3R_83()) return true; + Token xsp; + if (jj_3_15()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3_15()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_77() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_110()) { + jj_scanpos = xsp; + if (jj_3R_111()) return true; + } + return false; + } + + final private boolean jj_3_13() { + if (jj_scan_token(THIS)) return true; + if (jj_scan_token(DOT)) return true; + return false; + } + + final private boolean jj_3R_221() { + if (jj_scan_token(THROWS)) return true; + if (jj_3R_99()) return true; + return false; + } + + final private boolean jj_3R_103() { + if (jj_3R_83()) return true; + return false; + } + + final private boolean jj_3R_72() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_14()) { + jj_scanpos = xsp; + if (jj_3R_103()) return true; + } + return false; + } + + final private boolean jj_3_14() { + if (jj_3R_77()) return true; + return false; + } + + final private boolean jj_3R_74() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(47)) jj_scanpos = xsp; + if (jj_3R_104()) return true; + return false; + } + + final private boolean jj_3_12() { + if (jj_3R_76()) return true; + return false; + } + + final private boolean jj_3R_108() { + if (jj_3R_78()) return true; + return false; + } + + final private boolean jj_3R_107() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(DOT)) return true; + return false; + } + + final private boolean jj_3R_252() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_76() { + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_107()) { + jj_scanpos = xsp; + break; + } + } + xsp = jj_scanpos; + if (jj_3_13()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_108()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(52)) { + jj_scanpos = xsp; + if (jj_scan_token(49)) return true; + } + if (jj_3R_109()) return true; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_134() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_133()) return true; + return false; + } + + final private boolean jj_3R_223() { + if (jj_3R_49()) return true; + return false; + } + + final private boolean jj_3R_222() { + if (jj_3R_76()) return true; + return false; + } + + final private boolean jj_3R_220() { + if (jj_3R_97()) return true; + return false; + } + + final private boolean jj_3R_186() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_220()) jj_scanpos = xsp; + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_3R_53()) return true; + xsp = jj_scanpos; + if (jj_3R_221()) jj_scanpos = xsp; + if (jj_scan_token(LBRACE)) return true; + xsp = jj_scanpos; + if (jj_3R_222()) jj_scanpos = xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_223()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(RBRACE)) return true; + return false; + } + + final private boolean jj_3_11() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_75()) return true; + return false; + } + + final private boolean jj_3R_227() { + if (jj_scan_token(THROWS)) return true; + if (jj_3R_99()) return true; + return false; + } + + final private boolean jj_3R_98() { + if (jj_3R_133()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_134()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_133() { + if (jj_3R_50()) return true; + if (jj_3R_72()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(119)) jj_scanpos = xsp; + if (jj_3R_184()) return true; + return false; + } + + final private boolean jj_3R_53() { + if (jj_scan_token(LPAREN)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_98()) jj_scanpos = xsp; + if (jj_scan_token(RPAREN)) return true; + return false; + } + + final private boolean jj_3_48() { + if (jj_3R_72()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(LPAREN)) return true; + return false; + } + + final private boolean jj_3R_226() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_3R_53()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_252()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_228() { + if (jj_3R_104()) return true; + return false; + } + + final private boolean jj_3R_225() { + if (jj_3R_97()) return true; + return false; + } + + final private boolean jj_3R_292() { + if (jj_3R_75()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_11()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_188() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_225()) jj_scanpos = xsp; + if (jj_3R_86()) return true; + if (jj_3R_226()) return true; + xsp = jj_scanpos; + if (jj_3R_227()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_228()) { + jj_scanpos = xsp; + if (jj_scan_token(81)) return true; + } + return false; + } + + final private boolean jj_3R_198() { + if (jj_scan_token(ASSIGN)) return true; + if (jj_3R_75()) return true; + return false; + } + + final private boolean jj_3R_224() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_161()) return true; + return false; + } + + final private boolean jj_3_47() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_93()) return true; + return false; + } + + final private boolean jj_3R_217() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_147() { + if (jj_scan_token(LBRACE)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_292()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(82)) jj_scanpos = xsp; + if (jj_scan_token(RBRACE)) return true; + return false; + } + + final private boolean jj_3R_73() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_106() { + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_105() { + if (jj_3R_147()) return true; + return false; + } + + final private boolean jj_3R_75() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_105()) { + jj_scanpos = xsp; + if (jj_3R_106()) return true; + } + return false; + } + + final private boolean jj_3R_184() { + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_217()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_160() { + if (jj_scan_token(LBRACE)) return true; + if (jj_3R_93()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_47()) { + jj_scanpos = xsp; + break; + } + } + xsp = jj_scanpos; + if (jj_scan_token(82)) jj_scanpos = xsp; + if (jj_scan_token(RBRACE)) return true; + return false; + } + + final private boolean jj_3R_276() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_275()) return true; + return false; + } + + final private boolean jj_3R_161() { + if (jj_3R_184()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_198()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_127() { + if (jj_3R_101()) return true; + return false; + } + + final private boolean jj_3_9() { + if (jj_3R_72()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_73()) { + jj_scanpos = xsp; + break; + } + } + xsp = jj_scanpos; + if (jj_scan_token(82)) { + jj_scanpos = xsp; + if (jj_scan_token(85)) { + jj_scanpos = xsp; + if (jj_scan_token(81)) return true; + } + } + return false; + } + + final private boolean jj_3R_126() { + if (jj_3R_160()) return true; + return false; + } + + final private boolean jj_3R_71() { + if (jj_3R_97()) return true; + return false; + } + + final private boolean jj_3R_93() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_125()) { + jj_scanpos = xsp; + if (jj_3R_126()) { + jj_scanpos = xsp; + if (jj_3R_127()) return true; + } + } + return false; + } + + final private boolean jj_3R_125() { + if (jj_3R_102()) return true; + return false; + } + + final private boolean jj_3_8() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_71()) jj_scanpos = xsp; + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(LPAREN)) return true; + return false; + } + + final private boolean jj_3R_187() { + if (jj_3R_72()) return true; + if (jj_3R_161()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_224()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_275() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(ASSIGN)) return true; + if (jj_3R_93()) return true; + return false; + } + + final private boolean jj_3R_140() { + if (jj_3R_188()) return true; + return false; + } + + final private boolean jj_3R_139() { + if (jj_3R_187()) return true; + return false; + } + + final private boolean jj_3R_249() { + if (jj_scan_token(BIT_AND)) return true; + if (jj_3R_149()) return true; + return false; + } + + final private boolean jj_3R_138() { + if (jj_3R_186()) return true; + return false; + } + + final private boolean jj_3R_255() { + if (jj_3R_275()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_276()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_231() { + if (jj_3R_255()) return true; + return false; + } + + final private boolean jj_3R_137() { + if (jj_3R_185()) return true; + return false; + } + + final private boolean jj_3R_92() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(ASSIGN)) return true; + return false; + } + + final private boolean jj_3R_136() { + if (jj_3R_130()) return true; + return false; + } + + final private boolean jj_3R_192() { + if (jj_scan_token(AT)) return true; + if (jj_3R_91()) return true; + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_93()) return true; + if (jj_scan_token(RPAREN)) return true; + return false; + } + + final private boolean jj_3R_286() { + if (jj_3R_182()) return true; + return false; + } + + final private boolean jj_3R_100() { + if (jj_3R_50()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_136()) { + jj_scanpos = xsp; + if (jj_3R_137()) { + jj_scanpos = xsp; + if (jj_3R_138()) { + jj_scanpos = xsp; + if (jj_3R_139()) { + jj_scanpos = xsp; + if (jj_3R_140()) return true; + } + } + } + } + return false; + } + + final private boolean jj_3R_193() { + if (jj_scan_token(AT)) return true; + if (jj_3R_91()) return true; + return false; + } + + final private boolean jj_3_46() { + if (jj_scan_token(AT)) return true; + if (jj_3R_91()) return true; + if (jj_scan_token(LPAREN)) return true; + return false; + } + + final private boolean jj_3_10() { + if (jj_3R_74()) return true; + return false; + } + + final private boolean jj_3R_55() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_10()) { + jj_scanpos = xsp; + if (jj_3R_100()) { + jj_scanpos = xsp; + if (jj_scan_token(81)) return true; + } + } + return false; + } + + final private boolean jj_3R_191() { + if (jj_scan_token(AT)) return true; + if (jj_3R_91()) return true; + if (jj_scan_token(LPAREN)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_231()) jj_scanpos = xsp; + if (jj_scan_token(RPAREN)) return true; + return false; + } + + final private boolean jj_3_45() { + if (jj_scan_token(AT)) return true; + if (jj_3R_91()) return true; + if (jj_scan_token(LPAREN)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_92()) { + jj_scanpos = xsp; + if (jj_scan_token(76)) return true; + } + return false; + } + + final private boolean jj_3R_215() { + if (jj_3R_55()) return true; + return false; + } + + final private boolean jj_3R_132() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_131()) return true; + return false; + } + + final private boolean jj_3R_183() { + if (jj_3R_216()) return true; + return false; + } + + final private boolean jj_3R_285() { + if (jj_3R_109()) return true; + return false; + } + + final private boolean jj_3R_145() { + if (jj_3R_193()) return true; + return false; + } + + final private boolean jj_3R_182() { + if (jj_scan_token(LBRACE)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_215()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(RBRACE)) return true; + return false; + } + + final private boolean jj_3R_144() { + if (jj_3R_192()) return true; + return false; + } + + final private boolean jj_3R_113() { + return false; + } + + final private boolean jj_3R_102() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_143()) { + jj_scanpos = xsp; + if (jj_3R_144()) { + jj_scanpos = xsp; + if (jj_3R_145()) return true; + } + } + return false; + } + + final private boolean jj_3R_143() { + if (jj_3R_191()) return true; + return false; + } + + final private boolean jj_3R_216() { + if (jj_scan_token(EXTENDS)) return true; + if (jj_3R_149()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_249()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_131() { + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_183()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_114() { + return false; + } + + final private boolean jj_3_7() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_70()) return true; + return false; + } + + final private boolean jj_3R_80() { + Token xsp; + xsp = jj_scanpos; + lookingAhead = true; + jj_semLA = getToken(1).kind == GT && + ((Token.GTToken) getToken(1)).realKind == RSIGNEDSHIFT; + lookingAhead = false; + if (!jj_semLA || jj_3R_113()) return true; + if (jj_scan_token(GT)) return true; + if (jj_scan_token(GT)) return true; + return false; + } + + final private boolean jj_3R_97() { + if (jj_scan_token(LT)) return true; + if (jj_3R_131()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_132()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(GT)) return true; + return false; + } + + final private boolean jj_3R_272() { + if (jj_3R_55()) return true; + return false; + } + + final private boolean jj_3R_70() { + if (jj_3R_50()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_285()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_286()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_81() { + Token xsp; + xsp = jj_scanpos; + lookingAhead = true; + jj_semLA = getToken(1).kind == GT && + ((Token.GTToken) getToken(1)).realKind == RUNSIGNEDSHIFT; + lookingAhead = false; + if (!jj_semLA || jj_3R_114()) return true; + if (jj_scan_token(GT)) return true; + if (jj_scan_token(GT)) return true; + if (jj_scan_token(GT)) return true; + return false; + } + + final private boolean jj_3R_251() { + if (jj_scan_token(SEMICOLON)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_272()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_250() { + if (jj_3R_70()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_7()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_246() { + if (jj_scan_token(FINALLY)) return true; + if (jj_3R_104()) return true; + return false; + } + + final private boolean jj_3R_219() { + if (jj_scan_token(LBRACE)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_250()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_scan_token(82)) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_251()) jj_scanpos = xsp; + if (jj_scan_token(RBRACE)) return true; + return false; + } + + final private boolean jj_3R_245() { + if (jj_scan_token(CATCH)) return true; + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_133()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_3R_104()) return true; + return false; + } + + final private boolean jj_3R_212() { + if (jj_scan_token(TRY)) return true; + if (jj_3R_104()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_245()) { + jj_scanpos = xsp; + break; + } + } + xsp = jj_scanpos; + if (jj_3R_246()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_218() { + if (jj_3R_214()) return true; + return false; + } + + final private boolean jj_3R_185() { + if (jj_scan_token(ENUM)) return true; + if (jj_scan_token(IDENTIFIER)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_218()) jj_scanpos = xsp; + if (jj_3R_219()) return true; + return false; + } + + final private boolean jj_3R_211() { + if (jj_scan_token(SYNCHRONIZED)) return true; + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_3R_104()) return true; + return false; + } + + final private boolean jj_3R_244() { + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_248() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_149()) return true; + return false; + } + + final private boolean jj_3R_214() { + if (jj_scan_token(IMPLEMENTS)) return true; + if (jj_3R_149()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_248()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_210() { + if (jj_scan_token(THROW)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_271() { + if (jj_3R_284()) return true; + return false; + } + + final private boolean jj_3R_299() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_201()) return true; + return false; + } + + final private boolean jj_3R_209() { + if (jj_scan_token(RETURN)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_244()) jj_scanpos = xsp; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_247() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_149()) return true; + return false; + } + + final private boolean jj_3R_213() { + if (jj_scan_token(EXTENDS)) return true; + if (jj_3R_149()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_247()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_208() { + if (jj_scan_token(CONTINUE)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(72)) jj_scanpos = xsp; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_178() { + if (jj_scan_token(INTERFACE)) return true; + return false; + } + + final private boolean jj_3R_207() { + if (jj_scan_token(BREAK)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(72)) jj_scanpos = xsp; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_181() { + if (jj_3R_214()) return true; + return false; + } + + final private boolean jj_3R_180() { + if (jj_3R_213()) return true; + return false; + } + + final private boolean jj_3R_179() { + if (jj_3R_97()) return true; + return false; + } + + final private boolean jj_3R_284() { + if (jj_3R_296()) return true; + return false; + } + + final private boolean jj_3R_270() { + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_130() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(16)) { + jj_scanpos = xsp; + if (jj_3R_178()) return true; + } + if (jj_scan_token(IDENTIFIER)) return true; + xsp = jj_scanpos; + if (jj_3R_179()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_180()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_181()) jj_scanpos = xsp; + if (jj_3R_182()) return true; + return false; + } + + final private boolean jj_3_44() { + if (jj_3R_50()) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + return false; + } + + final private boolean jj_3R_296() { + if (jj_3R_201()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_299()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_241() { + if (jj_scan_token(ELSE)) return true; + if (jj_3R_129()) return true; + return false; + } + + final private boolean jj_3R_295() { + if (jj_3R_296()) return true; + return false; + } + + final private boolean jj_3_43() { + if (jj_3R_50()) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(COLON)) return true; + return false; + } + + final private boolean jj_3R_294() { + if (jj_3R_128()) return true; + return false; + } + + final private boolean jj_3R_283() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_294()) { + jj_scanpos = xsp; + if (jj_3R_295()) return true; + } + return false; + } + + final private boolean jj_3R_269() { + if (jj_3R_283()) return true; + return false; + } + + final private boolean jj_3R_243() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_269()) jj_scanpos = xsp; + if (jj_scan_token(SEMICOLON)) return true; + xsp = jj_scanpos; + if (jj_3R_270()) jj_scanpos = xsp; + if (jj_scan_token(SEMICOLON)) return true; + xsp = jj_scanpos; + if (jj_3R_271()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_242() { + if (jj_3R_50()) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(COLON)) return true; + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_54() { + if (jj_scan_token(THROWS)) return true; + if (jj_3R_99()) return true; + return false; + } + + final private boolean jj_3R_206() { + if (jj_scan_token(FOR)) return true; + if (jj_scan_token(LPAREN)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_242()) { + jj_scanpos = xsp; + if (jj_3R_243()) return true; + } + if (jj_scan_token(RPAREN)) return true; + if (jj_3R_129()) return true; + return false; + } + + final private boolean jj_3R_69() { + if (jj_3R_102()) return true; + return false; + } + + final private boolean jj_3R_205() { + if (jj_scan_token(DO)) return true; + if (jj_3R_129()) return true; + if (jj_scan_token(WHILE)) return true; + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_68() { + if (jj_scan_token(STRICTFP)) return true; + return false; + } + + final private boolean jj_3R_67() { + if (jj_scan_token(VOLATILE)) return true; + return false; + } + + final private boolean jj_3R_66() { + if (jj_scan_token(TRANSIENT)) return true; + return false; + } + + final private boolean jj_3R_204() { + if (jj_scan_token(WHILE)) return true; + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_3R_129()) return true; + return false; + } + + final private boolean jj_3R_65() { + if (jj_scan_token(NATIVE)) return true; + return false; + } + + final private boolean jj_3R_64() { + if (jj_scan_token(SYNCHRONIZED)) return true; + return false; + } + + final private boolean jj_3R_63() { + if (jj_scan_token(ABSTRACT)) return true; + return false; + } + + final private boolean jj_3R_268() { + if (jj_3R_49()) return true; + return false; + } + + final private boolean jj_3R_203() { + if (jj_scan_token(IF)) return true; + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_3R_129()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_241()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_62() { + if (jj_scan_token(FINAL)) return true; + return false; + } + + final private boolean jj_3R_61() { + if (jj_scan_token(PRIVATE)) return true; + return false; + } + + final private boolean jj_3R_162() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_161()) return true; + return false; + } + + final private boolean jj_3R_60() { + if (jj_scan_token(PROTECTED)) return true; + return false; + } + + final private boolean jj_3R_59() { + if (jj_scan_token(STATIC)) return true; + return false; + } + + final private boolean jj_3R_58() { + if (jj_scan_token(PUBLIC)) return true; + return false; + } + + final private boolean jj_3R_282() { + if (jj_scan_token(_DEFAULT)) return true; + if (jj_scan_token(COLON)) return true; + return false; + } + + final private boolean jj_3_6() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_58()) { + jj_scanpos = xsp; + if (jj_3R_59()) { + jj_scanpos = xsp; + if (jj_3R_60()) { + jj_scanpos = xsp; + if (jj_3R_61()) { + jj_scanpos = xsp; + if (jj_3R_62()) { + jj_scanpos = xsp; + if (jj_3R_63()) { + jj_scanpos = xsp; + if (jj_3R_64()) { + jj_scanpos = xsp; + if (jj_3R_65()) { + jj_scanpos = xsp; + if (jj_3R_66()) { + jj_scanpos = xsp; + if (jj_3R_67()) { + jj_scanpos = xsp; + if (jj_3R_68()) { + jj_scanpos = xsp; + if (jj_3R_69()) return true; + } + } + } + } + } + } + } + } + } + } + } + return false; + } + + final private boolean jj_3R_281() { + if (jj_scan_token(CASE)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(COLON)) return true; + return false; + } + + final private boolean jj_3R_267() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_281()) { + jj_scanpos = xsp; + if (jj_3R_282()) return true; + } + return false; + } + + final private boolean jj_3R_50() { + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_6()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_240() { + if (jj_3R_267()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_268()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3_42() { + if (jj_3R_90()) return true; + if (jj_3R_79()) return true; + return false; + } + + final private boolean jj_3R_202() { + if (jj_scan_token(SWITCH)) return true; + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_scan_token(LBRACE)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_240()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(RBRACE)) return true; + return false; + } + + final private boolean jj_3R_239() { + if (jj_3R_266()) return true; + return false; + } + + final private boolean jj_3R_57() { + if (jj_3R_102()) return true; + return false; + } + + final private boolean jj_3R_52() { + if (jj_3R_86()) return true; + return false; + } + + final private boolean jj_3R_238() { + if (jj_3R_265()) return true; + return false; + } + + final private boolean jj_3_5() { + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_57()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(PACKAGE)) return true; + return false; + } + + final private boolean jj_3R_237() { + if (jj_3R_264()) return true; + return false; + } + + final private boolean jj_3R_201() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_236()) { + jj_scanpos = xsp; + if (jj_3R_237()) { + jj_scanpos = xsp; + if (jj_3R_238()) { + jj_scanpos = xsp; + if (jj_3R_239()) return true; + } + } + } + return false; + } + + final private boolean jj_3R_236() { + if (jj_3R_263()) return true; + return false; + } + + final private boolean jj_3R_200() { + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3_41() { + if (jj_3R_50()) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + return false; + } + + final private boolean jj_3R_128() { + if (jj_3R_50()) return true; + if (jj_3R_72()) return true; + if (jj_3R_161()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_162()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_51() { + if (jj_3R_97()) return true; + return false; + } + + final private boolean jj_3R_235() { + if (jj_scan_token(COLON)) return true; + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_96() { + if (jj_3R_130()) return true; + return false; + } + + final private boolean jj_3R_95() { + if (jj_3R_129()) return true; + return false; + } + + final private boolean jj_3_4() { + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_94() { + if (jj_3R_128()) return true; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_49() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_94()) { + jj_scanpos = xsp; + if (jj_3R_95()) { + jj_scanpos = xsp; + if (jj_3R_96()) return true; + } + } + return false; + } + + final private boolean jj_3R_146() { + if (jj_3R_49()) return true; + return false; + } + + final private boolean jj_3_3() { + if (jj_3R_55()) return true; + return false; + } + + final private boolean jj_3R_104() { + if (jj_scan_token(LBRACE)) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_146()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(RBRACE)) return true; + return false; + } + + final private boolean jj_3_2() { + if (jj_3R_50()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_51()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_52()) jj_scanpos = xsp; + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_3R_53()) return true; + xsp = jj_scanpos; + if (jj_3R_54()) jj_scanpos = xsp; + if (jj_scan_token(LBRACE)) return true; + return false; + } + + final private boolean jj_3R_89() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(COLON)) return true; + if (jj_3R_129()) return true; + return false; + } + + final private boolean jj_3_1() { + if (jj_3R_49()) return true; + return false; + } + + final private boolean jj_3R_199() { + if (jj_scan_token(ASSERT)) return true; + if (jj_3R_56()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_235()) jj_scanpos = xsp; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_177() { + if (jj_3R_212()) return true; + return false; + } + + final private boolean jj_3R_176() { + if (jj_3R_211()) return true; + return false; + } + + final private boolean jj_3_38() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_175() { + if (jj_3R_210()) return true; + return false; + } + + final private boolean jj_3R_174() { + if (jj_3R_209()) return true; + return false; + } + + final private boolean jj_3R_173() { + if (jj_3R_208()) return true; + return false; + } + + final private boolean jj_3R_172() { + if (jj_3R_207()) return true; + return false; + } + + final private boolean jj_3R_171() { + if (jj_3R_206()) return true; + return false; + } + + final private boolean jj_3R_170() { + if (jj_3R_205()) return true; + return false; + } + + final private boolean jj_3R_169() { + if (jj_3R_204()) return true; + return false; + } + + final private boolean jj_3R_168() { + if (jj_3R_203()) return true; + return false; + } + + final private boolean jj_3R_167() { + if (jj_3R_202()) return true; + return false; + } + + final private boolean jj_3R_166() { + if (jj_3R_201()) return true; + if (jj_scan_token(SEMICOLON)) return true; + return false; + } + + final private boolean jj_3R_165() { + if (jj_3R_200()) return true; + return false; + } + + final private boolean jj_3R_164() { + if (jj_3R_104()) return true; + return false; + } + + final private boolean jj_3R_163() { + if (jj_3R_199()) return true; + return false; + } + + final private boolean jj_3R_260() { + if (jj_3R_78()) return true; + return false; + } + + final private boolean jj_3_40() { + if (jj_3R_89()) return true; + return false; + } + + final private boolean jj_3R_129() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_40()) { + jj_scanpos = xsp; + if (jj_3R_163()) { + jj_scanpos = xsp; + if (jj_3R_164()) { + jj_scanpos = xsp; + if (jj_3R_165()) { + jj_scanpos = xsp; + if (jj_3R_166()) { + jj_scanpos = xsp; + if (jj_3R_167()) { + jj_scanpos = xsp; + if (jj_3R_168()) { + jj_scanpos = xsp; + if (jj_3R_169()) { + jj_scanpos = xsp; + if (jj_3R_170()) { + jj_scanpos = xsp; + if (jj_3R_171()) { + jj_scanpos = xsp; + if (jj_3R_172()) { + jj_scanpos = xsp; + if (jj_3R_173()) { + jj_scanpos = xsp; + if (jj_3R_174()) { + jj_scanpos = xsp; + if (jj_3R_175()) { + jj_scanpos = xsp; + if (jj_3R_176()) { + jj_scanpos = xsp; + if (jj_3R_177()) + return true; + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + return false; + } + + final private boolean jj_3R_279() { + if (jj_3R_182()) return true; + return false; + } + + final private boolean jj_3R_291() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_278() { + Token xsp; + if (jj_3R_291()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3R_291()) { + jj_scanpos = xsp; + break; + } + } + if (jj_3R_147()) return true; + return false; + } + + final private boolean jj_3_37() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3_39() { + Token xsp; + if (jj_3_37()) return true; + while (true) { + xsp = jj_scanpos; + if (jj_3_37()) { + jj_scanpos = xsp; + break; + } + } + while (true) { + xsp = jj_scanpos; + if (jj_3_38()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_259() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_39()) { + jj_scanpos = xsp; + if (jj_3R_278()) return true; + } + return false; + } + + final private boolean jj_3R_262() { + if (jj_3R_109()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_279()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_232() { + if (jj_scan_token(COMMA)) return true; + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_261() { + if (jj_3R_259()) return true; + return false; + } + + final private boolean jj_3R_123() { + if (jj_scan_token(NEW)) return true; + if (jj_3R_149()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_260()) jj_scanpos = xsp; + xsp = jj_scanpos; + if (jj_3R_261()) { + jj_scanpos = xsp; + if (jj_3R_262()) return true; + } + return false; + } + + final private boolean jj_3R_87() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_36()) { + jj_scanpos = xsp; + if (jj_3R_123()) return true; + } + return false; + } + + final private boolean jj_3_36() { + if (jj_scan_token(NEW)) return true; + if (jj_3R_83()) return true; + if (jj_3R_259()) return true; + return false; + } + + final private boolean jj_3R_148() { + if (jj_3R_195()) return true; + return false; + } + + final private boolean jj_3R_195() { + if (jj_3R_56()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_232()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_109() { + if (jj_scan_token(LPAREN)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_148()) jj_scanpos = xsp; + if (jj_scan_token(RPAREN)) return true; + return false; + } + + final private boolean jj_3R_258() { + if (jj_scan_token(NULL)) return true; + return false; + } + + final private boolean jj_3R_257() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(56)) { + jj_scanpos = xsp; + if (jj_scan_token(25)) return true; + } + return false; + } + + final private boolean jj_3R_234() { + if (jj_3R_258()) return true; + return false; + } + + final private boolean jj_3R_233() { + if (jj_3R_257()) return true; + return false; + } + + final private boolean jj_3R_196() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(61)) { + jj_scanpos = xsp; + if (jj_scan_token(65)) { + jj_scanpos = xsp; + if (jj_scan_token(70)) { + jj_scanpos = xsp; + if (jj_scan_token(71)) { + jj_scanpos = xsp; + if (jj_3R_233()) { + jj_scanpos = xsp; + if (jj_3R_234()) return true; + } + } + } + } + } + return false; + } + + final private boolean jj_3R_152() { + if (jj_3R_196()) return true; + return false; + } + + final private boolean jj_3R_121() { + if (jj_3R_109()) return true; + return false; + } + + final private boolean jj_3R_120() { + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(IDENTIFIER)) return true; + return false; + } + + final private boolean jj_3_33() { + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(THIS)) return true; + return false; + } + + final private boolean jj_3R_119() { + if (jj_scan_token(LBRACKET)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3_32() { + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(SUPER)) return true; + if (jj_scan_token(DOT)) return true; + return false; + } + + final private boolean jj_3_35() { + if (jj_3R_88()) return true; + return false; + } + + final private boolean jj_3_34() { + if (jj_scan_token(DOT)) return true; + if (jj_3R_87()) return true; + return false; + } + + final private boolean jj_3R_118() { + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(THIS)) return true; + return false; + } + + final private boolean jj_3_31() { + if (jj_3R_86()) return true; + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(CLASS)) return true; + return false; + } + + final private boolean jj_3R_117() { + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(SUPER)) return true; + return false; + } + + final private boolean jj_3R_84() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_117()) { + jj_scanpos = xsp; + if (jj_3R_118()) { + jj_scanpos = xsp; + if (jj_3_34()) { + jj_scanpos = xsp; + if (jj_3_35()) { + jj_scanpos = xsp; + if (jj_3R_119()) { + jj_scanpos = xsp; + if (jj_3R_120()) { + jj_scanpos = xsp; + if (jj_3R_121()) return true; + } + } + } + } + } + } + return false; + } + + final private boolean jj_3R_85() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(DOT)) return true; + return false; + } + + final private boolean jj_3R_159() { + if (jj_3R_91()) return true; + return false; + } + + final private boolean jj_3_30() { + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_85()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(THIS)) return true; + return false; + } + + final private boolean jj_3R_158() { + if (jj_3R_86()) return true; + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(CLASS)) return true; + return false; + } + + final private boolean jj_3R_157() { + if (jj_3R_87()) return true; + return false; + } + + final private boolean jj_3R_156() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(RPAREN)) return true; + return false; + } + + final private boolean jj_3_29() { + if (jj_3R_84()) return true; + return false; + } + + final private boolean jj_3R_155() { + if (jj_scan_token(SUPER)) return true; + if (jj_scan_token(DOT)) return true; + if (jj_scan_token(IDENTIFIER)) return true; + return false; + } + + final private boolean jj_3R_197() { + if (jj_scan_token(IDENTIFIER)) return true; + if (jj_scan_token(DOT)) return true; + return false; + } + + final private boolean jj_3R_154() { + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_197()) { + jj_scanpos = xsp; + break; + } + } + if (jj_scan_token(THIS)) return true; + return false; + } + + final private boolean jj_3R_124() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_153()) { + jj_scanpos = xsp; + if (jj_3R_154()) { + jj_scanpos = xsp; + if (jj_3R_155()) { + jj_scanpos = xsp; + if (jj_3R_156()) { + jj_scanpos = xsp; + if (jj_3R_157()) { + jj_scanpos = xsp; + if (jj_3R_158()) { + jj_scanpos = xsp; + if (jj_3R_159()) return true; + } + } + } + } + } + } + return false; + } + + final private boolean jj_3R_153() { + if (jj_3R_196()) return true; + return false; + } + + final private boolean jj_3R_88() { + if (jj_scan_token(DOT)) return true; + if (jj_3R_78()) return true; + if (jj_scan_token(IDENTIFIER)) return true; + return false; + } + + final private boolean jj_3R_280() { + if (jj_3R_293()) return true; + return false; + } + + final private boolean jj_3_28() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_83()) return true; + return false; + } + + final private boolean jj_3R_90() { + if (jj_3R_124()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_29()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_319() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_3R_313()) return true; + return false; + } + + final private boolean jj_3R_318() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(RPAREN)) return true; + if (jj_3R_307()) return true; + return false; + } + + final private boolean jj_3R_317() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_318()) { + jj_scanpos = xsp; + if (jj_3R_319()) return true; + } + return false; + } + + final private boolean jj_3R_293() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(97)) { + jj_scanpos = xsp; + if (jj_scan_token(98)) return true; + } + return false; + } + + final private boolean jj_3_27() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(LBRACKET)) return true; + return false; + } + + final private boolean jj_3R_266() { + if (jj_3R_90()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_280()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_116() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(RPAREN)) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(88)) { + jj_scanpos = xsp; + if (jj_scan_token(87)) { + jj_scanpos = xsp; + if (jj_scan_token(75)) { + jj_scanpos = xsp; + if (jj_scan_token(72)) { + jj_scanpos = xsp; + if (jj_scan_token(52)) { + jj_scanpos = xsp; + if (jj_scan_token(49)) { + jj_scanpos = xsp; + if (jj_scan_token(39)) { + jj_scanpos = xsp; + if (jj_3R_152()) return true; + } + } + } + } + } + } + } + return false; + } + + final private boolean jj_3R_115() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_72()) return true; + if (jj_scan_token(LBRACKET)) return true; + if (jj_scan_token(RBRACKET)) return true; + return false; + } + + final private boolean jj_3R_82() { + Token xsp; + xsp = jj_scanpos; + if (jj_3_26()) { + jj_scanpos = xsp; + if (jj_3R_115()) { + jj_scanpos = xsp; + if (jj_3R_116()) return true; + } + } + return false; + } + + final private boolean jj_3_26() { + if (jj_scan_token(LPAREN)) return true; + if (jj_3R_83()) return true; + return false; + } + + final private boolean jj_3_25() { + if (jj_3R_82()) return true; + return false; + } + + final private boolean jj_3_24() { + if (jj_3R_81()) return true; + return false; + } + + final private boolean jj_3R_316() { + if (jj_3R_266()) return true; + return false; + } + + final private boolean jj_3R_315() { + if (jj_3R_317()) return true; + return false; + } + + final private boolean jj_3R_314() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(88)) { + jj_scanpos = xsp; + if (jj_scan_token(87)) return true; + } + if (jj_3R_307()) return true; + return false; + } + + final private boolean jj_3R_313() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_314()) { + jj_scanpos = xsp; + if (jj_3R_315()) { + jj_scanpos = xsp; + if (jj_3R_316()) return true; + } + } + return false; + } + + final private boolean jj_3R_264() { + if (jj_scan_token(DECR)) return true; + if (jj_3R_90()) return true; + return false; + } + + final private boolean jj_3R_306() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(99)) { + jj_scanpos = xsp; + if (jj_scan_token(100)) return true; + } + if (jj_3R_305()) return true; + return false; + } + + final private boolean jj_3R_308() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(101)) { + jj_scanpos = xsp; + if (jj_scan_token(102)) { + jj_scanpos = xsp; + if (jj_scan_token(106)) return true; + } + } + if (jj_3R_307()) return true; + return false; + } + + final private boolean jj_3_23() { + if (jj_3R_80()) return true; + return false; + } + + final private boolean jj_3R_263() { + if (jj_scan_token(INCR)) return true; + if (jj_3R_90()) return true; + return false; + } + + final private boolean jj_3R_312() { + if (jj_3R_313()) return true; + return false; + } + + final private boolean jj_3_22() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(107)) { + jj_scanpos = xsp; + if (jj_3_23()) { + jj_scanpos = xsp; + if (jj_3_24()) return true; + } + } + if (jj_3R_304()) return true; + return false; + } + + final private boolean jj_3R_311() { + if (jj_3R_264()) return true; + return false; + } + + final private boolean jj_3R_310() { + if (jj_3R_263()) return true; + return false; + } + + final private boolean jj_3R_309() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(99)) { + jj_scanpos = xsp; + if (jj_scan_token(100)) return true; + } + if (jj_3R_307()) return true; + return false; + } + + final private boolean jj_3R_307() { + Token xsp; + xsp = jj_scanpos; + if (jj_3R_309()) { + jj_scanpos = xsp; + if (jj_3R_310()) { + jj_scanpos = xsp; + if (jj_3R_311()) { + jj_scanpos = xsp; + if (jj_3R_312()) return true; + } + } + } + return false; + } + + final private boolean jj_3R_303() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(86)) { + jj_scanpos = xsp; + if (jj_scan_token(122)) { + jj_scanpos = xsp; + if (jj_scan_token(92)) { + jj_scanpos = xsp; + if (jj_scan_token(93)) return true; + } + } + } + if (jj_3R_302()) return true; + return false; + } + + final private boolean jj_3R_301() { + if (jj_scan_token(INSTANCEOF)) return true; + if (jj_3R_72()) return true; + return false; + } + + final private boolean jj_3R_305() { + if (jj_3R_307()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_308()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_298() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(91)) { + jj_scanpos = xsp; + if (jj_scan_token(94)) return true; + } + if (jj_3R_297()) return true; + return false; + } + + final private boolean jj_3R_304() { + if (jj_3R_305()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_306()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_302() { + if (jj_3R_304()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3_22()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_288() { + if (jj_scan_token(BIT_AND)) return true; + if (jj_3R_287()) return true; + return false; + } + + final private boolean jj_3R_300() { + if (jj_3R_302()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_303()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_254() { + if (jj_scan_token(BIT_OR)) return true; + if (jj_3R_253()) return true; + return false; + } + + final private boolean jj_3R_297() { + if (jj_3R_300()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_301()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_274() { + if (jj_scan_token(XOR)) return true; + if (jj_3R_273()) return true; + return false; + } + + final private boolean jj_3R_230() { + if (jj_scan_token(SC_AND)) return true; + if (jj_3R_229()) return true; + return false; + } + + final private boolean jj_3R_287() { + if (jj_3R_297()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_298()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_190() { + if (jj_scan_token(SC_OR)) return true; + if (jj_3R_189()) return true; + return false; + } + + final private boolean jj_3R_273() { + if (jj_3R_287()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_288()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_142() { + if (jj_scan_token(HOOK)) return true; + if (jj_3R_56()) return true; + if (jj_scan_token(COLON)) return true; + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_253() { + if (jj_3R_273()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_274()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_229() { + if (jj_3R_253()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_254()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_189() { + if (jj_3R_229()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_230()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_141() { + if (jj_3R_189()) return true; + Token xsp; + while (true) { + xsp = jj_scanpos; + if (jj_3R_190()) { + jj_scanpos = xsp; + break; + } + } + return false; + } + + final private boolean jj_3R_101() { + if (jj_3R_141()) return true; + Token xsp; + xsp = jj_scanpos; + if (jj_3R_142()) jj_scanpos = xsp; + return false; + } + + final private boolean jj_3R_265() { + if (jj_3R_90()) return true; + if (jj_3R_79()) return true; + if (jj_3R_56()) return true; + return false; + } + + final private boolean jj_3R_79() { + Token xsp; + xsp = jj_scanpos; + if (jj_scan_token(85)) { + jj_scanpos = xsp; + if (jj_scan_token(110)) { + jj_scanpos = xsp; + if (jj_scan_token(111)) { + jj_scanpos = xsp; + if (jj_scan_token(115)) { + jj_scanpos = xsp; + if (jj_scan_token(108)) { + jj_scanpos = xsp; + if (jj_scan_token(109)) { + jj_scanpos = xsp; + if (jj_scan_token(116)) { + jj_scanpos = xsp; + if (jj_scan_token(117)) { + jj_scanpos = xsp; + if (jj_scan_token(118)) { + jj_scanpos = xsp; + if (jj_scan_token(112)) { + jj_scanpos = xsp; + if (jj_scan_token(114)) { + jj_scanpos = xsp; + if (jj_scan_token(113)) + return true; + } + } + } + } + } + } + } + } + } + } + } + return false; + } + + final private boolean jj_3_21() { + if (jj_3R_79()) return true; + if (jj_3R_56()) return true; + return false; + } + + public JavaParserTokenManager token_source; + JavaCharStream jj_input_stream; + public Token token, jj_nt; + private int jj_ntk; + private Token jj_scanpos, jj_lastpos; + private int jj_la; + public boolean lookingAhead = false; + private boolean jj_semLA; + + public JavaParser(java.io.InputStream stream) { + this(stream, null); + } + + public JavaParser(java.io.InputStream stream, String encoding) { + try { + jj_input_stream = new JavaCharStream(stream, encoding, 1, 1); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + token_source = new JavaParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + } + + public void ReInit(java.io.InputStream stream) { + ReInit(stream, null); + } + + public void ReInit(java.io.InputStream stream, String encoding) { + try { + jj_input_stream.ReInit(stream, encoding, 1, 1); + } catch (java.io.UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + } + + public JavaParser(java.io.Reader stream) { + jj_input_stream = new JavaCharStream(stream, 1, 1); + token_source = new JavaParserTokenManager(jj_input_stream); + token = new Token(); + jj_ntk = -1; + } + + public void ReInit(java.io.Reader stream) { + jj_input_stream.ReInit(stream, 1, 1); + token_source.ReInit(jj_input_stream); + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + } + + public JavaParser(JavaParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + } + + public void ReInit(JavaParserTokenManager tm) { + token_source = tm; + token = new Token(); + jj_ntk = -1; + jjtree.reset(); + } + + final private Token jj_consume_token(int kind) throws ParseException { + Token oldToken; + if ((oldToken = token).next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + if (token.kind == kind) { + return token; + } + token = oldToken; + throw generateParseException(); + } + + static private final class LookaheadSuccess extends java.lang.Error { + } + + final private LookaheadSuccess jj_ls = new LookaheadSuccess(); + + final private boolean jj_scan_token(int kind) { + if (jj_scanpos == jj_lastpos) { + jj_la--; + if (jj_scanpos.next == null) { + jj_lastpos = jj_scanpos = jj_scanpos.next = token_source.getNextToken(); + } else { + jj_lastpos = jj_scanpos = jj_scanpos.next; + } + } else { + jj_scanpos = jj_scanpos.next; + } + if (jj_scanpos.kind != kind) return true; + if (jj_la == 0 && jj_scanpos == jj_lastpos) throw jj_ls; + return false; + } + + final public Token getNextToken() { + if (token.next != null) token = token.next; + else token = token.next = token_source.getNextToken(); + jj_ntk = -1; + return token; + } + + final public Token getToken(int index) { + Token t = lookingAhead ? jj_scanpos : token; + for (int i = 0; i < index; i++) { + if (t.next != null) t = t.next; + else t = t.next = token_source.getNextToken(); + } + return t; + } + + final private int jj_ntk() { + if ((jj_nt = token.next) == null) + return (jj_ntk = (token.next = token_source.getNextToken()).kind); + else + return (jj_ntk = jj_nt.kind); + } + + public ParseException generateParseException() { + Token errortok = token.next; + int line = errortok.beginLine, column = errortok.beginColumn; + String mess = (errortok.kind == 0) ? tokenImage[0] : errortok.image; + return new ParseException("Unable to parse Java code near token: " + mess, line, column); + } + + final public void enable_tracing() { + } + + final public void disable_tracing() { + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserConstants.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/JavaParserConstants.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserConstants.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserConstants.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,260 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. JavaParserConstants.java */ +package jaxx.parser; + +public interface JavaParserConstants { + + int EOF = 0; + int WHITE_SPACE = 3; + int SINGLE_LINE_COMMENT = 4; + int FORMAL_COMMENT = 5; + int MULTI_LINE_COMMENT = 6; + int ABSTRACT = 8; + int ASSERT = 9; + int BOOLEAN = 10; + int BREAK = 11; + int BYTE = 12; + int CASE = 13; + int CATCH = 14; + int CHAR = 15; + int CLASS = 16; + int CONST = 17; + int CONTINUE = 18; + int _DEFAULT = 19; + int DO = 20; + int DOUBLE = 21; + int ELSE = 22; + int ENUM = 23; + int EXTENDS = 24; + int FALSE = 25; + int FINAL = 26; + int FINALLY = 27; + int FLOAT = 28; + int FOR = 29; + int GOTO = 30; + int IF = 31; + int IMPLEMENTS = 32; + int IMPORT = 33; + int INSTANCEOF = 34; + int INT = 35; + int INTERFACE = 36; + int LONG = 37; + int NATIVE = 38; + int NEW = 39; + int NULL = 40; + int PACKAGE = 41; + int PRIVATE = 42; + int PROTECTED = 43; + int PUBLIC = 44; + int RETURN = 45; + int SHORT = 46; + int STATIC = 47; + int STRICTFP = 48; + int SUPER = 49; + int SWITCH = 50; + int SYNCHRONIZED = 51; + int THIS = 52; + int THROW = 53; + int THROWS = 54; + int TRANSIENT = 55; + int TRUE = 56; + int TRY = 57; + int VOID = 58; + int VOLATILE = 59; + int WHILE = 60; + int INTEGER_LITERAL = 61; + int DECIMAL_LITERAL = 62; + int HEX_LITERAL = 63; + int OCTAL_LITERAL = 64; + int FLOATING_POINT_LITERAL = 65; + int DECIMAL_FLOATING_POINT_LITERAL = 66; + int DECIMAL_EXPONENT = 67; + int HEXADECIMAL_FLOATING_POINT_LITERAL = 68; + int HEXADECIMAL_EXPONENT = 69; + int CHARACTER_LITERAL = 70; + int STRING_LITERAL = 71; + int IDENTIFIER = 72; + int LETTER = 73; + int PART_LETTER = 74; + int LPAREN = 75; + int RPAREN = 76; + int LBRACE = 77; + int RBRACE = 78; + int LBRACKET = 79; + int RBRACKET = 80; + int SEMICOLON = 81; + int COMMA = 82; + int DOT = 83; + int AT = 84; + int ASSIGN = 85; + int LT = 86; + int BANG = 87; + int TILDE = 88; + int HOOK = 89; + int COLON = 90; + int EQ = 91; + int LE = 92; + int GE = 93; + int NE = 94; + int SC_OR = 95; + int SC_AND = 96; + int INCR = 97; + int DECR = 98; + int PLUS = 99; + int MINUS = 100; + int STAR = 101; + int SLASH = 102; + int BIT_AND = 103; + int BIT_OR = 104; + int XOR = 105; + int REM = 106; + int LSHIFT = 107; + int PLUSASSIGN = 108; + int MINUSASSIGN = 109; + int STARASSIGN = 110; + int SLASHASSIGN = 111; + int ANDASSIGN = 112; + int ORASSIGN = 113; + int XORASSIGN = 114; + int REMASSIGN = 115; + int LSHIFTASSIGN = 116; + int RSIGNEDSHIFTASSIGN = 117; + int RUNSIGNEDSHIFTASSIGN = 118; + int ELLIPSIS = 119; + int RUNSIGNEDSHIFT = 120; + int RSIGNEDSHIFT = 121; + int GT = 122; + int STUFF_TO_IGNORE = 124; + + int DEFAULT = 0; + int IN_FORMAL_COMMENT = 1; + int IN_MULTI_LINE_COMMENT = 2; + + String[] tokenImage = { + "<EOF>", + "<token of kind 1>", + "\"/*\"", + "<WHITE_SPACE>", + "<SINGLE_LINE_COMMENT>", + "\"*/\"", + "\"*/\"", + "<token of kind 7>", + "\"abstract\"", + "\"assert\"", + "\"boolean\"", + "\"break\"", + "\"byte\"", + "\"case\"", + "\"catch\"", + "\"char\"", + "\"class\"", + "\"const\"", + "\"continue\"", + "\"default\"", + "\"do\"", + "\"double\"", + "\"else\"", + "\"enum\"", + "\"extends\"", + "\"false\"", + "\"final\"", + "\"finally\"", + "\"float\"", + "\"for\"", + "\"goto\"", + "\"if\"", + "\"implements\"", + "\"import\"", + "\"instanceof\"", + "\"int\"", + "\"interface\"", + "\"long\"", + "\"native\"", + "\"new\"", + "\"null\"", + "\"package\"", + "\"private\"", + "\"protected\"", + "\"public\"", + "\"return\"", + "\"short\"", + "\"static\"", + "\"strictfp\"", + "\"super\"", + "\"switch\"", + "\"synchronized\"", + "\"this\"", + "\"throw\"", + "\"throws\"", + "\"transient\"", + "\"true\"", + "\"try\"", + "\"void\"", + "\"volatile\"", + "\"while\"", + "<INTEGER_LITERAL>", + "<DECIMAL_LITERAL>", + "<HEX_LITERAL>", + "<OCTAL_LITERAL>", + "<FLOATING_POINT_LITERAL>", + "<DECIMAL_FLOATING_POINT_LITERAL>", + "<DECIMAL_EXPONENT>", + "<HEXADECIMAL_FLOATING_POINT_LITERAL>", + "<HEXADECIMAL_EXPONENT>", + "<CHARACTER_LITERAL>", + "<STRING_LITERAL>", + "<IDENTIFIER>", + "<LETTER>", + "<PART_LETTER>", + "\"(\"", + "\")\"", + "\"{\"", + "\"}\"", + "\"[\"", + "\"]\"", + "\";\"", + "\",\"", + "\".\"", + "\"@\"", + "\"=\"", + "\"<\"", + "\"!\"", + "\"~\"", + "\"?\"", + "\":\"", + "\"==\"", + "\"<=\"", + "\">=\"", + "\"!=\"", + "\"||\"", + "\"&&\"", + "\"++\"", + "\"--\"", + "\"+\"", + "\"-\"", + "\"*\"", + "\"/\"", + "\"&\"", + "\"|\"", + "\"^\"", + "\"%\"", + "\"<<\"", + "\"+=\"", + "\"-=\"", + "\"*=\"", + "\"/=\"", + "\"&=\"", + "\"|=\"", + "\"^=\"", + "\"%=\"", + "\"<<=\"", + "\">>=\"", + "\">>>=\"", + "\"...\"", + "\">>>\"", + "\">>\"", + "\">\"", + "\"\\u001a\"", + "<STUFF_TO_IGNORE>", + }; + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTokenManager.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/JavaParserTokenManager.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTokenManager.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTokenManager.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2072 @@ +/* Generated By:JJTree&JavaCC: Do not edit this line. JavaParserTokenManager.java */ +package jaxx.parser; + +public class JavaParserTokenManager implements JavaParserConstants { + public java.io.PrintStream debugStream = System.out; + + public void setDebugStream(java.io.PrintStream ds) { + debugStream = ds; + } + + private int jjStopStringLiteralDfa_0(int pos, long active0, long active1) { + switch (pos) { + case 0: + if ((active0 & 0x4L) != 0L || (active1 & 0x804000000000L) != 0L) + return 48; + if ((active1 & 0x80000000080000L) != 0L) + return 5; + if ((active0 & 0x1fffffffffffff00L) != 0L) { + jjmatchedKind = 72; + return 29; + } + return -1; + case 1: + if ((active0 & 0x4L) != 0L) + return 46; + if ((active0 & 0x1fffffff7fcfff00L) != 0L) { + if (jjmatchedPos != 1) { + jjmatchedKind = 72; + jjmatchedPos = 1; + } + return 29; + } + if ((active0 & 0x80300000L) != 0L) + return 29; + return -1; + case 2: + if ((active0 & 0x1dffff675fefff00L) != 0L) { + if (jjmatchedPos != 2) { + jjmatchedKind = 72; + jjmatchedPos = 2; + } + return 29; + } + if ((active0 & 0x200009820000000L) != 0L) + return 29; + return -1; + case 3: + if ((active0 & 0x18effe571f2f4f00L) != 0L) { + jjmatchedKind = 72; + jjmatchedPos = 3; + return 29; + } + if ((active0 & 0x510012040c0b000L) != 0L) + return 29; + return -1; + case 4: + if ((active0 & 0x88dbe57012c0700L) != 0L) { + if (jjmatchedPos != 4) { + jjmatchedKind = 72; + jjmatchedPos = 4; + } + return 29; + } + if ((active0 & 0x106240001e034800L) != 0L) + return 29; + return -1; + case 5: + if ((active0 & 0x8890e15090c0500L) != 0L) { + jjmatchedKind = 72; + jjmatchedPos = 5; + return 29; + } + if ((active0 & 0x44b04200200200L) != 0L) + return 29; + return -1; + case 6: + if ((active0 & 0x889081500040100L) != 0L) { + jjmatchedKind = 72; + jjmatchedPos = 6; + return 29; + } + if ((active0 & 0x60009080400L) != 0L) + return 29; + return -1; + case 7: + if ((active0 & 0x801000000040100L) != 0L) + return 29; + if ((active0 & 0x88081500000000L) != 0L) { + jjmatchedKind = 72; + jjmatchedPos = 7; + return 29; + } + return -1; + case 8: + if ((active0 & 0x8000500000000L) != 0L) { + jjmatchedKind = 72; + jjmatchedPos = 8; + return 29; + } + if ((active0 & 0x80081000000000L) != 0L) + return 29; + return -1; + case 9: + if ((active0 & 0x8000000000000L) != 0L) { + jjmatchedKind = 72; + jjmatchedPos = 9; + return 29; + } + if ((active0 & 0x500000000L) != 0L) + return 29; + return -1; + case 10: + if ((active0 & 0x8000000000000L) != 0L) { + jjmatchedKind = 72; + jjmatchedPos = 10; + return 29; + } + return -1; + default: + return -1; + } + } + + private int jjStartNfa_0(int pos, long active0, long active1) { + return jjMoveNfa_0(jjStopStringLiteralDfa_0(pos, active0, active1), pos + 1); + } + + private int jjStopAtPos(int pos, int kind) { + jjmatchedKind = kind; + jjmatchedPos = pos; + return pos + 1; + } + + private int jjStartNfaWithStates_0(int pos, int kind, int state) { + jjmatchedKind = kind; + jjmatchedPos = pos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return pos + 1; + } + return jjMoveNfa_0(state, pos + 1); + } + + private int jjMoveStringLiteralDfa0_0() { + switch (curChar) { + case 26: + return jjStopAtPos(0, 123); + case 33: + jjmatchedKind = 87; + return jjMoveStringLiteralDfa1_0(0x0L, 0x40000000L); + case 37: + jjmatchedKind = 106; + return jjMoveStringLiteralDfa1_0(0x0L, 0x8000000000000L); + case 38: + jjmatchedKind = 103; + return jjMoveStringLiteralDfa1_0(0x0L, 0x1000100000000L); + case 40: + return jjStopAtPos(0, 75); + case 41: + return jjStopAtPos(0, 76); + case 42: + jjmatchedKind = 101; + return jjMoveStringLiteralDfa1_0(0x0L, 0x400000000000L); + case 43: + jjmatchedKind = 99; + return jjMoveStringLiteralDfa1_0(0x0L, 0x100200000000L); + case 44: + return jjStopAtPos(0, 82); + case 45: + jjmatchedKind = 100; + return jjMoveStringLiteralDfa1_0(0x0L, 0x200400000000L); + case 46: + jjmatchedKind = 83; + return jjMoveStringLiteralDfa1_0(0x0L, 0x80000000000000L); + case 47: + jjmatchedKind = 102; + return jjMoveStringLiteralDfa1_0(0x4L, 0x800000000000L); + case 58: + return jjStopAtPos(0, 90); + case 59: + return jjStopAtPos(0, 81); + case 60: + jjmatchedKind = 86; + return jjMoveStringLiteralDfa1_0(0x0L, 0x10080010000000L); + case 61: + jjmatchedKind = 85; + return jjMoveStringLiteralDfa1_0(0x0L, 0x8000000L); + case 62: + jjmatchedKind = 122; + return jjMoveStringLiteralDfa1_0(0x0L, 0x360000020000000L); + case 63: + return jjStopAtPos(0, 89); + case 64: + return jjStopAtPos(0, 84); + case 91: + return jjStopAtPos(0, 79); + case 93: + return jjStopAtPos(0, 80); + case 94: + jjmatchedKind = 105; + return jjMoveStringLiteralDfa1_0(0x0L, 0x4000000000000L); + case 97: + return jjMoveStringLiteralDfa1_0(0x300L, 0x0L); + case 98: + return jjMoveStringLiteralDfa1_0(0x1c00L, 0x0L); + case 99: + return jjMoveStringLiteralDfa1_0(0x7e000L, 0x0L); + case 100: + return jjMoveStringLiteralDfa1_0(0x380000L, 0x0L); + case 101: + return jjMoveStringLiteralDfa1_0(0x1c00000L, 0x0L); + case 102: + return jjMoveStringLiteralDfa1_0(0x3e000000L, 0x0L); + case 103: + return jjMoveStringLiteralDfa1_0(0x40000000L, 0x0L); + case 105: + return jjMoveStringLiteralDfa1_0(0x1f80000000L, 0x0L); + case 108: + return jjMoveStringLiteralDfa1_0(0x2000000000L, 0x0L); + case 110: + return jjMoveStringLiteralDfa1_0(0x1c000000000L, 0x0L); + case 112: + return jjMoveStringLiteralDfa1_0(0x1e0000000000L, 0x0L); + case 114: + return jjMoveStringLiteralDfa1_0(0x200000000000L, 0x0L); + case 115: + return jjMoveStringLiteralDfa1_0(0xfc00000000000L, 0x0L); + case 116: + return jjMoveStringLiteralDfa1_0(0x3f0000000000000L, 0x0L); + case 118: + return jjMoveStringLiteralDfa1_0(0xc00000000000000L, 0x0L); + case 119: + return jjMoveStringLiteralDfa1_0(0x1000000000000000L, 0x0L); + case 123: + return jjStopAtPos(0, 77); + case 124: + jjmatchedKind = 104; + return jjMoveStringLiteralDfa1_0(0x0L, 0x2000080000000L); + case 125: + return jjStopAtPos(0, 78); + case 126: + return jjStopAtPos(0, 88); + default: + return jjMoveNfa_0(1, 0); + } + } + + private int jjMoveStringLiteralDfa1_0(long active0, long active1) { + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(0, active0, active1); + return 1; + } + switch (curChar) { + case 38: + if ((active1 & 0x100000000L) != 0L) + return jjStopAtPos(1, 96); + break; + case 42: + if ((active0 & 0x4L) != 0L) + return jjStartNfaWithStates_0(1, 2, 46); + break; + case 43: + if ((active1 & 0x200000000L) != 0L) + return jjStopAtPos(1, 97); + break; + case 45: + if ((active1 & 0x400000000L) != 0L) + return jjStopAtPos(1, 98); + break; + case 46: + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x80000000000000L); + case 60: + if ((active1 & 0x80000000000L) != 0L) { + jjmatchedKind = 107; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x10000000000000L); + case 61: + if ((active1 & 0x8000000L) != 0L) + return jjStopAtPos(1, 91); + else if ((active1 & 0x10000000L) != 0L) + return jjStopAtPos(1, 92); + else if ((active1 & 0x20000000L) != 0L) + return jjStopAtPos(1, 93); + else if ((active1 & 0x40000000L) != 0L) + return jjStopAtPos(1, 94); + else if ((active1 & 0x100000000000L) != 0L) + return jjStopAtPos(1, 108); + else if ((active1 & 0x200000000000L) != 0L) + return jjStopAtPos(1, 109); + else if ((active1 & 0x400000000000L) != 0L) + return jjStopAtPos(1, 110); + else if ((active1 & 0x800000000000L) != 0L) + return jjStopAtPos(1, 111); + else if ((active1 & 0x1000000000000L) != 0L) + return jjStopAtPos(1, 112); + else if ((active1 & 0x2000000000000L) != 0L) + return jjStopAtPos(1, 113); + else if ((active1 & 0x4000000000000L) != 0L) + return jjStopAtPos(1, 114); + else if ((active1 & 0x8000000000000L) != 0L) + return jjStopAtPos(1, 115); + break; + case 62: + if ((active1 & 0x200000000000000L) != 0L) { + jjmatchedKind = 121; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0L, active1, 0x160000000000000L); + case 97: + return jjMoveStringLiteralDfa2_0(active0, 0x24002006000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa2_0(active0, 0x100L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa2_0(active0, 0x208000080000L, active1, 0L); + case 102: + if ((active0 & 0x80000000L) != 0L) + return jjStartNfaWithStates_0(1, 31, 29); + break; + case 104: + return jjMoveStringLiteralDfa2_0(active0, 0x1070400000008000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa2_0(active0, 0xc000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa2_0(active0, 0x10410000L, active1, 0L); + case 109: + return jjMoveStringLiteralDfa2_0(active0, 0x300000000L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa2_0(active0, 0x1c00800000L, active1, 0L); + case 111: + if ((active0 & 0x100000L) != 0L) { + jjmatchedKind = 20; + jjmatchedPos = 1; + } + return jjMoveStringLiteralDfa2_0(active0, 0xc00002060260400L, active1, 0L); + case 114: + return jjMoveStringLiteralDfa2_0(active0, 0x3800c0000000800L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa2_0(active0, 0x200L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa2_0(active0, 0x1800000000000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa2_0(active0, 0x2110000000000L, active1, 0L); + case 119: + return jjMoveStringLiteralDfa2_0(active0, 0x4000000000000L, active1, 0L); + case 120: + return jjMoveStringLiteralDfa2_0(active0, 0x1000000L, active1, 0L); + case 121: + return jjMoveStringLiteralDfa2_0(active0, 0x8000000001000L, active1, 0L); + case 124: + if ((active1 & 0x80000000L) != 0L) + return jjStopAtPos(1, 95); + break; + default: + break; + } + return jjStartNfa_0(0, active0, active1); + } + + private int jjMoveStringLiteralDfa2_0(long old0, long active0, long old1, long active1) { + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(0, old0, old1); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(1, active0, active1); + return 2; + } + switch (curChar) { + case 46: + if ((active1 & 0x80000000000000L) != 0L) + return jjStopAtPos(2, 119); + break; + case 61: + if ((active1 & 0x10000000000000L) != 0L) + return jjStopAtPos(2, 116); + else if ((active1 & 0x20000000000000L) != 0L) + return jjStopAtPos(2, 117); + break; + case 62: + if ((active1 & 0x100000000000000L) != 0L) { + jjmatchedKind = 120; + jjmatchedPos = 2; + } + return jjMoveStringLiteralDfa3_0(active0, 0L, active1, 0x40000000000000L); + case 97: + return jjMoveStringLiteralDfa3_0(active0, 0x80800000018000L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa3_0(active0, 0x100000000000L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa3_0(active0, 0x20000000000L, active1, 0L); + case 101: + return jjMoveStringLiteralDfa3_0(active0, 0x800L, active1, 0L); + case 102: + return jjMoveStringLiteralDfa3_0(active0, 0x80000L, active1, 0L); + case 105: + return jjMoveStringLiteralDfa3_0(active0, 0x1414040000000000L, active1, 0L); + case 108: + return jjMoveStringLiteralDfa3_0(active0, 0x800010002000000L, active1, 0L); + case 110: + return jjMoveStringLiteralDfa3_0(active0, 0x800200c060000L, active1, 0L); + case 111: + return jjMoveStringLiteralDfa3_0(active0, 0x480010000400L, active1, 0L); + case 112: + return jjMoveStringLiteralDfa3_0(active0, 0x2000300000000L, active1, 0L); + case 114: + if ((active0 & 0x20000000L) != 0L) + return jjStartNfaWithStates_0(2, 29, 29); + return jjMoveStringLiteralDfa3_0(active0, 0x61000000000000L, active1, 0L); + case 115: + return jjMoveStringLiteralDfa3_0(active0, 0x400402300L, active1, 0L); + case 116: + if ((active0 & 0x800000000L) != 0L) { + jjmatchedKind = 35; + jjmatchedPos = 2; + } + return jjMoveStringLiteralDfa3_0(active0, 0x205041005000L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa3_0(active0, 0x100000000a00000L, active1, 0L); + case 119: + if ((active0 & 0x8000000000L) != 0L) + return jjStartNfaWithStates_0(2, 39, 29); + break; + case 121: + if ((active0 & 0x200000000000000L) != 0L) + return jjStartNfaWithStates_0(2, 57, 29); + break; + default: + break; + } + return jjStartNfa_0(1, active0, active1); + } + + private int jjMoveStringLiteralDfa3_0(long old0, long active0, long old1, long active1) { + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(1, old0, old1); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(2, active0, active1); + return 3; + } + switch (curChar) { + case 61: + if ((active1 & 0x40000000000000L) != 0L) + return jjStopAtPos(3, 118); + break; + case 97: + return jjMoveStringLiteralDfa4_0(active0, 0x80000001c080800L, active1, 0L); + case 98: + return jjMoveStringLiteralDfa4_0(active0, 0x200000L, active1, 0L); + case 99: + return jjMoveStringLiteralDfa4_0(active0, 0x8000000004000L, active1, 0L); + case 100: + if ((active0 & 0x400000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 58, 29); + break; + case 101: + if ((active0 & 0x1000L) != 0L) + return jjStartNfaWithStates_0(3, 12, 29); + else if ((active0 & 0x2000L) != 0L) + return jjStartNfaWithStates_0(3, 13, 29); + else if ((active0 & 0x400000L) != 0L) + return jjStartNfaWithStates_0(3, 22, 29); + else if ((active0 & 0x100000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 56, 29); + return jjMoveStringLiteralDfa4_0(active0, 0x2001001000200L, active1, 0L); + case 103: + if ((active0 & 0x2000000000L) != 0L) + return jjStartNfaWithStates_0(3, 37, 29); + break; + case 105: + return jjMoveStringLiteralDfa4_0(active0, 0x1004000000000L, active1, 0L); + case 107: + return jjMoveStringLiteralDfa4_0(active0, 0x20000000000L, active1, 0L); + case 108: + if ((active0 & 0x10000000000L) != 0L) + return jjStartNfaWithStates_0(3, 40, 29); + return jjMoveStringLiteralDfa4_0(active0, 0x1000100100000400L, active1, 0L); + case 109: + if ((active0 & 0x800000L) != 0L) + return jjStartNfaWithStates_0(3, 23, 29); + break; + case 110: + return jjMoveStringLiteralDfa4_0(active0, 0x80000000000000L, active1, 0L); + case 111: + if ((active0 & 0x40000000L) != 0L) + return jjStartNfaWithStates_0(3, 30, 29); + return jjMoveStringLiteralDfa4_0(active0, 0x60000200000000L, active1, 0L); + case 114: + if ((active0 & 0x8000L) != 0L) + return jjStartNfaWithStates_0(3, 15, 29); + return jjMoveStringLiteralDfa4_0(active0, 0x400000000000L, active1, 0L); + case 115: + if ((active0 & 0x10000000000000L) != 0L) + return jjStartNfaWithStates_0(3, 52, 29); + return jjMoveStringLiteralDfa4_0(active0, 0x2030000L, active1, 0L); + case 116: + return jjMoveStringLiteralDfa4_0(active0, 0x4880400040100L, active1, 0L); + case 117: + return jjMoveStringLiteralDfa4_0(active0, 0x200000000000L, active1, 0L); + case 118: + return jjMoveStringLiteralDfa4_0(active0, 0x40000000000L, active1, 0L); + default: + break; + } + return jjStartNfa_0(2, active0, active1); + } + + private int jjMoveStringLiteralDfa4_0(long old0, long active0, long old1, long active1) { + if (((active0 &= old0) | (active1 &= old1)) == 0L) + return jjStartNfa_0(2, old0, old1); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(3, active0, 0L); + return 4; + } + switch (curChar) { + case 97: + return jjMoveStringLiteralDfa5_0(active0, 0x60400000000L); + case 99: + return jjMoveStringLiteralDfa5_0(active0, 0x5000000000000L); + case 101: + if ((active0 & 0x2000000L) != 0L) + return jjStartNfaWithStates_0(4, 25, 29); + else if ((active0 & 0x1000000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 60, 29); + return jjMoveStringLiteralDfa5_0(active0, 0x80100000400L); + case 104: + if ((active0 & 0x4000L) != 0L) + return jjStartNfaWithStates_0(4, 14, 29); + return jjMoveStringLiteralDfa5_0(active0, 0x8000000000000L); + case 105: + return jjMoveStringLiteralDfa5_0(active0, 0x900000040000L); + case 107: + if ((active0 & 0x800L) != 0L) + return jjStartNfaWithStates_0(4, 11, 29); + break; + case 108: + if ((active0 & 0x4000000L) != 0L) { + jjmatchedKind = 26; + jjmatchedPos = 4; + } + return jjMoveStringLiteralDfa5_0(active0, 0x8200000L); + case 110: + return jjMoveStringLiteralDfa5_0(active0, 0x1000000L); + case 114: + if ((active0 & 0x2000000000000L) != 0L) + return jjStartNfaWithStates_0(4, 49, 29); + return jjMoveStringLiteralDfa5_0(active0, 0x201200000300L); + case 115: + if ((active0 & 0x10000L) != 0L) + return jjStartNfaWithStates_0(4, 16, 29); + return jjMoveStringLiteralDfa5_0(active0, 0x80000000000000L); + case 116: + if ((active0 & 0x20000L) != 0L) + return jjStartNfaWithStates_0(4, 17, 29); + else if ((active0 & 0x10000000L) != 0L) + return jjStartNfaWithStates_0(4, 28, 29); + else if ((active0 & 0x400000000000L) != 0L) + return jjStartNfaWithStates_0(4, 46, 29); + return jjMoveStringLiteralDfa5_0(active0, 0x800000000000000L); + case 117: + return jjMoveStringLiteralDfa5_0(active0, 0x80000L); + case 118: + return jjMoveStringLiteralDfa5_0(active0, 0x4000000000L); + case 119: + if ((active0 & 0x20000000000000L) != 0L) { + jjmatchedKind = 53; + jjmatchedPos = 4; + } + return jjMoveStringLiteralDfa5_0(active0, 0x40000000000000L); + default: + break; + } + return jjStartNfa_0(3, active0, 0L); + } + + private int jjMoveStringLiteralDfa5_0(long old0, long active0) { + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(3, old0, 0L); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(4, active0, 0L); + return 5; + } + switch (curChar) { + case 97: + return jjMoveStringLiteralDfa6_0(active0, 0x500L); + case 99: + if ((active0 & 0x100000000000L) != 0L) + return jjStartNfaWithStates_0(5, 44, 29); + else if ((active0 & 0x800000000000L) != 0L) + return jjStartNfaWithStates_0(5, 47, 29); + return jjMoveStringLiteralDfa6_0(active0, 0x80000000000L); + case 100: + return jjMoveStringLiteralDfa6_0(active0, 0x1000000L); + case 101: + if ((active0 & 0x200000L) != 0L) + return jjStartNfaWithStates_0(5, 21, 29); + else if ((active0 & 0x4000000000L) != 0L) + return jjStartNfaWithStates_0(5, 38, 29); + break; + case 102: + return jjMoveStringLiteralDfa6_0(active0, 0x1000000000L); + case 103: + return jjMoveStringLiteralDfa6_0(active0, 0x20000000000L); + case 104: + if ((active0 & 0x4000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 50, 29); + break; + case 105: + return jjMoveStringLiteralDfa6_0(active0, 0x880000000000000L); + case 108: + return jjMoveStringLiteralDfa6_0(active0, 0x8080000L); + case 109: + return jjMoveStringLiteralDfa6_0(active0, 0x100000000L); + case 110: + if ((active0 & 0x200000000000L) != 0L) + return jjStartNfaWithStates_0(5, 45, 29); + return jjMoveStringLiteralDfa6_0(active0, 0x400040000L); + case 114: + return jjMoveStringLiteralDfa6_0(active0, 0x8000000000000L); + case 115: + if ((active0 & 0x40000000000000L) != 0L) + return jjStartNfaWithStates_0(5, 54, 29); + break; + case 116: + if ((active0 & 0x200L) != 0L) + return jjStartNfaWithStates_0(5, 9, 29); + else if ((active0 & 0x200000000L) != 0L) + return jjStartNfaWithStates_0(5, 33, 29); + return jjMoveStringLiteralDfa6_0(active0, 0x1040000000000L); + default: + break; + } + return jjStartNfa_0(4, active0, 0L); + } + + private int jjMoveStringLiteralDfa6_0(long old0, long active0) { + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(4, old0, 0L); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(5, active0, 0L); + return 6; + } + switch (curChar) { + case 97: + return jjMoveStringLiteralDfa7_0(active0, 0x1000000000L); + case 99: + return jjMoveStringLiteralDfa7_0(active0, 0x400000100L); + case 101: + if ((active0 & 0x20000000000L) != 0L) + return jjStartNfaWithStates_0(6, 41, 29); + else if ((active0 & 0x40000000000L) != 0L) + return jjStartNfaWithStates_0(6, 42, 29); + return jjMoveStringLiteralDfa7_0(active0, 0x80000100000000L); + case 102: + return jjMoveStringLiteralDfa7_0(active0, 0x1000000000000L); + case 108: + return jjMoveStringLiteralDfa7_0(active0, 0x800000000000000L); + case 110: + if ((active0 & 0x400L) != 0L) + return jjStartNfaWithStates_0(6, 10, 29); + break; + case 111: + return jjMoveStringLiteralDfa7_0(active0, 0x8000000000000L); + case 115: + if ((active0 & 0x1000000L) != 0L) + return jjStartNfaWithStates_0(6, 24, 29); + break; + case 116: + if ((active0 & 0x80000L) != 0L) + return jjStartNfaWithStates_0(6, 19, 29); + return jjMoveStringLiteralDfa7_0(active0, 0x80000000000L); + case 117: + return jjMoveStringLiteralDfa7_0(active0, 0x40000L); + case 121: + if ((active0 & 0x8000000L) != 0L) + return jjStartNfaWithStates_0(6, 27, 29); + break; + default: + break; + } + return jjStartNfa_0(5, active0, 0L); + } + + private int jjMoveStringLiteralDfa7_0(long old0, long active0) { + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(5, old0, 0L); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(6, active0, 0L); + return 7; + } + switch (curChar) { + case 99: + return jjMoveStringLiteralDfa8_0(active0, 0x1000000000L); + case 101: + if ((active0 & 0x40000L) != 0L) + return jjStartNfaWithStates_0(7, 18, 29); + else if ((active0 & 0x800000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 59, 29); + return jjMoveStringLiteralDfa8_0(active0, 0x80400000000L); + case 110: + return jjMoveStringLiteralDfa8_0(active0, 0x88000100000000L); + case 112: + if ((active0 & 0x1000000000000L) != 0L) + return jjStartNfaWithStates_0(7, 48, 29); + break; + case 116: + if ((active0 & 0x100L) != 0L) + return jjStartNfaWithStates_0(7, 8, 29); + break; + default: + break; + } + return jjStartNfa_0(6, active0, 0L); + } + + private int jjMoveStringLiteralDfa8_0(long old0, long active0) { + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(6, old0, 0L); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(7, active0, 0L); + return 8; + } + switch (curChar) { + case 100: + if ((active0 & 0x80000000000L) != 0L) + return jjStartNfaWithStates_0(8, 43, 29); + break; + case 101: + if ((active0 & 0x1000000000L) != 0L) + return jjStartNfaWithStates_0(8, 36, 29); + break; + case 105: + return jjMoveStringLiteralDfa9_0(active0, 0x8000000000000L); + case 111: + return jjMoveStringLiteralDfa9_0(active0, 0x400000000L); + case 116: + if ((active0 & 0x80000000000000L) != 0L) + return jjStartNfaWithStates_0(8, 55, 29); + return jjMoveStringLiteralDfa9_0(active0, 0x100000000L); + default: + break; + } + return jjStartNfa_0(7, active0, 0L); + } + + private int jjMoveStringLiteralDfa9_0(long old0, long active0) { + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(7, old0, 0L); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(8, active0, 0L); + return 9; + } + switch (curChar) { + case 102: + if ((active0 & 0x400000000L) != 0L) + return jjStartNfaWithStates_0(9, 34, 29); + break; + case 115: + if ((active0 & 0x100000000L) != 0L) + return jjStartNfaWithStates_0(9, 32, 29); + break; + case 122: + return jjMoveStringLiteralDfa10_0(active0, 0x8000000000000L); + default: + break; + } + return jjStartNfa_0(8, active0, 0L); + } + + private int jjMoveStringLiteralDfa10_0(long old0, long active0) { + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(8, old0, 0L); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(9, active0, 0L); + return 10; + } + switch (curChar) { + case 101: + return jjMoveStringLiteralDfa11_0(active0, 0x8000000000000L); + default: + break; + } + return jjStartNfa_0(9, active0, 0L); + } + + private int jjMoveStringLiteralDfa11_0(long old0, long active0) { + if (((active0 &= old0)) == 0L) + return jjStartNfa_0(9, old0, 0L); + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + jjStopStringLiteralDfa_0(10, active0, 0L); + return 11; + } + switch (curChar) { + case 100: + if ((active0 & 0x8000000000000L) != 0L) + return jjStartNfaWithStates_0(11, 51, 29); + break; + default: + break; + } + return jjStartNfa_0(10, active0, 0L); + } + + private void jjCheckNAdd(int state) { + if (jjrounds[state] != jjround) { + jjstateSet[jjnewStateCnt++] = state; + jjrounds[state] = jjround; + } + } + + private void jjAddStates(int start, int end) { + do { + jjstateSet[jjnewStateCnt++] = jjnextStates[start]; + } while (start++ != end); + } + + private void jjCheckNAddTwoStates(int state1, int state2) { + jjCheckNAdd(state1); + jjCheckNAdd(state2); + } + + private void jjCheckNAddStates(int start, int end) { + do { + jjCheckNAdd(jjnextStates[start]); + } while (start++ != end); + } + + private void jjCheckNAddStates(int start) { + jjCheckNAdd(jjnextStates[start]); + jjCheckNAdd(jjnextStates[start + 1]); + } + + static final long[] jjbitVec0 = { + 0xfffffffffffffffeL, 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffffffffffffL + }; + static final long[] jjbitVec2 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0xffffffffffffffffL + }; + static final long[] jjbitVec3 = { + 0xfff0000000200002L, 0xffffffffffffdfffL, 0xfffff00f7fffffffL, 0x12000000007fffffL + }; + static final long[] jjbitVec4 = { + 0x0L, 0x0L, 0x420043c00000000L, 0xff7fffffff7fffffL + }; + static final long[] jjbitVec5 = { + 0xffffcffffffffL, 0xffffffffffff0000L, 0xf9ff3fffffffffffL, 0x401f00030003L + }; + static final long[] jjbitVec6 = { + 0x0L, 0x400000000000000L, 0xfffffffbffffd740L, 0xffffffcff7fffL + }; + static final long[] jjbitVec7 = { + 0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffffff003L, 0x33fffffffff199fL + }; + static final long[] jjbitVec8 = { + 0xfffe000000000000L, 0xfffffffe027fffffL, 0xffL, 0x707ffffff0000L + }; + static final long[] jjbitVec9 = { + 0x7fffffe00000000L, 0xfffe0000000007ffL, 0xffffffffffffffffL, 0x1c000060002fffffL + }; + static final long[] jjbitVec10 = { + 0x1ffffffd0000L, 0x0L, 0x3fffffffffL, 0x0L + }; + static final long[] jjbitVec11 = { + 0x23ffffffffffffe0L, 0x3ff010000L, 0x3c5fdfffff99fe0L, 0xf0003b0000000L + }; + static final long[] jjbitVec12 = { + 0x36dfdfffff987e0L, 0x1c00005e000000L, 0x23edfdfffffbafe0L, 0x100010000L + }; + static final long[] jjbitVec13 = { + 0x23cdfdfffff99fe0L, 0x3b0000000L, 0x3bfc718d63dc7e0L, 0x0L + }; + static final long[] jjbitVec14 = { + 0x3effdfffffddfe0L, 0x300000000L, 0x3effdfffffddfe0L, 0x340000000L + }; + static final long[] jjbitVec15 = { + 0x3fffdfffffddfe0L, 0x300000000L, 0x2ffbfffffc7fffe0L, 0x7fL + }; + static final long[] jjbitVec16 = { + 0x800dfffffffffffeL, 0x7fL, 0x200decaefef02596L, 0x3000005fL + }; + static final long[] jjbitVec17 = { + 0x1L, 0x7fffffffeffL, 0xf00L, 0x0L + }; + static final long[] jjbitVec18 = { + 0x6fbffffffffL, 0x3f0000L, 0xffffffff00000000L, 0x7fffffffff003fL + }; + static final long[] jjbitVec19 = { + 0xffffffffffffffffL, 0xffffffff83ffffffL, 0xffffff07ffffffffL, 0x3ffffffffffffffL + }; + static final long[] jjbitVec20 = { + 0xffffffffffffff7fL, 0xffffffff3d7f3d7fL, 0x7f3d7fffffff3d7fL, 0xffff7fffff7f7f3dL + }; + static final long[] jjbitVec21 = { + 0xffffffff7f3d7fffL, 0x7ffff7fL, 0xffffffff00000000L, 0x1fffffffffffffL + }; + static final long[] jjbitVec22 = { + 0xffffffffffffffffL, 0x7f9fffffffffffL, 0xffffffff07fffffeL, 0x7ffffffffffL + }; + static final long[] jjbitVec23 = { + 0x0L, 0x0L, 0xfffffffffffffL, 0x8000000L + }; + static final long[] jjbitVec24 = { + 0xffffffff00000000L, 0xffffffffffffffL, 0x1ffffffffffL, 0x0L + }; + static final long[] jjbitVec25 = { + 0xffffffffffffffffL, 0xffffffffffffffffL, 0xffffffff0fffffffL, 0x3ffffffffffffffL + }; + static final long[] jjbitVec26 = { + 0xffffffff3f3fffffL, 0x3fffffffaaff3f3fL, 0x5fdfffffffffffffL, 0x1fdc1fff0fcf1fdcL + }; + static final long[] jjbitVec27 = { + 0x8000000000000000L, 0x8000000000000001L, 0xffff00000000L, 0x0L + }; + static final long[] jjbitVec28 = { + 0x3fbbd503e2ffc84L, 0xffffffff00000000L, 0xfL, 0x0L + }; + static final long[] jjbitVec29 = { + 0x73e03fe000000e0L, 0xfffffffffffffffeL, 0xfffffffe601fffffL, 0x7fffffffffffffffL + }; + static final long[] jjbitVec30 = { + 0xfffe1fffffffffe0L, 0xffffffffffffffffL, 0xffffff00007fffL, 0x0L + }; + static final long[] jjbitVec31 = { + 0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffffffL, 0x0L + }; + static final long[] jjbitVec32 = { + 0xffffffffffffffffL, 0xffffffffffffffffL, 0x3fffffffffL, 0x0L + }; + static final long[] jjbitVec33 = { + 0xffffffffffffffffL, 0xffffffffffffffffL, 0x1fffL, 0x0L + }; + static final long[] jjbitVec34 = { + 0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffL, 0x0L + }; + static final long[] jjbitVec35 = { + 0x3fffffffffffL, 0x0L, 0x0L, 0x0L + }; + static final long[] jjbitVec36 = { + 0x5f7ffdffa0f8007fL, 0xffffffffffffffdbL, 0x3ffffffffffffL, 0xfffffffffff80000L + }; + static final long[] jjbitVec37 = { + 0x3fffffffffffffffL, 0xffffffffffff0000L, 0xfffffffffffcffffL, 0xfff0000000000ffL + }; + static final long[] jjbitVec38 = { + 0x18000000000000L, 0xffd702000000e000L, 0xffffffffffffffffL, 0x1fffffffffffffffL + }; + static final long[] jjbitVec39 = { + 0x87fffffe00000010L, 0xffffffe007fffffeL, 0x7fffffffffffffffL, 0x631cfcfcfcL + }; + static final long[] jjbitVec40 = { + 0x0L, 0x0L, 0x420043cffffffffL, 0xff7fffffff7fffffL + }; + static final long[] jjbitVec41 = { + 0xffffffffffffffffL, 0x400000700007fffL, 0xfffffffbffffd740L, 0xffffffcff7fffL + }; + static final long[] jjbitVec42 = { + 0xffffffffffffffffL, 0xffffffffffffffffL, 0xfffffffffffff07bL, 0x33fffffffff199fL + }; + static final long[] jjbitVec43 = { + 0xfffe000000000000L, 0xfffffffe027fffffL, 0xbbfffffbfffe00ffL, 0x707ffffff0016L + }; + static final long[] jjbitVec44 = { + 0x7fffffe00000000L, 0xffff03ff003fffffL, 0xffffffffffffffffL, 0x1fff3dff9fefffffL + }; + static final long[] jjbitVec45 = { + 0xffff1fffffff8000L, 0x7ffL, 0x1ffffffffffffL, 0x0L + }; + static final long[] jjbitVec46 = { + 0xf3ffffffffffffeeL, 0xffcfff1f3fffL, 0xd3c5fdfffff99feeL, 0xfffcfb080399fL + }; + static final long[] jjbitVec47 = { + 0xd36dfdfffff987e4L, 0x1fffc05e003987L, 0xf3edfdfffffbafeeL, 0xffc100013bbfL + }; + static final long[] jjbitVec48 = { + 0xf3cdfdfffff99feeL, 0xffc3b0c0398fL, 0xc3bfc718d63dc7ecL, 0xff8000803dc7L + }; + static final long[] jjbitVec49 = { + 0xc3effdfffffddfeeL, 0xffc300603ddfL, 0xc3effdfffffddfecL, 0xffc340603ddfL + }; + static final long[] jjbitVec50 = { + 0xc3fffdfffffddfecL, 0xffc300803dcfL, 0x2ffbfffffc7fffecL, 0xc0000ff5f847fL + }; + static final long[] jjbitVec51 = { + 0x87fffffffffffffeL, 0x3ff7fffL, 0x3bffecaefef02596L, 0x33ff3f5fL + }; + static final long[] jjbitVec52 = { + 0xc2a003ff03000001L, 0xfffe07fffffffeffL, 0x1ffffffffeff0fdfL, 0x40L + }; + static final long[] jjbitVec53 = { + 0x3c7f6fbffffffffL, 0x3ff03ffL, 0xffffffff00000000L, 0x7fffffffff003fL + }; + static final long[] jjbitVec54 = { + 0xffffffff7f3d7fffL, 0x3fe0007ffff7fL, 0xffffffff00000000L, 0x1fffffffffffffL + }; + static final long[] jjbitVec55 = { + 0x0L, 0x0L, 0xffffffffffffffffL, 0x3ff080fffffL + }; + static final long[] jjbitVec56 = { + 0xffffffff03ff7800L, 0xffffffffffffffL, 0x3ffffffffffL, 0x0L + }; + static final long[] jjbitVec57 = { + 0x80007c000000f000L, 0x8000fc0000000001L, 0xffff00000000L, 0x21fff0000L + }; + static final long[] jjbitVec58 = { + 0x73efffe000000e0L, 0xfffffffffffffffeL, 0xfffffffe661fffffL, 0x7fffffffffffffffL + }; + static final long[] jjbitVec59 = { + 0x5f7ffdffe0f8007fL, 0xffffffffffffffdbL, 0x3ffffffffffffL, 0xfffffffffff80000L + }; + static final long[] jjbitVec60 = { + 0x18000f00000000L, 0xffd702000000e000L, 0xffffffffffffffffL, 0x9fffffffffffffffL + }; + static final long[] jjbitVec61 = { + 0x87fffffe03ff0010L, 0xffffffe007fffffeL, 0x7fffffffffffffffL, 0xe0000631cfcfcfcL + }; + + private int jjMoveNfa_0(int startState, int curPos) { + int[] nextStates; + int startsAt = 0; + jjnewStateCnt = 71; + int i = 1; + jjstateSet[0] = startState; + int j, kind = 0x7fffffff; + for (; ;) { + if (++jjround == 0x7fffffff) + ReInitRounds(); + if (curChar < 64) { + long l = 1L << curChar; + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 1: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(0, 6); + else if ((0x100003600L & l) != 0L) { + if (kind > 3) + kind = 3; + jjCheckNAdd(0); + } else if (curChar == 47) + jjAddStates(7, 8); + else if (curChar == 36) { + if (kind > 72) + kind = 72; + jjCheckNAdd(29); + } else if (curChar == 34) + jjCheckNAddStates(9, 11); + else if (curChar == 39) + jjAddStates(12, 13); + else if (curChar == 46) + jjCheckNAdd(5); + if ((0x3fe000000000000L & l) != 0L) { + if (kind > 61) + kind = 61; + jjCheckNAddTwoStates(2, 3); + } else if (curChar == 48) { + if (kind > 61) + kind = 61; + jjCheckNAddStates(14, 18); + } + break; + case 48: + if (curChar == 47) { + if (kind > 4) + kind = 4; + jjCheckNAddStates(19, 21); + } else if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 46; + break; + case 0: + if ((0x100003600L & l) == 0L) + break; + if (kind > 3) + kind = 3; + jjCheckNAdd(0); + break; + case 2: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 61) + kind = 61; + jjCheckNAddTwoStates(2, 3); + break; + case 4: + if (curChar == 46) + jjCheckNAdd(5); + break; + case 5: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 65) + kind = 65; + jjCheckNAddStates(22, 24); + break; + case 7: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(8); + break; + case 8: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 65) + kind = 65; + jjCheckNAddTwoStates(8, 9); + break; + case 10: + if (curChar == 39) + jjAddStates(12, 13); + break; + case 11: + if ((0xffffff7fffffdbffL & l) != 0L) + jjCheckNAdd(12); + break; + case 12: + if (curChar == 39 && kind > 70) + kind = 70; + break; + case 14: + if ((0x8400000000L & l) != 0L) + jjCheckNAdd(12); + break; + case 15: + if ((0xff000000000000L & l) != 0L) + jjCheckNAddTwoStates(16, 12); + break; + case 16: + if ((0xff000000000000L & l) != 0L) + jjCheckNAdd(12); + break; + case 17: + if ((0xf000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 18; + break; + case 18: + if ((0xff000000000000L & l) != 0L) + jjCheckNAdd(16); + break; + case 19: + if (curChar == 34) + jjCheckNAddStates(9, 11); + break; + case 20: + if ((0xfffffffbffffdbffL & l) != 0L) + jjCheckNAddStates(9, 11); + break; + case 22: + if ((0x8400000000L & l) != 0L) + jjCheckNAddStates(9, 11); + break; + case 23: + if (curChar == 34 && kind > 71) + kind = 71; + break; + case 24: + if ((0xff000000000000L & l) != 0L) + jjCheckNAddStates(25, 28); + break; + case 25: + if ((0xff000000000000L & l) != 0L) + jjCheckNAddStates(9, 11); + break; + case 26: + if ((0xf000000000000L & l) != 0L) + jjstateSet[jjnewStateCnt++] = 27; + break; + case 27: + if ((0xff000000000000L & l) != 0L) + jjCheckNAdd(25); + break; + case 28: + if (curChar != 36) + break; + if (kind > 72) + kind = 72; + jjCheckNAdd(29); + break; + case 29: + if ((0x3ff00100fffc1ffL & l) == 0L) + break; + if (kind > 72) + kind = 72; + jjCheckNAdd(29); + break; + case 30: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(0, 6); + break; + case 31: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(29, 31); + break; + case 33: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(34); + break; + case 34: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(34, 9); + break; + case 35: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(35, 36); + break; + case 37: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(38); + break; + case 38: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 65) + kind = 65; + jjCheckNAddTwoStates(38, 9); + break; + case 39: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(39, 40); + break; + case 40: + if (curChar != 46) + break; + if (kind > 65) + kind = 65; + jjCheckNAddStates(32, 34); + break; + case 41: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 65) + kind = 65; + jjCheckNAddStates(32, 34); + break; + case 43: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(44); + break; + case 44: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 65) + kind = 65; + jjCheckNAddTwoStates(44, 9); + break; + case 45: + if (curChar == 47) + jjAddStates(7, 8); + break; + case 46: + if (curChar == 42) + jjstateSet[jjnewStateCnt++] = 47; + break; + case 47: + if ((0xffff7fffffffffffL & l) != 0L && kind > 1) + kind = 1; + break; + case 49: + if (curChar != 47) + break; + if (kind > 4) + kind = 4; + jjCheckNAddStates(19, 21); + break; + case 50: + if ((0xffffffffffffdbffL & l) == 0L) + break; + if (kind > 4) + kind = 4; + jjCheckNAddStates(19, 21); + break; + case 51: + if ((0x2400L & l) != 0L && kind > 4) + kind = 4; + break; + case 52: + if (curChar == 10 && kind > 4) + kind = 4; + break; + case 53: + if (curChar == 13) + jjstateSet[jjnewStateCnt++] = 52; + break; + case 54: + if (curChar != 48) + break; + if (kind > 61) + kind = 61; + jjCheckNAddStates(14, 18); + break; + case 56: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 61) + kind = 61; + jjCheckNAddTwoStates(56, 3); + break; + case 57: + if ((0xff000000000000L & l) == 0L) + break; + if (kind > 61) + kind = 61; + jjCheckNAddTwoStates(57, 3); + break; + case 59: + if ((0x3ff000000000000L & l) != 0L) + jjAddStates(35, 36); + break; + case 60: + if (curChar == 46) + jjCheckNAdd(61); + break; + case 61: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddTwoStates(61, 62); + break; + case 63: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(64); + break; + case 64: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 65) + kind = 65; + jjCheckNAddTwoStates(64, 9); + break; + case 66: + if ((0x3ff000000000000L & l) != 0L) + jjCheckNAddStates(37, 39); + break; + case 67: + if (curChar == 46) + jjCheckNAdd(68); + break; + case 69: + if ((0x280000000000L & l) != 0L) + jjCheckNAdd(70); + break; + case 70: + if ((0x3ff000000000000L & l) == 0L) + break; + if (kind > 65) + kind = 65; + jjCheckNAddTwoStates(70, 9); + break; + default: + break; + } + } while (i != startsAt); + } else if (curChar < 128) { + long l = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 1: + if ((0x7fffffe87fffffeL & l) == 0L) + break; + if (kind > 72) + kind = 72; + jjCheckNAdd(29); + break; + case 3: + if ((0x100000001000L & l) != 0L && kind > 61) + kind = 61; + break; + case 6: + if ((0x2000000020L & l) != 0L) + jjAddStates(40, 41); + break; + case 9: + if ((0x5000000050L & l) != 0L && kind > 65) + kind = 65; + break; + case 11: + if ((0xffffffffefffffffL & l) != 0L) + jjCheckNAdd(12); + break; + case 13: + if (curChar == 92) + jjAddStates(42, 44); + break; + case 14: + if ((0x14404410000000L & l) != 0L) + jjCheckNAdd(12); + break; + case 20: + if ((0xffffffffefffffffL & l) != 0L) + jjCheckNAddStates(9, 11); + break; + case 21: + if (curChar == 92) + jjAddStates(45, 47); + break; + case 22: + if ((0x14404410000000L & l) != 0L) + jjCheckNAddStates(9, 11); + break; + case 29: + if ((0x87fffffe87fffffeL & l) == 0L) + break; + if (kind > 72) + kind = 72; + jjCheckNAdd(29); + break; + case 32: + if ((0x2000000020L & l) != 0L) + jjAddStates(48, 49); + break; + case 36: + if ((0x2000000020L & l) != 0L) + jjAddStates(50, 51); + break; + case 42: + if ((0x2000000020L & l) != 0L) + jjAddStates(52, 53); + break; + case 47: + if (kind > 1) + kind = 1; + break; + case 50: + if (kind > 4) + kind = 4; + jjAddStates(19, 21); + break; + case 55: + if ((0x100000001000000L & l) != 0L) + jjCheckNAdd(56); + break; + case 56: + if ((0x7e0000007eL & l) == 0L) + break; + if (kind > 61) + kind = 61; + jjCheckNAddTwoStates(56, 3); + break; + case 58: + if ((0x100000001000000L & l) != 0L) + jjCheckNAddTwoStates(59, 60); + break; + case 59: + if ((0x7e0000007eL & l) != 0L) + jjCheckNAddTwoStates(59, 60); + break; + case 61: + if ((0x7e0000007eL & l) != 0L) + jjAddStates(54, 55); + break; + case 62: + if ((0x1000000010000L & l) != 0L) + jjAddStates(56, 57); + break; + case 65: + if ((0x100000001000000L & l) != 0L) + jjCheckNAdd(66); + break; + case 66: + if ((0x7e0000007eL & l) != 0L) + jjCheckNAddStates(37, 39); + break; + case 68: + if ((0x1000000010000L & l) != 0L) + jjAddStates(58, 59); + break; + default: + break; + } + } while (i != startsAt); + } else { + int hiByte = (int) (curChar >> 8); + int i1 = hiByte >> 6; + long l1 = 1L << (hiByte & 077); + int i2 = (curChar & 0xff) >> 6; + long l2 = 1L << (curChar & 077); + MatchLoop: + do { + switch (jjstateSet[--i]) { + case 1: + if (!jjCanMove_1(hiByte, i1, i2, l1, l2)) + break; + if (kind > 72) + kind = 72; + jjCheckNAdd(29); + break; + case 11: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + jjstateSet[jjnewStateCnt++] = 12; + break; + case 20: + if (jjCanMove_0(hiByte, i1, i2, l1, l2)) + jjAddStates(9, 11); + break; + case 29: + if (!jjCanMove_2(hiByte, i1, i2, l1, l2)) + break; + if (kind > 72) + kind = 72; + jjCheckNAdd(29); + break; + case 47: + if (jjCanMove_0(hiByte, i1, i2, l1, l2) && kind > 1) + kind = 1; + break; + case 50: + if (!jjCanMove_0(hiByte, i1, i2, l1, l2)) + break; + if (kind > 4) + kind = 4; + jjAddStates(19, 21); + break; + default: + break; + } + } while (i != startsAt); + } + if (kind != 0x7fffffff) { + jjmatchedKind = kind; + jjmatchedPos = curPos; + kind = 0x7fffffff; + } + ++curPos; + if ((i = jjnewStateCnt) == (startsAt = 71 - (jjnewStateCnt = startsAt))) + return curPos; + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return curPos; + } + } + } + + private int jjMoveStringLiteralDfa0_2() { + switch (curChar) { + case 42: + return jjMoveStringLiteralDfa1_2(0x40L); + default: + return 1; + } + } + + private int jjMoveStringLiteralDfa1_2(long active0) { + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return 1; + } + switch (curChar) { + case 47: + if ((active0 & 0x40L) != 0L) + return jjStopAtPos(1, 6); + break; + default: + return 2; + } + return 2; + } + + private int jjMoveStringLiteralDfa0_1() { + switch (curChar) { + case 42: + return jjMoveStringLiteralDfa1_1(0x20L); + default: + return 1; + } + } + + private int jjMoveStringLiteralDfa1_1(long active0) { + try { + curChar = input_stream.readChar(); + } + catch (java.io.IOException e) { + return 1; + } + switch (curChar) { + case 47: + if ((active0 & 0x20L) != 0L) + return jjStopAtPos(1, 5); + break; + default: + return 2; + } + return 2; + } + + static final int[] jjnextStates = { + 31, 32, 9, 35, 36, 39, 40, 48, 49, 20, 21, 23, 11, 13, 55, 57, + 3, 58, 65, 50, 51, 53, 5, 6, 9, 20, 21, 25, 23, 31, 32, 9, + 41, 42, 9, 59, 60, 66, 67, 68, 7, 8, 14, 15, 17, 22, 24, 26, + 33, 34, 37, 38, 43, 44, 61, 62, 63, 64, 69, 70, + }; + + private static boolean jjCanMove_0(int hiByte, int i1, int i2, long l1, long l2) { + switch (hiByte) { + case 0: + return ((jjbitVec2[i2] & l2) != 0L); + default: + if ((jjbitVec0[i1] & l1) != 0L) + return true; + return false; + } + } + + private static boolean jjCanMove_1(int hiByte, int i1, int i2, long l1, long l2) { + switch (hiByte) { + case 0: + return ((jjbitVec4[i2] & l2) != 0L); + case 2: + return ((jjbitVec5[i2] & l2) != 0L); + case 3: + return ((jjbitVec6[i2] & l2) != 0L); + case 4: + return ((jjbitVec7[i2] & l2) != 0L); + case 5: + return ((jjbitVec8[i2] & l2) != 0L); + case 6: + return ((jjbitVec9[i2] & l2) != 0L); + case 7: + return ((jjbitVec10[i2] & l2) != 0L); + case 9: + return ((jjbitVec11[i2] & l2) != 0L); + case 10: + return ((jjbitVec12[i2] & l2) != 0L); + case 11: + return ((jjbitVec13[i2] & l2) != 0L); + case 12: + return ((jjbitVec14[i2] & l2) != 0L); + case 13: + return ((jjbitVec15[i2] & l2) != 0L); + case 14: + return ((jjbitVec16[i2] & l2) != 0L); + case 15: + return ((jjbitVec17[i2] & l2) != 0L); + case 16: + return ((jjbitVec18[i2] & l2) != 0L); + case 17: + return ((jjbitVec19[i2] & l2) != 0L); + case 18: + return ((jjbitVec20[i2] & l2) != 0L); + case 19: + return ((jjbitVec21[i2] & l2) != 0L); + case 20: + return ((jjbitVec0[i2] & l2) != 0L); + case 22: + return ((jjbitVec22[i2] & l2) != 0L); + case 23: + return ((jjbitVec23[i2] & l2) != 0L); + case 24: + return ((jjbitVec24[i2] & l2) != 0L); + case 30: + return ((jjbitVec25[i2] & l2) != 0L); + case 31: + return ((jjbitVec26[i2] & l2) != 0L); + case 32: + return ((jjbitVec27[i2] & l2) != 0L); + case 33: + return ((jjbitVec28[i2] & l2) != 0L); + case 48: + return ((jjbitVec29[i2] & l2) != 0L); + case 49: + return ((jjbitVec30[i2] & l2) != 0L); + case 77: + return ((jjbitVec31[i2] & l2) != 0L); + case 159: + return ((jjbitVec32[i2] & l2) != 0L); + case 164: + return ((jjbitVec33[i2] & l2) != 0L); + case 215: + return ((jjbitVec34[i2] & l2) != 0L); + case 250: + return ((jjbitVec35[i2] & l2) != 0L); + case 251: + return ((jjbitVec36[i2] & l2) != 0L); + case 253: + return ((jjbitVec37[i2] & l2) != 0L); + case 254: + return ((jjbitVec38[i2] & l2) != 0L); + case 255: + return ((jjbitVec39[i2] & l2) != 0L); + default: + if ((jjbitVec3[i1] & l1) != 0L) + return true; + return false; + } + } + + private static boolean jjCanMove_2(int hiByte, int i1, int i2, long l1, long l2) { + switch (hiByte) { + case 0: + return ((jjbitVec40[i2] & l2) != 0L); + case 2: + return ((jjbitVec5[i2] & l2) != 0L); + case 3: + return ((jjbitVec41[i2] & l2) != 0L); + case 4: + return ((jjbitVec42[i2] & l2) != 0L); + case 5: + return ((jjbitVec43[i2] & l2) != 0L); + case 6: + return ((jjbitVec44[i2] & l2) != 0L); + case 7: + return ((jjbitVec45[i2] & l2) != 0L); + case 9: + return ((jjbitVec46[i2] & l2) != 0L); + case 10: + return ((jjbitVec47[i2] & l2) != 0L); + case 11: + return ((jjbitVec48[i2] & l2) != 0L); + case 12: + return ((jjbitVec49[i2] & l2) != 0L); + case 13: + return ((jjbitVec50[i2] & l2) != 0L); + case 14: + return ((jjbitVec51[i2] & l2) != 0L); + case 15: + return ((jjbitVec52[i2] & l2) != 0L); + case 16: + return ((jjbitVec53[i2] & l2) != 0L); + case 17: + return ((jjbitVec19[i2] & l2) != 0L); + case 18: + return ((jjbitVec20[i2] & l2) != 0L); + case 19: + return ((jjbitVec54[i2] & l2) != 0L); + case 20: + return ((jjbitVec0[i2] & l2) != 0L); + case 22: + return ((jjbitVec22[i2] & l2) != 0L); + case 23: + return ((jjbitVec55[i2] & l2) != 0L); + case 24: + return ((jjbitVec56[i2] & l2) != 0L); + case 30: + return ((jjbitVec25[i2] & l2) != 0L); + case 31: + return ((jjbitVec26[i2] & l2) != 0L); + case 32: + return ((jjbitVec57[i2] & l2) != 0L); + case 33: + return ((jjbitVec28[i2] & l2) != 0L); + case 48: + return ((jjbitVec58[i2] & l2) != 0L); + case 49: + return ((jjbitVec30[i2] & l2) != 0L); + case 77: + return ((jjbitVec31[i2] & l2) != 0L); + case 159: + return ((jjbitVec32[i2] & l2) != 0L); + case 164: + return ((jjbitVec33[i2] & l2) != 0L); + case 215: + return ((jjbitVec34[i2] & l2) != 0L); + case 250: + return ((jjbitVec35[i2] & l2) != 0L); + case 251: + return ((jjbitVec59[i2] & l2) != 0L); + case 253: + return ((jjbitVec37[i2] & l2) != 0L); + case 254: + return ((jjbitVec60[i2] & l2) != 0L); + case 255: + return ((jjbitVec61[i2] & l2) != 0L); + default: + if ((jjbitVec3[i1] & l1) != 0L) + return true; + return false; + } + } + + public static final String[] jjstrLiteralImages = { + "", null, null, null, null, null, null, null, + "\141\142\163\164\162\141\143\164", "\141\163\163\145\162\164", "\142\157\157\154\145\141\156", + "\142\162\145\141\153", "\142\171\164\145", "\143\141\163\145", "\143\141\164\143\150", + "\143\150\141\162", "\143\154\141\163\163", "\143\157\156\163\164", + "\143\157\156\164\151\156\165\145", "\144\145\146\141\165\154\164", "\144\157", "\144\157\165\142\154\145", + "\145\154\163\145", "\145\156\165\155", "\145\170\164\145\156\144\163", "\146\141\154\163\145", + "\146\151\156\141\154", "\146\151\156\141\154\154\171", "\146\154\157\141\164", "\146\157\162", + "\147\157\164\157", "\151\146", "\151\155\160\154\145\155\145\156\164\163", + "\151\155\160\157\162\164", "\151\156\163\164\141\156\143\145\157\146", "\151\156\164", + "\151\156\164\145\162\146\141\143\145", "\154\157\156\147", "\156\141\164\151\166\145", "\156\145\167", + "\156\165\154\154", "\160\141\143\153\141\147\145", "\160\162\151\166\141\164\145", + "\160\162\157\164\145\143\164\145\144", "\160\165\142\154\151\143", "\162\145\164\165\162\156", + "\163\150\157\162\164", "\163\164\141\164\151\143", "\163\164\162\151\143\164\146\160", + "\163\165\160\145\162", "\163\167\151\164\143\150", + "\163\171\156\143\150\162\157\156\151\172\145\144", "\164\150\151\163", "\164\150\162\157\167", "\164\150\162\157\167\163", + "\164\162\141\156\163\151\145\156\164", "\164\162\165\145", "\164\162\171", "\166\157\151\144", + "\166\157\154\141\164\151\154\145", "\167\150\151\154\145", null, null, null, null, null, null, null, null, null, + null, null, null, null, null, "\50", "\51", "\173", "\175", "\133", "\135", "\73", + "\54", "\56", "\100", "\75", "\74", "\41", "\176", "\77", "\72", "\75\75", "\74\75", + "\76\75", "\41\75", "\174\174", "\46\46", "\53\53", "\55\55", "\53", "\55", "\52", + "\57", "\46", "\174", "\136", "\45", "\74\74", "\53\75", "\55\75", "\52\75", + "\57\75", "\46\75", "\174\75", "\136\75", "\45\75", "\74\74\75", "\76\76\75", + "\76\76\76\75", "\56\56\56", "\76\76\76", "\76\76", "\76", "\32", null,}; + public static final String[] lexStateNames = { + "DEFAULT", + "IN_FORMAL_COMMENT", + "IN_MULTI_LINE_COMMENT", + }; + public static final int[] jjnewLexState = { + -1, 1, 2, -1, -1, 0, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + }; + static final long[] jjtoToken = { + 0x3fffffffffffff01L, 0x1ffffffffffff9c2L, + }; + static final long[] jjtoSkip = { + 0x78L, 0x0L, + }; + static final long[] jjtoSpecial = { + 0x78L, 0x0L, + }; + static final long[] jjtoMore = { + 0x86L, 0x0L, + }; + protected JavaCharStream input_stream; + private final int[] jjrounds = new int[71]; + private final int[] jjstateSet = new int[142]; + StringBuffer image; + int jjimageLen; + int lengthOfMatch; + protected char curChar; + + public JavaParserTokenManager(JavaCharStream stream) { + if (JavaCharStream.staticFlag) + throw new Error("ERROR: Cannot use a static CharStream class with a non-static lexical analyzer."); + input_stream = stream; + } + + public JavaParserTokenManager(JavaCharStream stream, int lexState) { + this(stream); + SwitchTo(lexState); + } + + public void ReInit(JavaCharStream stream) { + jjmatchedPos = jjnewStateCnt = 0; + curLexState = defaultLexState; + input_stream = stream; + ReInitRounds(); + } + + private void ReInitRounds() { + int i; + jjround = 0x80000001; + for (i = 71; i-- > 0;) + jjrounds[i] = 0x80000000; + } + + public void ReInit(JavaCharStream stream, int lexState) { + ReInit(stream); + SwitchTo(lexState); + } + + public void SwitchTo(int lexState) { + if (lexState >= 3 || lexState < 0) + throw new TokenMgrError("Error: Ignoring invalid lexical state : " + lexState + ". State unchanged.", TokenMgrError.INVALID_LEXICAL_STATE); + else + curLexState = lexState; + } + + protected Token jjFillToken() { + Token t = Token.newToken(jjmatchedKind); + t.kind = jjmatchedKind; + String im = jjstrLiteralImages[jjmatchedKind]; + t.image = (im == null) ? input_stream.GetImage() : im; + t.beginLine = input_stream.getBeginLine(); + t.beginColumn = input_stream.getBeginColumn(); + t.endLine = input_stream.getEndLine(); + t.endColumn = input_stream.getEndColumn(); + return t; + } + + int curLexState = 0; + int defaultLexState = 0; + int jjnewStateCnt; + int jjround; + int jjmatchedPos; + int jjmatchedKind; + + public Token getNextToken() { + int kind; + Token specialToken = null; + Token matchedToken; + int curPos = 0; + + EOFLoop: + for (; ;) { + try { + curChar = input_stream.BeginToken(); + } + catch (java.io.IOException e) { + jjmatchedKind = 0; + matchedToken = jjFillToken(); + matchedToken.specialToken = specialToken; + return matchedToken; + } + image = null; + jjimageLen = 0; + + for (; ;) { + switch (curLexState) { + case 0: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_0(); + if (jjmatchedPos == 0 && jjmatchedKind > 124) { + jjmatchedKind = 124; + } + break; + case 1: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_1(); + if (jjmatchedPos == 0 && jjmatchedKind > 7) { + jjmatchedKind = 7; + } + break; + case 2: + jjmatchedKind = 0x7fffffff; + jjmatchedPos = 0; + curPos = jjMoveStringLiteralDfa0_2(); + if (jjmatchedPos == 0 && jjmatchedKind > 7) { + jjmatchedKind = 7; + } + break; + } + if (jjmatchedKind != 0x7fffffff) { + if (jjmatchedPos + 1 < curPos) + input_stream.backup(curPos - jjmatchedPos - 1); + if ((jjtoToken[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) { + matchedToken = jjFillToken(); + matchedToken.specialToken = specialToken; + TokenLexicalActions(matchedToken); + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + return matchedToken; + } else + if ((jjtoSkip[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) { + if ((jjtoSpecial[jjmatchedKind >> 6] & (1L << (jjmatchedKind & 077))) != 0L) { + matchedToken = jjFillToken(); + if (specialToken == null) + specialToken = matchedToken; + else { + matchedToken.specialToken = specialToken; + specialToken = (specialToken.next = matchedToken); + } + SkipLexicalActions(matchedToken); + } else + SkipLexicalActions(null); + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + continue EOFLoop; + } + MoreLexicalActions(); + if (jjnewLexState[jjmatchedKind] != -1) + curLexState = jjnewLexState[jjmatchedKind]; + curPos = 0; + jjmatchedKind = 0x7fffffff; + try { + curChar = input_stream.readChar(); + continue; + } + catch (java.io.IOException e1) { + } + } + int error_line = input_stream.getEndLine(); + int error_column = input_stream.getEndColumn(); + String error_after = null; + boolean EOFSeen = false; + try { + input_stream.readChar(); + input_stream.backup(1); + } + catch (java.io.IOException e1) { + EOFSeen = true; + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + if (curChar == '\n' || curChar == '\r') { + error_line++; + error_column = 0; + } else + error_column++; + } + if (!EOFSeen) { + input_stream.backup(1); + error_after = curPos <= 1 ? "" : input_stream.GetImage(); + } + throw new TokenMgrError(EOFSeen, curLexState, error_line, error_column, error_after, curChar, TokenMgrError.LEXICAL_ERROR); + } + } + } + + void SkipLexicalActions(Token matchedToken) { + switch (jjmatchedKind) { + default: + break; + } + } + + void MoreLexicalActions() { + jjimageLen += (lengthOfMatch = jjmatchedPos + 1); + switch (jjmatchedKind) { + case 1: + if (image == null) + image = new StringBuffer(); + image.append(input_stream.GetSuffix(jjimageLen)); + jjimageLen = 0; + input_stream.backup(1); + break; + default: + break; + } + } + + void TokenLexicalActions(Token matchedToken) { + switch (jjmatchedKind) { + case 120: + if (image == null) + image = new StringBuffer(); + image.append(jjstrLiteralImages[120]); + matchedToken.kind = GT; + ((Token.GTToken) matchedToken).realKind = RUNSIGNEDSHIFT; + input_stream.backup(2); + matchedToken.image = ">"; + break; + case 121: + if (image == null) + image = new StringBuffer(); + image.append(jjstrLiteralImages[121]); + matchedToken.kind = GT; + ((Token.GTToken) matchedToken).realKind = RSIGNEDSHIFT; + input_stream.backup(1); + matchedToken.image = ">"; + break; + default: + break; + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTreeConstants.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/JavaParserTreeConstants.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTreeConstants.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/JavaParserTreeConstants.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,230 @@ +/* Generated By:JJTree: Do not edit this line. ./JavaParserTreeConstants.java */ + +package jaxx.parser; + +public interface JavaParserTreeConstants { + public int JJTLINE = 0; + public int JJTCOMPILATIONUNIT = 1; + public int JJTPACKAGEDECLARATION = 2; + public int JJTIMPORTDECLARATION = 3; + public int JJTMODIFIERS = 4; + public int JJTTYPEDECLARATION = 5; + public int JJTCLASSORINTERFACEDECLARATION = 6; + public int JJTEXTENDSLIST = 7; + public int JJTIMPLEMENTSLIST = 8; + public int JJTENUMDECLARATION = 9; + public int JJTENUMBODY = 10; + public int JJTENUMCONSTANT = 11; + public int JJTTYPEPARAMETERS = 12; + public int JJTTYPEPARAMETER = 13; + public int JJTTYPEBOUND = 14; + public int JJTCLASSORINTERFACEBODY = 15; + public int JJTCLASSORINTERFACEBODYDECLARATION = 16; + public int JJTFIELDDECLARATION = 17; + public int JJTVARIABLEDECLARATOR = 18; + public int JJTVARIABLEDECLARATORID = 19; + public int JJTVARIABLEINITIALIZER = 20; + public int JJTARRAYINITIALIZER = 21; + public int JJTMETHODDECLARATION = 22; + public int JJTMETHODDECLARATOR = 23; + public int JJTFORMALPARAMETERS = 24; + public int JJTFORMALPARAMETER = 25; + public int JJTCONSTRUCTORDECLARATION = 26; + public int JJTEXPLICITCONSTRUCTORINVOCATION = 27; + public int JJTINITIALIZER = 28; + public int JJTTYPE = 29; + public int JJTREFERENCETYPE = 30; + public int JJTCLASSORINTERFACETYPE = 31; + public int JJTTYPEARGUMENTS = 32; + public int JJTTYPEARGUMENT = 33; + public int JJTWILDCARDBOUNDS = 34; + public int JJTPRIMITIVETYPE = 35; + public int JJTRESULTTYPE = 36; + public int JJTNAME = 37; + public int JJTNAMELIST = 38; + public int JJTEXPRESSION = 39; + public int JJTASSIGNMENTOPERATOR = 40; + public int JJTASSIGNMENTEXPRESSION = 41; + public int JJTCONDITIONALEXPRESSION = 42; + public int JJTCONDITIONALOREXPRESSION = 43; + public int JJTCONDITIONALANDEXPRESSION = 44; + public int JJTINCLUSIVEOREXPRESSION = 45; + public int JJTEXCLUSIVEOREXPRESSION = 46; + public int JJTANDEXPRESSION = 47; + public int JJTEQUALITYEXPRESSION = 48; + public int JJTINSTANCEOFEXPRESSION = 49; + public int JJTRELATIONALEXPRESSION = 50; + public int JJTSHIFTEXPRESSION = 51; + public int JJTADDITIVEEXPRESSION = 52; + public int JJTMULTIPLICATIVEEXPRESSION = 53; + public int JJTUNARYEXPRESSION = 54; + public int JJTPREINCREMENTEXPRESSION = 55; + public int JJTPREDECREMENTEXPRESSION = 56; + public int JJTUNARYEXPRESSIONNOTPLUSMINUS = 57; + public int JJTCASTLOOKAHEAD = 58; + public int JJTPOSTFIXEXPRESSION = 59; + public int JJTPOSTFIXOPERATOR = 60; + public int JJTCASTEXPRESSION = 61; + public int JJTPRIMARYEXPRESSION = 62; + public int JJTMEMBERSELECTOR = 63; + public int JJTPRIMARYPREFIX = 64; + public int JJTPRIMARYSUFFIX = 65; + public int JJTLITERAL = 66; + public int JJTBOOLEANLITERAL = 67; + public int JJTNULLLITERAL = 68; + public int JJTARGUMENTS = 69; + public int JJTARGUMENTLIST = 70; + public int JJTALLOCATIONEXPRESSION = 71; + public int JJTARRAYDIMSANDINITS = 72; + public int JJTSTATEMENT = 73; + public int JJTASSERTSTATEMENT = 74; + public int JJTLABELEDSTATEMENT = 75; + public int JJTBLOCK = 76; + public int JJTBLOCKSTATEMENT = 77; + public int JJTLOCALVARIABLEDECLARATION = 78; + public int JJTEMPTYSTATEMENT = 79; + public int JJTSTATEMENTEXPRESSION = 80; + public int JJTSWITCHSTATEMENT = 81; + public int JJTSWITCHLABEL = 82; + public int JJTIFSTATEMENT = 83; + public int JJTWHILESTATEMENT = 84; + public int JJTDOSTATEMENT = 85; + public int JJTFORSTATEMENT = 86; + public int JJTFORINIT = 87; + public int JJTSTATEMENTEXPRESSIONLIST = 88; + public int JJTFORUPDATE = 89; + public int JJTBREAKSTATEMENT = 90; + public int JJTCONTINUESTATEMENT = 91; + public int JJTRETURNSTATEMENT = 92; + public int JJTTHROWSTATEMENT = 93; + public int JJTSYNCHRONIZEDSTATEMENT = 94; + public int JJTTRYSTATEMENT = 95; + public int JJTRUNSIGNEDSHIFT = 96; + public int JJTRSIGNEDSHIFT = 97; + public int JJTANNOTATION = 98; + public int JJTNORMALANNOTATION = 99; + public int JJTMARKERANNOTATION = 100; + public int JJTSINGLEMEMBERANNOTATION = 101; + public int JJTMEMBERVALUEPAIRS = 102; + public int JJTMEMBERVALUEPAIR = 103; + public int JJTMEMBERVALUE = 104; + public int JJTMEMBERVALUEARRAYINITIALIZER = 105; + public int JJTANNOTATIONTYPEDECLARATION = 106; + public int JJTANNOTATIONTYPEBODY = 107; + public int JJTANNOTATIONTYPEMEMBERDECLARATION = 108; + public int JJTDEFAULTVALUE = 109; + + + public String[] jjtNodeName = { + "Line", + "CompilationUnit", + "PackageDeclaration", + "ImportDeclaration", + "Modifiers", + "TypeDeclaration", + "ClassOrInterfaceDeclaration", + "ExtendsList", + "ImplementsList", + "EnumDeclaration", + "EnumBody", + "EnumConstant", + "TypeParameters", + "TypeParameter", + "TypeBound", + "ClassOrInterfaceBody", + "ClassOrInterfaceBodyDeclaration", + "FieldDeclaration", + "VariableDeclarator", + "VariableDeclaratorId", + "VariableInitializer", + "ArrayInitializer", + "MethodDeclaration", + "MethodDeclarator", + "FormalParameters", + "FormalParameter", + "ConstructorDeclaration", + "ExplicitConstructorInvocation", + "Initializer", + "Type", + "ReferenceType", + "ClassOrInterfaceType", + "TypeArguments", + "TypeArgument", + "WildcardBounds", + "PrimitiveType", + "ResultType", + "Name", + "NameList", + "Expression", + "AssignmentOperator", + "AssignmentExpression", + "ConditionalExpression", + "ConditionalOrExpression", + "ConditionalAndExpression", + "InclusiveOrExpression", + "ExclusiveOrExpression", + "AndExpression", + "EqualityExpression", + "InstanceOfExpression", + "RelationalExpression", + "ShiftExpression", + "AdditiveExpression", + "MultiplicativeExpression", + "UnaryExpression", + "PreIncrementExpression", + "PreDecrementExpression", + "UnaryExpressionNotPlusMinus", + "CastLookahead", + "PostfixExpression", + "PostfixOperator", + "CastExpression", + "PrimaryExpression", + "MemberSelector", + "PrimaryPrefix", + "PrimarySuffix", + "Literal", + "BooleanLiteral", + "NullLiteral", + "Arguments", + "ArgumentList", + "AllocationExpression", + "ArrayDimsAndInits", + "Statement", + "AssertStatement", + "LabeledStatement", + "Block", + "BlockStatement", + "LocalVariableDeclaration", + "EmptyStatement", + "StatementExpression", + "SwitchStatement", + "SwitchLabel", + "IfStatement", + "WhileStatement", + "DoStatement", + "ForStatement", + "ForInit", + "StatementExpressionList", + "ForUpdate", + "BreakStatement", + "ContinueStatement", + "ReturnStatement", + "ThrowStatement", + "SynchronizedStatement", + "TryStatement", + "RUNSIGNEDSHIFT", + "RSIGNEDSHIFT", + "Annotation", + "NormalAnnotation", + "MarkerAnnotation", + "SingleMemberAnnotation", + "MemberValuePairs", + "MemberValuePair", + "MemberValue", + "MemberValueArrayInitializer", + "AnnotationTypeDeclaration", + "AnnotationTypeBody", + "AnnotationTypeMemberDeclaration", + "DefaultValue", + }; +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Node.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/Node.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Node.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Node.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,51 @@ +/* Generated By:JJTree: Do not edit this line. Node.java */ + +package jaxx.parser; + +/* All AST nodes must implement this interface. It provides basic + machinery for constructing the parent and child relationships + between nodes. */ + +public interface Node { + + /** + * This method is called after the node has been made the current + * node. It indicates that child nodes can now be added to it. + */ + public void jjtOpen(); + + /** + * This method is called after all the child nodes have been + * added. + */ + public void jjtClose(); + + /** + * This pair of methods are used to inform the node of its + * parent. + * + * @param n node + */ + public void jjtSetParent(Node n); + + public Node jjtGetParent(); + + /** + * This method tells the node to add its argument to the node's + * list of children. + * + * @param n node + * @param i index ? + */ + public void jjtAddChild(Node n, int i); + + /** + * @param i index of child + * @return a child node. The children are numbered + * from zero, left to right. + */ + public Node jjtGetChild(int i); + + /** @return the number of children the node has. */ + public int jjtGetNumChildren(); +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/ParseException.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/ParseException.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/ParseException.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/ParseException.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,214 @@ +/* Generated By:JavaCC: Do not edit this line. ParseException.java Version 3.0 */ +package jaxx.parser; + +/** + * This exception is thrown when parse errors are encountered. + * You can explicitly create objects of this exception type by + * calling the method generateParseException in the generated + * parser. + * <p/> + * You can modify this class to customize your error reporting + * mechanisms so long as you retain the public fields. + */ +public class ParseException extends jaxx.CompilerException { + int line; + int column; + private static final long serialVersionUID = 6179854408401024700L; + + /** + * This constructor is used by the method "generateParseException" + * in the generated parser. Calling this constructor generates + * a new object of this type with the fields "currentToken", + * "expectedTokenSequences", and "tokenImage" set. The boolean + * flag "specialConstructor" is also set to true to indicate that + * this constructor was used to create this object. + * This constructor calls its super class with the empty string + * to force the "toString" method of parent class "Throwable" to + * print the error message in the form: + * ParseException: <result of getMessage> + * + * @param currentTokenVal ? + * @param expectedTokenSequencesVal ? + * @param tokenImageVal ? + */ + public ParseException(Token currentTokenVal, + int[][] expectedTokenSequencesVal, + String[] tokenImageVal + ) { + super(""); + specialConstructor = true; + currentToken = currentTokenVal; + expectedTokenSequences = expectedTokenSequencesVal; + tokenImage = tokenImageVal; + } + + /** + * The following constructors are for use by you for whatever + * purpose you can think of. Constructing the exception in this + * manner makes the exception behave in the normal way - i.e., as + * documented in the class "Throwable". The fields "errorToken", + * "expectedTokenSequences", and "tokenImage" do not contain + * relevant information. The JavaCC generated code does not use + * these constructors. + */ + + public ParseException() { + super(); + specialConstructor = false; + } + + public ParseException(String message) { + super(message); + specialConstructor = false; + } + + public ParseException(String message, int line, int column) { + super(message); + specialConstructor = false; + this.line = line; + this.column = column; + } + + + /** + * This variable determines which constructor was used to create + * this object and thereby affects the semantics of the + * "getMessage" method (see below). + */ + protected boolean specialConstructor; + + /** + * This is the last token that has been consumed successfully. If + * this object has been created due to a parse error, the token + * followng this token will (therefore) be the first error token. + */ + public Token currentToken; + + /** + * Each entry in this array is an array of integers. Each array + * of integers represents a sequence of tokens (by their ordinal + * values) that is expected at this point of the parse. + */ + public int[][] expectedTokenSequences; + + /** + * This is a reference to the "tokenImage" array of the generated + * parser within which the parse error occurred. This array is + * defined in the generated ...Constants interface. + */ + public String[] tokenImage; + + /** + * This method has the standard behavior when this object has been + * created using the standard constructors. Otherwise, it uses + * "currentToken" and "expectedTokenSequences" to generate a parse + * error message and returns it. If this object has been created + * due to a parse error, and you do not catch it (it gets thrown + * from the parser), then this method is called during the printing + * of the final stack trace, and hence the correct error message + * gets displayed. + */ + public String getMessage() { + if (!specialConstructor) { + return super.getMessage(); + } + StringBuffer expected = new StringBuffer(); + int maxSize = 0; + for (int[] expectedTokenSequence : expectedTokenSequences) { + if (maxSize < expectedTokenSequence.length) { + maxSize = expectedTokenSequence.length; + } + for (int anExpectedTokenSequence : expectedTokenSequence) { + expected.append(tokenImage[anExpectedTokenSequence]).append(" "); + } + if (expectedTokenSequence[expectedTokenSequence.length - 1] != 0) { + expected.append("..."); + } + expected.append(eol).append(" "); + } + String retval = "Encountered \""; + Token tok = currentToken.next; + for (int i = 0; i < maxSize; i++) { + if (i != 0) retval += " "; + if (tok.kind == 0) { + retval += tokenImage[0]; + break; + } + retval += add_escapes(tok.image); + tok = tok.next; + } + retval += "\" at line " + currentToken.next.beginLine + ", column " + currentToken.next.beginColumn; + retval += "." + eol; + if (expectedTokenSequences.length == 1) { + retval += "Was expecting:" + eol + " "; + } else { + retval += "Was expecting one of:" + eol + " "; + } + retval += expected.toString(); + return retval; + } + + + public int getLine() { + return line; + } + + public int getColumn() { + return column; + } + + /** The end of line string for this machine. */ + protected String eol = System.getProperty("line.separator", "\n"); + + /** + * Used to convert raw characters to their escaped version + * when these raw version cannot be used as part of an ASCII + * string literal. + * + * @param str text to treate + * @return the escaped version of text + */ + protected String add_escapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) { + case 0: + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u").append(s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + } + } + return retval.toString(); + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/SimpleNode.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/SimpleNode.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/SimpleNode.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/SimpleNode.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,135 @@ +/* Generated By:JJTree: Do not edit this line. SimpleNode.java */ + +package jaxx.parser; + +import jaxx.reflect.ClassDescriptor; + +public class SimpleNode implements Node { + protected Node parent; + protected Node[] children; + protected int id; + protected JavaParser parser; + public Token firstToken; + public Token lastToken; + private ClassDescriptor javaType; + + + public SimpleNode(int i) { + id = i; + } + + public SimpleNode(JavaParser p, int i) { + this(i); + parser = p; + } + + + public int getId() { + return id; + } + + public void jjtOpen() { + } + + public void jjtClose() { + } + + public void jjtSetParent(Node n) { + parent = n; + } + + public Node jjtGetParent() { + return parent; + } + + public SimpleNode getParent() { + return (SimpleNode) parent; + } + + + public ClassDescriptor getJavaType() { + return javaType; + } + + + public void setJavaType(ClassDescriptor javaType) { + this.javaType = javaType; + } + + public void jjtAddChild(Node n, int i) { + if (children == null) { + children = new Node[i + 1]; + } else if (i >= children.length) { + Node c[] = new Node[i + 1]; + System.arraycopy(children, 0, c, 0, children.length); + children = c; + } + children[i] = n; + } + + public Node jjtGetChild(int i) { + return children[i]; + } + + public SimpleNode getChild(int i) { + return (SimpleNode) children[i]; + } + + public int jjtGetNumChildren() { + return (children == null) ? 0 : children.length; + } + + /* You can override these two methods in subclasses of SimpleNode to +customize the way the node appears when the tree is dumped. If +your output uses more than one line you should override +toString(String), otherwise overriding toString() is probably all +you need to do. */ + + @Override + public String toString() { + return getClass().getName() + "[" + getText() + "]"; + } + + public String toString(String prefix) { + return prefix + toString(); + } + + /* Override this method if you want to customize how the node dumps + out its children. */ + + public void dump(String prefix) { + System.out.println(toString(prefix)); + if (children != null) { + for (Node aChildren : children) { + SimpleNode n = (SimpleNode) aChildren; + if (n != null) { + n.dump(prefix + " "); + } + } + } + } + + private void appendSpecialTokens(StringBuffer s, Token st) { + if (st != null) { + appendSpecialTokens(s, st.specialToken); + s.append(st.image); + } + } + + + /** @return the text of the tokens comprising this node. */ + public String getText() { + StringBuffer text = new StringBuffer(); + Token t = firstToken; + while (t != null) { + appendSpecialTokens(text, t.specialToken); + text.append(t.image); + if (t == lastToken) + break; + t = t.next; + } + + return text.toString(); + } +} + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Token.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/Token.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Token.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/Token.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,79 @@ +/* Generated By:JavaCC: Do not edit this line. Token.java Version 3.0 */ +package jaxx.parser; + +/** Describes the input token stream. */ + +public class Token { + /** + * An integer that describes the kind of this token. This numbering + * system is determined by JavaCCParser, and a table of these numbers is + * stored in the file ...Constants.java. + */ + public int kind; + + /** + * beginLine and beginColumn describe the position of the first character + * of this token; endLine and endColumn describe the position of the + * last character of this token. + */ + public int beginLine, beginColumn, endLine, endColumn; + + /** The string image of the token. */ + public String image; + + /** + * A reference to the next regular (non-special) token from the input + * stream. If this is the last token from the input stream, or if the + * token manager has not read tokens beyond this one, this field is + * set to null. This is true only if this token is also a regular + * token. Otherwise, see below for a description of the contents of + * this field. + */ + public Token next; + + /** + * This field is used to access special tokens that occur prior to this + * token, but after the immediately preceding regular (non-special) token. + * If there are no such special tokens, this field is set to null. + * When there are more than one such special token, this field refers + * to the last of these special tokens, which in turn refers to the next + * previous special token through its specialToken field, and so on + * until the first special token (whose specialToken field is null). + * The next fields of special tokens refer to other special tokens that + * immediately follow it (without an intervening regular token). If there + * is no such token, this field is null. + */ + public Token specialToken; + + /** Returns the image. */ + public String toString() { + return image; + } + + /** + * Returns a new Token object, by default. However, if you want, you + * can create and return subclass objects based on the value of ofKind. + * Simply add the cases to the switch for all those special cases. + * For example, if you have a subclass of Token called IDToken that + * you want to create if ofKind is ID, simlpy add something like : + * <p/> + * case MyParserConstants.ID : return new IDToken(); + * <p/> + * to the following switch statement. Then you can cast matchedToken + * variable to the appropriate type and use it in your lexical actions. + */ + public static final Token newToken(int ofKind) { + switch (ofKind) { + default: + return new Token(); + case JavaParserConstants.RUNSIGNEDSHIFT: + case JavaParserConstants.RSIGNEDSHIFT: + case JavaParserConstants.GT: + return new GTToken(); + } + } + + public static class GTToken extends Token { + int realKind = JavaParserConstants.GT; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/TokenMgrError.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/parser/TokenMgrError.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/TokenMgrError.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/parser/TokenMgrError.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,126 @@ +/* Generated By:JavaCC: Do not edit this line. TokenMgrError.java Version 3.0 */ +package jaxx.parser; + +public class TokenMgrError extends Error { + /* + * Ordinals for various reasons why an Error of this type can be thrown. + */ + + /** Lexical error occured. */ + static final int LEXICAL_ERROR = 0; + + /** An attempt wass made to create a second instance of a static token manager. */ + static final int STATIC_LEXER_ERROR = 1; + + /** Tried to change to an invalid lexical state. */ + static final int INVALID_LEXICAL_STATE = 2; + + /** Detected (and bailed out of) an infinite loop in the token manager. */ + static final int LOOP_DETECTED = 3; + + /** + * Indicates the reason why the exception is thrown. It will have + * one of the above 4 values. + */ + int errorCode; + private static final long serialVersionUID = -9131500865453532454L; + + /** + * Replaces unprintable characters by their espaced (or unicode escaped) + * equivalents in the given string + * + * @param str text to treate + * @return the treated text + */ + protected static String addEscapes(String str) { + StringBuffer retval = new StringBuffer(); + char ch; + for (int i = 0; i < str.length(); i++) { + switch (str.charAt(i)) { + case 0: + continue; + case '\b': + retval.append("\\b"); + continue; + case '\t': + retval.append("\\t"); + continue; + case '\n': + retval.append("\\n"); + continue; + case '\f': + retval.append("\\f"); + continue; + case '\r': + retval.append("\\r"); + continue; + case '\"': + retval.append("\\\""); + continue; + case '\'': + retval.append("\\\'"); + continue; + case '\\': + retval.append("\\\\"); + continue; + default: + if ((ch = str.charAt(i)) < 0x20 || ch > 0x7e) { + String s = "0000" + Integer.toString(ch, 16); + retval.append("\\u").append(s.substring(s.length() - 4, s.length())); + } else { + retval.append(ch); + } + } + } + return retval.toString(); + } + + /** + * @param EOFSeen : indicates if EOF caused the lexicl error + * @param lexState : lexical state in which this error occured + * @param errorLine : line number when the error occured + * @param errorColumn : column number when the error occured + * @param errorAfter : prefix that was seen before this error occured + * @param curChar : the offending character + * Note: You can customize the lexical error message by modifying this method. + * @return a detailed message for the Error when it is thrown by the + * token manager to indicate a lexical error. + */ + protected static String LexicalError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar) { + return ("Lexical error at line " + + errorLine + ", column " + + errorColumn + ". Encountered: " + + (EOFSeen ? "<EOF> " : ("\"" + addEscapes(String.valueOf(curChar)) + "\"") + " (" + (int) curChar + "), ") + + "after : \"" + addEscapes(errorAfter) + "\""); + } + + /** + * You can also modify the body of this method to customize your error messages. + * For example, cases like LOOP_DETECTED and INVALID_LEXICAL_STATE are not + * of end-users concern, so you can return something like : + * <p/> + * "Internal Error : Please file a bug report .... " + * <p/> + * from this method for such cases in the release version of your parser. + */ + @Override + public String getMessage() { + return super.getMessage(); + } + + /* + * Constructors of various flavors follow. + */ + + public TokenMgrError() { + } + + public TokenMgrError(String message, int reason) { + super(message); + errorCode = reason; + } + + public TokenMgrError(boolean EOFSeen, int lexState, int errorLine, int errorColumn, String errorAfter, char curChar, int reason) { + this(LexicalError(EOFSeen, lexState, errorLine, errorColumn, errorAfter, curChar), reason); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptor.java (from rev 1096, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/reflect/ClassDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,166 @@ +package jaxx.reflect; + +import jaxx.runtime.JAXXObjectDescriptor; + +import java.util.Arrays; + +/** + * Mirrors the class <code>java.lang.Class</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code> + * almost everywhere so that it can handle circular dependencies (there can't be a <code>Class</code> object for an uncompiled + * JAXX or Java source file, and a compiler must be allow references to symbols in uncompiled source files in order to handle + * circular dependencies). + */ +public abstract class ClassDescriptor { + private String name; + private String packageName; + private String superclass; + private String[] interfaces; + private boolean isInterface; + private boolean isArray; + private String componentType; + private JAXXObjectDescriptor jaxxObjectDescriptor; + private ClassLoader classLoader; + private MethodDescriptor[] methodDescriptors; + private FieldDescriptor[] fieldDescriptors; + + + ClassDescriptor(String name, String packageName, String superclass, String[] interfaces, boolean isInterface, + boolean isArray, String componentType, JAXXObjectDescriptor jaxxObjectDescriptor, + ClassLoader classLoader, MethodDescriptor[] methodDescriptors, FieldDescriptor[] fieldDescriptors) { + this.name = name; + this.packageName = packageName; + this.superclass = superclass; + this.interfaces = interfaces; + this.isInterface = isInterface; + this.isArray = isArray; + this.componentType = componentType; + this.jaxxObjectDescriptor = jaxxObjectDescriptor; + this.classLoader = classLoader; + this.methodDescriptors = methodDescriptors; + this.fieldDescriptors = fieldDescriptors; + } + + + public String getName() { + return name; + } + + + public String getPackageName() { + return packageName; + } + + + public ClassDescriptor getSuperclass() { + try { + return superclass != null ? ClassDescriptorLoader.getClassDescriptor(superclass, getClassLoader()) : null; + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + + public ClassDescriptor[] getInterfaces() { + try { + ClassDescriptor[] result = new ClassDescriptor[interfaces.length]; + for (int i = 0; i < result.length; i++) { + result[i] = ClassDescriptorLoader.getClassDescriptor(interfaces[i], getClassLoader()); + } + return result; + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + + public boolean isInterface() { + return isInterface; + } + + + public boolean isArray() { + return isArray; + } + + + public ClassDescriptor getComponentType() { + try { + return componentType != null ? ClassDescriptorLoader.getClassDescriptor(componentType, getClassLoader()) : null; + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + + public ClassLoader getClassLoader() { + return classLoader; + } + + + public MethodDescriptor[] getMethodDescriptors() { + return methodDescriptors; + } + + + public MethodDescriptor getMethodDescriptor(String name, ClassDescriptor... parameterTypes) throws NoSuchMethodException { + for (MethodDescriptor methodDescriptor : methodDescriptors) { + if (methodDescriptor.getName().equals(name) + && methodDescriptor.getParameterTypes().length == parameterTypes.length + && Arrays.equals(methodDescriptor.getParameterTypes(), parameterTypes)) { + return methodDescriptor; + } + } + throw new NoSuchMethodException("Could not find method " + name + "(" + Arrays.asList(parameterTypes) + ") in " + getName()); + } + + + public abstract MethodDescriptor getDeclaredMethodDescriptor(String name, ClassDescriptor... parameterTypes) throws NoSuchMethodException; + + + public FieldDescriptor[] getFieldDescriptors() { + return fieldDescriptors; + } + + + public FieldDescriptor getFieldDescriptor(String name) throws NoSuchFieldException { + for (FieldDescriptor fieldDescriptor : fieldDescriptors) { + if (fieldDescriptor.getName().equals(name)) { + return fieldDescriptor; + } + } + throw new NoSuchFieldException("Could not find field " + name + " in " + getName()); + } + + + public abstract FieldDescriptor getDeclaredFieldDescriptor(String name) throws NoSuchFieldException; + + + public JAXXObjectDescriptor getJAXXObjectDescriptor() { + return jaxxObjectDescriptor; + } + + + public boolean isAssignableFrom(ClassDescriptor descriptor) { + while (descriptor != null) { + if (descriptor == this) { + return true; + } + ClassDescriptor[] interfaces = descriptor.getInterfaces(); + for (ClassDescriptor anInterface : interfaces) { + if (anInterface == this) { + return true; + } + } + descriptor = descriptor.getSuperclass(); + } + return false; + } + + @Override + public String toString() { + return "ClassDescriptor[" + getName() + "]"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptorLoader.java (from rev 1096, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/reflect/ClassDescriptorLoader.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptorLoader.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/ClassDescriptorLoader.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,362 @@ +package jaxx.reflect; + +import jaxx.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerLaunchor; +import jaxx.compiler.SymbolTable; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.JAXXObjectDescriptor; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.Reader; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import java.net.URL; +import java.util.Arrays; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Mirrors the class <code>java.lang.ClassLoader</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code> + * almost everywhere so that it can handle circular dependencies (there can't be a <code>Class</code> object for an uncompiled + * JAXX or Java source file, and a compiler must be allow references to symbols in uncompiled source files in order to handle + * circular dependencies). + */ +public class ClassDescriptorLoader { + + private static Map<String, ClassDescriptor> descriptors = new HashMap<String, ClassDescriptor>(); + + private ClassDescriptorLoader() { + } + + + public static synchronized ClassDescriptor getClassDescriptor(String className) throws ClassNotFoundException { + return getClassDescriptor(className, Thread.currentThread().getContextClassLoader()); + //return getClassDescriptor(className, ClassDescriptorLoader.class.getClassLoader()); + } + + public static synchronized ClassDescriptor getClassDescriptor(String className, ClassLoader classLoader) throws ClassNotFoundException { + ClassDescriptor result = descriptors.get(className); + if (result == null) { + if (JAXXCompilerLaunchor.isRegistred() && JAXXCompilerLaunchor.get().getSymbolTable(className) != null) { + result = createClassDescriptorFromSymbolTable(className, classLoader); + } else { + if (classLoader == null) { + classLoader = ClassDescriptorLoader.class.getClassLoader(); + } + + String relativePath = className.replaceAll("\\.", "/"); + String relativePathPattern = ".*";// + className + ".*"; // used to ensure that the located resource has the right character cases + + // find the most recently updated source for the class -- Java source, JAXX source, or compiled class file + long javaLastModified = -1; + URL javaFile = classLoader.getResource(relativePath + ".java"); + if (javaFile != null && javaFile.toString().startsWith("file:") && javaFile.toString().matches(relativePathPattern)) { + javaLastModified = JAXXCompiler.URLtoFile(javaFile).lastModified(); + } + + long classLastModified = -1; + URL classFile = classLoader.getResource(relativePath + ".class"); + if (classFile != null && classFile.toString().startsWith("file:") && classFile.toString().matches(relativePathPattern)) { + classLastModified = JAXXCompiler.URLtoFile(classFile).lastModified(); + } + + long jaxxLastModified = -1; + URL jaxxFile = classLoader.getResource(relativePath + ".jaxx"); + if (jaxxFile != null && jaxxFile.toString().startsWith("file:") && jaxxFile.toString().matches(relativePathPattern)) { + File jaxxFilePath = JAXXCompiler.URLtoFile(jaxxFile); + jaxxLastModified = jaxxFilePath.lastModified(); + String simplePath = jaxxFilePath.getPath(); + simplePath = simplePath.substring(0, simplePath.length() - ".jaxx".length()); + File cssFilePath = new File(simplePath + ".css"); + if (cssFilePath.exists()) { + jaxxLastModified = Math.max(jaxxLastModified, cssFilePath.lastModified()); + } + File scriptFilePath = new File(simplePath + ".script"); + if (scriptFilePath.exists()) { + jaxxLastModified = Math.max(jaxxLastModified, scriptFilePath.lastModified()); + } + } + + if (jaxxLastModified != -1 && JAXXCompilerLaunchor.isRegistred() && JAXXCompilerLaunchor.get().getSymbolTable(className) == null) { + jaxxLastModified = -1; // file has been modified, but wasn't included in this + } + // compilation set so we don't have a symbol table + + if (javaLastModified != -1 || classLastModified != -1 || jaxxLastModified != -1) { + if (jaxxLastModified > classLastModified && jaxxLastModified > javaLastModified) { + result = createClassDescriptorFromSymbolTable(className, classLoader); + } else if (javaLastModified > classLastModified && javaLastModified > jaxxLastModified) { + result = createClassDescriptorFromJavaSource(javaFile, classLoader); + } + } + // else work off of the class file. This also handles the case where the class is available, but wasn't in a location where + // we could check its last modified date (in a JAR, over the network, etc.) + if (result == null) { + Class javaClass = getClass(className, classLoader); + result = createClassDescriptorFromClass(javaClass); + } + } + descriptors.put(className, result); + } + return result; + } + + + public static ClassDescriptor getClassDescriptor(Class javaClass) { + try { + return getClassDescriptor(javaClass.getName(), javaClass.getClassLoader()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + public static Class getClass(String className, ClassLoader classLoader) throws ClassNotFoundException { + if (className.equals("boolean")) { + return boolean.class; + } + if (className.equals("byte")) { + return byte.class; + } + if (className.equals("short")) { + return short.class; + } + if (className.equals("int")) { + return int.class; + } + if (className.equals("long")) { + return long.class; + } + if (className.equals("float")) { + return float.class; + } + if (className.equals("double")) { + return double.class; + } + if (className.equals("char")) { + return char.class; + } + int arrayCount = 0; + while (className.endsWith("[]")) { + arrayCount++; + className = className.substring(0, className.length() - 2); + } + if (arrayCount > 0) { + className = "L" + className + ";"; + while (arrayCount > 0) { + className = "[" + className; + arrayCount--; + } + } + try { + return classLoader != null ? Class.forName(className, true, classLoader) : Class.forName(className); + } catch (ClassNotFoundException e) { + // perharps we are in a inner class ? + int dotIndex = className.lastIndexOf("."); + if (dotIndex > -1) { + String parentFQN = className.substring(0, dotIndex); + String simpleName = className.substring(dotIndex + 1); + try { + Class<?> parentClass = classLoader != null ? Class.forName(parentFQN, true, classLoader) : Class.forName(parentFQN); + for (Class<?> innerClass : parentClass.getClasses()) { + if (simpleName.equals(innerClass.getSimpleName())) { + return innerClass; + } + } + } catch (ClassNotFoundException e1) { + // no super class,so let the first exception throw... + } + } + throw e; + } + catch (NoClassDefFoundError e) { + + throw new ClassNotFoundException(e.toString()); + } + } + + + private static MethodDescriptor createMethodDescriptor(Method javaMethod, ClassLoader classLoader) { + String methodName = javaMethod.getName(); + int modifiers = javaMethod.getModifiers(); + String returnType = javaMethod.getReturnType().getName(); + Class[] javaParameters = javaMethod.getParameterTypes(); + String[] parameters = new String[javaParameters.length]; + for (int i = 0; i < parameters.length; i++) { + parameters[i] = javaParameters[i].getName(); + } + return new MethodDescriptor(methodName, modifiers, returnType, parameters, classLoader); + } + + + private static FieldDescriptor createFieldDescriptor(Field javaField, ClassLoader classLoader) { + String fieldName = javaField.getName(); + int modifiers = javaField.getModifiers(); + String type = javaField.getType().getName(); + return new FieldDescriptor(fieldName, modifiers, type, classLoader); + } + + + private static JAXXObjectDescriptor getJAXXObjectDescriptor(Class<?> jaxxClass) { + if (!JAXXObject.class.isAssignableFrom(jaxxClass) || jaxxClass == JAXXObject.class) { + return null; + } + try { + Method getJAXXObjectDescriptor = jaxxClass.getMethod("$getJAXXObjectDescriptor", new Class[0]); + return (JAXXObjectDescriptor) getJAXXObjectDescriptor.invoke(null); + } + catch (NoSuchMethodException e) { + throw new CompilerException("Expected JAXXObject " + jaxxClass.getName() + " to have a static method named $getJAXXObjectDescriptor"); + } + catch (IllegalAccessException e) { + throw new CompilerException("Expected JAXXObject " + jaxxClass.getName() + "'s $getJAXXObjectDescriptor method to be public"); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + + private static ClassDescriptor createClassDescriptorFromJavaSource(URL javaSource, ClassLoader classLoader) throws ClassNotFoundException { + try { + InputStream in = javaSource.openStream(); + Reader reader = new InputStreamReader(in, "utf-8"); + ClassDescriptor result = JavaFileParser.parseJavaFile(javaSource.toString(), reader, classLoader); + reader.close(); + return result; + } + catch (IOException e) { + throw new ClassNotFoundException(e.toString()); + } + } + + + private static ClassDescriptor createClassDescriptorFromSymbolTable(String className, ClassLoader classLoader) throws ClassNotFoundException { + final JAXXCompiler compiler = JAXXCompilerLaunchor.get().getJAXXCompiler(className); + final SymbolTable symbolTable = JAXXCompilerLaunchor.get().getSymbolTable(className); + if (symbolTable == null) { + throw new CompilerException("Internal error: no symbol table was generated for class '" + className + "'"); + } + ClassDescriptor superclass = getClassDescriptor(symbolTable.getSuperclassName(), classLoader); + List<MethodDescriptor> publicMethods = symbolTable.getScriptMethods(); + List<FieldDescriptor> publicFields = symbolTable.getScriptFields(); + //List<MethodDescriptor> declaredMethods = new ArrayList<MethodDescriptor>(publicMethods); + //List<FieldDescriptor> declaredFields = new ArrayList<FieldDescriptor>(publicFields); + Iterator<MethodDescriptor> methods = publicMethods.iterator(); + while (methods.hasNext()) { + MethodDescriptor method = methods.next(); + if (!Modifier.isPublic(method.getModifiers())) { + methods.remove(); + } + } + Iterator<FieldDescriptor> fields = publicFields.iterator(); + while (fields.hasNext()) { + FieldDescriptor field = fields.next(); + if (!Modifier.isPublic(field.getModifiers())) { + fields.remove(); + } + } + publicMethods.addAll(Arrays.asList(superclass.getMethodDescriptors())); + publicFields.addAll(Arrays.asList(superclass.getFieldDescriptors())); + int dotPos = className.lastIndexOf("."); + String packageName = dotPos != -1 ? className.substring(0, dotPos) : null; + Set<String> interfaces = new HashSet<String>(); + ClassDescriptor[] superclassInterfaces = superclass.getInterfaces(); + for (ClassDescriptor superclassInterface : superclassInterfaces) { + interfaces.add(superclassInterface.getName()); + } + interfaces.add(JAXXObject.class.getName()); + return new ClassDescriptor(className, packageName, symbolTable.getSuperclassName(), + (String[]) interfaces.toArray(new String[interfaces.size()]), false, false, null, null, classLoader, + (MethodDescriptor[]) publicMethods.toArray(new MethodDescriptor[publicMethods.size()]), + (FieldDescriptor[]) publicFields.toArray(new FieldDescriptor[publicFields.size()])) { + public FieldDescriptor getDeclaredFieldDescriptor(String name) throws NoSuchFieldException { + String type = symbolTable.getClassTagIds().get(name); + if (type != null) { + return new FieldDescriptor(name, Modifier.PROTECTED, type, compiler.getClassLoader()); + } + throw new NoSuchFieldException(name); + } + + + public MethodDescriptor getDeclaredMethodDescriptor(String name, ClassDescriptor... parameterTypes) throws NoSuchMethodException { + throw new NoSuchMethodException(name); + } + + @Override + public JAXXObjectDescriptor getJAXXObjectDescriptor() { + return compiler.getJAXXObjectDescriptor(); + } + }; + } + + + private static ClassDescriptor createClassDescriptorFromClass(final Class<?> javaClass) { + String name = javaClass.getName(); + Package p = javaClass.getPackage(); + String packageName = p != null ? p.getName() : null; + Class superclass = javaClass.getSuperclass(); + String superclassName = superclass != null ? superclass.getName() : null; + Class[] interfaces = javaClass.getInterfaces(); + String[] interfaceNames = new String[interfaces.length]; + for (int i = 0; i < interfaces.length; i++) { + interfaceNames[i] = interfaces[i].getName(); + } + boolean isInterface = javaClass.isInterface(); + boolean isArray = javaClass.isArray(); + String componentTypeName = isArray ? javaClass.getComponentType().getName() : null; + JAXXObjectDescriptor jaxxObjectDescriptor = getJAXXObjectDescriptor(javaClass); + ClassLoader classLoader = javaClass.getClassLoader(); + Method[] javaMethods = javaClass.getMethods(); + MethodDescriptor[] methods = new MethodDescriptor[javaMethods.length]; + for (int i = 0; i < methods.length; i++) { + methods[i] = createMethodDescriptor(javaMethods[i], javaClass.getClassLoader()); + } + Field[] javaFields = javaClass.getFields(); + FieldDescriptor[] fields = new FieldDescriptor[javaFields.length]; + for (int i = 0; i < fields.length; i++) { + fields[i] = createFieldDescriptor(javaFields[i], javaClass.getClassLoader()); + } + return new ClassDescriptor(name, packageName, superclassName, interfaceNames, isInterface, isArray, componentTypeName, jaxxObjectDescriptor, classLoader, methods, fields) { + public FieldDescriptor getDeclaredFieldDescriptor(String name) throws NoSuchFieldException { + return createFieldDescriptor(javaClass.getDeclaredField(name), javaClass.getClassLoader()); + } + + public MethodDescriptor getDeclaredMethodDescriptor(String name, ClassDescriptor... parameterTypes) throws NoSuchMethodException { + try { + Class[] parameterTypeClasses = new Class[parameterTypes.length]; + for (int i = 0; i < parameterTypes.length; i++) { + parameterTypeClasses[i] = Class.forName(parameterTypes[i].getName()); + } + return createMethodDescriptor(javaClass.getDeclaredMethod(name, parameterTypeClasses), javaClass.getClassLoader()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + }; + } + + public static void checkSupportClass(Class<?> handlerClass, ClassDescriptor beanClass, Class<?>... tagClasses) { + for (Class<?> tagClass : tagClasses) { + if (getClassDescriptor(tagClass).isAssignableFrom(beanClass)) { + return; + } + } + throw new IllegalArgumentException(handlerClass.getName() + " does not support the class " + beanClass.getName()); + } + + public static void reset() { + descriptors.clear(); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/FieldDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/reflect/FieldDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/FieldDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/FieldDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,27 @@ +package jaxx.reflect; + +/** + * Mirrors the class <code>java.lang.ref.Field</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code> + * almost everywhere so that it can handle circular dependencies (there can't be a <code>Class</code> object for an uncompiled + * JAXX or Java source file, and a compiler must be allow references to symbols in uncompiled source files in order to handle + * circular dependencies). + */ +public class FieldDescriptor extends MemberDescriptor { + private String type; + + + public FieldDescriptor(String name, int modifiers, String type, ClassLoader classLoader) { + super(name, modifiers, classLoader); + this.type = type; + } + + + public ClassDescriptor getType() { + try { + return ClassDescriptorLoader.getClassDescriptor(type, getClassLoader()); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/JavaFileParser.java (from rev 1096, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/reflect/JavaFileParser.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/JavaFileParser.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/JavaFileParser.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,227 @@ +package jaxx.reflect; + +import jaxx.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerLaunchor; +import jaxx.parser.JavaParser; +import jaxx.parser.JavaParserTreeConstants; +import jaxx.parser.ParseException; +import jaxx.parser.SimpleNode; +import jaxx.tags.TagManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.Reader; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.List; + +// TODO: need to unify this implementation with the parsing in ScriptManager +public class JavaFileParser { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(JavaFileParser.class); + + + private JAXXCompiler compiler; + private String className; + private String packageName = null; + private String superclass = "java.lang.Object"; + private List<MethodDescriptor> methods = new ArrayList<MethodDescriptor>(); + private List<FieldDescriptor> fields = new ArrayList<FieldDescriptor>(); + + + private JavaFileParser(ClassLoader classLoader) { + compiler = JAXXCompilerLaunchor.createDummyCompiler(classLoader); + } + + public static ClassDescriptor parseJavaFile(String displayName, Reader src, ClassLoader classLoader) throws ClassNotFoundException { + // has some limitations -- it reports all members as public, leaves getDeclaredMethod and getDeclaredField + // undefined, and doesn't report interfaces. It's safe to leave those the way they are for now, because + // JAXX doesn't look at any of those for non-JAXX classes. + JavaFileParser parser = new JavaFileParser(classLoader); + if (log.isDebugEnabled()) { + log.debug("starting parsing : " + displayName); + } + try { + parser.doParse(displayName, src); + } catch (Exception e) { + log.error(e.getMessage()); + throw new RuntimeException(e); + } + + List<MethodDescriptor> publicMethods = parser.methods; + List<FieldDescriptor> publicFields = parser.fields; + //List/*<MethodDescriptor>*/ declaredMethods = new ArrayList/*<MethodDescriptor>*/(publicMethods); + //List/*<FieldDescriptor>*/ declaredFields = new ArrayList/*<FieldDescriptor>*/(publicFields); + Iterator<MethodDescriptor> methods = publicMethods.iterator(); + while (methods.hasNext()) { + MethodDescriptor method = methods.next(); + if (!Modifier.isPublic(method.getModifiers())) { + methods.remove(); + } + } + Iterator<FieldDescriptor> fields = publicFields.iterator(); + while (fields.hasNext()) { + FieldDescriptor field = fields.next(); + if (!Modifier.isPublic(field.getModifiers())) { + fields.remove(); + } + } + ClassDescriptor superclassDescriptor = ClassDescriptorLoader.getClassDescriptor(parser.superclass, classLoader); + publicMethods.addAll(Arrays.asList(superclassDescriptor.getMethodDescriptors())); + publicFields.addAll(Arrays.asList(superclassDescriptor.getFieldDescriptors())); + //Set<String> interfaces = new HashSet<String>(); + //ClassDescriptor[] superclassInterfaces = superclassDescriptor.getInterfaces(); + //for (ClassDescriptor superclassInterface : superclassInterfaces) { + //interfaces.add(superclassInterface.getName()); + //} + return new ClassDescriptor(parser.className, parser.packageName, parser.superclass, new String[0], false, false, null, null, classLoader, + (MethodDescriptor[]) publicMethods.toArray(new MethodDescriptor[publicMethods.size()]), + (FieldDescriptor[]) publicFields.toArray(new FieldDescriptor[publicFields.size()])) { + public FieldDescriptor getDeclaredFieldDescriptor(String name) throws NoSuchFieldException { + throw new NoSuchFieldException(name); + } + + public MethodDescriptor getDeclaredMethodDescriptor(String name, ClassDescriptor... parameterTypes) throws NoSuchMethodException { + throw new NoSuchMethodException(name); + } + }; + } + + + private void doParse(String displayName, Reader src) { + try { + JavaParser p = new JavaParser(src); + p.CompilationUnit(); + SimpleNode node = p.popNode(); + if (node != null) { + scanCompilationUnit(node); + return; + } + throw new CompilerException("Internal error: null node parsing Java file from " + src); + } + catch (ParseException e) { + throw new CompilerException("Error parsing Java source code " + displayName + ": " + e.getMessage()); + } + } + + + private void scanCompilationUnit(SimpleNode node) { + for (int i = 0; i < node.jjtGetNumChildren(); i++) { + SimpleNode child = node.getChild(i); + int nodeType = child.getId(); + if (nodeType == JavaParserTreeConstants.JJTPACKAGEDECLARATION) { + packageName = child.getChild(1).getText().trim(); + compiler.addImport(packageName + ".*"); + } else + if (nodeType == JavaParserTreeConstants.JJTIMPORTDECLARATION) { + String text = child.getText().trim(); + if (text.startsWith("import")) { + text = text.substring("import".length()).trim(); + } + if (text.endsWith(";")) { + text = text.substring(0, text.length() - 1); + } + compiler.addImport(text); + } else if (nodeType == JavaParserTreeConstants.JJTTYPEDECLARATION) { + scanCompilationUnit(child); + } else + if (nodeType == JavaParserTreeConstants.JJTCLASSORINTERFACEDECLARATION) { + scanClass(child); + } + } + } + + + // scans the main ClassOrInterfaceDeclaration + private void scanClass(SimpleNode node) { + boolean isInterface = node.firstToken.image.equals("interface"); + className = node.firstToken.next.image; + if (packageName != null) + className = packageName + "." + className; + for (int i = 0; i < node.jjtGetNumChildren(); i++) { + SimpleNode child = node.getChild(i); + int nodeType = child.getId(); + if (nodeType == JavaParserTreeConstants.JJTEXTENDSLIST) { + if (!isInterface) { + assert child.jjtGetNumChildren() == 1 : "expected ExtendsList to have exactly one child for a non-interface class"; + String rawName = child.getChild(0).getText().trim(); + superclass = TagManager.resolveClassName(rawName, compiler); + if (superclass == null) { + throw new CompilerException("Could not find class: " + rawName); + } + } + } else + if (nodeType == JavaParserTreeConstants.JJTCLASSORINTERFACEBODY) { + scanClassNode(child); + } + } + } + + + // scans class body nodes + private void scanClassNode(SimpleNode node) { + int nodeType = node.getId(); + if (nodeType == JavaParserTreeConstants.JJTMETHODDECLARATION) { + String returnType = null; + String name = null; + List<String> parameterTypes = new ArrayList<String>(); + //List<String> parameterNames = new ArrayList<String>(); + for (int i = 0; i < node.jjtGetNumChildren(); i++) { + SimpleNode child = node.getChild(i); + int type = child.getId(); + if (type == JavaParserTreeConstants.JJTRESULTTYPE) + returnType = TagManager.resolveClassName(child.getText().trim(), compiler); + else if (type == JavaParserTreeConstants.JJTMETHODDECLARATOR) { + name = child.firstToken.image.trim(); + SimpleNode formalParameters = child.getChild(0); + assert formalParameters.getId() == JavaParserTreeConstants.JJTFORMALPARAMETERS; + for (int j = 0; j < formalParameters.jjtGetNumChildren(); j++) + { + SimpleNode parameter = formalParameters.getChild(j); + String rawParameterType = parameter.getChild(1).getText().trim().replaceAll("\\.\\.\\.", "[]"); + String parameterType = TagManager.resolveClassName(rawParameterType, compiler); + if (parameterType == null && JAXXCompiler.STRICT_CHECKS) { + throw new CompilerException("could not find class '" + rawParameterType + "'"); + } + parameterTypes.add(parameterType); + //parameterNames.add(parameter.getChild(2).getText().trim()); + } + } + } + methods.add(new MethodDescriptor(name, Modifier.PUBLIC, returnType, parameterTypes.toArray(new String[parameterTypes.size()]), compiler.getClassLoader())); // TODO: determine the actual modifiers + } else + if (nodeType == JavaParserTreeConstants.JJTCLASSORINTERFACEDECLARATION) { + // TODO: handle inner classes + } else + if (nodeType == JavaParserTreeConstants.JJTCONSTRUCTORDECLARATION) { + // TODO: handle constructors + } else if (nodeType == JavaParserTreeConstants.JJTFIELDDECLARATION) { + String text = node.getText(); + String declaration = text; + int equals = text.indexOf("="); + if (equals != -1) { + declaration = declaration.substring(0, equals); + } + declaration = declaration.trim(); + String[] declarationTokens = declaration.split("\\s"); + //boolean isFinal = Arrays.asList(declarationTokens).contains("final"); + //boolean isStatic = Arrays.asList(declarationTokens).contains("static"); + String name = declarationTokens[declarationTokens.length - 1]; + if (name.endsWith(";")) { + name = name.substring(0, name.length() - 1).trim(); + } + String className = declarationTokens[declarationTokens.length - 2]; + String type = TagManager.resolveClassName(className, compiler); + fields.add(new FieldDescriptor(name, Modifier.PUBLIC, type, compiler.getClassLoader())); // TODO: determine the actual modifiers + } else { + for (int i = 0; i < node.jjtGetNumChildren(); i++) { + SimpleNode child = node.getChild(i); + scanClassNode(child); + } + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MemberDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/reflect/MemberDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MemberDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MemberDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,40 @@ +package jaxx.reflect; + +/** + * Mirrors the class <code>java.lang.ref.Member</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code> + * almost everywhere so that it can handle circular dependencies (there can't be a <code>Class</code> object for an uncompiled + * JAXX or Java source file, and a compiler must be allow references to symbols in uncompiled source files in order to handle + * circular dependencies). + */ +public abstract class MemberDescriptor { + private String name; + private int modifiers; + private ClassLoader classLoader; + + + MemberDescriptor(String name, int modifiers, ClassLoader classLoader) { + this.name = name; + this.modifiers = modifiers; + this.classLoader = classLoader; + } + + + public String getName() { + return name; + } + + + public int getModifiers() { + return modifiers; + } + + + protected ClassLoader getClassLoader() { + return classLoader; + } + + @Override + public String toString() { + return getClass().getName() + "[" + getName() + "]"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MethodDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/reflect/MethodDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MethodDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/reflect/MethodDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,50 @@ +package jaxx.reflect; + +import jaxx.compiler.JAXXCompiler; + +/** + * Mirrors the class <code>java.lang.ref.Method</code>. JAXX uses <code>ClassDescriptor</code> instead of <code>Class</code> + * almost everywhere so that it can handle circular dependencies (there can't be a <code>Class</code> object for an uncompiled + * JAXX or Java source file, and a compiler must be allow references to symbols in uncompiled source files in order to handle + * circular dependencies). + */ +public class MethodDescriptor extends MemberDescriptor { + private String returnType; + private String[] parameterTypes; + + + public MethodDescriptor(String name, int modifiers, String returnType, String[] parameterTypes, ClassLoader classLoader) { + super(name, modifiers, classLoader); + this.returnType = returnType; + this.parameterTypes = parameterTypes; + if (JAXXCompiler.STRICT_CHECKS && java.util.Arrays.asList(parameterTypes).contains(null)) { + throw new NullPointerException(name); + } + } + + + public ClassDescriptor getReturnType() { + try { + return ClassDescriptorLoader.getClassDescriptor(returnType); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + + public ClassDescriptor[] getParameterTypes() { + ClassDescriptor[] result = new ClassDescriptor[parameterTypes.length]; + try { + for (int i = 0; i < result.length; i++) { + if (parameterTypes[i] != null) { + result[i] = ClassDescriptorLoader.getClassDescriptor(parameterTypes[i], getClassLoader()); + } + } + return result; + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/spi/Initializer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/spi/Initializer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/spi/Initializer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/spi/Initializer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,15 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.spi; + +/** + * Performs SPI initialization, typically to register new tags, beans and converter. + * <p/> + * <b>Note:</b> To load such Initializer, we use the {@link java.util.ServiceLoader} mecanism. + */ +public interface Initializer { + /** Performs SPI initialization, typically to register new tags, beans and converter */ + void initialize(); +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultComponentHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultComponentHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultComponentHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultComponentHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,263 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.I18nHelper; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; + +import java.awt.Component; +import java.awt.Container; +import java.awt.event.ComponentListener; +import java.awt.event.ContainerListener; +import java.awt.event.FocusListener; +import java.beans.IntrospectionException; +import java.io.IOException; +import java.lang.reflect.Field; + +public class DefaultComponentHandler extends DefaultObjectHandler { + /** log */ + protected static final Log log = LogFactory.getLog(DefaultComponentHandler.class); + + private String containerDelegate; + + public DefaultComponentHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, Component.class); + } + + @Override + protected void init() throws IntrospectionException { + if (jaxxBeanInfo == null) { + super.init(); + + containerDelegate = (String) getJAXXBeanInfo().getJAXXBeanDescriptor().getValue("containerDelegate"); + if (containerDelegate == null && ClassDescriptorLoader.getClassDescriptor(Container.class).isAssignableFrom(getBeanClass().getSuperclass())) { + containerDelegate = ((DefaultComponentHandler) TagManager.getTagHandler(getBeanClass().getSuperclass())).getContainerDelegate(); + } + } + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("hasFocus", FocusListener.class); + addProxyEventInfo("isVisible", ComponentListener.class); + addProxyEventInfo("getBounds", ComponentListener.class); + addProxyEventInfo("getLocation", ComponentListener.class); + addProxyEventInfo("getLocationOnScreen", ComponentListener.class); + addProxyEventInfo("getSize", ComponentListener.class); + addProxyEventInfo("getX", ComponentListener.class); + addProxyEventInfo("getY", ComponentListener.class); + addProxyEventInfo("getWidth", ComponentListener.class); + addProxyEventInfo("getHeight", ComponentListener.class); + if (ClassDescriptorLoader.getClassDescriptor(Container.class).isAssignableFrom(getBeanClass())) { + addProxyEventInfo("getComponentCount", ContainerListener.class); + } + } + + @Override + protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + super.setDefaults(object, tag, compiler); + setAttribute(object, "name", object.getId(), false, compiler); + openComponent(object, tag, compiler); + } + + @Override + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + super.compileFirstPass(tag, compiler); + } + + @Override + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + super.compileSecondPass(tag, compiler); + closeComponent(compiler.getOpenComponent(), tag, compiler); + } + + + protected void openComponent(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + String constraints = tag.getAttribute("constraints"); + if (constraints != null && constraints.length() > 0) { + compiler.openComponent(object, constraints); + } else { + compiler.openComponent(object); + } + } + + protected void closeComponent(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + compiler.closeComponent(object); + } + + @Override + public boolean isPropertyInherited(String property) throws UnsupportedAttributeException { + return property.equals("font") || property.startsWith("font-") || property.equals("foreground") || property.equals("enabled"); + } + + @Override + public ClassDescriptor getPropertyType(CompiledObject object, String propertyName, JAXXCompiler compiler) throws CompilerException { + if (propertyName.equals("x") || propertyName.equals("y") || propertyName.equals("width") || propertyName.equals("height") || + "font-size".equals(propertyName)) { + return ClassDescriptorLoader.getClassDescriptor(Integer.class); + } + if (propertyName.equals("font-face") || propertyName.equals("font-style") || propertyName.equals("font-weight")) { + return ClassDescriptorLoader.getClassDescriptor(String.class); + } + return super.getPropertyType(object, propertyName, compiler); + } + + @Override + public String getGetPropertyCode(String id, String name, JAXXCompiler compiler) throws CompilerException { + if (name.equals("font-face")) { + return id + ".getFont().getFontName()"; + } + if (name.equals("font-size")) { + return id + ".getFont().getSize()"; + } + if (name.equals("font-weight")) { + return "(" + id + ".getFont().getStyle() & Font.BOLD) != 0 ? \"bold\" : \"normal\""; + } + if (name.equals("font-style")) { + return "(" + id + ".getFont().getStyle() & Font.ITALIC) != 0 ? \"italic\" : \"normal\""; + } + return super.getGetPropertyCode(id, name, compiler); + } + + @Override + public String getSetPropertyCode(String id, String name, String valueCode, JAXXCompiler compiler) throws CompilerException { + if (name.equals("x")) { + return id + ".setLocation(" + valueCode + ", " + id + ".getY());"; + } + if (name.equals("y")) { + return id + ".setLocation(" + id + ".getX(), " + valueCode + ");"; + } + if (name.equals("width")) { // need to optimize case when both width and height are being assigned + return "jaxx.runtime.Util.setComponentWidth(" + id + "," + valueCode + ");\n"; + } + if (name.equals("height")) { + return "jaxx.runtime.Util.setComponentHeight(" + id + "," + valueCode + ");\n"; + } + if (name.equals("font-face")) { + return "if (" + id + ".getFont() != null) " + id + ".setFont(new Font(" + valueCode + ", " + id + ".getFont().getStyle(), " + id + ".getFont().getSize()));"; + } + if (name.equals("font-size")) { + return "if (" + id + ".getFont() != null) " + id + ".setFont(" + id + ".getFont().deriveFont((float) " + valueCode + "));"; + } + if (name.equals("font-weight")) { + if (valueCode.equals("\"bold\"")) { + return "if (" + id + ".getFont() != null) " + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() | Font.BOLD));"; + } + if (valueCode.equals("\"normal\"")) { + return "if (" + id + ".getFont() != null) " + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() & ~Font.BOLD));"; + } + if (!valueCode.startsWith("\"")) { + return "if (" + id + ".getFont() != null) { if ((" + valueCode + ").equals(\"bold\")) " + + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() | Font.BOLD)); else " + + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() & ~Font.BOLD)); }"; + } + compiler.reportError("font-weight must be either \"normal\" or \"bold\", found " + valueCode); + return ""; + } + if (name.equals("font-style")) { + if (valueCode.equals("\"italic\"")) { + return "if (" + id + ".getFont() != null) " + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() | Font.ITALIC));"; + } + if (valueCode.equals("\"normal\"")) { + return "if (" + id + ".getFont() != null) " + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() & ~Font.ITALIC));"; + } + if (!valueCode.startsWith("\"")) { + return "if (" + id + ".getFont() != null) { if ((" + valueCode + ").equals(\"italic\")) " + + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() | Font.ITALIC)); else " + + id + ".setFont(" + id + ".getFont().deriveFont(" + id + ".getFont().getStyle() & ~Font.ITALIC)); }"; + } + compiler.reportError("font-style must be either \"normal\" or \"italic\", found " + valueCode); + return ""; + } + if (ClassDescriptorLoader.getClassDescriptor(Container.class).isAssignableFrom(getBeanClass()) && name.equals("layout")) { // handle containerDelegate (e.g. contentPane on JFrame) + String containerDelegate = (String) getJAXXBeanInfo().getJAXXBeanDescriptor().getValue("containerDelegate"); + if (containerDelegate != null) { + return id + '.' + containerDelegate + "().setLayout(" + valueCode + ");"; + } + } + // ajout du support i18n + if (I18nHelper.isI18nableAttribute(name, compiler)) { + valueCode = I18nHelper.addI18nInvocation(id, name, valueCode, compiler); + } + + return super.getSetPropertyCode(id, name, valueCode, compiler); + } + + + /** + * Maps string values onto integers, so that int-valued enumeration properties can be specified by strings. For + * example, when passed a key of 'alignment', this method should normally map the values 'left', 'center', and + * 'right' onto SwingConstants.LEFT, SwingConstants.CENTER, and SwingConstants.RIGHT respectively. + * <p/> + * You do not normally need to call this method yourself; it is invoked by {@link #convertFromString} when an + * int-valued property has a value which is not a valid number. By default, this method looks at the + * <code>enumerationValues</code> value of the <code>JAXXPropertyDescriptor</code>. + * + * @param key the name of the int-typed property + * @param value the non-numeric value that was specified for the property + * @throws IllegalArgumentException if the property is an enumeration, but the value is not valid + * @throws NumberFormatException if the property is not an enumeration + */ + protected int constantValue(String key, String value) { + if ((key.equals("mnemonic") || key.equals("displayedMnemonic"))) { + if (value.length() == 1) { + return value.charAt(0); + } + try { + Field vk = java.awt.event.KeyEvent.class.getField(value); + return (Integer) vk.get(null); + } catch (NoSuchFieldException e) { + throw new IllegalArgumentException("mnemonics must be either a single character or the name of a field in KeyEvent (found: '" + value + "')"); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } + return super.constantValue(key, value); + } + + + /** + * Returns <code>true</code> if this component can contain other components. For children to be + * allowed, the component must be a subclass of <code>Container</code> and its <code>JAXXBeanInfo</code> + * must not have the value <code>false</code> for its <code>isContainer</code> value. + * + * @return <code>true</code> if children are allowed + */ + public boolean isContainer() { + boolean container = ClassDescriptorLoader.getClassDescriptor(Container.class).isAssignableFrom(getBeanClass()); + if (container) { + try { + init(); + if (Boolean.FALSE.equals(getJAXXBeanInfo().getJAXXBeanDescriptor().getValue("isContainer"))) { + container = false; + } + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + } + return container; + } + + + public String getContainerDelegate() { + try { + init(); + return containerDelegate; + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultObjectHandler.java (from rev 1097, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultObjectHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,1136 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JavaArgument; +import jaxx.compiler.JavaMethod; +import jaxx.css.Stylesheet; +import jaxx.css.StylesheetHelper; +import jaxx.introspection.JAXXBeanInfo; +import jaxx.introspection.JAXXEventSetDescriptor; +import jaxx.introspection.JAXXIntrospector; +import jaxx.introspection.JAXXPropertyDescriptor; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.FieldDescriptor; +import jaxx.reflect.MethodDescriptor; +import jaxx.runtime.ComponentDescriptor; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.JAXXObjectDescriptor; +import jaxx.types.TypeManager; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyChangeListener; +import java.io.IOException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +/** + * Default handler for class tags. Class tags are tags which represent instances of Java classes, + * such as <code><JButton label='Close'/></code>. <code>DefaultObjectHandler</code> + * provides support for attributes and events which adhere to JavaBeans naming conventions as + * well as basic JAXX features like the <code>id</code> attribute and data binding by means of + * curly braces. + * <p/> + * Throughout this class, the word "member" refers to the name of a field or method (e.g. + * <code>"getDocument"</code>) and the word "property" refers to the JavaBeans-style simple + * name of a property (e.g. <code>"document"</code>). + */ +public class DefaultObjectHandler implements TagHandler { + /** The class that this handler provides support for. */ + private ClassDescriptor beanClass; + + /** The JAXXBeanInfo for the beanClass. */ + protected JAXXBeanInfo jaxxBeanInfo; + + /** Maps property names to their respective JAXXPropertyDescriptors. */ + private Map<String, JAXXPropertyDescriptor> properties; + + /** Maps event names to their respective JAXXEventSetDescriptors. */ + private Map<String, JAXXEventSetDescriptor> events; + + /** Maps property names to their respective ProxyEventInfos. */ + private Map<String, ProxyEventInfo> eventInfos; + + /** Maps XML tags to the CompiledObjects created from them. */ + protected static Map<Element, CompiledObject> objectMap = new WeakHashMap<Element, CompiledObject>(); + + /** + * Encapsulates information about a "proxy event handler", which is an event handler that + * fires PropertyChangeEvents when it is triggered. ProxyEventInfos simplify the data binding + * system by allowing all dependencies to fire the same kind of event even if they would + * normally throw something else, like <code>DocumentEvent</code>. + */ + private class ProxyEventInfo { + /** The name of the method or field being proxied, e.g. "getText". */ + String memberName; + + /** The "actual" event listener for the property in question, e.g. DocumentListener. */ + ClassDescriptor listenerClass; + + /** + * In cases where a different object (such as a model) is more directly responsible for + * managing the property, this is the name of the property where that object can be + * found, e.g. "document" (which is turned into a call to "getDocument()"). This property + * is also treated as a dependency of the data binding expression, and any updates to it + * (assuming it is bound) will cause the listener to be removed from the old value and + * attached to the new value, and the data binding to be processed. + */ + String modelName; + + /** The name of the method used to add the "native" event listener, e.g. "addDocumentListener". */ + String addMethod; + + /** The name of the method used to remove the "native" event listener, e.g. "removeDocumentListener". */ + String removeMethod; + } + + + /** + * Creates a new <code>DefaultObjectHandler</code> which provides support for the specified class. The + * class is not actually introspected until the {@link #compileFirstPass} method is invoked. + * + * @param beanClass the class which this handler supports + */ + public DefaultObjectHandler(ClassDescriptor beanClass) { + this.beanClass = beanClass; + } + + + /** + * Performs introspection on the beanClass and stores the results. + * + * @throws java.beans.IntrospectionException + * TODO + */ + protected void init() throws IntrospectionException { + if (jaxxBeanInfo == null) { + // perform introspection & cache the results + jaxxBeanInfo = getJAXXBeanInfo(beanClass); + + JAXXPropertyDescriptor[] propertiesArray = jaxxBeanInfo.getJAXXPropertyDescriptors(); + properties = new HashMap<String, JAXXPropertyDescriptor>(); + for (int i = propertiesArray.length - 1; i >= 0; i--) { + properties.put(propertiesArray[i].getName(), propertiesArray[i]); + } + + JAXXEventSetDescriptor[] eventsArray = jaxxBeanInfo.getJAXXEventSetDescriptors(); + events = new HashMap<String, JAXXEventSetDescriptor>(); + for (int i = eventsArray.length - 1; i >= 0; i--) { + MethodDescriptor[] methods = eventsArray[i].getListenerMethods(); + for (MethodDescriptor method : methods) { + events.put(method.getName(), eventsArray[i]); + } + } + + configureProxyEventInfo(); + } + } + + + /** + * Returns + * + * @return the class which this <code>DefaultObjectHandler</code> supports. + */ + public ClassDescriptor getBeanClass() { + return beanClass; + } + + + /** + * @return the <code>JAXXBeanInfo</code> for the class which this <code>DefaultObjectHandler</code> + * supports. + */ + public JAXXBeanInfo getJAXXBeanInfo() { + try { + init(); + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + return jaxxBeanInfo; + } + + + /** + * Returns the <code>JAXXBeanInfo</code> for the specified class. + * + * @param beanClass the bean class for which to retrieve <code>JAXXBeanInfo</code> + * @return the class' <code>JAXXBeanInfo</code> + * @throws java.beans.IntrospectionException + * ? + */ + public static JAXXBeanInfo getJAXXBeanInfo(ClassDescriptor beanClass) throws IntrospectionException { + return JAXXIntrospector.getJAXXBeanInfo(beanClass); + } + + + /** + * Returns the type of the named property. This is the return type of the property's <code>get</code> method; + * for instance <code>JLabel</code>'s <code>text</code> property is a <code>String</code>. + * + * @param object the object being compiled + * @param propertyName the simple JavaBeans-style name of the property + * @param compiler the current <code>JAXXCompiler</code> + * @return the property's type + * @throws CompilerException if the type cannot be determined + */ + public ClassDescriptor getPropertyType(CompiledObject object, String propertyName, JAXXCompiler compiler) { + try { + init(); + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + + JAXXPropertyDescriptor property = properties.get(propertyName); + if (property != null) { + return property.getPropertyType(); + } + throw new UnsupportedAttributeException("property '" + propertyName + "' not found in " + object); + } + + + /** + * @param name ? + * @return <code>true</code> if the named member is <i>bound</i> (fires <code>PropertyChangeEvent</code> + * when modified). Members are either fields (represented by the simple name of the field) or <code>get/is</code> + * methods (represented by the simple name of the method, <b>not</b> the simplified JavaBeans-style name). + * Methods which are not actually bound in their native class, but for which proxy events have been + * configured (such as <code>JTextField.getText</code>, return <code>true</code>. + * @throws jaxx.UnsupportedAttributeException + * ? + */ + public boolean isMemberBound(String name) throws UnsupportedAttributeException { + try { + init(); + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + + if (eventInfos != null && eventInfos.containsKey(name)) { + return true; + } + + if (name.equals("getClass")) { + return false; + } + + String propertyName = null; + if (name.startsWith("get")) { + propertyName = Introspector.decapitalize(name.substring("get".length())); + } else if (name.startsWith("is")) { + propertyName = Introspector.decapitalize(name.substring("is".length())); + } + JAXXPropertyDescriptor property = propertyName != null ? properties.get(propertyName) : null; + if (property != null) { + return property.isBound(); + } + try { + FieldDescriptor field = getBeanClass().getFieldDescriptor(name); + return Modifier.isFinal(field.getModifiers()); // final fields might as well be considered bound -- they can't be modified anyway + } catch (NoSuchFieldException e) { + throw new UnsupportedAttributeException("cannot find property '" + name + "' of " + getBeanClass()); + } + } + + + private static ClassDescriptor getEventClass(ClassDescriptor listenerClass) { + return listenerClass.getMethodDescriptors()[0].getParameterTypes()[0]; + } + + + /** + * @param memberName name of the member + * @return an array of members on which the given property depends. For + * example, the JTextField.getText() member depends upon the getModel() + * member. Returns <code>null</code> if there are no dependencies. + */ + public String[] getMemberDependencies(String memberName) { + ProxyEventInfo eventInfo = eventInfos != null ? eventInfos.get(memberName) : null; + return eventInfo == null ? null : new String[]{eventInfo.modelName}; + } + + + /** + * Returns a snippet of Java code which will cause a <code>PropertyChangeListener</code> to be notified + * when the member's value changes. The <code>PropertyChangeListener</code> is provided in the form + * of a Java code snippet that evaluates to a listener object. + * <p/> + * For ordinary bound JavaBeans properties, the Java code returned is a simple call to + * <code>addPropertyChangeListener</code>. Fields and methods which do not actually fire + * <code>PropertyChangeEvents</code> when they change necessitate more complex code. + * + * @param objectCode Java code which evaluates to the object to which to add the listener + * *@param dataBinding the name of the data binding this listener is a part of + * @param dataBinding databinding + * @param memberName the name of the field or method to listen to + * @param propertyChangeListenerCode Java code which evaluates to a <code>PropertyChangeListener</code> + * @param compiler the current <code>JAXXCompiler</code> + * @return Java code snippet which causes the listener to be added to the object + */ + public String getAddMemberListenerCode(String objectCode, String dataBinding, String memberName, String propertyChangeListenerCode, JAXXCompiler compiler) { + if ("getClass".equals(memberName)) { + return null; + } + + ProxyEventInfo eventInfo = eventInfos != null ? eventInfos.get(memberName) : null; + if (eventInfo != null) { // a "proxied" event is one that doesn't fire PropertyChangeEvent, so we need to convert its native event type into PropertyChangeEvents + StringBuffer result = new StringBuffer(); + String methodName = "$pr" + compiler.getUniqueId(propertyChangeListenerCode); + boolean methodExists = compiler.hasMethod(methodName); + ClassDescriptor eventClass = getEventClass(eventInfo.listenerClass); + if (!methodExists) { + compiler.addMethodToJavaFile(new JavaMethod(Modifier.PUBLIC, "void", methodName, + new JavaArgument[]{new JavaArgument(JAXXCompiler.getCanonicalName(eventClass), "event")}, null, + propertyChangeListenerCode + ".propertyChange(null);")); + } + String code = objectCode + (eventInfo.modelName != null ? ".get" + org.apache.commons.lang.StringUtils.capitalize(eventInfo.modelName) + "()" : ""); + result.append("$bindingSources.put(\"").append(code).append("\", ").append(code).append(");").append(JAXXCompiler.getLineSeparator()); + result.append(code).append('.').append(eventInfo.addMethod).append("((").append(JAXXCompiler.getCanonicalName(eventInfo.listenerClass)).append(") jaxx.runtime.Util.getEventListener(").append(JAXXCompiler.getCanonicalName(eventInfo.listenerClass)).append(".class, ").append(compiler.getRootObject().getJavaCode()).append(", ").append(TypeManager.getJavaCode(methodName)).append("));\n"); + if (eventInfo.modelName != null) { + result.append(getAddMemberListenerCode(objectCode, dataBinding, "get" + org.apache.commons.lang.StringUtils.capitalize(eventInfo.modelName), + "jaxx.runtime.Util.getDataBindingUpdateListener(this , \"" + dataBinding + "\")", + compiler)); + } + return result.toString(); + } else { + String propertyName = null; + if (memberName.startsWith("get")) { + propertyName = Introspector.decapitalize(memberName.substring("get".length())); + } else if (memberName.startsWith("is")) { + propertyName = Introspector.decapitalize(memberName.substring("is".length())); + } else { + try { + getBeanClass().getFieldDescriptor(memberName); + propertyName = memberName; + } catch (NoSuchFieldException e) { + // ignore ? + } + } + if (propertyName != null) { + try { + // check for property-specific addPropertyChangeListener method + getBeanClass().getMethodDescriptor("addPropertyChangeListener", ClassDescriptorLoader.getClassDescriptor(String.class), + ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)); + return objectCode + ".addPropertyChangeListener(\"" + propertyName + "\", " + propertyChangeListenerCode + ");\n"; + } catch (NoSuchMethodException e) { + // no property-specific method, use general one + return objectCode + ".addPropertyChangeListener(" + propertyChangeListenerCode + ");\n"; + } + } + return null; + } + } + + + public String getRemoveMemberListenerCode(String objectCode, String dataBinding, String memberName, String propertyChangeListenerCode, JAXXCompiler compiler) { + if ("getClass".equals(memberName)) { + return null; + } + + ProxyEventInfo eventInfo = eventInfos != null ? eventInfos.get(memberName) : null; + if (eventInfo != null) { // a "proxied" event is one that doesn't fire PropertyChangeEvent, so we need to convert its native event type into PropertyChangeEvents + StringBuffer result = new StringBuffer(); + String methodName = "$pr" + compiler.getUniqueId(propertyChangeListenerCode); + boolean methodExists = compiler.hasMethod(methodName); + if (!methodExists) { + ClassDescriptor eventClass = getEventClass(eventInfo.listenerClass); + compiler.addMethodToJavaFile(new JavaMethod(Modifier.PUBLIC, "void", methodName, + new JavaArgument[]{new JavaArgument(JAXXCompiler.getCanonicalName(eventClass), "event")}, null, + propertyChangeListenerCode + ".propertyChange(null);")); + } + try { + String modelMemberName = eventInfo.modelName != null ? "get" + org.apache.commons.lang.StringUtils.capitalize(eventInfo.modelName) : null; + String modelClassName = modelMemberName != null ? getBeanClass().getMethodDescriptor(modelMemberName).getReturnType().getName() : JAXXCompiler.getCanonicalName(getBeanClass()); + String code = objectCode + (eventInfo.modelName != null ? "." + modelMemberName + "()" : ""); + result.append("((").append(modelClassName).append(") $bindingSources.remove(\"").append(code).append("\")).").append(eventInfo.removeMethod).append("((").append(JAXXCompiler.getCanonicalName(eventInfo.listenerClass)).append(") jaxx.runtime.Util.getEventListener(").append(JAXXCompiler.getCanonicalName(eventInfo.listenerClass)).append(".class, ").append(compiler.getRootObject().getJavaCode()).append(", ").append(TypeManager.getJavaCode(methodName)).append("));\n"); + if (eventInfo.modelName != null) { + result.append(getRemoveMemberListenerCode(objectCode, dataBinding, "get" + org.apache.commons.lang.StringUtils.capitalize(eventInfo.modelName), + "jaxx.runtime.Util.getDataBindingUpdateListener(this, \"" + dataBinding + "\")", + compiler)); + } + return result.toString(); + } + catch (NoSuchMethodException e) { + throw new CompilerException("Internal error: " + e); + } + } else { + String propertyName = null; + if (memberName.startsWith("get")) { + propertyName = Introspector.decapitalize(memberName.substring("get".length())); + } else if (memberName.startsWith("is")) { + propertyName = Introspector.decapitalize(memberName.substring("is".length())); + } else { + try { + getBeanClass().getFieldDescriptor(memberName); + propertyName = memberName; + } catch (NoSuchFieldException e) { + // ignore ? + } + } + if (propertyName != null) { + try { + // check for property-specific removePropertyChangeListener method + getBeanClass().getMethodDescriptor("removePropertyChangeListener", ClassDescriptorLoader.getClassDescriptor(String.class), + ClassDescriptorLoader.getClassDescriptor(PropertyChangeListener.class)); + return objectCode + ".removePropertyChangeListener(\"" + propertyName + "\", " + propertyChangeListenerCode + ");\n"; + } catch (NoSuchMethodException e) { + // no property-specific method, use general one + return objectCode + ".removePropertyChangeListener(" + propertyChangeListenerCode + ");\n"; + } + } + return null; + } + } + + + /** + * Configures the event handling for members which do not fire <code>PropertyChangeEvent</code> when + * modified. The default implementation does nothing. Subclasses should override this method to call + * <code>addProxyEventInfo</code> for each member which requires special handling. + */ + protected void configureProxyEventInfo() { + } + + + /** + * Configures a proxy event handler which fires <code>PropertyChangeEvents</code> when a non-bound + * member is updated. This is necessary for all fields (which cannot be bound) and for methods that are + * not bound property <code>get</code> methods. The proxy event handler will attach the specified kind + * of listener to the class and fire a <code>PropertyChangeEvent</code> whenever the listener receives + * any kind of event. + * <p/> + * Even though this method can theoretically be applied to fields (in addition to methods), it would be an + * unusual situation in which that would actually work -- as fields cannot fire events when modified, it would + * be difficult to have a listener that was always notified when a field value changed. + * + * @param memberName the name of the field or method being proxied + * @param listenerClass the type of listener which receives events when the field or method is updated + */ + public void addProxyEventInfo(String memberName, Class listenerClass) { + addProxyEventInfo(memberName, listenerClass, null); + } + + + /** + * Configures a proxy event handler which fires <code>PropertyChangeEvents</code> when a non-bound + * member is updated. This is necessary for all fields (which cannot be bound) and for methods that are + * not bound property <code>get</code> methods. This variant attaches a listener to a property of the + * object (such as <code>model</code>) and not the object itself, which is useful when there is a model + * that is the "real" container of the information. The proxy event handler will attach the specified kind + * of listener to the property's value (retrieved using the property's <code>get</code> method) and fire + * a <code>PropertyChangeEvent</code> whenever the listener receives any kind of event. + * <p/> + * If the property is itself bound (typically the case with models), any updates to the property's value will + * cause the listener to be removed from the old property value and reattached to the new property value, + * as well as cause a <code>PropertyChangeEvent</code> to be fired. + * <p/> + * Even though this method can theoretically be applied to fields (in addition to methods), it would be an + * unusual situation in which that would actually work -- as fields cannot fire events when modified, it would + * be difficult to have a listener that was always notified when a field value changed. + * + * @param memberName the name of the field or method being proxied + * @param listenerClass the type of listener which receives events when the field or method is updated + * @param modelName the JavaBeans-style name of the model property + */ + public void addProxyEventInfo(String memberName, Class listenerClass, String modelName) { + String listenerName = listenerClass.getName(); + listenerName = listenerName.substring(listenerName.lastIndexOf(".") + 1); + addProxyEventInfo(memberName, listenerClass, modelName, "add" + listenerName, "remove" + listenerName); + } + + + // TODO: remove this temporary method, complete switchover to ClassDescriptors + public void addProxyEventInfo(String memberName, Class listenerClass, + String modelName, String addMethod, String removeMethod) { + try { + addProxyEventInfo(memberName, ClassDescriptorLoader.getClassDescriptor(listenerClass.getName()), modelName, addMethod, removeMethod); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + } + + + /** + * Configures a proxy event handler which fires <code>PropertyChangeEvents</code> when a non-bound + * member is updated. This is necessary for all fields (which cannot be bound) and for methods that are + * not bound property <code>get</code> methods. This variant attaches a listener to a property of the + * object (such as <code>model</code>) and not the object itself, which is useful when there is a model + * that is the "real" container of the information. The proxy event handler will attach the specified kind + * of listener to the property's value (retrieved using the property's <code>get</code> method) and fire + * a <code>PropertyChangeEvent</code> whenever the listener receives any kind of event. + * <p/> + * If the property is itself bound (typically the case with models), any updates to the property's value will + * cause the listener to be removed from the old property value and reattached to the new property value, + * as well as cause a <code>PropertyChangeEvent</code> to be fired. + * <p/> + * This variant of <code>addProxyEventInfo</code> allows the names of the methods that add and remove + * the event listener to be specified, in cases where the names are not simply <code>add<listenerClassName></code> + * and <code>remove<listenerClassName></code>. + * <p/> + * Even though this method can theoretically be applied to fields (in addition to methods), it would be an + * unusual situation in which that would actually work -- as fields cannot fire events when modified, it would + * be difficult to have a listener that was always notified when a field value changed. + * + * @param memberName the name of the field or method being proxied + * @param listenerClass the type of listener which receives events when the field or method is updated + * @param modelName the JavaBeans-style name of the model property + * @param addMethod add method name + * @param removeMethod remove method name + */ + public void addProxyEventInfo(String memberName, ClassDescriptor listenerClass, + String modelName, String addMethod, String removeMethod) { + ProxyEventInfo info = new ProxyEventInfo(); + info.memberName = memberName; + info.listenerClass = listenerClass; + info.modelName = modelName; + info.addMethod = addMethod; + info.removeMethod = removeMethod; + if (eventInfos == null) { + eventInfos = new HashMap<String, ProxyEventInfo>(); + } + eventInfos.put(memberName, info); + } + + + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + scanAttributesForDependencies(tag, compiler); + compileChildrenFirstPass(tag, compiler); + } + + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + try { + init(); + } catch (IntrospectionException e) { + throw new CompilerException(e); + } + CompiledObject object = objectMap.get(tag); + if (object == null) { + throw new IllegalStateException("unable to find CompiledObject associated with tag <" + tag.getTagName() + ">; should have been registered before second pass"); + } + compiler.checkOverride(object); + String constructorParams = tag.getAttribute("constructorParams"); + if (constructorParams != null && constructorParams.length() > 0) { + object.setConstructorParams(compiler.getScriptManager().trimScript(constructorParams)); + } + + setDefaults(object, tag, compiler); + setAttributes(object, tag, compiler); + + compileChildrenSecondPass(tag, compiler); + } + + + public void registerCompiledObject(Element tag, JAXXCompiler compiler) { + String id = tag.getAttribute("id"); + if (id == null || id.length() == 0) { + id = compiler.getAutoId(getBeanClass()); + } + CompiledObject object = createCompiledObject(id, compiler); + objectMap.put(tag, object); + String styleClass = tag.getAttribute("styleClass").trim(); + if (styleClass.length() > 0) { + object.setStyleClass(styleClass); + } + compiler.registerCompiledObject(object); + } + + + /** + * Creates the <code>CompiledObject</code> which will represent the object created by this <code>TagHandler</code>. + * + * @param id the <code>CompiledObject's</code> ID. + * @param compiler compiler to use + * @return the <code>CompiledObject</code> to use + */ + protected CompiledObject createCompiledObject(String id, JAXXCompiler compiler) { + return new CompiledObject(id, getBeanClass(), compiler); + } + + + /** + * Initializes the default settings of the object, prior to setting its attribute values. The default + * implementation does nothing. + * + * @param object the object to initialize + * @param tag the tag being compiled + * @param compiler the current <code>JAXXCompiler</code> + */ + protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) { + } + + + /** + * @param property property name to test + * @return <code>true</code> if the specified property should be inherited by child components when specified + * via CSS. + * @throws jaxx.UnsupportedAttributeException + * ? + */ + public boolean isPropertyInherited(String property) throws UnsupportedAttributeException { + return false; + } + + + /** + * @param name name of event + * @return <code>true</code> if the specified name has the form of an event handler attribute + * (e.g. "onActionPerformed"). + */ + public boolean isEventHandlerName(String name) { + return name.length() > 2 && name.startsWith("on") && Character.isUpperCase(name.charAt(2)); + } + + + /** + * Scans all attributes for any dependency classes and adds them to the current compilation + * set. Called by <code>compileFirstPass()</code> (it is an error to add dependencies after + * pass 1 is complete). + * + * @param tag tag to scan + * @param compiler compiler to use + */ + protected void scanAttributesForDependencies(Element tag, JAXXCompiler compiler) { + List<Attr> attributes = new ArrayList<Attr>(); + NamedNodeMap children = tag.getAttributes(); + for (int i = 0; i < children.getLength(); i++) { + attributes.add((Attr) children.item(i)); + } + Collections.sort(attributes, getAttributeComparator()); + + for (Attr attribute : attributes) { + String name = attribute.getName(); + String value = attribute.getValue(); + if (name.equals("javaBean")) { + continue; + } + if (name.equals("constraints") || isEventHandlerName(name)) { + compiler.preprocessScript(value); // adds dependencies as a side effect + } else if (name.equals("constructorParams")) { + for (String param : value.split("\\s*,\\s*")) { + compiler.preprocessScript(param); + } + } else if (value.startsWith("{") && value.endsWith("}")) { + compiler.preprocessScript(value.substring(1, value.length() - 1)); + } + } + } + + + /** + * Processes the attributes of an XML tag. Four kinds of attributes are supported: simple property values (of any + * datatype supported by {@link #convertFromString}), data binding expressions (attributes containing curly-brace + * pairs), event listeners (attributes starting with 'on', such as 'onActionPerformed'), and JAXX-defined properties + * such as 'id'. + * + * @param object the object to be modified + * @param tag the tag from which to pull attributes + * @param compiler the current <code>JAXXCompiler</code> + */ + public void setAttributes(CompiledObject object, Element tag, JAXXCompiler compiler) { + List<Attr> attributes = new ArrayList<Attr>(); + NamedNodeMap children = tag.getAttributes(); + for (int i = 0; i < children.getLength(); i++) { + attributes.add((Attr) children.item(i)); + } + Collections.sort(attributes, getAttributeComparator()); + + for (Attr attribute : attributes) { + String name = attribute.getName(); + String value = attribute.getValue().trim(); + if (name.equals("id") || name.equals("constraints") || name.equals("constructorParams") || name.equals("styleClass") || + name.startsWith("xmlns") || JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) { + // ignore, already handled + continue; + } + if (name.equals("javaBean")) { + object.setJavaBean(true); + if (!value.isEmpty()) { + object.setJavaBeanInitCode(value); + } + continue; + } + if (name.equals("implements")) { + if (object != compiler.getRootObject()) { + // can ony be apply to root object + compiler.reportError("'implements' attribute can only be found on root tag but was found on tag " + tag); + return; + } + String[] interfaces = value.split(","); + compiler.setExtraInterfaces(interfaces); + continue; + } + + if (isEventHandlerName(name)) { + // event handler + if (!value.endsWith(";")) { + value += ";"; + } + addEventHandler(object, Introspector.decapitalize(name.substring(2)), value, compiler); + continue; + } + // simple property + setAttribute(object, name, value, true, compiler); + } + } + + + /** + * Returns a <code>Comparator</code> which defines the ordering in which the tag's attributes should be processed. The + * default implementation sorts the attributes according to the order defined by the {@link #getAttributeOrdering} method. + * + * @return a <code>Comparator</code> defining the order of attribute processing + */ + protected Comparator<Attr> getAttributeComparator() { + return new Comparator<Attr>() { + public int compare(Attr a, Attr b) { + int aOrder = getAttributeOrdering(a); + int bOrder = getAttributeOrdering(b); + + return aOrder - bOrder; + } + }; + } + + + /** + * Returns the priority with which a particular attribute should be processed. Lower numbers should be processed before + * higher numbers. This value is used by the {@link #getAttributeComparator} method to define the sort ordering. + * + * @param attr the attribute to treate + * @return the attribute's priority + */ + protected int getAttributeOrdering(Attr attr) { + if (attr.getName().equals("displayedMnemonicIndex") || attr.getName().equals("displayedMnemonic") || attr.getName().equals("mnemonic")) { + return 1; + } + return 0; + } + + + public String getApplyPropertyOrDataBindingCode(CompiledObject object, String propertyName, String stringValue, JAXXCompiler compiler) { + ClassDescriptor type = getPropertyType(object, propertyName, compiler); + String binding = compiler.processDataBindings(stringValue, type); + if (binding != null) { + return ""; + } + try { + Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; + Object value = convertFromString(propertyName, stringValue, typeClass); + return getSetPropertyCode(object.getJavaCode(), propertyName, TypeManager.getJavaCode(value), compiler); + } catch (NumberFormatException e) { + compiler.reportError("could not convert literal string '" + stringValue + "' to type " + type.getName()); + } catch (IllegalArgumentException e) { + compiler.reportError("could not convert literal string '" + stringValue + "' to type " + type.getName()); + } catch (ClassNotFoundException e) { + compiler.reportError("could not find class " + type.getName()); + } + return ""; + } + + + /** + * Set a single property on an object. The value may be either a simple value or contain data binding expressions. + * Simple values are first converted to the property's type using {@link #convertFromString}. + * + * @param object the object on which to set the property + * @param propertyName the name of the property to set + * @param stringValue the raw string value of the property from the XML + * @param inline <code>true</code> if the value was directly specified as an inline class tag attribute, <code>false</code> otherwise (a default value, specified in CSS, etc.) + * @param compiler the current <code>JAXXCompiler</code> + */ + public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) { + try { + if (ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(object.getObjectClass())) { + // check for data binding & remove if found + JAXXObjectDescriptor jaxxObjectDescriptor = object.getObjectClass().getJAXXObjectDescriptor(); + ComponentDescriptor root = jaxxObjectDescriptor.getComponentDescriptors()[0]; + object.appendInitializationCode(object.getJavaCode() + ".removeDataBinding(" + TypeManager.getJavaCode(root.getId() + "." + propertyName) + ");" + JAXXCompiler.getLineSeparator()); + } + object.addProperty(propertyName, stringValue); + ClassDescriptor type = getPropertyType(object, propertyName, compiler); + String binding = compiler.processDataBindings(stringValue, type); + if (binding != null) { + if (inline) { + compiler.addInlineStyle(object, propertyName, true); + } + ClassDescriptor propertyType = getPropertyType(object, propertyName, compiler); + if (propertyType != null && + propertyType != ClassDescriptorLoader.getClassDescriptor(Boolean.class) && + propertyType != ClassDescriptorLoader.getClassDescriptor(Byte.class) && + propertyType != ClassDescriptorLoader.getClassDescriptor(Short.class) && + propertyType != ClassDescriptorLoader.getClassDescriptor(Integer.class) && + propertyType != ClassDescriptorLoader.getClassDescriptor(Float.class) && + propertyType != ClassDescriptorLoader.getClassDescriptor(Double.class) && + propertyType != ClassDescriptorLoader.getClassDescriptor(Character.class)) { + //binding = "((" + propertyType.getName() + ") " + binding + ")"; + } + if (propertyName.equals("layout")) { // handle containerDelegate (e.g. contentPane on JFrame) + // have to set layout early, before children are added + object.appendInitializationCode(getSetPropertyCode(object.getJavaCode(), propertyName, binding, compiler)); + } + object.registerDataBinding(binding, propertyName, getSetPropertyCode(object.getJavaCode(), propertyName, binding, compiler), compiler); + } else { // no bindings, convert from string + if (inline) { + compiler.addInlineStyle(object, propertyName, false); + } + try { + Class typeClass = type != null ? ClassDescriptorLoader.getClass(type.getName(), type.getClassLoader()) : null; + Object value = convertFromString(propertyName, stringValue, typeClass); + setProperty(object, propertyName, value, compiler); + } catch (NumberFormatException e) { + compiler.reportError("could not convert literal string '" + stringValue + "' to type " + type.getName()); + } catch (IllegalArgumentException e) { + compiler.reportError("could not convert literal string '" + stringValue + "' to type " + type.getName()); + } catch (ClassNotFoundException e) { + compiler.reportError("could not find class " + type.getName()); + } + } + } catch (UnsupportedAttributeException e) { + compiler.reportError("class " + object.getObjectClass().getName() + " does not support attribute '" + propertyName + "'"); + } + } + + + public void applyStylesheets(CompiledObject object, JAXXCompiler compiler) { + applyStylesheets(object, compiler, null); + } + + + private void applyStylesheets(final CompiledObject object, JAXXCompiler compiler, Stylesheet overrides) { + applyStylesheets(object, compiler, overrides, true); + } + + + private void applyStylesheets(final CompiledObject object, JAXXCompiler compiler, Stylesheet overrides, boolean recurse) { + try { + Stylesheet stylesheet = compiler.getStylesheet(); + ClassDescriptor objectClass = object.getObjectClass(); + if (recurse && ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(objectClass)) { + JAXXObjectDescriptor jaxxObjectDescriptor = objectClass.getJAXXObjectDescriptor(); + ComponentDescriptor[] descriptors = jaxxObjectDescriptor.getComponentDescriptors(); + for (ComponentDescriptor descriptor : descriptors) { + ClassDescriptor classDescriptor = ClassDescriptorLoader.getClassDescriptor(descriptor.getJavaClassName()); + boolean isRoot = classDescriptor != objectClass; + String id = isRoot ? object.getId() + ' ' + descriptor.getId() : "( " + object.getId() + " ) " + descriptor.getId(); + CompiledObject child = new CompiledObject(id, + "((" + JAXXCompiler.getCanonicalName(classDescriptor) + ") " + + object.getJavaCode() + ".getObjectById(" + TypeManager.getJavaCode(descriptor.getId()) + "))", + classDescriptor, + compiler, + true); + ComponentDescriptor parentDescriptor = descriptor.getParent(); + CompiledObject currentObject = child; + while (parentDescriptor != null) { + CompiledObject parent = new CompiledObject("internal", ClassDescriptorLoader.getClassDescriptor(parentDescriptor.getJavaClassName()), compiler); + currentObject.setParent(parent); + currentObject = parent; + parentDescriptor = parentDescriptor.getParent(); + } + currentObject.setParent(object); + String styleClass = object.getStyleClass(); + if (styleClass == null) { + styleClass = descriptor.getStyleClass(); + } + child.setStyleClass(styleClass); + Stylesheet mergedStylesheet = overrides; + Stylesheet childOverrides = jaxxObjectDescriptor.getStylesheet(); + if (childOverrides != null) { + if (mergedStylesheet == null) { + mergedStylesheet = childOverrides; + } else { + mergedStylesheet.add(childOverrides.getRules()); + } + } + TagManager.getTagHandler(objectClass).applyStylesheets(child, compiler, mergedStylesheet, isRoot); + object.appendInitializationCode(child.getInitializationCode(compiler)); + } + } else if (stylesheet != null) { + StylesheetHelper.applyTo(object, compiler,stylesheet, overrides); + } + } + catch (ClassNotFoundException e) { + throw new CompilerException(e); + } catch (IllegalArgumentException e) { + compiler.reportError(e.getMessage()); + } + } + + + /** + * Adds the necessary Java code to a <code>CompiledObject</code> to add an event listener at runtime. + * + * @param object the <code>CompiledObject</code> to which the event listener should be added + * @param name the name of the event listener, such as <code>"actionPerformed"</code> + * @param value the Java code snippet to execute when the event is fired + * @param compiler the current <code>JAXXCompiler</code> + */ + public void addEventHandler(CompiledObject object, String name, String value, JAXXCompiler compiler) { + JAXXEventSetDescriptor JAXXEventSetDescriptor = events.get(name); + if (JAXXEventSetDescriptor != null) { + MethodDescriptor[] listenerMethods = JAXXEventSetDescriptor.getListenerMethods(); + MethodDescriptor listenerMethod = null; + for (MethodDescriptor listenerMethod1 : listenerMethods) { + if (listenerMethod1.getName().equals(name)) { + listenerMethod = listenerMethod1; + break; + } + } + if (listenerMethod == null) { + throw new RuntimeException("expected to find method '" + name + "' in JAXXEventSetDescriptor.getListenerMethods()"); + } + try { + value = compiler.preprocessScript(value); + object.addEventHandler(name, JAXXEventSetDescriptor.getAddListenerMethod(), listenerMethod, value, compiler); + } catch (CompilerException e) { + compiler.reportError("While parsing event handler for '" + name + "': " + e.getMessage()); + } + } else { + compiler.reportError("could not find event '" + name + "' for object " + object); + } + } + + + /** + * Returns a snippet of Java code which will retrieve an object property at runtime. Typically the code is + * just a call to the property's <code>get</code> method, but it can be arbitrarily complex. + * + * @param javaCode Java code for the object whose property is being retrieved + * @param name the name of the property to retrieve + * @param compiler the current <code>JAXXCompiler</code> + * @return the snippet + * @throws CompilerException if a compilation error occurs + */ + public String getGetPropertyCode(String javaCode, String name, JAXXCompiler compiler) { + try { + init(); + } catch (IntrospectionException e) { + throw new RuntimeException(e); + } + + JAXXPropertyDescriptor property = properties.get(name); + if (property != null) { + if (property.getReadMethodDescriptor() != null) { + return javaCode + '.' + property.getReadMethodDescriptor().getName() + "()"; + } + throw new UnsupportedAttributeException("property '" + name + "' of " + getBeanClass().getName() + " has no read method"); + } + throw new UnsupportedAttributeException("property '" + name + "' could not be found in class " + getBeanClass().getName()); + } + + + /** + * Returns a snippet of Java code which will set an object property at runtime. Typically the code is + * just a call to the property's <code>set</code> method, but it can be arbitrarily complex. + * + * @param javaCode Java code for the object whose property is being set + * @param name the name of the property to set + * @param valueCode Java expression representing the value to set the property to + * @param compiler the current <code>JAXXCompiler</code> + * @return the snippet + * @throws CompilerException if a compilation error occurs + */ + public String getSetPropertyCode(String javaCode, String name, String valueCode, JAXXCompiler compiler) { + JAXXPropertyDescriptor property = properties.get(name); + if (property != null) { + if (property.getWriteMethodDescriptor() != null) { + return javaCode + '.' + property.getWriteMethodDescriptor().getName() + '(' + valueCode + ");"; + } + throw new UnsupportedAttributeException("property '" + name + "' of " + getBeanClass().getName() + " is read-only"); + } + throw new UnsupportedAttributeException("property '" + name + "' could not be found in class " + getBeanClass().getName()); + } + + + /** + * Appends Java code to a <code>CompiledObject</code> in order to implement a property assignment. + * <code>setProperty</code> is invoked in response to most XML attributes (those which are not more + * complicated cases, like data bindings or event handlers). + * <p/> + * By the time it reaches this method, the <code>value</code> has already been converted from its XML + * string representation to the appropriate destination type for the property (i.e. if + * <code>JLabel.foreground</code> is being set, <code>value</code> will be a <code>Color</code>). + * + * @param object the object being modified + * @param name the name of the property to set + * @param value the value to set the property to + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if a compilation error occurs + */ + public void setProperty(CompiledObject object, String name, Object value, JAXXCompiler compiler) { + object.appendInitializationCode(getSetPropertyCode(object.getJavaCodeForProperty(name), name, TypeManager.getJavaCode(value), compiler)); + } + + + /** + * Maps string values onto integers, so that int-valued enumeration properties can be specified by strings. For + * example, when passed a key of 'alignment', this method should normally map the values 'left', 'center', and + * 'right' onto SwingConstants.LEFT, SwingConstants.CENTER, and SwingConstants.RIGHT respectively. + * <p/> + * You do not normally need to call this method yourself; it is invoked by {@link #convertFromString} when an + * int-valued property has a value which is not a valid number. By default, this method looks at the + * <code>enumerationValues</code> value of the <code>JAXXPropertyDescriptor</code>. + * + * @param key the name of the int-typed property + * @param value the non-numeric value that was specified for the property + * @return the constant integer value + * @throws IllegalArgumentException if the property is an enumeration, but the value is not valid + * @throws NumberFormatException if the property is not an enumeration + */ + protected int constantValue(String key, String value) { + JAXXBeanInfo JAXXBeanInfo = getJAXXBeanInfo(); + JAXXPropertyDescriptor[] properties = JAXXBeanInfo.getJAXXPropertyDescriptors(); + String lowercaseValue = value.toLowerCase(); + for (JAXXPropertyDescriptor property : properties) { + if (property.getName().equals(key)) { + Object[] values = (Object[]) property.getValue("enumerationValues"); + if (values != null) { + for (int j = 0; j < values.length - 2; j += 3) { + if (((String) values[j]).toLowerCase().equals(lowercaseValue)) { + return (Integer) values[j + 1]; + } + } + + StringBuffer message = new StringBuffer("value of '" + key + "' must be one of: ["); + for (int j = 0; j < values.length - 2; j += 3) { + if (j != 0) { + message.append(", "); + } + message.append(((String) values[j]).toLowerCase()); + } + message.append("] (found '").append(value).append("')"); + throw new IllegalArgumentException(message.toString()); + } + } + } + throw new NumberFormatException(value); + } + + + /** + * As {@link TypeManager#convertFromString(String, Class)}, except that it additionally supports constant names + * for <code>int</code>-valued types. + * + * @param key the name of the property whose value is being converted + * @param value the raw string value of the property as it appears in the XML + * @param type the datatype to convert the string into + * @return the converted object + * @see #constantValue + */ + protected Object convertFromString(String key, String value, Class type) { + if (type == null || type == Object.class) { + return value; + } + + try { + return TypeManager.convertFromString(value, type); + } catch (NumberFormatException e) { + if (type == int.class || type == Integer.class) { + return constantValue(key, value); + } + throw e; + } + } + + + /** + * Compiles the child tags of the current tag. The default implementation invokes {@link #compileChildTagFirstPass} + * for each child tag. + * + * @param tag the tag whose children to compile + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if a compilation error occurs + * @throws IOException if an I/O error occurs + */ + protected void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagFirstPass(child, compiler); + } + } + } + + + /** + * Compiles the child tags of the current tag. The default implementation invokes {@link #compileChildTagFirstPass} + * for each child tag. + * + * @param tag the tag whose children to compile + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if a compilation error occurs + * @throws IOException if an I/O error occurs + */ + protected void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagSecondPass(child, compiler); + } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) { + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + } + + + /** + * Compiles a child of the current tag. The default implementation calls {@link JAXXCompiler#compileFirstPass + * JAXXCompiler.compileFirstPass}. + * + * @param tag the child tag to compile + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if a compilation error occurs + * @throws IOException if an I/O error occurs + */ + protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileFirstPass(tag); + } + + + /** + * Compiles a child of the current tag. The default implementation calls {@link JAXXCompiler#compileFirstPass + * JAXXCompiler.compileSecondPass}. + * + * @param tag the child tag to compile + * @param compiler the current <code>JAXXCompiler</code> + * @throws CompilerException if a compilation error occurs + * @throws IOException if an I/O error occurs + */ + protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileSecondPass(tag); + } + + @Override + public String toString() { + return getClass().getName() + "[" + getBeanClass().getName() + "]"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/ScriptHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/ScriptHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/ScriptHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/ScriptHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,81 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.JAXXCompiler; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringWriter; + +/** + * Handles the <code><script></code> tag. + * + * @author Ethan Nicholas + */ +public class ScriptHandler implements TagHandler { + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + File scriptFile = null; + NamedNodeMap attributes = tag.getAttributes(); + for (int i = 0; i < attributes.getLength(); i++) { + Attr attribute = (Attr) attributes.item(i); + String name = attribute.getName(); + String attrValue = attribute.getValue(); + if (name.equals("source")) { + scriptFile = new File(compiler.getBaseDir(), attrValue.replace('/', File.separatorChar)); + StringWriter scriptBuffer = new StringWriter(); + try { + FileReader in = new FileReader(scriptFile); + char[] readBuffer = new char[2048]; + int c; + while ((c = in.read(readBuffer)) > 0) { + scriptBuffer.write(readBuffer, 0, c); + } + } + catch (FileNotFoundException e) { + compiler.reportError("script file not found: " + scriptFile); + } + compiler.registerScript(scriptBuffer.toString(), scriptFile); + } else + if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) + throw new UnsupportedAttributeException(name); + } + + StringBuffer script = new StringBuffer(); + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + switch (child.getNodeType()) { + case Node.ELEMENT_NODE: + compiler.reportError("<script> tag may not contain child elements: " + tag); + case Node.TEXT_NODE: // fall through + case Node.CDATA_SECTION_NODE: + script.append(((Text) child).getData()); + } + } + + String scriptString = script.toString().trim(); + if (scriptString.length() > 0) { + if (scriptFile != null) { + compiler.reportError("<script> tag has both a source attribute and an inline script"); + } + compiler.registerScript(script.toString()); + } + } + + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/StyleHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/StyleHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/StyleHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/StyleHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,180 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.JAXXCompiler; +import jaxx.css.CSSParser; +import jaxx.css.CSSParserConstants; +import jaxx.css.CSSParserTreeConstants; +import jaxx.css.Rule; +import jaxx.css.Selector; +import jaxx.css.SimpleNode; +import jaxx.css.Stylesheet; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * Handles the <code><style></code> tag. + * + * @author Ethan Nicholas + */ +public class StyleHandler implements TagHandler { + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + boolean source = false; + NamedNodeMap attributes = tag.getAttributes(); + for (int i = 0; i < attributes.getLength(); i++) { + Attr attribute = (Attr) attributes.item(i); + String name = attribute.getName(); + String attrValue = attribute.getValue(); + if (name.equals("source")) { + source = true; + File styleFile = new File(compiler.getBaseDir(), attrValue.replace('/', File.separatorChar)); + StringWriter styleBuffer = new StringWriter(); + try { + FileReader in = new FileReader(styleFile); + char[] readBuffer = new char[2048]; + int c; + while ((c = in.read(readBuffer)) > 0) + styleBuffer.write(readBuffer, 0, c); + } + catch (FileNotFoundException e) { + compiler.reportError("stylesheet file not found: " + styleFile); + } + compiler.getSourceFiles().push(styleFile); + compiler.registerStylesheet(processStylesheet(styleBuffer.toString())); + compiler.getSourceFiles().pop(); + } else + if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) + throw new UnsupportedAttributeException(name); + } + + StringBuffer style = new StringBuffer(); + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node child = children.item(i); + switch (child.getNodeType()) { + case Node.ELEMENT_NODE: + compiler.reportError("<style> tag may not contain child elements: " + tag); + case Node.TEXT_NODE: // fall through + case Node.CDATA_SECTION_NODE: + style.append(((Text) child).getData()); + } + } + + String styleString = style.toString().trim(); + if (styleString.length() > 0) { + if (source) + compiler.reportError("<style> tag has both a source attribute and an inline stylesheet"); + compiler.registerStylesheet(processStylesheet(style.toString())); + } + } + + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + } + + + protected Selector processSelector(SimpleNode selector) { + if (selector.getId() != CSSParserTreeConstants.JJTSELECTOR) + throw new IllegalArgumentException("argument node is not a Selector"); + String javaClassName = null; + String styleClass = null; + String pseudoClass = null; + String id = null; + + for (int i = 0; i < selector.jjtGetNumChildren(); i++) { + SimpleNode child = selector.getChild(i); + switch (child.getId()) { + case CSSParserTreeConstants.JJTJAVACLASS: + if (!child.getText().trim().equals("*")) + javaClassName = child.getText(); + break; + case CSSParserTreeConstants.JJTCLASS: + styleClass = child.getText().substring(1); + break; + case CSSParserTreeConstants.JJTPSEUDOCLASS: + pseudoClass = child.getText().substring(1); + break; + case CSSParserTreeConstants.JJTID: + id = child.getText().substring(1); + break; + + default: + throw new IllegalStateException("unexpected child of Selector node, type=" + child.getId()); + } + } + + return new Selector(javaClassName, styleClass, pseudoClass, id); + } + + + protected Rule processRule(SimpleNode ruleNode) { + if (ruleNode.getId() != CSSParserTreeConstants.JJTRULE) { + throw new IllegalArgumentException("argument node is not a Rule"); + } + SimpleNode selectorsNode = ruleNode.getChild(0); + assert selectorsNode.getId() == CSSParserTreeConstants.JJTSELECTORS : "expected node to be of type Selectors"; + + List<Selector> selectors = new ArrayList<Selector>(); + for (int i = 0; i < selectorsNode.jjtGetNumChildren(); i++) { + SimpleNode selectorNode = selectorsNode.getChild(i); + selectors.add(processSelector(selectorNode)); + } + + Map<String, String> properties = new HashMap<String, String>(); + for (int i = 1; i < ruleNode.jjtGetNumChildren(); i++) { + SimpleNode declarationNode = ruleNode.getChild(i); + if (declarationNode.getId() == CSSParserTreeConstants.JJTDECLARATION) { + String key = declarationNode.getChild(0).getText(); + SimpleNode valueNode = declarationNode.getChild(1); + String value = valueNode.getText(); + if (valueNode.firstToken.kind == CSSParserConstants.STRING) { + value = value.substring(1, value.length() - 1); + } + properties.put(key, value); + } + } + Rule rule; + rule = new Rule(selectors.toArray(new Selector[selectors.size()]), properties); + return rule; + } + + + protected Stylesheet processStylesheet(String stylesheetText) throws CompilerException { + CSSParser p = new CSSParser(new StringReader(stylesheetText)); + SimpleNode node; + try { + node = p.Stylesheet(); + } catch (Error e) { + throw new CompilerException(e); + } + List<Rule> rules = new ArrayList<Rule>(); + for (int i = 0; i < node.jjtGetNumChildren(); i++) { + SimpleNode ruleNode = node.getChild(i); + Rule rule = processRule(ruleNode); + rules.add(rule); + } + Stylesheet stylesheet; + stylesheet = new Stylesheet(rules.toArray(new Rule[rules.size()])); + return stylesheet; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/TagHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,46 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags; + +import jaxx.CompilerException; +import jaxx.compiler.JAXXCompiler; +import org.w3c.dom.Element; + +import java.io.IOException; + +/** + * Implementations of <code>TagHandler</code> produce Java source code from XML tags. + * <code>TagHandlers</code> are mapped to particular XML tags (such as <JFrame>) in {@link JAXXCompiler}. + * There is only one <code>TagHandler</code> for any given XML tag, and therefore implementations must be + * stateless. + * + * @author Ethan Nicholas + */ +public interface TagHandler { + /** + * Performs the first pass of compilation on an XML tag from a JAXX source file. + * <code>TagHandler</code> implementations affect the generated <code>.java</code> + * file by calling methods in the <code>JAXXCompiler</code>. + * + * @param tag the XML tag to compile + * @param compiler the active JAXXCompiler + * @throws CompilerException if a compilation error occurs + * @throws IOException if an I/O error occurs + */ + void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException; + + + /** + * Performs the second pass of compilation on an XML tag from a JAXX source file. + * <code>TagHandler</code> implementations affect the generated <code>.java</code> + * file by calling methods in the <code>JAXXCompiler</code>. + * + * @param tag the XML tag to compile + * @param compiler the active JAXXCompiler + * @throws CompilerException if a compilation error occurs + * @throws IOException if an I/O error occurs + */ + void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException; +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/TagManager.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tags/TagManager.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,478 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags; + +import jaxx.ClassMap; +import jaxx.CompilerException; +import jaxx.compiler.*; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +/** Manages TagHandlers, including automatically compiling .jaxx files corresponding to class tags. */ +public class TagManager { + /** log */ + protected static final Log log = LogFactory.getLog(TagManager.class); + + /** + * Namespace for JAXX's non-class tags, such as <script;>. The namespace normally does not + * need to be specified but can be used to resolve ambiguities. + */ + public static final String JAXX_NAMESPACE = "http://www.jaxxframework.org/"; + + /** Maps simple tag names to their default namespaces (package names). */ + private static Map<String, String> defaultNamespaces = new HashMap<String, String>(); + + /** Maps qualified tag names to the TagHandlers responsible for processing them. */ + private static Map<QName, TagHandler> registeredTags = new HashMap<QName, TagHandler>(); + + /** Keeps track of whether or not named classes exist. */ + private static Map<String, Boolean> classExistenceCache = new HashMap<String, Boolean>(); + + /** + * Maps bean classes to their TagHandler classes. The mapping is to TagHandler classes, rather than to + * TagHandler instances, because subclasses of the bean class should be handled by the same TagHandler + * (assuming no more specific mappings exist), which requires creating a new instance of the TagHandler. + */ + private static ClassMap<Class<? extends TagHandler>> registeredBeans = new ClassMap<Class<? extends TagHandler>>(); + + // still targeting 1.4, so I can't use javax.xml.namespace.QName + private static class QName { + private String namespaceURI; + private String localPart; + + public QName(String namespaceURI, String localPart) { + if (localPart == null) + throw new NullPointerException(); + this.namespaceURI = namespaceURI; + this.localPart = localPart; + } + + + public String getNamespaceURI() { + return namespaceURI; + } + + + public String getLocalPart() { + return localPart; + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof QName)) + return false; + QName qname = (QName) o; + return qname.getNamespaceURI().equals(getNamespaceURI()) && qname.getLocalPart().equals(getLocalPart()); + } + + @Override + public int hashCode() { + return (namespaceURI != null ? namespaceURI.hashCode() : 0) ^ getLocalPart().hashCode(); + } + } + + + private TagManager() { /* not instantiable */ } + + + public static void reset(boolean verbose) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException { + registeredBeans.clear(); + registeredTags.clear(); + defaultNamespaces.clear(); + JAXXCompilerLaunchor.loadLibraries(verbose); + } + + + /** + * Maps a class tag to a specific <code>TagHandler</code>. When a tag representing the bean class is + * encountered (either the class' simple name, if it is unambiguous, or its fully-qualified name), the specified + * <code>TagHandler</code> will be invoked to compile it. + * + * @param beanClass the class to associate with a <code>TagHandler</code> + * @param handler the <code>TagHandler</code> class, which must descend from <code>DefaultObjectHandler</code> + * @throws IllegalArgumentException if the handler class does not descend from <code>DefaultObjectHandler</code> + */ + public static <T extends TagHandler> void registerBean(ClassDescriptor beanClass, Class<T> handler) { + if (!DefaultObjectHandler.class.isAssignableFrom(handler)) { + throw new IllegalArgumentException("handler class must be a subclass of DefaultObjectHandler"); + } + registeredBeans.put(beanClass, handler); + if (log.isDebugEnabled()) { + log.debug(beanClass + " : " + handler); + } + String name = beanClass.getName(); + int dotPos = name.lastIndexOf("."); + String namespace = name.substring(0, dotPos + 1) + "*"; + name = name.substring(dotPos + 1); + registerDefaultNamespace(name, namespace); + } + + + /** + * Sets the default namespace for a tag. When the tag is encountered with no namespace specified, + * the specified namespace will be assumed. Mapping the same tag to two or more default namespaces + * removes the mapping and marks the entry as being ambiguous (by putting a <code>null</code> + * value into the map); this causes an error to be thrown if the tag is used without a namespace being + * specified. + * <p/> + * Java package names on tags are automatically converted into namespaces (e.g. <javax.swing.JButton/> + * and <JButton xmlns="javax.swing.*"/> are equivalent), so tags with package names are considered + * to have namespaces specified. + * + * @param tag tag name + * @param namespace namespace + */ + public static void registerDefaultNamespace(String tag, String namespace) { + if (defaultNamespaces.containsKey(tag) && !defaultNamespaces.get(tag).equals(namespace)) { + defaultNamespaces.put(tag, null); // tag name is now ambiguous + } else { + defaultNamespaces.put(tag, namespace); + } + } + + + /** + * Registers a <code>TagHandler</code> for a tag. When a tag with the given name and namespace + * is encountered, the <code>TagHandler's compileFirstPass</code> and <code>compileSecondPass</code> + * methods will be invoked to handle it. + * <p/> + * It is not an error to register an already-registered tag and namespace combination. The new mapping + * will replace the old mapping. + * + * @param namespace the tag's namespace + * @param tag the simple name of the tag + * @param handler the <code>TagHandler</code> which should process the tag + */ + public static <T extends TagHandler> void registerTag(String namespace, String tag, T handler) { + if (namespace == null) { + namespace = "*"; + } + //System.out.println("registerTag "+namespace+" : "+tag+" : "+handler); + if (log.isDebugEnabled()) { + log.debug(tag + " : " + handler); + } + registeredTags.put(new QName(namespace, tag), handler); + registerDefaultNamespace(tag, namespace); + } + + + /** + * Returns the <code>TagHandler</code> that should be used to process the specified tag. + * If the tag represents the class name of an uncompiled <code>.jaxx</code> file, the + * <code>.jaxx</code> is first compiled. + * + * @param namespace the tag's namespace (may be <code>null</code>) + * @param tag the tag's simple name + * @param compiler the current <code>JAXXCompiler</code> + * @return the <code>TagHandler</code> for the tag + * @throws jaxx.CompilerException ? + */ + public static TagHandler getTagHandler(String namespace, String tag, JAXXCompiler compiler) throws CompilerException { + return getTagHandler(namespace, tag, false, compiler); + } + + + private static String getNamespace(ClassDescriptor beanClass) { + String packageName = beanClass.getPackageName(); + return packageName != null ? packageName + ".*" : "*"; + + } + + + private static String getSimpleName(ClassDescriptor beanClass) { + String packageName = beanClass.getPackageName(); + if (packageName != null) { + assert beanClass.getName().startsWith(packageName); + return beanClass.getName().substring(packageName.length() + 1); + } + return beanClass.getName(); + } + + + /** + * @param beanClass the tag class + * @return the <code>TagHandler</code> that should be used to process the specified class. + * Only <code>TagHandlers</code> previously registered with <code>registerBean</code> + * are considered. + * @throws jaxx.CompilerException ? + */ + public static DefaultObjectHandler getTagHandler(ClassDescriptor beanClass) throws CompilerException { + try { + if (beanClass == null) { + throw new NullPointerException(); + } + String namespace = getNamespace(beanClass); + String tag = getSimpleName(beanClass); + DefaultObjectHandler handler = (DefaultObjectHandler) registeredTags.get(new QName(namespace, tag)); + if (handler == null) { + Class<? extends TagHandler> handlerClass = registeredBeans.get(beanClass); + if (handlerClass == null) { + throw new CompilerException("unable to find handler for " + beanClass); + } + Constructor<? extends TagHandler> constructor = handlerClass.getConstructor(ClassDescriptor.class); + handler = (DefaultObjectHandler) constructor.newInstance(beanClass); + registerTag(namespace, tag, handler); + } + return handler; + } + catch (InstantiationException e) { + throw new RuntimeException(e); + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + + + private static boolean classExists(String className, JAXXCompiler compiler) { + if (classExistenceCache.containsKey(className)) { + return classExistenceCache.get(className); + } + + boolean found = false; + try { + Class.forName(className, true, compiler.getClassLoader()); + found = true; + } + catch (ClassNotFoundException e) { + // ignore ? + } + catch (NoClassDefFoundError e) { // we get this instead of ClassNotFoundException on case-insensitive file systems when + // looking up a class with the wrong case + } + + if (!found) { // couldn't find .class, check for .java + URL javaURL = compiler.getClassLoader().getResource(className.replace('.', '/') + ".java"); + found = javaURL != null; + } + + if (!found) { // couldn't find .java, check for .jaxx + URL jaxxURL = compiler.getClassLoader().getResource(className.replace('.', '/') + ".jaxx"); + found = jaxxURL != null; + } + + classExistenceCache.put(className, found); + + return found; + } + + + private static String determinePackage(String simpleClassName, String defaultPackage, JAXXCompiler compiler) { + String namespace = null; + Set<String> classes = compiler.getImportedClasses(); + for (String className : classes) { // search class imports (e.g. import java.util.Date;) + if (className.equals(simpleClassName) || className.endsWith("." + simpleClassName)) { + namespace = className.substring(0, className.lastIndexOf(".") + 1) + "*"; + } + } + if (namespace == null) { // search package imports (e.g. import java.util.*;) + Set<String> searchList = compiler.getImportedPackages(); + if (defaultPackage != null) { + if (!defaultPackage.endsWith("*")) { + throw new IllegalArgumentException("defaultPackage must end in '*', found '" + defaultPackage + "'"); + } + if (classExists(defaultPackage.substring(0, defaultPackage.length() - 1) + simpleClassName, compiler)) { + return defaultPackage; + } + } + for (String currentPackage : searchList) { + String className = currentPackage + simpleClassName; + if (classExists(className, compiler)) { + if (namespace != null) { // we've already found the same name in another package + compiler.reportError("symbol '" + simpleClassName + "' is ambiguous, found matching classes " + namespace.substring(0, namespace.length() - 1) + simpleClassName + " and " + currentPackage + simpleClassName + ". Use fully-qualified name to disambiguate."); + return null; + } + namespace = currentPackage + "*"; + } + } + } + + return namespace; + } + + + /** + * Returns the <code>TagHandler</code> that should be used to process the specified tag. + * <p/> + * The <code>namespacePrefix</code> parameter is used only for error checking, as it is an + * error to specify conflicting package names using both a fully-qualified tag name and a + * namespace prefix, but it is not an error to specify conflicting package names using a + * fully-qualified tag name and a <i>default</i> namespace (i.e. <awt:javax.swing.JButton xmlns:awt='java.awt.*'/> + * is an error, whereas <javax.swing.JButton xmlns='java.awt.*'/> is not). + * + * @param namespace the tag's namespace (may be <code>null</code>) + * @param tag the tag's simple name (which can include fully-qualified Java class names) + * @param namespacePrefix <code>true</code> if the namespace was specified by means of a namespace prefix (as opposed to a default namespace) + * @param compiler the current <code>JAXXCompiler</code> + * @return the <code>TagHandler</code> for the tag + * @throws jaxx.CompilerException ? + */ + public static TagHandler getTagHandler(String namespace, String tag, boolean namespacePrefix, JAXXCompiler compiler) throws CompilerException { + if (tag == null) { + throw new NullPointerException(); + } + if (namespace == null && defaultNamespaces.containsKey(tag)) { + namespace = defaultNamespaces.get(tag); + if (namespace == null) { // defaultNamespaces map contains a null value, which is put there to indicate ambiguity + compiler.reportError("tag '" + tag + "' is ambiguous; specify fully-qualified name (package and class) to disambiguate"); + return null; + } + } + + TagHandler handler = registeredTags.get(new QName(namespace, tag)); + if (handler == null) { + if (namespace == null || namespace.endsWith("*")) { + String className; + if (namespace != null) { + className = resolveClassName(namespace.substring(0, namespace.length() - 1) + tag, compiler); + if (className == null) { + className = resolveClassName(tag, compiler); + if (namespacePrefix && !className.startsWith(namespace.substring(0, namespace.length() - 1))) { + className = null; // namespace was specified, but we found it in a different package - ignore + } + } + } else { + className = resolveClassName(tag, compiler); + } + if (className != null) { + int dotPos = className.lastIndexOf("."); + namespace = className.substring(0, dotPos + 1) + "*"; + tag = className.substring(dotPos + 1); + handler = registeredTags.get(new QName(namespace, tag)); + if (handler == null) { + try { + handler = getTagHandler(ClassDescriptorLoader.getClassDescriptor(className, compiler.getClassLoader())); + } + catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + } + } + } + return handler; + } + + + /** + * Resolves a simple class name (like <code>Object</code> or <code>String</code>) to its fully-qualified name. Inner + * classes should be represented as they would appear in Java source code (e.g. JPopupMenu.Separator). Fully-qualified names, + * such as <code>java.lang.Object</code> are legal and will be returned unmodified (and in fact it is generally impossible to + * even know whether a given reference is fully qualified until it has been resolved). Returns <code>null</code> if no matching + * class could be found. + * + * @param name name to resolve + * @param compiler compile to use + * @return the resolved fqn class name + */ + public static String resolveClassName(String name, JAXXCompiler compiler) { + if (name.endsWith("[]")) + return resolveClassName(name.substring(0, name.length() - 2), compiler) + "[]"; + if (name.indexOf("<") != -1) + name = name.substring(0, name.indexOf("<")); // strip off generic types + + name = name.intern(); + if (name.equals("boolean") || name.equals("byte") || name.equals("short") || name.equals("int") || + name.equals("long") || name.equals("float") || name.equals("double") || name.equals("char")) + return name; + + String result = null; + String originalName = name; + String defaultNamespace = null; + if (defaultNamespaces.containsKey(name)) { + defaultNamespace = defaultNamespaces.get(name); + if (defaultNamespace == null) { // defaultNamespaces map contains a null value, which is put there to indicate ambiguity + compiler.reportError("class '" + name + "' is ambiguous; specify fully-qualified name (package and class) to disambiguate"); + return null; + } + } + if (defaultNamespace != null && defaultNamespace.endsWith("*")) { + result = defaultNamespace.substring(0, defaultNamespace.length() - 1) + name; + } + + if (result == null) { + // Inner class names (like JPopupMenu.Separator) present a special challenge. The name before the dot might be + // a package name, or it might be a class name. If it's a class name, it might be fully qualified, or it might + // not. And it's also not actually the correct name of the class, as far as the JVM is concerned -- the correct + // name uses a dollar sign instead of a dot (javax.swing.JPopupMenu$Separator). And there could be more than + // one inner class -- it's possible to have com.mycompany.Outer$Inner$Innerer$Innerest. + // + // The basic strategy is to start by treating the part before the last dot as a package name, as that is by far + // the most likely case. If we don't find the class there, change the last dot to a dollar sign and try again. + // Suppose we have the tag <com.mycompany.Outer.Inner.Innerer.Innerest/>, matching the class above. Resolution + // proceeds like this: + // com.mycompany.Outer.Inner.Innerer.* : Innerest + // com.mycompany.Outer.Inner.* : Innerer$Innerest + // com.mycompany.Outer.* : Inner$Innerer$Innerest + // com.mycompany.* : Outer$Inner$Innerer$Innerest + // And at this point we have a match with the class Outer$Inner$Innerer$Innerest in package com.mycompany. + int dotPos = originalName.lastIndexOf('.'); + for (; ;) { + String namespace = dotPos != -1 ? originalName.substring(0, dotPos) + ".*" : "*"; + name = originalName.substring(dotPos + 1).replace('.', '$'); + String packageName = determinePackage(name, namespace, compiler); + if (packageName != null) { + assert packageName.endsWith("*"); + if (packageName.equals(namespace) || namespace.equals("*")) { + // check for an alias (like javax.swing.JComboBox actually being jaxx.runtime.swing.JAXXComboBox) + TagHandler handler = registeredTags.get(new QName(namespace, name)); + if (handler != null) { // determine alias by looking at handler + ClassDescriptor alias = ((DefaultObjectHandler) handler).getBeanClass(); + // make sure the same handler is used for both the aliased and non-aliased names, in order to avoid "no CompiledObject has been registered" error + // the line below doesn't bother to handle the case where the aliased class name doesn't have a package, since it's a pretty safe assumption that + // that will never happen + assert alias.getPackageName() != null && alias.getPackageName().length() > 0 : "aliasing with no package name has not been implemented"; + registeredTags.put(new QName(alias.getPackageName() + ".*", alias.getName().substring(alias.getPackageName().length() + 1)), handler); + result = alias.getName(); + break; + } else { // no alias + result = packageName.substring(0, packageName.length() - 1) + name; + break; + } + } + // else we found a class by the same name, but in the wrong package + } + + if (dotPos <= 0) + break; + dotPos = originalName.lastIndexOf('.', dotPos - 1); + } + } + + if (result != null && !result.equals(originalName)) + result = resolveClassName(result, compiler); // check for aliases against the new name as well + + return result; + } + + + public static ClassDescriptor resolveClass(String className, JAXXCompiler compiler) { + try { + className = resolveClassName(className, compiler); + if (className == null) + return null; + return ClassDescriptorLoader.getClassDescriptor(className, compiler.getClassLoader()); + } + catch (ClassNotFoundException e) { + return null; + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tools/jaxxcapture) Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/CapturedObject.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tools/jaxxcapture/CapturedObject.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/CapturedObject.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -110,8 +110,9 @@ public void appendInnerXML(String xml) { - if (this.innerXML.length() > 0) + if (this.innerXML.length() > 0) { this.innerXML.append(JAXXCompiler.getLineSeparator()); + } this.innerXML.append(xml); } @@ -122,8 +123,9 @@ public void appendScriptCode(String script) { - if (this.script.length() > 0) + if (this.script.length() > 0) { this.script.append(JAXXCompiler.getLineSeparator()); + } this.script.append(script); } Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/JAXXCapture.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tools/jaxxcapture/JAXXCapture.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/JAXXCapture.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -50,9 +50,14 @@ private static ClassMap<Object> objectHandlers = new ClassMap<Object>(); static { + //TODO make a serviceLoader mecanism to allow inter-module loading objectHandlers.put(ClassDescriptorLoader.getClassDescriptor(Object.class), new ObjectHandler()); objectHandlers.put(ClassDescriptorLoader.getClassDescriptor(JTabbedPane.class), new JTabbedPaneHandler()); - objectHandlers.put(ClassDescriptorLoader.getClassDescriptor(jaxx.runtime.swing.Table.class), new TableHandler()); + try { + objectHandlers.put(ClassDescriptorLoader.getClassDescriptor("jaxx.runtime.swing.Table"), new TableHandler()); + } catch (ClassNotFoundException e) { + System.err.println(e); + } } private Map<String, Object> sourceObjects = new HashMap<String, Object>(); @@ -73,14 +78,17 @@ public void dispatchEvent(AWTEvent event) { if (event.getID() == MouseEvent.MOUSE_PRESSED && ((MouseEvent) event).isControlDown()) { Component target = ((MouseEvent) event).getComponent(); - if (!(target instanceof Window)) + if (!(target instanceof Window)) { target = SwingUtilities.getWindowAncestor(target); - if (target instanceof JFrame) + } + if (target instanceof JFrame) { target = ((JFrame) target).getContentPane(); - else if (target instanceof JDialog) + } else if (target instanceof JDialog) { target = ((JDialog) target).getContentPane(); - if (target instanceof JWindow) + } + if (target instanceof JWindow) { target = ((JWindow) target).getContentPane(); + } if (target != null) { Thread.currentThread().setContextClassLoader(classLoader); JAXXCapture capture = new JAXXCapture(classLoader); @@ -132,8 +140,9 @@ if (target instanceof Container) { Container container = (Container) target; - for (int i = 0; i < container.getComponentCount(); i++) + for (int i = 0; i < container.getComponentCount(); i++) { applyNames(container.getComponent(i)); + } } } @@ -147,8 +156,9 @@ StringBuffer result = new StringBuffer(); result.append('('); for (int i = 0; i < arguments.length; i++) { - if (i != 0) + if (i != 0) { result.append(", "); + } result.append(getJavaCode(arguments[i])); } result.append(')'); @@ -161,7 +171,7 @@ if (node instanceof PropertyNode) { ContextNode[] arguments = node.getArguments(); result.append(arguments.length == 0 ? "get" : "set"); - result.append(JAXXCompiler.capitalize(((PropertyNode) node).getProperty())); + result.append(org.apache.commons.lang.StringUtils.capitalize(((PropertyNode) node).getProperty())); result.append(getArgumentsCode(arguments)); } else if (node instanceof MethodNode) { result.append((((MethodNode) node).getMethodName())); @@ -177,12 +187,13 @@ assert id != null; result.append(id); } - } else if (node instanceof ValueNode) + } else if (node instanceof ValueNode) { result.append(TypeManager.getJavaCode(((ValueNode) node).getValue())); - else if (node instanceof LiteralNode) + } else if (node instanceof LiteralNode) { result.append(((LiteralNode) node).getJavaCode()); - else + } else { throw new IllegalArgumentException("unrecognized node type: " + node); + } return result.toString(); } @@ -263,10 +274,11 @@ try { String methodName; ContextNode[] argumentNodes = node.getArguments(); - if (node instanceof MethodNode) + if (node instanceof MethodNode) { methodName = ((MethodNode) node).getMethodName(); - else - methodName = (argumentNodes.length == 0 ? "get" : "set") + JAXXCompiler.capitalize(((PropertyNode) node).getProperty()); + } else { + methodName = (argumentNodes.length == 0 ? "get" : "set") + org.apache.commons.lang.StringUtils.capitalize(((PropertyNode) node).getProperty()); + } Object[] arguments = new Object[argumentNodes.length]; Class[] argumentTypes = new Class[argumentNodes.length]; for (int j = 0; j < argumentNodes.length; j++) { @@ -279,8 +291,9 @@ } else if (argumentNodes[j] instanceof LiteralNode) { arguments[j] = ((LiteralNode) argumentNodes[j]).getValue(); argumentTypes[j] = arguments[j].getClass(); - } else + } else { throw new IllegalArgumentException("unsupported argument type: " + argumentNodes[j]); + } } Method method = getMethod(contextClass, methodName, argumentTypes); @@ -290,8 +303,9 @@ result.append(')'); method = getMethod(contextObject.getClass(), methodName, argumentTypes); } - if (method == null) + if (method == null) { throw new RuntimeException("could not find method " + methodName + Arrays.asList(argumentTypes) + " in " + contextObject.getClass() + " (context: " + context + ")"); + } contextObject = method.invoke(contextObject, arguments); contextClass = method.getReturnType(); } @@ -300,8 +314,9 @@ } } - if (i > start) + if (i > start) { result.append('.'); + } result.append(getJavaCode(node)); } @@ -325,8 +340,9 @@ catch (ClassNotFoundException e) { throw new RuntimeException(e); } - } else + } else { handler = (ObjectHandler) objectHandlers.get(ClassDescriptorLoader.getClassDescriptor(Object.class)); + } return handler.processObject(objectTag, context, this); } Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/handlers/ObjectHandler.java =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tools/jaxxcapture/handlers/ObjectHandler.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/tools/jaxxcapture/handlers/ObjectHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,7 +1,7 @@ package jaxx.tools.jaxxcapture.handlers; +import jaxx.compiler.JavaFile; import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JavaFile; import jaxx.tools.jaxxcapture.CapturedObject; import jaxx.tools.jaxxcapture.ContextNode; import jaxx.tools.jaxxcapture.JAXXCapture; @@ -34,8 +34,9 @@ Node child = children.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { Element innerTag = (Element) child; - if (innerTag.getTagName().equals("void")) + if (innerTag.getTagName().equals("void")) { result = true; + } evaluate(innerTag, context, capture); } } @@ -64,11 +65,12 @@ ContextNode[] arguments = newContext.getArguments(); if (arguments.length == 1) { if (current instanceof CapturedObject && arguments[0] instanceof ValueNode) // simple property assignment + { ((CapturedObject) current).setProperty(property, dataBindingEncode(String.valueOf(((ValueNode) arguments[0]).getValue()))); - else - if (current instanceof CapturedObject && arguments[0] instanceof CapturedObject && ((CapturedObject) arguments[0]).isInlineable()) // simple data binding + } else if (current instanceof CapturedObject && arguments[0] instanceof CapturedObject && ((CapturedObject) arguments[0]).isInlineable()) // simple data binding + { ((CapturedObject) current).setProperty(property, "{" + capture.getJavaCode(arguments[0]) + "}"); - else { + } else { contextObject.setInlineable(false); contextObject.appendScriptCode(capture.getJavaCode(context)); } @@ -115,8 +117,9 @@ } } - if (!voidChildren && !add) + if (!voidChildren && !add) { contextObject.appendScriptCode(capture.getJavaCode(context)); + } assert context.peek() == newContext; context.pop(); @@ -142,34 +145,37 @@ catch (Exception e) { throw new RuntimeException(e); } - } else + } else { currentNode.addArgument(capture.processObject(tag, context)); + } } else if (tagName.equals("void")) { String property = tag.getAttribute("property"); - if (property.length() > 0) + if (property.length() > 0) { evaluateProperty(tag, context, capture); - else + } else { evaluateMethod(tag, context, capture); - } else if (tagName.equals("string")) + } + } else if (tagName.equals("string")) { context.peek().addArgument(new ValueNode(JAXXCapture.getText(tag))); - else if (tagName.equals("boolean")) + } else if (tagName.equals("boolean")) { context.peek().addArgument(new ValueNode(Boolean.valueOf(JAXXCapture.getText(tag)))); - else if (tagName.equals("char")) + } else if (tagName.equals("char")) { context.peek().addArgument(new ValueNode(JAXXCapture.getText(tag).charAt(0))); - else if (tagName.equals("short")) + } else if (tagName.equals("short")) { context.peek().addArgument(new ValueNode(Short.valueOf(JAXXCapture.getText(tag)))); - else if (tagName.equals("int")) + } else if (tagName.equals("int")) { context.peek().addArgument(new ValueNode(Integer.valueOf(JAXXCapture.getText(tag)))); - else if (tagName.equals("long")) + } else if (tagName.equals("long")) { context.peek().addArgument(new ValueNode(Long.valueOf(JAXXCapture.getText(tag)))); - else if (tagName.equals("float")) + } else if (tagName.equals("float")) { context.peek().addArgument(new ValueNode(Float.valueOf(JAXXCapture.getText(tag)))); - else if (tagName.equals("double")) + } else if (tagName.equals("double")) { context.peek().addArgument(new ValueNode(Double.valueOf(JAXXCapture.getText(tag)))); - else if (tagName.equals("null")) + } else if (tagName.equals("null")) { context.peek().addArgument(new ValueNode(null)); - else + } else { System.err.println("unsupported tag: " + tag.getTagName()); + } } @@ -185,8 +191,9 @@ context.push(capturedObject); NodeList children = objectTag.getChildNodes(); String id = objectTag.getAttribute("id"); - if (id.length() == 0 || capture.getCapturedObjects().containsKey(id)) + if (id.length() == 0 || capture.getCapturedObjects().containsKey(id)) { id = "Auto" + ++count; + } assert !capture.getCapturedObjects().containsKey(id); capture.getCapturedObjects().put(id, capturedObject); capturedObject.setProperty("id", id); @@ -211,8 +218,9 @@ Node child = children.item(i); if (child.getNodeType() == Node.ELEMENT_NODE) { Element element = (Element) child; - if (!element.getTagName().equals("void") || !element.getAttribute("property").equals("name")) + if (!element.getTagName().equals("void") || !element.getAttribute("property").equals("name")) { evaluate(element, context, capture); + } } } assert context.peek() == capturedObject; @@ -221,8 +229,9 @@ return capturedObject; } else { CapturedObject result = capture.getCapturedObjects().get(objectTag.getAttribute("idref")); - if (result == null) + if (result == null) { throw new RuntimeException("Internal error: could not find tag with id " + objectTag.getAttribute("idref")); + } result.setInlineable(false); // we have at least two references to it, and so can't inline it return result; } @@ -238,8 +247,9 @@ StringBuffer result = new StringBuffer(); result.append('<'); String className = object.getClassName(); - if (className.startsWith("javax.swing.")) + if (className.startsWith("javax.swing.")) { className = className.substring("javax.swing.".length()); + } result.append(className); Map<String, String> properties = object.getProperties(); for (Map.Entry<String, String> e : properties.entrySet()) { @@ -253,8 +263,9 @@ if (arguments != null && arguments.length > 0) { result.append(" constructorParams='"); for (int j = 0; j < arguments.length; j++) { - if (j != 0) + if (j != 0) { result.append(", "); + } result.append(capture.getJavaCode(arguments[j])); } result.append('\''); @@ -262,11 +273,12 @@ boolean tagClosed = false; String children = getChildXML(object, capture); + String lineSeparator = JAXXCompiler.getLineSeparator(); if (children != null && children.length() > 0) { if (!tagClosed) { tagClosed = true; result.append('>'); - result.append(JAXXCompiler.getLineSeparator()); + result.append(lineSeparator); } result.append(children); } @@ -276,21 +288,22 @@ if (!tagClosed) { tagClosed = true; result.append('>'); - result.append(JAXXCompiler.getLineSeparator()); + result.append(lineSeparator); } result.append(" <script>"); - result.append(JAXXCompiler.getLineSeparator()); - result.append(JavaFile.indent(script, 4, false)); - result.append(JAXXCompiler.getLineSeparator()); + result.append(lineSeparator); + result.append(JavaFile.indent(script, 4, false, lineSeparator)); + result.append(lineSeparator); result.append(" </script>"); - result.append(JAXXCompiler.getLineSeparator()); + result.append(lineSeparator); } if (tagClosed) { result.append("</"); result.append(className); result.append('>'); - } else + } else { result.append("/>"); + } return result.toString(); } @@ -298,10 +311,11 @@ protected String getChildXML(CapturedObject object, JAXXCapture capture) { StringBuffer result = new StringBuffer(); CapturedObject[] children = object.getChildren(); + String lineSeparator = JAXXCompiler.getLineSeparator(); for (CapturedObject aChildren : children) { if (!aChildren.isInlineable()) { - result.append(JavaFile.indent(aChildren.getXML(capture), 2, false)); - result.append(JAXXCompiler.getLineSeparator()); + result.append(JavaFile.indent(aChildren.getXML(capture), 2, false, lineSeparator)); + result.append(lineSeparator); } } return result.toString(); Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/PrimitiveConverter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/PrimitiveConverter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/PrimitiveConverter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/PrimitiveConverter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,78 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +import jaxx.compiler.JAXXCompiler; + +public class PrimitiveConverter implements TypeConverter { + public String getJavaCode(Object object) { + if (object instanceof Boolean) { + return String.valueOf(((Boolean) object).booleanValue()); + } + if (object instanceof Byte) { + return String.valueOf(((Byte) object).byteValue()); + } + if (object instanceof Short) { + return String.valueOf(((Short) object).shortValue()); + } + if (object instanceof Integer) { + return String.valueOf(((Integer) object).intValue()); + } + if (object instanceof Long) { + return String.valueOf(((Long) object).longValue()) + "L"; + } + if (object instanceof Float) { + return String.valueOf(((Float) object).floatValue()) + "F"; + } + if (object instanceof Double) { + return String.valueOf(((Double) object).doubleValue()); + } + if (object instanceof String) { + return '"' + JAXXCompiler.escapeJavaString((String) object) + '"'; + } + throw new IllegalArgumentException("unsupported object: " + object); + } + + + public Object convertFromString(String string, Class type) { + if (type == String.class || type == Object.class || type == null) { + return string; + } + if (type == int.class || type == Integer.class) { + return Integer.valueOf(string); + } + if (type == boolean.class || type == Boolean.class) { + if (string.toLowerCase().equals("true")) { + return Boolean.TRUE; + } + if (string.toLowerCase().equals("false")) { + return Boolean.FALSE; + } + throw new IllegalArgumentException("expected 'true' or 'false', found '" + string + "'"); + } + if (type == byte.class || type == Byte.class) { + return Byte.valueOf(string); + } + if (type == short.class || type == Short.class) { + return Short.valueOf(string); + } + if (type == long.class || type == Long.class) { + return Long.valueOf(string); + } + if (type == float.class || type == Float.class) { + return Float.valueOf(string); + } + if (type == double.class || type == Double.class) { + return Double.valueOf(string); + } + if (type == char.class || type == Character.class) { + if (string.length() == 1) { + return string.charAt(0); + } + throw new IllegalArgumentException("expected a single character, found '" + string + "'"); + } + throw new IllegalArgumentException("unsupported type: " + type); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeConverter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/TypeConverter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeConverter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeConverter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,11 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +public interface TypeConverter { + String getJavaCode(Object object); + + Object convertFromString(String string, Class type); +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeManager.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/TypeManager.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeManager.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/java/jaxx/types/TypeManager.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,45 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +import java.util.HashMap; +import java.util.Map; + +public class TypeManager { + private static Map<Class, TypeConverter> converters = new HashMap<Class, TypeConverter>(); + + private TypeManager() { /* not instantiable */ } + + + public static void registerTypeConverter(Class type, TypeConverter converter) { + converters.put(type, converter); + } + + + public static TypeConverter getTypeConverter(Class type) { + return converters.get(type); + } + + + public static String getJavaCode(Object object) { + if (object == null) { + return "null"; + } + TypeConverter converter = getTypeConverter(object.getClass()); + if (converter == null) { + throw new IllegalArgumentException("unsupported type: " + object.getClass()); + } + return converter.getJavaCode(object); + } + + + public static Object convertFromString(String string, Class type) { + TypeConverter converter = getTypeConverter(type); + if (converter == null) { + throw new IllegalArgumentException("unsupported type: " + type); + } + return converter.convertFromString(string, type); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/resources/META-INF/services) Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.compiler.Generator (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/resources/META-INF/services/jaxx.spi.Initializer) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.compiler.Generator (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.compiler.Generator 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1 @@ +jaxx.compiler.JAXXObjectGenerator \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.compiler.Generator ___________________________________________________________________ Name: svn:mergeinfo + Modified: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.spi.Initializer =================================================================== --- lutinjaxx/trunk/jaxx-core/src/main/resources/META-INF/services/jaxx.spi.Initializer 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/main/resources/META-INF/services/jaxx.spi.Initializer 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,2 +1 @@ jaxx.DefaultInitializer -jaxx.tags.swing.SwingInitializer \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/BeanValidator.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/BeanValidator.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/BeanValidator.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,179 @@ +------------- +BeanValidator +------------- + +.. contents:: + + +Présentation +============ + +Ajout du support de validation dans JAXX. + +La techonologie utilisée est celle de Struts 2 (XWorks 2). + + +Configuration +============= + +La configuration des validateurs se font via des fichier xml (on peut aussi utiliser des annotations,...). + +Ajout d'un validateur +********************* + +Pour enregister un nouveau validateur sur un bean, il suffit de placer dans le même paquetage que le bean un fichier *XXX-validation.xml* où XXX est le nom non qualifié du bean. + +On peut de plus affecter un context de validation, dans ce cas le fichier doit s'appeler *XXX-YYY-validation.xml*, où YYY est le nom du context de validation. + +Ainsi on peut valider de différentes manières un bean (par exemple selon son cycle de vie :création, modification, ...). + +Ajout d'un nouveau type de validateur +************************************* + +Il est aussi possible de définir de nouveau type de validateurs : + + * créer une classe qui étend FieldValidator + * ajouter un fichier validators.xml (ou ajouter dans un tel fichier la définition du nouveau validator) à la racine du class-path. + +I18n +**** + +Afin de rendre le mécanisme multi-langue, on propose dans les fichiers de validations d'utiliser des clef i18n pour les messages. + +Un nouveau parseur dans notre plugin i18n a été ajouté pour détecter ces clefs. (*maven-i18n-plugin:0.7:parserValidation*) + + +Intégration dans JAXX +===================== + +Deux nouveaux tags ont été conçus pour pouvoir décrire un validateur dans les fichiers JAXX. + +Ce développement est dans le paquetage *jaxx.tags.validator*. + +tag BeanValidator +***************** + +Permet de définir un nouveau validateur dans une classe JAXX. + +Les attributs autorisés sont les suivants : + + * *id* : le nom du validateur + + * *bean* : l'id d'un bean connu par la classe JAXX. On ne peut pas utiliser ici une expression car on n'est pas sûr de pouvoir déterminer le type de cette expression pendant le parsing ? (a verifier). + + * *beanClass* : le FQN de classe du bean à valider. Peut-être non présent si l'attribut *bean* est renseigné. + + * *beanInitializer* : une expression pour initialiser le bean à valider. TODO a revoir : on devrait utiliser uniquement un seul attribut *bean*... + + * *contextName* : le nom du contexte de validation. + + * *autoField* : flag pour indiquer l'inscription implicite des validateurs de champs du bean. Pour ce faire on parcourt l'ensemble des champs du bean et on ne considère uniquement ceux dont on connait dans la classe JAXX un composent d'édition du champ (id=nom du champ). Il est possible de surcharger ce configuration implicite en rajoutant explicitement des champs (voir le tag *field*). + + * *errorList* : le composant graphique pour afficher la liste des erreurs, doit étendre *javax.swing.JList*. Si non présent, on essayera le component d'id *errorList*. + + * *errorListModel* : le modèle qui contient la liste des erreurs (et est liée au composant *errorList*), doit étendre *jaxx.runtime.validator.BeanValidatorErrorListModel*. Si non présent on essayera le composent d'id *errorListModel*. + + * *uiClass* : le FQN de la classe utilisé pour le rendu des erreurs sur les wigets d'édition. La classe doit étendre *jaxx.runtime.validator.ui.AbstractBeanValidatorUI*. Si non présent, on utilise par défaut le render *jaxx.runtime.validator.ui.IconValidationUI*. + + +Le tag supporte aussi l'ajout de tag *field* comme fils pour définir explicitement des champs à validater. + +tag field +********* + +Le tag *field* définit une entrée dans le validateur, on définit une correspondance entre le champ à valider et le composant d'édition de ce champ. + +Le tag supporte les attributs suivants : + + * *name* : le nom de la propriété du bean associée. + Cet attribut est obligatoire. + + * *component* : l'id du composant graphique d'édition associé à la propriété du bean. + Cet attribut peut être omis si le nom de la propriété du bean est identique à celui du composent graphique d'édition. + + +Les classes du runtime +====================== + +Ce développement est dans le paquetage *jaxx.runtime.validator* (sauf pour l'interface *jaxx.runtime.JAXXValidator*). + +Il s'agit de l'ensemble des classes ajoutées dans le module *jaxx-core* pour encapsuler la validation dans les fichiers java générés à partir des fichiers JAXX. + + +interface jaxx.runtime.JAXXValidator +************************************ + +Ce contrat a été ajouté à tous les objets JAXX générés (donc l'interface JAXXObject étend JAXXValidator). + +On définit ici uniquement des méthodes d'accès aux validateurs enregistrés dans le JAXXObject. + +TODO on pourrait ajouter des méthodes pour savoir l'état de validation d'un validateur ? + + +classe jaxx.runtime.validator.BeanValidator +******************************************* + +Il s'agit de la classe principale d'encapsulation d'un validateur XWorks 2. + +Le principe est simple : le validateur écoute les modifications sur le bean associé et revalide le bean à chaque modification. La validation met à jour la liste des erreurs asociées. + +On se base sur les PropertyChangeListener pour écouter les modification des beans. Il faut donc que les beans supporte ces listeners. + +Pour les entités de ToPIA, il suffit de positionner un contexte (topia) au bean pour profiter des listeners liés. + +Pour les DTO de ToPIA, les générateurs ont été modifiés pour gérer ce support. + +Les méthodes à retenir sont : + + * *setBean* pour affecter un bean au validateur (pour déasactiver passer null). Lors de la désactivation d'un bean, les erreurs associés sont retirées de la liste des erreurs. + + * *setContextName* pour affecter un nouveau nom de context de validation (par défaut on utilise pas de context de validation). + + * *validate* pour lancer une validation sur le bean liée (ne sera opérant uniquement si un bean est liée et qu'une liste d'erreur est liée). + + * *isValid* pour connaitre l'état du validateur à un moment donné. + +Normalement la méthode *validate* ne devrait pas être appelée directement. : elle est automatiquement invoquée lorsqu'une propriété du bean est modifiée. + +classe jaxx.runtime.validator.BeanValidatorError +************************************************ + +Modélisation d'une erreur renvoyé par le validateur, on conserve ici : + + * le validateur qui a provoqué l'erreur + + * la propriété du bean en faute + + * le composent graphique d'édtion de la propriété + +classe jaxx.runtime.validator.BeanValidatorErrorListModel +********************************************************* + +Le modèle de la liste des erreurs renvoyées par le validateur. Il s'agit d'une extension d'un *javax.swing.DefaultListModel* qui permet de gérer une liste d'erreurs provenant de plusieurs validateurs en même temps. + +classe jaxx.runtime.validator.ErrorListMouseListener +**************************************************** + +Un listener écoutant les double clics sur une liste d'erreurs et qui donne le focus au composent graphique d'édition associée à la propriété dont l'erreur est sélectionné. + + +Les conversions +=============== + +Pour l'édition de proriétés qui ne sont pas des chaines de caractères, des erreurs de conversions peuvent survenir (conversion de la valeur de l'édtieur graphique vers le bean), avant que l'on utilise +réellement la mécanique de la validation. + +Pour palier à ce problème on a intégré la gestion des erreurs de conversion dans le validateur. +Pour ce faire, il suffit de faire appel à la méthode suivante pour injecter dans un bean une propriété : + + :: + + jaxx.runtime.Util.convert(validator,"nomDeLaPropriété",widget.getText(),TypeDeLaProriete.class); + + +On obtiendra si une erreur de conversion intervient, une erreur dont le libellé est de la forme *error.convertor.XXX* +où XXX est nom simple en minuscule du type de la propruité. (par exemple : *error.convertor.integer*). + + + + Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/I18n.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/I18n.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/I18n.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,56 @@ +---- +I18n +---- + +.. contents:: + + +Présentation +============ + +Ajout du support i18n dans JAXX. + +On utilise la système i18n développé dans la librairie des lutins (*lutinlib*). + +Configuration +============= + +Une option a été ajoutée dans le plugin maven de JAXX : *i18nable* pour permettre ou non l'utilisation de ce système. + +Par défaut, l'option est active (donc aucune configuration supplémentaire n'est nécessaire pour utiliser i18n dans JAXX). + + +Fonctionnement +============== + +Le fonctionnement est simple : lors de la compilation JAXX, lorsque l'on rencontre certains attributs on encapsule la +valeur de l'attribution par un appel à la méthode + +:: + + org.codelutin.i18n.I18n._(String) + + +La liste des attributs en question sont les suivants : + + - title + - text + - toolTipText + + +Ensuite l'utilisation du *parserJava* du plugin i18n permet la détection des clefs i18n. + + +Pourquoi ne plus utiliser l'ancien parserJaxx du plugin i18n +============================================================ + +Un parseur avait été développé initialement pour détecter dans les fichiers JAXX (*parserJaxx*), les appels à la méthode de traduction +i18n dans les attributs. + +Ce parseur n'est plus d'actualité car on ne doit plus avoir d'appel explicite à cette méthode dans les fichiers JAXX. + +De plus, même sans avoir mis en place le mécanisme i18n dans JAXX, ce parseur n'était plus d'actualité : il se base +sur une liste prédéfinie d'attributs xml à scanner pour détecter des appels i18n; ce qui n'était pas acceptable à terme +car si on ajoute un nouveau composent dans JAXX, le plugin i18n n'est pas capable de détecter les nouvelles clefs. + +Donc on préconise l'utilisation du *parserJava* du plugin i18n qui lui est capable de détecter tous les appels i18n. Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Interface.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Interface.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Interface.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,38 @@ +--------- +Interface +--------- + +.. contents:: + + +Présentation +============ + +Ajout de contrats sur le code généré dans JAXX. + +Mécanisme +========= + +Le compilateur JAXX génère des classes à partir de fichiers JAXX mais n'est pas capable d'ajouter des contrats sur +les objets générés, donc interdit en quelque sorte la programmation par contrat. + +Pour palier à cette limitation, on a ajouté un attribut spécial *implements*. + +Cette attribut ne doit être placé que sur le tag racine d'un fichier JAXX et son contenu est le nom qualifié d'un ou +plusieurs contrats séparaés par des virgules. + +:: + + <JPanel implements='java.lang.Comparable'> + + <script>public int compareTo(JPanel o) { return getName().compareTo(o.getName()); }</script> + + </JPanel> + +La classe générée aura bien le contrat *java.lang.Comparable*. + +TODO +==== + +Il serait intéressant lors de l'injection de contrats sur un objet jaxx de pouvoir vérifier si toutes les méthodes du +contrat sont bien implantées dans la classe, et si ce n'est pas le cas de rendre la classe abstraite. Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JAXXContext.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JAXXContext.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JAXXContext.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,161 @@ +----------- +JAXXContext +----------- + +.. contents:: + + +Présentation +============ + +Ajout d'un context applicatif dans JAXX. + +Le besoin initial de ce développement est de pouvoir facilement intégrer un context applicatif dans JAXX et de pouvoir +l'utiliser dans les fichiers JAXX pour injecter par exemple des données dans les widgets. + +jaxx.runtime.JAXXContext +======================== + +Il s'agit du contrat de base du context applicatif. + +Les entrées dans le context +*************************** + +Chaque donnée utilisable dans le context est caractérisée par deux propriétés : + + * la type de l'objet + + * un nom (facultatif) associé à la donnée + +Le type de l'objet correspondant en fait à la classe de la donnée. + +Le nom qui est facultatif permet de pouvoir distinguer plusieurs données d'un même type dans le context. Si le nom +n'est pas utilisé pour caractériser une données on fixera alors sa valeur à *null*. + +Afin de pouvoir caractériser les entrées dans le context, une classe a été définie *jaxx.runtime.JAXXContextEntryDef*. + +Les méthodes de lecture +*********************** + +On a définit deux méthodes de lecture de données dans le context : + + * *getContextValue(Class)* récupère la donnée *non nommée* dont le type correspond à celui passé. + + * *getContextValue(Class,String)* récupère la donnée nommé dont le type correspond à celui passé. + +Les méthodes d'écriture +*********************** + +On a définit quatre méthodes d'écriture de données dans le context : + + * *setContextValue(Object)* enregistre dans le context la donnée *non nommée*. + + * *setContextValue(Object,String)* enregistre dans le context la donnée *nommée*. + + * *removeContextValue(Class)* supprime du context, la donnée *non nommée* dont le type est passé. + + * *removeContextValue(Class, String)* supprime du context, la donnée *nommée* dont le type est passé. + +Afin de pouvoir assurer une cohérence dans le context, chaque injection de donnée, sera toujours précédée par une +suppression d'un éventuellement ancienne valeur qui aurait la même définition d'entrée. + +L'héritage +********** + +Il est possible d'avoir une hériarchie de context qui s'enchaînent. Ce mécanisme a été mis en place pour répondre à un +besion précis : chaque fichier JAXX donne lieu à une nouvelle classe qui possède son propre context. + +On peut avoir des fichiers JAXX qui utilisent d'autres fichiers JAXX, il faut donc être capable de lier le context du +composent parent avec ses fils. + +La mise en place de l'héritage est transparente pour l'utilisateur : aucune méthode supplémentaire n'est requise. + +Les implantations de context +============================ + +jaxx.runtime.DefaultJAXXContext +******************************* + +Il s'agit de l'implantation par défaut utilisée par les objects *JAXXObject* (objets générés). + +A noter que pour les opérations d'injection ou de suppression, on effectuera les opérations sur le context qui contient +réellement la donnée, ce qui est important pour conserver la cohérence des contexts dans les contexts chaînés. + +Pour traiter le context parent, aucune méthode publique supplémentaire n'a été rajoutée, il suffit d'injecter un objet +de type *JAXXContext* *non nommé* qui le context courant qui sera détecté comme une entrée de type context. + +Cette entrée spéciale ne sera pas stockée avec les autres entrées afin d'optimiser les algorithmes d'injection et de +restitution. + +jaxx.runtime.JAXXInitialContext +******************************* + +On a implanté un second type de context qui lui peut servir à l'initialisation des JAXXObject. + +Ce second type de context ajoute des méthodes pour préparer le context avant l'instanciation des JAXXObject. + +Ce context admet certaine limitation (pas de suppression dans le context), et apporte trois nouvelles méthodes : + + * add(Object) : injecte dans le context une entrée non nommée et retourne l'instance du context. + + * add(String,Object) : injecte dans le context une entrée nommé et retourne l'instance du context. + + * to(JAXXContext) : injecte dans le context passé toutes les entrée du context. + +Les méthodes *add* peuvent être chaînées comme dans l'exemple suivant : + +:: + + JAXXInitialContext context = new JAXXInitialContext().add("string").add(0).add("currentDate",new Date()); + + +Intégration dans les JAXXObject +=============================== + +Le traitement d'un fichier JAXX donne lieu à une classe qui possède le contrat *jaxx.runtime.JAXXObject*. + +Ce contrat hérite donc du contrat *JAXXContext* (afin de pouvoir l'utiliser de manière transparente dans les fichiers JAXX). + +Afin de simplifier la génération et les évolutions du context indépendemment des évolutions des JAXXObject, on utilise +un pattern de délégation au sein des object générés. + +Paramétrage de l'implantation du context +**************************************** + +Une propriété a été rajoutée sur le plugin JAXX, afin de pouvoir préciser l'implantation de context à utiliser : + +:: + + jaxx.jaxxContextImplementorClass + +Il s'agit du nom qualifié de la classe d'implantation à utiliser. + +Par défaut, si rien n'est renseigné, on utilisera un *jaxx.runtime.DefaultJAXXContext*. + + +Initialisation d'un JAXXObject +****************************** + +Un nouveau constructeur a été ajouté dans les JAXXObjet générés afin de pouvoir facilement initialisé un tel objet à +partir d'un context parent, son unique paramètre est le context parent. Ce constructeur est capable de différencer le +type de context passé : + + * s'il s'agit d'un *JAXXInitialContext*, on recopie alors dans le context réel de l'objet toutes les entrées du context passé. + + * sinon le context passé est simplement injecté dans le context de l'objet (et donc sera utilisé comme le context parent de celui de l'objet). + +Voici un exemple d'initialisation d'un JAXXObject : + +:: + + java.util.Date currentDate = new java.util.Date(); + JAXXInitialContext context = new JAXXInitialContext().add("string").add(0).add("currentDate",currentDate); + JAXXObject ui = new MyUI(context); + + assert "string".equals(myUI.getContextValue(String.class)); + assert 0 == myUI.getContextValue(Integer.class); + assert currentDate.equals(myUI.getContextValue(java.util.Date.class,"currentDate")); + +A noter, que l'initialisation du context d'un *JAXXObject* sera toujours effectuée avant la méthode *$initialize* générée +par le compilateur JAXX, ce qui permet de pouvoir utiliser le context pour l'initialisation des widgets dans les fichiers JAXX. + Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JavaBean.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JavaBean.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/JavaBean.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,50 @@ +-------- +JavaBean +-------- + +.. contents:: + + +Présentation +============ + +Ajout du support complêt des javaBean dans JAXX. + +Mécanisme +========= + +Il est possible dans JAXX de rajouter des objets quelconques via leur nom qualifié de classe : + +:: + + <JPanel> + <java.lang.Boolean id='myState' constructorParams='true'/> + <JLabel text='text' visible='{isMySate()}'/> + </JPanel> + +Avant l'ajout de la fonctionnalité, le code généré possèdait : + + * une propriété en lecture seul nommé *myState*. + +Aucun support javaBean n'était présent et le databinding sur la propriété *visible* du label n'est pas créé. Cela veut +dire que le label sera initialisé avec la valeur initiale du boolean et c'est tout... + +Avec l'ajout du support javaBean, on peut maintenant faire ces bindings, pour ce faire il suffit d'ajouter un attribut +*javaBean* sur l'objet : + +:: + + <JPanel> + <java.lang.Boolean id='myState' constructorParams='true' javaBean='anyValue'/> + <JLabel text='text' visible='{isMySate()}'/> + </JPanel> + +On aura donc en plus : + + * un mutateur sur la propriété *myState* qui déclanchera l'envoie d'un *PropertyChange* sur la propriété lors de modification de valeur. + +Ainsi le compilateur JAXX sera capable d'enregistrer un novueau dataBindig sur la propriété *visible* du label et la +modification de l'état *myState* sera automatiquement répercuté sur la propriété. + + + Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/NavigationTreeModel.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/NavigationTreeModel.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/NavigationTreeModel.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,168 @@ +------------------- +NavigationTreeModel +------------------- + +.. contents:: + + +Présentation +============ + +Ajout d'un modèle d'arbre de navigation. + +Le but de cette fonctionnalité est de pouvoir créer un arbre de navigation lié au context de JAXX, de définir des UI +rattachés à chaque noeud. + +Le développement est effectué dans le paquetage *jaxx.runtime.swing.navigation*. + +jaxx.runtime.swing.navigation.NavigationTreeModel +================================================= + +Il s'agit du modèle de l'arbre utilisé, c'est une extension d'un *javax.swing.tree.DefaultTreeModel*. + +Les noeuds présents dans ce modèle sont aussi typés en *jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode*. + +L'idée principale est de pouvoir associé à un noeud précis un chemin depuis la racine, ce que l'on appele *chemin de navigation*. + +Pour obtenir le chemin de navigation d'un noeud donné, on récupère l'enmseble des neoud depuis la racine vers ce noeud +et les concatène en suffixant par le caractère séparateur défini. + +Définition d'un noeud +===================== + +Le noeud (*jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode*) est une extension d'un *javax.swing.tree.DefaultMutableTreeNode*. + +Il apporte les nouvelles propriétés suivantes : + + * *navigationPAth* : nom de chemin de navigation de ce noeud. + + * *jaxxClass* : nom qualifié de la classe d'ui associé à ce noeud (doit être obligatoirement un *JAXXObject*) + + * *jaxxActionClass* : nom qualifié de la classe d'handler d'ui associé à ce noeud (doit être obligatoirement un *JAXXAction*). + + * *jaxxContextEntryDef* : définition de l'entrée dans le context JAXX associé à ce noeud. + + * *jaxxContextEntryJXPath* : définition d'une expression JXPath à appliquer sur le bean associé au noeud. + + +Retrouver un noeud à partir du chemin de navigation +*************************************************** + +Il est possible en connaissant le chemin de navigation d'un noued de récupérer le noeud dans l'arbre via la méthode + +:: + + model.findNode("chemin.de.navigation") + +Trouver la valeur associée dans le context JAXX à partir du chemin de navigation +******************************************************************************** + +Il est possible en connaissant le chemin de navigation d'un noued de récupérer la valeur associée dans le context JAXX. + +:: + + model.getJAXXContextValue(myJAXXContext, "chemin.de.navigation")* . + +L'algrotihme est le suivant : + + * récupération du noeud associé au chemin de navigation + + * recherche du premier noeud (dans les noeuds qui remontent vers la racine de l'arbre) dont la propriété *jaxxContextEntry* est non nulle, il s'agit du point d'entré dans le context JAXX. + + * redescendre à partir de ce noeud vers le noeud d'origine (si ce noeud était différent) et en descendant conjointement dans l'objet du context JAXX : + + - on utilise l'expression JXPath pour obtenir l'objet associé au noeud + +Exemple : + +:: + + "$root" + <-- la racine de l'abre + | + + "string" <-- attaché au context JAXX <java.lang.String,"string"> + | + + "liste" + <-- attaché au context JAXX <java.util.List.class,"liste"> + | | + | + "0" <-- le premier élément de la liste + | | + | + "1" <-- le second élément de la liste + | | + | + "2" <-- le troisième élément de la liste + | + + "locale" + <-- attaché au context JAXX <java.util.Locale> + | + + country + | + + language + + // preparation du context + java.util.List myList = java.util.Arrays.asList("one","two","three"); + java.util.Locale myLocale = java.util.Locale.FRENCH; + context.setContextValue(myList, "liste"); + context.setContextValue("stringValue","string"); + context.setContextValue(myLocale); + + + // récupération des valeurs dans le context à partir de chemin de navigation + assert model.getJAXXContextValue(context, "$root") == null; + assert model.getJAXXContextValue(context, "$root.string") == "stringValue"; + assert model.getJAXXContextValue(context, "$root.liste") == myList; + assert model.getJAXXContextValue(context, "$root.liste.0") == "one"; + assert model.getJAXXContextValue(context, "$root.liste.1") == "two"; + assert model.getJAXXContextValue(context, "$root.liste.2") == "three"; + assert model.getJAXXContextValue(context, "$root.locale") == myLocale; + assert model.getJAXXContextValue(context, "$root.locale.country") == myLocale.getCountry(); + assert model.getJAXXContextValue(context, "$root.locale.language") == myLocale.getLanguage(); + +TODO mettre à jour cet exemple suite à l'utilisation de JXPath pour naviguer dans les objets. + +A noter qu'une seconde méthode de récupération de valeur du context JAXX est disponible pour pouvoir récupérer cette +valeur en connaissant le noeud : + +:: + + model.getJAXXContextValue(context, myNode); + +jaxx.runtime.swing.navigation.NavigationTreeSelectionAdapter +============================================================ + +Il s'agit d'un listener sur la sélection d'un noeud dans l'arbre de navigation basé sur notre modèle de navigation. Il +étend *javax.swing.event.TreeSelectionListener*. + +Ce listener contient la gestion de passage d'un noeud à un autre avec interaction avec le context JAXX et affichage automatique de l'ui associé au noeud sélectionné. + +**Attention : la mécanique ne fonctionne que pour un arbre à selection unique.** + +Algorithme +********** + +Voici l'algorithme utilisé lors de la sélection d'un nouveau noeud : + + * *closeUI* : tentative de fermeture de l'ui lié au noeud précédemment selectionné, si cela n'aboutit pas on retourne sur le noeud précédent. + + * *attachBeanFromNodeToContext* : injection dans le context JAXX de la valeur associée au nouveau noeud + + * *createUI* : création de la nouvelle ui (si elle n'existe pas) + + * *openUI* : ouverture de la nouvelle ui + +Si une erreur survient lors de ces opérations, on entre dans la méthode *goBackToPreviousNode* qui est abstraite et permet de notifier les erreur de retourner au noeud précdent. + +jaxx.runtime.swing.navigation.NavigationTreeSelectionAdapterWithCardLayout +************************************************************************** + +Il s'agit d'une implantation du listener précédent qui suppose que les uis associées aux noeuds sont affichées dans un +unique container en utilisant le layout *jaxx.runtime.swing.CardLayout2*. + +La contrainte de chaque ui sera extactement le chemin de navigation du noeud associé. + +Il possède deux méthodes abstraites : + + * *getContentContainer* : qui indique le container d'ui. + + * *getContentLayout* : qui indique le layout utilisé. + +Pour pouvoir utilisé cet *adapter*, il vous suffit de définir la méthode suivante (en plus des deux méthodes abstraites) : + + * *goBackToPreviousNode* : comment gérer les erreurs et retourner au noeud précedent. + Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Todo.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Todo.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/Todo.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,15 @@ +==== +TODO +==== + + - réorganiser ce module maven en deux modules : + + * un premier module de runtime + + * un second module contenant uniquement le compilateur et non nécessaire au runtime. + + Le second module pourrait être facultatif et le code pourrait directement être placé dans le module du plugin. + + Cependant cela n'est pas possible actuelement car certains objets du runtime contiennent aussi du code utilisé + par le compilateur JAXX (par exemple StyleSheet). Il faut avant tout cloisonner le code non runtime. + \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/index.rst =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/index.rst (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/site/fr/rst/index.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,41 @@ +jaxx-core +========= + +.. contents:: + + +Présentation +------------ + +Le compilateur Jaxx TODO + +**Veuillez consulter la JavaDoc pour de plus ample détails sur les différentes +librairies.** + +Nouvelles fonctionnalités +------------------------- + + * I18n_ + + * JAXXContext_ + + * BeanValidator_ + + * NavigationTreeModel_ + + * JavaBean_ + + * Interface_ + + +.. _I18n: I18n.html + +.. _JAXXContext: JAXXContext.html + +.. _BeanValidator: BeanValidator.html + +.. _NavigationTreeModel: NavigationTreeModel.html + +.. _Javabean: JavaBean.html + +.. _Interface: Interface.html \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/beaninfos/BeanIntoUtilTest.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/beaninfos/BeanIntoUtilTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/beaninfos/BeanIntoUtilTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,34 @@ +package jaxx.beaninfos; + +import org.junit.Assert; +import org.junit.Test; + +import java.beans.Introspector; + +/** @author chemit */ +public class BeanIntoUtilTest { + + @Test + public void testExtraBeanInfoPath() { + BeanInfoUtil.reset(); + String[] searchPath0 = Introspector.getBeanInfoSearchPath(); + + BeanInfoUtil.addJaxxBeanInfoPath("jaxx.beaninfos"); + + String[] searchPath = Introspector.getBeanInfoSearchPath(); + Assert.assertEquals(searchPath0.length + 1, searchPath.length); + + BeanInfoUtil.reset(); + Assert.assertEquals(searchPath0.length, Introspector.getBeanInfoSearchPath().length); + + String packageName = getClass().getPackage().getName()+".dummy"; + BeanInfoUtil.addJaxxBeanInfoPath("jaxx.beaninfos", packageName); + + searchPath = Introspector.getBeanInfoSearchPath(); + Assert.assertEquals(searchPath0.length + 2, searchPath.length); + Assert.assertEquals(packageName, searchPath[searchPath.length - 1]); + + BeanInfoUtil.reset(); + Assert.assertEquals(searchPath0.length, Introspector.getBeanInfoSearchPath().length); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/ClassDescriptorTest.java (from rev 1098, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/ClassDescriptorTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/ClassDescriptorTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/ClassDescriptorTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,63 @@ +package jaxx.junit; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.reflect.MethodDescriptor; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; +import org.junit.Test; + +public class ClassDescriptorTest { + + /*@Test + public void testGetClassDescriptor() throws Exception { + ClassDescriptorLoader.getClassDescriptor("jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode"); + }*/ + + @Test + public void testBuiltInClassName() throws ClassNotFoundException, NoSuchMethodException { + ClassDescriptor object = ClassDescriptorLoader.getClassDescriptor("java.lang.Object"); + MethodDescriptor toString = object.getMethodDescriptor("toString"); + assertEquals(toString.getName(), "toString"); + assertEquals(toString.getParameterTypes().length, 0); + + MethodDescriptor equals = object.getMethodDescriptor("equals", object); + assertEquals(equals.getName(), "equals"); + assertEquals(equals.getParameterTypes().length, 1); + assertEquals(equals.getParameterTypes()[0], object); + } + + @Test + public void testBuiltInClass() throws ClassNotFoundException, NoSuchMethodException { + ClassDescriptor object1 = ClassDescriptorLoader.getClassDescriptor("java.lang.Object"); + ClassDescriptor object2 = ClassDescriptorLoader.getClassDescriptor(Object.class); + assertEquals(object1, object2); + } + + @Test + public void testUserClassName() throws ClassNotFoundException, NoSuchMethodException { + ClassDescriptor me = ClassDescriptorLoader.getClassDescriptor("jaxx.junit.ClassDescriptorTest", getClass().getClassLoader()); + MethodDescriptor testUserClassName = me.getMethodDescriptor("testUserClassName"); + assertEquals(testUserClassName.getName(), "testUserClassName"); + assertEquals(testUserClassName.getParameterTypes().length, 0); + } + + @Test(expected = ClassNotFoundException.class) + public void testWrongCase() throws ClassNotFoundException { + //try { + //ClassDescriptor object = + ClassDescriptorLoader.getClassDescriptor("jaxx.junit.classdescriptortest", getClass().getClassLoader()); + // fail("Found descriptor using wrong case: " + object); + //} + //catch (ClassNotFoundException e) { + //} + } + + @Test + public void testArrays() throws ClassNotFoundException { + ClassDescriptor intArray = ClassDescriptorLoader.getClassDescriptor(int[].class); + assertNotNull(intArray); + ClassDescriptor objectArray = ClassDescriptorLoader.getClassDescriptor(Object[].class); + assertNotNull(objectArray); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaFileParserTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/JavaFileParserTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaFileParserTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaFileParserTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,57 @@ +package jaxx.junit; + +import jaxx.CompilerException; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.JavaFileParser; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.junit.Assert; +import org.junit.BeforeClass; +import org.junit.Test; + +import java.io.File; +import java.io.FileReader; +import java.io.Reader; + +public class JavaFileParserTest { + + + /** log */ + protected static final Log log = LogFactory.getLog(JavaFileParserTest.class); + + static File basedir; + + @BeforeClass + public static void initBaseDir() { + // get maven env basedir + String basedir = System.getenv("basedir"); + if (basedir == null) { + basedir = new File("").getAbsolutePath(); + } + JavaFileParserTest.basedir = new File(basedir); + } + + @Test + public void testParseJavaSourceFile() throws Exception { + + File testSourceRoot = new File(basedir, "src" + File.separator + "test" + File.separator + "java"); + Assert.assertTrue(testSourceRoot.exists()); + + File src = new File(testSourceRoot, getClass().getName().replaceAll("\\.", File.separator) + ".java"); + Assert.assertTrue(src.exists()); + log.info("trying parsing file " + src); + Reader reader = new FileReader(src); + try { + ClassDescriptor result = JavaFileParser.parseJavaFile("TestParserJava", reader, getClass().getClassLoader()); + Assert.assertNotNull(result); + + } catch (CompilerException e) { + log.error("could not parse file " + src + " for reason " + e.getMessage(), e); + Assert.fail(e.getMessage()); + } + finally { + reader.close(); + } + } + +} Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaFileParserTest.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaMethodTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/JavaMethodTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaMethodTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/JavaMethodTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,52 @@ +package jaxx.junit; + +import jaxx.compiler.JavaMethod; +import jaxx.compiler.JavaMethod.MethodOrder; +import org.junit.Assert; +import org.junit.Test; + +import java.lang.reflect.Modifier; +import java.util.EnumSet; + +/** @author chemit */ +public class JavaMethodTest { + + @Test + public void testGetMethodOrderScope() { + EnumSet<MethodOrder> allConstants = EnumSet.allOf(MethodOrder.class); + + EnumSet<MethodOrder> constants; + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.STATIC); + + Assert.assertEquals(1, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.statics)); + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.PUBLIC); + + Assert.assertEquals(8, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.constructors)); + Assert.assertTrue(constants.contains(MethodOrder.JAXXObject)); + Assert.assertTrue(constants.contains(MethodOrder.JAXXContext)); + Assert.assertTrue(constants.contains(MethodOrder.JAXXValidation)); + Assert.assertTrue(constants.contains(MethodOrder.events)); + Assert.assertTrue(constants.contains(MethodOrder.publicGetters)); + Assert.assertTrue(constants.contains(MethodOrder.publicSetters)); + Assert.assertTrue(constants.contains(MethodOrder.otherPublic)); + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.PROTECTED); + + Assert.assertEquals(3, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.protectedGetters)); + Assert.assertTrue(constants.contains(MethodOrder.protecteds)); + Assert.assertTrue(constants.contains(MethodOrder.createMethod)); + + + constants = JavaMethod.getMethodOrderScope(allConstants, Modifier.PRIVATE); + Assert.assertEquals(3, constants.size()); + Assert.assertTrue(constants.contains(MethodOrder.createMethod)); + Assert.assertTrue(constants.contains(MethodOrder.packageLocal)); + Assert.assertTrue(constants.contains(MethodOrder.privates)); + + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/PrimitiveConverterTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/PrimitiveConverterTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/PrimitiveConverterTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/java/jaxx/junit/PrimitiveConverterTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,113 @@ +package jaxx.junit; + +import jaxx.types.PrimitiveConverter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class PrimitiveConverterTest { + + PrimitiveConverter converter; + + + @Before + public void setUp() { + converter = new PrimitiveConverter(); + } + + @Test + public void testBoolean() { + Boolean value = (Boolean) converter.convertFromString("true", Boolean.class); + Assert.assertTrue(value); + + value = (Boolean) converter.convertFromString("false", Boolean.class); + Assert.assertFalse(value); + + } + + @Test(expected = IllegalArgumentException.class) + public void testBoolean2() { + converter.convertFromString("yes", Boolean.class); + } + + @Test + public void testByte() { + Byte value = (Byte) converter.convertFromString(String.valueOf(Byte.MAX_VALUE), Byte.class); + Assert.assertEquals(value.byteValue(), Byte.MAX_VALUE); + + } + + @Test(expected = IllegalArgumentException.class) + public void testByte2() { + + converter.convertFromString(String.valueOf(1 + Byte.MAX_VALUE), Byte.class); + } + + @Test + public void testShort() { + Short value = (Short) converter.convertFromString(String.valueOf(Short.MAX_VALUE), Short.class); + Assert.assertEquals(value.shortValue(), Short.MAX_VALUE); + + + } + + @Test(expected = IllegalArgumentException.class) + public void testShort2() { + + converter.convertFromString(String.valueOf(1 + Short.MAX_VALUE), Short.class); + } + + @Test + public void testInteger() { + Integer value = (Integer) converter.convertFromString(String.valueOf(Integer.MAX_VALUE), Integer.class); + Assert.assertEquals(value.intValue(), Integer.MAX_VALUE); + } + + @Test(expected = IllegalArgumentException.class) + public void testInteger2() { + + converter.convertFromString(String.valueOf(1L + Integer.MAX_VALUE), Integer.class); + } + + @Test + public void testLong() { + Long value = (Long) converter.convertFromString(String.valueOf(Long.MAX_VALUE), Long.class); + Assert.assertEquals(value.longValue(), Long.MAX_VALUE); + } + + @Test + public void testFloat() { + Float value = (Float) converter.convertFromString("3.1415", Float.class); + Assert.assertTrue(value == 3.1415f); + } + + @Test + public void testDouble() { + Double value = (Double) converter.convertFromString("3.1415", Double.class); + Assert.assertTrue(value == 3.1415); + } + + @Test + public void testCharacter() { + Character value = (Character) converter.convertFromString("A", Character.class); + Assert.assertEquals(value.charValue(), 'A'); + } + + @Test(expected = IllegalArgumentException.class) + public void testCharacter2() { + + converter.convertFromString("12", Character.class); + + } + + @Test(expected = IllegalArgumentException.class) + public void testCharacter3() { + converter.convertFromString("", Character.class); + } + + @Test + public void testString() { + String value = (String) converter.convertFromString("Test", String.class); + Assert.assertEquals(value, "Test"); + } +} \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/resources/log4j.properties =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/resources/log4j.properties (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-api/src/test/resources/log4j.properties 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,8 @@ +# Global logging configuration +log4j.rootLogger=ERROR, stdout +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n + +log4j.logger.jaxx=DEBUG Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-swing ___________________________________________________________________ Name: svn:ignore + target *.iml *.log Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/LICENSE.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/LICENSE.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/LICENSE.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/README.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/README.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/README.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/changelog.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/changelog.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/changelog.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,90 @@ +1.0 ???? 200812?? + +0.8 ??? 200812?? + * 20081228 [chemit] - generify ClassDescriptor + - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from + JAXXCompiler and make possible to extract compiler engine from runtime + + * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation + * 20081218 [chemit] - improve generation of methods + * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) + - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option) + - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection + - add addSourcesToClassPath property to add sources directories in class-path + - improve classloader managment + - keep in DataSource objetCode + - fix bug when processDataBinding on a null objectCode + - always clean node cached values when selected it + - add usefull databinding method in Util + +* 20081213 [chemit] - improve navigation tree node rendering with some caches + - introduce a ChildBuilder to simplify building of child nodes from a collection or array + +0.7 chemit 20081210 +* 20081210 [chemit] - fix bug 1751 +* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) +* 20081208 [chemit] - javabBean attribute use to initialize bean + - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) + - introduce MultiJXPathDecorator + - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers + + * 20081207 [chemit] use lutinproject 3.1 + - can exclude field from validator + * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter + - fix bug when searching for a inner class + + * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator + - add setcontextValue and removeContextValue on JAXXContextEntryDef + - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff + - only enter once in $initialize method in generated code + + 0.6 chemit 20081117 + * 20081118 [chemit] introduce NavigationUtil, save in context selected node + * 20081107 [chemit] improve data binding and code generation : + - make possible inheritance in binding + - add an attribute javaBean to an object : will generate a full java bean support property + - make possible binding to the javaBean added properties + - clean generated code + + * 20081105 [chemit] introduce a CardLayout2 to extends awt CardLayout + introduce a NavigationTreeModel + introduce a Decorator to render Object + propagate constructor JAXXContext(JAXXContext) in JAXXObject generation + begin of rst documentation + + * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer + * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor. + * 20081102 [chemit] improve JAXXContext : + - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext + - do javadoc in JAXXContext + - add logic in DefaultJAXXContext : seek in parent context if entry not found + * 20081102 [chemit] improve tests : + - fix the last failed test from Jaxx original version :) + - dumps tests to JUnit4 :) + * 20081030 [chemit] improve BeanValidator : + - add full PropertyChangeEvent java-bean support and a property valid + - when remove bean from validator, must remove errors from model + - make possible to have a dynamic errorListModel in jaxx files + * 20081030 [chemit] improve JAXXContext : + - fix setContextValue bug when setting twice a same type for a same key + - implements a DefaultJAXXContext + - use this default implementation with delegate pattern in JAXXObject + * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext + * 20081027 [chemit] fix bug 1722 + * 20081027 [chemit] add conversion support in validator + * 20081025 [chemit] improve BeanValidator tag : + - add a errorList attribute for set a ErrorListMouseListener on the errorList + - add a beanInitializer attribute for set the validator's bean at runtime + - add a default errorListModel value 'errors' + * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method + * 20081024 [chemit] fix validator context lost if UI is launched from another thread + ver-0-5 chemit 20081002 + * 20081017 [chemit] add validator support + * 20081013 [chemit] can generate logger on jaxx files + * 20081011 [chemit] improve site + * 20081011 [chemit] fix bug on JavaFileParser : works again + * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin + * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules) + * 20081002 [chemit] Introduce JAXXContext + * 20081002 [chemit] Fix bug on method creation via scripting + * 20081002 [chemit] Improve i18n integration (works now also for tabs) Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/pom.xml =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/pom.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.codelutin</groupId> + <artifactId>lutinjaxx</artifactId> + <version>0.8-SNAPSHOT</version> + </parent> + + <artifactId>jaxx-compiler-swing</artifactId> + + <dependencies> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-swing</artifactId> + </dependency> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-compiler-api</artifactId> + </dependency> + + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + <name>jaxx-compiler-swing</name> + <description>Jaxx compiler swing extension</description> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + <packaging>jar</packaging> + + <build> + <defaultGoal>install</defaultGoal> + </build> + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + <scm> + <connection>${maven.scm.connection.child}</connection> + <developerConnection>${maven.scm.developerConnection.child}</developerConnection> + <url>${maven.scm.url.child}</url> + </scm> +</project> Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingCompiler.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingCompiler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingCompiler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,73 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.compiler; + +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultObjectHandler; + +import java.io.File; + +/** + * Swing JAXX compiler. + * <p/> + * todo finish javadoc + */ +public class SwingCompiler extends JAXXCompiler { + + /*---------------------------------------------------------------------------------*/ + /*-- Constructor methods ----------------------------------------------------------*/ + /*---------------------------------------------------------------------------------*/ + + public SwingCompiler(ClassLoader classLoader) { + super(classLoader, + new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(Object.class)), + "java.awt.*", + "java.awt.event.*", + "java.beans.*", + "java.io.*", + "java.lang.*", + "java.util.*", + "javax.swing.*", + "javax.swing.border.*", + "javax.swing.event.*", + "jaxx.runtime.swing.JAXXButtonGroup", + "jaxx.runtime.swing.HBox", + "jaxx.runtime.swing.VBox", + "jaxx.runtime.swing.Table", + "static org.codelutin.i18n.I18n._", + "static jaxx.runtime.Util.createImageIcon"); + + + } + + /** + * Creates a new SwingCompiler. + * + * @param baseDir classpath location + * @param options options to pass to javac + * @param src location of file to compile + * @param outputClassName the out file name + */ + public SwingCompiler(File baseDir, File src, String outputClassName, CompilerOptions options) { + super(baseDir, src, outputClassName, options, + new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(Object.class)), + "java.awt.*", + "java.awt.event.*", + "java.beans.*", + "java.io.*", + "java.lang.*", + "java.util.*", + "javax.swing.*", + "javax.swing.border.*", + "javax.swing.event.*", + "jaxx.runtime.swing.JAXXButtonGroup", + "jaxx.runtime.swing.HBox", + "jaxx.runtime.swing.VBox", + "jaxx.runtime.swing.Table", + "static org.codelutin.i18n.I18n._", + "static jaxx.runtime.Util.createImageIcon"); + } + +} \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingGenerator.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingGenerator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/compiler/SwingGenerator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,26 @@ +package jaxx.compiler; + +import jaxx.reflect.ClassDescriptorLoader; + +import java.lang.reflect.Modifier; + +/** @author chemit */ +public class SwingGenerator implements Generator { + @Override + public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { + + } + + @Override + public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { + + //TODO : move this to jaxx-compiler-swing generator + if (ClassDescriptorLoader.getClassDescriptor("jaxx.runtime.swing.Application").isAssignableFrom(root.getObjectClass()) && !compiler.isMainDeclared()) { + // TODO: check for existing main method first + javaFile.addMethod(JavaMethod.newMethod(Modifier.PUBLIC | Modifier.STATIC, "void", "main", + "SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });", + new JavaArgument("String[]", "arg")) + ); + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ApplicationHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/ApplicationHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ApplicationHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ApplicationHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,41 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Application; +import jaxx.types.TypeManager; +import org.w3c.dom.Element; + +import javax.swing.WindowConstants; + +public class ApplicationHandler extends JWindowHandler { + + public ApplicationHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, Application.class); + } + + + @Override + public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) throws CompilerException { + if (propertyName.equals("lookAndFeel") && stringValue != null && !stringValue.trim().startsWith("{")) { + compiler.appendBodyCode("{ " + object.getJavaCode() + ".setLookAndFeel(" + TypeManager.getJavaCode(stringValue) + "); }" + JAXXCompiler.getLineSeparator()); + } else { + super.setAttribute(object, propertyName, stringValue, inline, compiler); + } + } + + + @Override + protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + super.setDefaults(object, tag, compiler); + setAttribute(object, "defaultCloseOperation", String.valueOf(WindowConstants.EXIT_ON_CLOSE), false, compiler); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CellHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/CellHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CellHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CellHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,149 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.JAXXCompiler; +import jaxx.tags.TagHandler; +import jaxx.types.TypeManager; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import java.awt.GridBagConstraints; +import java.awt.Insets; +import java.io.IOException; + +public class CellHandler implements TagHandler { + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compileChildrenFirstPass(tag, compiler); + } + + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + Node parent = tag.getParentNode(); + if (parent.getNodeType() != Node.ELEMENT_NODE || !parent.getLocalName().equals("row")) { + compiler.reportError("cell tag may only appear within row tag"); + return; + } + + TableHandler.CompiledTable table = (TableHandler.CompiledTable) compiler.getOpenComponent(); + table.newCell(); + GridBagConstraints c = table.getCellConstraints(); + setAttributes(c, tag); + compileChildrenSecondPass(tag, compiler); + } + + + public static void setAttribute(GridBagConstraints c, String name, String value) throws CompilerException { + value = value.trim(); + if (name.equals("insets")) + c.insets = (Insets) TypeManager.convertFromString(value, Insets.class); + else if (name.equals("weightx")) + c.weightx = Double.parseDouble(value); + else if (name.equals("weighty")) + c.weighty = Double.parseDouble(value); + else if (name.equals("columns")) + c.gridwidth = Integer.parseInt(value); + else if (name.equals("rows")) + c.gridheight = Integer.parseInt(value); + else if (name.equals("fill")) { + if (value.equals("none")) + c.fill = GridBagConstraints.NONE; + else if (value.equals("horizontal")) + c.fill = GridBagConstraints.HORIZONTAL; + else if (value.equals("vertical")) + c.fill = GridBagConstraints.VERTICAL; + else if (value.equals("both")) + c.fill = GridBagConstraints.BOTH; + else + throw new IllegalArgumentException("invalid value for fill attribute: '" + value + "'"); + } else if (name.equals("anchor")) { + if (value.equals("north")) + c.anchor = GridBagConstraints.NORTH; + else if (value.equals("northeast")) + c.anchor = GridBagConstraints.NORTHEAST; + else if (value.equals("east")) + c.anchor = GridBagConstraints.EAST; + else if (value.equals("southeast")) + c.anchor = GridBagConstraints.SOUTHEAST; + else if (value.equals("south")) + c.anchor = GridBagConstraints.SOUTH; + else if (value.equals("southwest")) + c.anchor = GridBagConstraints.SOUTHWEST; + else if (value.equals("west")) + c.anchor = GridBagConstraints.WEST; + else if (value.equals("northwest")) + c.anchor = GridBagConstraints.NORTHWEST; + else if (value.equals("center")) + c.anchor = GridBagConstraints.CENTER; + else + throw new IllegalArgumentException("invalid value for anchor attribute: '" + value + "'"); + } else + throw new UnsupportedAttributeException(name); + } + + + public static void setAttributes(GridBagConstraints c, Element tag) throws CompilerException { + NamedNodeMap children = tag.getAttributes(); + for (int i = 0; i < children.getLength(); i++) { + Attr attribute = (Attr) children.item(i); + String name = attribute.getName(); + String value = attribute.getValue(); + if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) + setAttribute(c, name, value); + } + } + + + protected void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagFirstPass(child, compiler); + } else + if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + + + protected void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagSecondPass(child, compiler); + } else + if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + + + protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileFirstPass(tag); + } + + + protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileSecondPass(tag); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CompiledItemContainer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/CompiledItemContainer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CompiledItemContainer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/CompiledItemContainer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,53 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.runtime.swing.Item; + +import java.util.ArrayList; +import java.util.List; +import java.util.Stack; + +/** Compiled representation of a class that contains Items arranged in a list or tree structure (JComboBox, JList, JTree). */ +class CompiledItemContainer extends CompiledObject { + private List<Item> items = new ArrayList<Item>(); + private Stack<Item> openNodes = new Stack<Item>(); + + public CompiledItemContainer(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException { + super(id, objectClass, compiler); + } + + + public void openItem(Item item) { + if (openNodes.isEmpty()) { + items.add(item); + } else { + Item openNode = openNodes.peek(); + openNode.addChild(item); + } + openNodes.add(item); + } + + + public void closeItem(Item item) { + if (openNodes.pop() != item) { + throw new IllegalArgumentException(item + " was not at the top of the item stack"); + } + } + + + public List<Item> getItems() { + return items; + } + + + public void setItems(List<Item> items) { + this.items = items; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ItemHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/ItemHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ItemHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/ItemHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,144 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Item; +import jaxx.tags.TagHandler; +import jaxx.types.TypeManager; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import java.io.IOException; +import java.util.List; + +public class ItemHandler implements TagHandler { + private String DATA_BINDING = "<data binding has not been processed yet>"; + + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compileChildrenFirstPass(tag, compiler); + } + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + String id = tag.getAttribute("id"); + if (id == null || id.length() == 0) + id = compiler.getAutoId(ClassDescriptorLoader.getClassDescriptor(Item.class)); + String label = null; + String value = null; + boolean selected = false; + NamedNodeMap children = tag.getAttributes(); + + for (int i = 0; i < children.getLength(); i++) { + Attr attribute = (Attr) children.item(i); + String name = attribute.getName(); + String attrValue = attribute.getValue(); + if (name.equals("id")) { + // already handled + continue; + } + if (name.equals(Item.LABEL_PROPERTY)) { + String labelBinding = compiler.processDataBindings(attrValue, ClassDescriptorLoader.getClassDescriptor(String.class)); + if (labelBinding != null) + compiler.registerDataBinding(labelBinding, id + ".label", id + ".setLabel(" + labelBinding + ");"); + else + label = attrValue; + continue; + } + if (name.equals(Item.VALUE_PROPERTY)) { + String valueBinding = compiler.processDataBindings(attrValue, ClassDescriptorLoader.getClassDescriptor(Object.class)); + if (valueBinding != null) { + value = DATA_BINDING; + compiler.registerDataBinding(valueBinding, id + ".value", id + ".setValue(" + valueBinding + ");"); + } else + value = attrValue; + continue; + } + if (name.equals(Item.SELECTED_PROPERTY)) { + String selectedBinding = compiler.processDataBindings(attrValue, ClassDescriptorLoader.getClassDescriptor(Boolean.class)); + if (selectedBinding != null) + compiler.registerDataBinding(selectedBinding, id + ".selected", id + ".setSelected(" + selectedBinding + ");"); + else + selected = (Boolean) TypeManager.convertFromString(attrValue, Boolean.class); + continue; + } + + if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) { + throw new UnsupportedAttributeException(name); + } + } + + Item item = new Item(id, label, value, selected); + CompiledItemContainer list = (CompiledItemContainer) compiler.getOpenComponent(); + if (value == null) + compiler.reportError("<item> tag is missing required 'value' attribute"); + else { + if (!value.equals(DATA_BINDING)) { + List<Item> items = list.getItems(); + for (Item item1 : items) { + if (item1.getValue().equals(value)) { + compiler.reportError("This container already has an <item> tag with the value '" + value + "'"); + break; + } + } + } + list.openItem(item); + compileChildrenSecondPass(tag, compiler); + list.closeItem(item); + } + } + + + protected void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagFirstPass(child, compiler); + } else + if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + + + protected void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagSecondPass(child, compiler); + } else + if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + + + protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileFirstPass(tag); + } + + + protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileSecondPass(tag); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JAXXTabHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JAXXTabHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JAXXTabHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JAXXTabHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,28 @@ +/* +* \#\#% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin, +* Tony Chemit, Gabriel Landais +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* \#\#% */ +package jaxx.tags.swing; + +import jaxx.reflect.ClassDescriptor; + +/** @author chemit */ +public class JAXXTabHandler extends TableHandler { + public JAXXTabHandler(ClassDescriptor beanClass) { + super(beanClass); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JCheckBoxHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JCheckBoxHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JCheckBoxHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JCheckBoxHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,25 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; + +import javax.swing.AbstractButton; +import javax.swing.event.ChangeListener; + +public class JCheckBoxHandler extends DefaultComponentHandler { + public JCheckBoxHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, AbstractButton.class); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("isSelected", ChangeListener.class, "model"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JComboBoxHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JComboBoxHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JComboBoxHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JComboBoxHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,65 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Item; +import jaxx.runtime.swing.JAXXComboBox; +import jaxx.tags.DefaultComponentHandler; +import jaxx.types.TypeManager; +import org.w3c.dom.Element; + +import java.awt.event.ItemListener; +import java.io.IOException; +import java.util.List; + +public class JComboBoxHandler extends DefaultComponentHandler { + + public JComboBoxHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JAXXComboBox.class); + } + + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getSelectedIndex", ItemListener.class); + addProxyEventInfo("getSelectedItem", ItemListener.class); + } + + + @Override + protected CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledItemContainer(id, getBeanClass(), compiler); + } + + + @Override + public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + super.compileChildrenSecondPass(tag, compiler); + CompiledItemContainer list = (CompiledItemContainer) compiler.getOpenComponent(); + List<Item> items = list.getItems(); + if (items != null && !items.isEmpty()) { + String listName = list.getId() + "$items"; + list.appendAdditionCode("java.util.List<jaxx.runtime.swing.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();"); + for (Item item : items) { + String id = item.getId(); + CompiledObject compiledItem = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(Item.class), compiler); + compiledItem.setConstructorParams(TypeManager.getJavaCode(id) + ", " + TypeManager.getJavaCode(item.getLabel()) + ", " + TypeManager.getJavaCode(item.getValue()) + ", " + item.isSelected()); + compiler.registerCompiledObject(compiledItem); + list.appendAdditionCode(listName + ".add(" + id + ");"); + } + list.appendAdditionCode(list.getId() + ".setItems(" + listName + ");"); + } + } +} + + + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,54 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import org.w3c.dom.Element; + +import javax.swing.JInternalFrame; +import javax.swing.JMenuBar; +import javax.swing.WindowConstants; + +public class JInternalFrameHandler extends DefaultComponentHandler { + + public JInternalFrameHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JInternalFrame.class); + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledObject(id, getBeanClass(), compiler) { + @Override + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + if (ClassDescriptorLoader.getClassDescriptor(JMenuBar.class).isAssignableFrom(child.getObjectClass())) { + appendAdditionCode(getId() + ".setJMenuBar(" + child.getId() + ");"); + } else { + super.addChild(child, constraints, compiler); + } + } + }; + } + + @Override + protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + super.setDefaults(object, tag, compiler); + setAttribute(object, "visible", "true", false, compiler); + setAttribute(object, "closable", "true", false, compiler); + setAttribute(object, "defaultCloseOperation", String.valueOf(WindowConstants.DISPOSE_ON_CLOSE), false, compiler); + } + + + @Override + public void setAttributes(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + super.setAttributes(object, tag, compiler); + compiler.appendInitializerCode(object.getId() + ".pack();\n"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JListHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JListHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JListHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JListHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,64 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Item; +import jaxx.runtime.swing.JAXXList; +import jaxx.tags.DefaultComponentHandler; +import jaxx.types.TypeManager; +import org.w3c.dom.Element; + +import javax.swing.event.ListSelectionListener; +import java.io.IOException; +import java.util.List; + +public class JListHandler extends DefaultComponentHandler { + public JListHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JAXXList.class); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getSelectedIndex", ListSelectionListener.class, "selectionModel"); + addProxyEventInfo("getSelectedIndices", ListSelectionListener.class, "selectionModel"); + addProxyEventInfo("getSelectedValue", ListSelectionListener.class, "selectionModel"); + addProxyEventInfo("getSelectedValues", ListSelectionListener.class, "selectionModel"); + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledItemContainer(id, getBeanClass(), compiler); + } + + @Override + public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + super.compileChildrenSecondPass(tag, compiler); + CompiledItemContainer list = (CompiledItemContainer) compiler.getOpenComponent(); + List<Item> items = list.getItems(); + if (items != null && !items.isEmpty()) { + String listName = list.getId() + "$items"; + //TODO Add the correct generic type + list.appendAdditionCode("java.util.List<jaxx.runtime.swing.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();"); + for (Item item : items) { + String id = item.getId(); + CompiledObject compiledItem = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(Item.class), compiler); + compiledItem.setConstructorParams(TypeManager.getJavaCode(id) + ", " + TypeManager.getJavaCode(item.getLabel()) + ", " + TypeManager.getJavaCode(item.getValue()) + ", " + item.isSelected()); + compiler.registerCompiledObject(compiledItem); + list.appendAdditionCode(listName + ".add(" + id + ");"); + } + list.appendAdditionCode(list.getId() + ".setItems(" + listName + ");"); + } + } +} + + + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JMenuHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JMenuHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JMenuHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JMenuHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,26 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; + +import javax.swing.JMenu; +import javax.swing.event.MenuListener; + +public class JMenuHandler extends DefaultComponentHandler { + + public JMenuHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JMenu.class); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("isSelected", MenuListener.class); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPasswordFieldHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JPasswordFieldHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPasswordFieldHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPasswordFieldHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,25 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; + +import javax.swing.JPasswordField; +import javax.swing.event.DocumentListener; + +public class JPasswordFieldHandler extends JTextComponentHandler { + + public JPasswordFieldHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JPasswordField.class); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getPassword", DocumentListener.class, "document"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPopupMenuHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JPopupMenuHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPopupMenuHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JPopupMenuHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,31 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import org.w3c.dom.Element; + +import javax.swing.JPopupMenu; + +public class JPopupMenuHandler extends DefaultComponentHandler { + public JPopupMenuHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JPopupMenu.class); + } + + @Override + public boolean isContainer() { + return true; + } + + @Override + protected void openComponent(CompiledObject object, Element tag, JAXXCompiler compiler) { + compiler.openInvisibleComponent(object); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JProgressBarHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JProgressBarHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JProgressBarHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JProgressBarHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,26 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; + +import javax.swing.JProgressBar; +import javax.swing.event.ChangeListener; + +public class JProgressBarHandler extends DefaultComponentHandler { + + public JProgressBarHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JProgressBar.class); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getValue", ChangeListener.class, "change"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JRadioButtonHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,81 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.JAXXButtonGroup; +import jaxx.tags.DefaultComponentHandler; +import jaxx.types.TypeManager; + +import javax.swing.AbstractButton; +import javax.swing.event.ChangeListener; + +public class JRadioButtonHandler extends DefaultComponentHandler { + private static final String VALUE_PROPERTY = JAXXButtonGroup.VALUE_CLIENT_PROPERTY.substring(1); + private static final String BUTTON_GROUP_PROPERTY = JAXXButtonGroup.BUTTON8GROUP_CLIENT_PROPERTY.substring(1); + + public JRadioButtonHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, AbstractButton.class); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("isSelected", ChangeListener.class, "model"); + } + + @Override + public ClassDescriptor getPropertyType(CompiledObject object, String name, JAXXCompiler compiler) throws CompilerException { + if (name.equals(BUTTON_GROUP_PROPERTY)) { + return null; // accepts either a String or a ButtonGroup + } else if (name.equals(VALUE_PROPERTY)) { + return ClassDescriptorLoader.getClassDescriptor(Object.class); + } else { + return super.getPropertyType(object, name, compiler); + } + } + + @Override + public boolean isMemberBound(String name) throws UnsupportedAttributeException { + return !(name.equals(BUTTON_GROUP_PROPERTY) || name.equals(VALUE_PROPERTY)) && super.isMemberBound(name); + } + + // handle buttonGroup assignment in addition block rather than initialization block + @Override + public void setProperty(CompiledObject object, String name, Object value, JAXXCompiler compiler) { + if (name.equals(BUTTON_GROUP_PROPERTY)) { + object.appendAdditionCode(getSetPropertyCode(object.getJavaCode(), name, TypeManager.getJavaCode(value), compiler)); + } else { + super.setProperty(object, name, value, compiler); + } + } + + @Override + public String getSetPropertyCode(String id, String name, String valueCode, JAXXCompiler compiler) throws CompilerException { + if (name.equals(BUTTON_GROUP_PROPERTY)) { + if (valueCode.startsWith("\"") && valueCode.endsWith("\"")) { + valueCode = valueCode.substring(1, valueCode.length() - 1); + CompiledObject buttonGroup = compiler.getCompiledObject(valueCode); + if (buttonGroup == null) { + buttonGroup = new CompiledObject(valueCode, ClassDescriptorLoader.getClassDescriptor(JAXXButtonGroup.class), compiler); + compiler.registerCompiledObject(buttonGroup); + } + } + return "{ javax.swing.ButtonGroup $buttonGroup = " + valueCode + "; " + id + ".putClientProperty(\"$buttonGroup\", $buttonGroup); $buttonGroup.add(" + id + "); }\n"; + } else if (name.equals(VALUE_PROPERTY)) { + return "{ " + id + ".putClientProperty(\"" + JAXXButtonGroup.VALUE_CLIENT_PROPERTY + "\", " + valueCode + "); Object $buttonGroup = " + id + ".getClientProperty(\"" + JAXXButtonGroup.BUTTON8GROUP_CLIENT_PROPERTY + "\");" + + " if ($buttonGroup instanceof jaxx.runtime.swing.JAXXButtonGroup) { ((jaxx.runtime.swing.JAXXButtonGroup) $buttonGroup).updateSelectedValue(); } }\n"; + } else { + return super.getSetPropertyCode(id, name, valueCode, compiler); + } + } + +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JScrollPaneHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JScrollPaneHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JScrollPaneHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JScrollPaneHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,41 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; + +import javax.swing.JScrollPane; + +public class JScrollPaneHandler extends DefaultComponentHandler { + + public JScrollPaneHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JScrollPane.class); + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledObject(id, getBeanClass(), compiler) { + boolean hasChild; + + @Override + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + if (constraints != null) { + compiler.reportError("JScrollPane does not accept constraints"); + } + if (hasChild) { + compiler.reportError("JScrollPane may only have one child"); + } + super.addChild(child, constraints, compiler); + hasChild = true; + } + }; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSliderHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JSliderHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSliderHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSliderHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,45 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; + +import javax.swing.JSlider; +import javax.swing.event.ChangeListener; + +public class JSliderHandler extends DefaultComponentHandler { + public JSliderHandler(ClassDescriptor beanClass) { + super(beanClass); + if (!ClassDescriptorLoader.getClassDescriptor(JSlider.class).isAssignableFrom(beanClass)) + throw new IllegalArgumentException(getClass().getName() + " does not support the class " + beanClass.getName()); + } + + + protected int getAttributeOrdering(Attr attr) { + if (attr.getName().equals("value")) + return 1; + else + return super.getAttributeOrdering(attr); + } + + + protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + super.setDefaults(object, tag, compiler); + setAttribute(object, "value", "0", false, compiler); + } + + + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getValue", ChangeListener.class, "model"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSpinnerHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JSpinnerHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSpinnerHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSpinnerHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,92 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import org.w3c.dom.Element; + +import javax.swing.JSpinner; +import javax.swing.event.ChangeListener; + +public class JSpinnerHandler extends DefaultComponentHandler { + public static String MINIMUM_PROPERTY = "minimum"; + public static String MAXIMUM_PROPERTY = "maximum"; + public static String VALUE_PROPERTY = "value"; + + public JSpinnerHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JSpinner.class); + } + + public static class CompiledSpinner extends CompiledObject { + Integer minimum = null; + Integer maximum = null; + Integer value = null; + + public CompiledSpinner(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException { + super(id, objectClass, compiler); + } + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledSpinner(id, getBeanClass(), compiler); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getValue", ChangeListener.class, "model"); + } + + @Override + public ClassDescriptor getPropertyType(CompiledObject object, String propertyName, JAXXCompiler compiler) throws CompilerException { + if (propertyName.equals(MINIMUM_PROPERTY) || propertyName.equals(MAXIMUM_PROPERTY) || + propertyName.equals(VALUE_PROPERTY)) { + return ClassDescriptorLoader.getClassDescriptor(Integer.class); + } + return super.getPropertyType(object, propertyName, compiler); + } + + @Override + public void setProperty(CompiledObject object, String name, Object value, JAXXCompiler compiler) throws CompilerException { + if (name.equals(MINIMUM_PROPERTY)) { + ((CompiledSpinner) object).minimum = (Integer) value; + } else if (name.equals(MAXIMUM_PROPERTY)) { + ((CompiledSpinner) object).maximum = (Integer) value; + } else if (name.equals(VALUE_PROPERTY)) { + ((CompiledSpinner) object).value = (Integer) value; + } else { + super.setProperty(object, name, value, compiler); + } + } + + @Override + protected void closeComponent(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + CompiledSpinner spinner = (CompiledSpinner) object; + if (spinner.minimum != null || spinner.maximum != null || spinner.value != null) { + if (spinner.getConstructorParams() != null) { + compiler.reportError("constructorParams and minimum/maximum may not both be specified for the same JSpinner"); + } + if (spinner.minimum == null) { + spinner.minimum = Math.min(0, spinner.maximum != null ? spinner.maximum.intValue() : 0); + } + if (spinner.maximum == null) { + spinner.maximum = Math.max(100, spinner.minimum.intValue()); + } + if (spinner.value == null) { + spinner.value = spinner.minimum; + } + spinner.setConstructorParams("new SpinnerNumberModel(" + spinner.value + ", " + spinner.minimum + ", " + spinner.maximum + ", 1)"); + } + + super.closeComponent(object, tag, compiler); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSplitPaneHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JSplitPaneHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSplitPaneHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JSplitPaneHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,69 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import org.w3c.dom.Element; + +import javax.swing.JSplitPane; +import java.awt.Component; + +public class JSplitPaneHandler extends DefaultComponentHandler { + public JSplitPaneHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JSplitPane.class); + } + + protected Component createRawComponent(Element tag) { + return new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); + } + + /** + * Add support for <code>orientation="vertical"</code> and <code>orientation="horizontal"</code>. The + * values required by the JAXXBeanInfo are the unwieldy <code>vertical_split</code> and <code>horizontal_split</code> + * (which are also recognized). + */ + @Override + protected int constantValue(String key, String value) { + if (key.equals("orientation")) { + value = value.trim().toLowerCase(); + if (value.equals("horizontal") || value.equals("horizontal_split")) { + return JSplitPane.HORIZONTAL_SPLIT; + } + if (value.equals("vertical") || value.equals("vertical_split")) { + return JSplitPane.VERTICAL_SPLIT; + } + throw new IllegalArgumentException("orientation must be 'horizontal' or 'vertical', found '" + value + "'"); + } + return super.constantValue(key, value); + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledObject(id, getBeanClass(), compiler) { + private int count; + + @Override + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + if (constraints != null) { + compiler.reportError("JSplitPane does not accept constraints"); + } + if (count == 0) { + super.addChild(child, "JSplitPane.LEFT", compiler); + } else if (count == 1) { + super.addChild(child, "JSplitPane.RIGHT", compiler); + } else { + compiler.reportError("JSplitPane is limited to two children"); + } + count++; + } + }; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTabbedPaneHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JTabbedPaneHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTabbedPaneHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTabbedPaneHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,135 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.I18nHelper; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.TabInfo; +import jaxx.tags.DefaultComponentHandler; +import jaxx.types.TypeManager; + +import javax.swing.Icon; +import javax.swing.JTabbedPane; +import javax.swing.event.ChangeListener; +import java.awt.Color; +import java.awt.event.ContainerListener; + +public class JTabbedPaneHandler extends DefaultComponentHandler { + public JTabbedPaneHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JTabbedPane.class); + } + + public static class CompiledTabbedPane extends CompiledObject { + private static final TabInfo USED = new TabInfo("ALREADY USED"); + + int tabCount; + TabInfo tabInfo; + + public CompiledTabbedPane(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException { + super(id, objectClass, compiler); + } + + @Override + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + if (constraints != null) { + compiler.reportError("JTabbedPane tabs may not have constraints"); + } + + super.addChild(child, constraints, compiler); + + if (tabInfo == null) { + compiler.reportError("JTabbedPaneHandler may only have 'tab' tags as children (found " + child.getObjectClass() + ")"); + return; + } else if (tabInfo == USED) { + compiler.reportError("<tab> tags may only have one child component"); + return; + } + + int tabIndex = ++tabCount - 1; + appendAdditionCode(tabInfo.getId() + ".addPropertyChangeListener(new jaxx.runtime.swing.TabInfoPropertyChangeListener(" + getId() + ", " + tabIndex + "));"); + + String title = tabInfo.getTitle(); + if (title != null) { + if (I18nHelper.isI18nAttribute("title")) { + if (!title.startsWith("_(\"")) { + // we did not have the invocation code, add it + title = I18nHelper.addI18nInvocation(getId(), "title", TypeManager.getJavaCode(title), compiler); + } + } else { + title = TypeManager.getJavaCode(title); + } + appendAdditionCode(getId() + ".setTitleAt(" + tabIndex + ", " + title + ");"); + } + + String toolTipText = tabInfo.getToolTipText(); + if (toolTipText != null) { + if (I18nHelper.isI18nAttribute("toolTipText")) { + if (!toolTipText.startsWith("_(\"")) { + // we did not have the invocation code, add it + toolTipText = I18nHelper.addI18nInvocation(getId(), "toolTipText", TypeManager.getJavaCode(toolTipText), compiler); + } + } else { + toolTipText = TypeManager.getJavaCode(toolTipText); + } + appendAdditionCode(getId() + ".setToolTipTextAt(" + tabIndex + ", " + toolTipText + ");"); + } + + boolean enabled = tabInfo.isEnabled(); + if (!enabled) { + appendAdditionCode(getId() + ".setEnabledAt(" + tabIndex + ", false);"); + } + + Color foreground = tabInfo.getForeground(); + if (foreground != null) { + appendAdditionCode(getId() + ".setForegroundAt(" + tabIndex + ", " + TypeManager.getJavaCode(foreground) + ");"); + } + + Color background = tabInfo.getBackground(); + if (background != null) { + appendAdditionCode(getId() + ".setBackgroundAt(" + tabIndex + ", " + TypeManager.getJavaCode(background) + ");"); + } + + int mnemonic = tabInfo.getMnemonic(); + if (mnemonic != -1) { + appendAdditionCode(getId() + ".setMnemonicAt(" + tabIndex + ", " + mnemonic + ");"); + } + + int displayedMnemonicIndex = tabInfo.getDisplayedMnemonicIndex(); + if (displayedMnemonicIndex != -1) { + appendAdditionCode(getId() + ".setDisplayedMnemonicIndexAt(" + tabIndex + ", " + displayedMnemonicIndex + ");"); + } + + Icon icon = tabInfo.getIcon(); + if (icon != null) { + appendAdditionCode(getId() + ".setIconAt(" + tabIndex + ", " + icon + ");"); + } + + Icon disabledIcon = tabInfo.getDisabledIcon(); + if (disabledIcon != null) { + appendAdditionCode(getId() + ".setDisabledIconAt(" + tabIndex + ", " + disabledIcon + ");"); + } + + tabInfo = USED; + } + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledTabbedPane(id, getBeanClass(), compiler); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getSelectedIndex", ChangeListener.class); + addProxyEventInfo("getSelectedComponent", ChangeListener.class); + addProxyEventInfo("getTabCount", ContainerListener.class); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTextComponentHandler.java (from rev 1098, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JTextComponentHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTextComponentHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTextComponentHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,68 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; + +import javax.swing.JTextArea; +import javax.swing.event.DocumentListener; +import javax.swing.text.JTextComponent; + +public class JTextComponentHandler extends DefaultComponentHandler { + private static final int DEFAULT_COLUMNS = 15; + + public JTextComponentHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JTextComponent.class); + } + + @Override + protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + super.setDefaults(object, tag, compiler); + try { + object.getObjectClass().getMethodDescriptor("setColumns", ClassDescriptorLoader.getClassDescriptor(int.class)); + setAttribute(object, "columns", String.valueOf(DEFAULT_COLUMNS), false, compiler); + } + catch (NoSuchMethodException e) { + // ignore ? + } + + if (ClassDescriptorLoader.getClassDescriptor(JTextArea.class).isAssignableFrom(object.getObjectClass())) { + setAttribute(object, "lineWrap", "true", false, compiler); + setAttribute(object, "wrapStyleWord", "true", false, compiler); + } + } + + @Override + public String getSetPropertyCode(String id, String name, String valueCode, JAXXCompiler compiler) throws CompilerException { + if (name.equals("text")) { + return "jaxx.runtime.swing.Utils.setText(" + id + ", " + valueCode + ");\n"; + } + return super.getSetPropertyCode(id, name, valueCode, compiler); + } + + @Override + protected int getAttributeOrdering(Attr attr) { + // delay text in case other attributes affect how it's processed, as is the case + // with JEditorPane's contentType + if (attr.getName().equals("text")) { + return 1; + } + return super.getAttributeOrdering(attr); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getText", DocumentListener.class, "document"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JToolBarHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JToolBarHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JToolBarHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JToolBarHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,38 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; + +import javax.swing.JToolBar; + +public class JToolBarHandler extends DefaultComponentHandler { + public JToolBarHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JToolBar.class); + } + + /** + * Add support for <code>orientation="vertical"</code> and <code>orientation="horizontal"</code>. These values should + * have been supported without any special effort on my part, but JToolBar's BeanInfo doesn't contain the enum attribute + * for the orientation property. + */ + @Override + protected int constantValue(String key, String value) { + if (key.equals("orientation")) { + value = value.trim().toLowerCase(); + if (value.equals("horizontal")) { + return JToolBar.HORIZONTAL; + } + if (value.equals("vertical")) { + return JToolBar.VERTICAL; + } + throw new IllegalArgumentException("orientation must be 'horizontal' or 'vertical', found '" + value + "'"); + } + return super.constantValue(key, value); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTreeHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JTreeHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTreeHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JTreeHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,69 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Item; +import jaxx.runtime.swing.JAXXTree; +import jaxx.tags.DefaultComponentHandler; +import jaxx.types.TypeManager; +import org.w3c.dom.Element; + +import javax.swing.event.TreeSelectionListener; +import java.io.IOException; +import java.util.List; + +public class JTreeHandler extends DefaultComponentHandler { + public JTreeHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JAXXTree.class); + } + + @Override + protected void configureProxyEventInfo() { + super.configureProxyEventInfo(); + addProxyEventInfo("getSelectionCount", TreeSelectionListener.class, "selectionModel"); + addProxyEventInfo("getSelectionPath", TreeSelectionListener.class, "selectionModel"); + addProxyEventInfo("getSelectionPaths", TreeSelectionListener.class, "selectionModel"); + addProxyEventInfo("getSelectionRows", TreeSelectionListener.class, "selectionModel"); + addProxyEventInfo("getSelectionValue", TreeSelectionListener.class, "selectionModel"); + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledItemContainer(id, getBeanClass(), compiler); + } + + private void createItems(CompiledObject tree, List<Item> items, String addMethod, JAXXCompiler compiler) throws CompilerException { + for (Item item : items) { + String id = item.getId(); + CompiledObject compiledItem = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(Item.class), compiler); + compiledItem.setConstructorParams(TypeManager.getJavaCode(id) + ", " + TypeManager.getJavaCode(item.getLabel()) + ", " + TypeManager.getJavaCode(item.getValue()) + ", " + item.isSelected()); + compiler.registerCompiledObject(compiledItem); + tree.appendAdditionCode(addMethod + "(" + id + ");"); + createItems(tree, item.getChildren(), id + ".addChild", compiler); + } + } + + @Override + public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + super.compileChildrenSecondPass(tag, compiler); + CompiledItemContainer tree = (CompiledItemContainer) compiler.getOpenComponent(); + List<Item> items = tree.getItems(); + if (items != null && !items.isEmpty()) { + String listName = tree.getId() + "$items"; + tree.appendAdditionCode("java.util.List<jaxx.runtime.swing.Item> " + listName + " = new java.util.ArrayList<jaxx.runtime.swing.Item>();"); + createItems(tree, items, listName + ".add", compiler); + tree.appendAdditionCode(tree.getId() + ".setItems(" + listName + ");"); + } + } +} + + + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JWindowHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JWindowHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JWindowHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/JWindowHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,61 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import org.w3c.dom.Element; + +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JMenuBar; +import javax.swing.JWindow; +import java.io.IOException; +import java.util.Map; + +public class JWindowHandler extends DefaultComponentHandler { + + public JWindowHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, JWindow.class, JFrame.class, JDialog.class); + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledObject(id, getBeanClass(), compiler) { + @Override + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + if (ClassDescriptorLoader.getClassDescriptor(JMenuBar.class).isAssignableFrom(child.getObjectClass())) { + appendAdditionCode(getId() + ".setJMenuBar(" + child.getId() + ");"); + } else { + super.addChild(child, constraints, compiler); + } + } + }; + } + + @Override + protected void openComponent(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException { + if (compiler.getOpenComponent() != null) { + compiler.openInvisibleComponent(object); + } else { + super.openComponent(object, tag, compiler); + } + } + + @Override + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + super.compileSecondPass(tag, compiler); + CompiledObject object = objectMap.get(tag); + Map properties = object.getProperties(); + if (!properties.containsKey("width") && !properties.containsKey("height")) { + compiler.appendLateInitializer(object.getId() + ".pack();\n"); + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/RowHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/RowHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/RowHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/RowHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,85 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Table; +import jaxx.tags.TagHandler; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import java.awt.GridBagConstraints; +import java.io.IOException; + +public class RowHandler implements TagHandler { + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compileChildrenFirstPass(tag, compiler); + } + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + if (!ClassDescriptorLoader.getClassDescriptor(Table.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { + compiler.reportError("row tag may only appear within Table tag"); + return; + } + + TableHandler.CompiledTable table = (TableHandler.CompiledTable) compiler.getOpenComponent(); + table.newRow(); + GridBagConstraints c = table.getRowConstraints(); + CellHandler.setAttributes(c, tag); + compileChildrenSecondPass(tag, compiler); + } + + public void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + if (!child.getLocalName().equals("cell")) { + compiler.reportError("tag '" + tag.getLocalName() + "' may only contain cell tags as children"); + } + compileChildTagFirstPass(child, compiler); + } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) { + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + } + + public void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + if (!child.getLocalName().equals("cell")) { + compiler.reportError("tag '" + tag.getLocalName() + "' may only contain cell tags as children"); + } + compileChildTagSecondPass(child, compiler); + } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) { + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + } + + protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileFirstPass(tag); + } + + protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileSecondPass(tag); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/SwingInitializer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/SwingInitializer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/SwingInitializer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/SwingInitializer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,88 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Application; +import jaxx.runtime.swing.JAXXButtonGroup; +import jaxx.runtime.swing.JAXXComboBox; +import jaxx.runtime.swing.JAXXList; +import jaxx.runtime.swing.JAXXTab; +import jaxx.runtime.swing.JAXXTree; +import jaxx.runtime.swing.Table; +import jaxx.spi.Initializer; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.TagManager; +import jaxx.types.ColorConverter; +import jaxx.types.GridBagConstraintsConverter; +import jaxx.types.InsetsConverter; +import jaxx.types.KeyStrokeConverter; +import jaxx.types.TypeManager; +import jaxx.beaninfos.BeanInfoUtil; + +import javax.swing.*; +import javax.swing.text.JTextComponent; +import java.awt.Color; +import java.awt.GridBagConstraints; +import java.awt.Insets; + +public class SwingInitializer implements Initializer { + + public void initialize() { + + BeanInfoUtil.addJaxxBeanInfoPath("jaxx.beaninfos"); + + TagManager.registerTag("java.awt.*", "ButtonGroup", new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(JAXXButtonGroup.class))); + + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(Application.class), ApplicationHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JCheckBox.class), JCheckBoxHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JCheckBoxMenuItem.class), JCheckBoxHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXComboBox.class), JComboBoxHandler.class); + TagManager.registerTag("javax.swing.*", "JComboBox", new JComboBoxHandler(ClassDescriptorLoader.getClassDescriptor(JAXXComboBox.class))); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JDialog.class), JWindowHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JFrame.class), JWindowHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JInternalFrame.class), JInternalFrameHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXList.class), JListHandler.class); + TagManager.registerTag("javax.swing.*", "JList", new JListHandler(ClassDescriptorLoader.getClassDescriptor(JAXXList.class))); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JMenu.class), JMenuHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JPasswordField.class), JPasswordFieldHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JPopupMenu.class), JPopupMenuHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JProgressBar.class), JProgressBarHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JRadioButton.class), JRadioButtonHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JRadioButtonMenuItem.class), JRadioButtonHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JScrollPane.class), JScrollPaneHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JSlider.class), JSliderHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JSpinner.class), JSpinnerHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JSplitPane.class), JSplitPaneHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JTabbedPane.class), JTabbedPaneHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JTextComponent.class), JTextComponentHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JToggleButton.class), JRadioButtonHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JToolBar.class), JToolBarHandler.class); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXTree.class), JTreeHandler.class); + TagManager.registerTag("javax.swing.*", "JTree", new JTreeHandler(ClassDescriptorLoader.getClassDescriptor(JAXXTree.class))); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JWindow.class), JWindowHandler.class); + + TagManager.registerDefaultNamespace("JEditorPane", "javax.swing.*"); + TagManager.registerDefaultNamespace("JFormattedTextField", "javax.swing.*"); + TagManager.registerDefaultNamespace("JPasswordField", "javax.swing.*"); + TagManager.registerDefaultNamespace("JTextArea", "javax.swing.*"); + TagManager.registerDefaultNamespace("JTextField", "javax.swing.*"); + TagManager.registerDefaultNamespace("JTextPane", "javax.swing.*"); + + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "tab", new TabHandler()); + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(Table.class), TableHandler.class); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "row", new RowHandler()); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "cell", new CellHandler()); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, "item", new ItemHandler()); + + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(JAXXTab.class), JAXXTabHandler.class); + + TypeManager.registerTypeConverter(Color.class, new ColorConverter()); + TypeManager.registerTypeConverter(GridBagConstraints.class, new GridBagConstraintsConverter()); + TypeManager.registerTypeConverter(Insets.class, new InsetsConverter()); + TypeManager.registerTypeConverter(KeyStroke.class, new KeyStrokeConverter()); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TabHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/TabHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TabHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TabHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,175 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.I18nHelper; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.TabInfo; +import jaxx.tags.TagHandler; +import jaxx.types.TypeManager; +import org.w3c.dom.Attr; +import org.w3c.dom.Element; +import org.w3c.dom.NamedNodeMap; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.w3c.dom.Text; + +import javax.swing.Icon; +import javax.swing.JTabbedPane; +import java.awt.Color; +import java.io.IOException; + +public class TabHandler implements TagHandler { + + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compileChildrenFirstPass(tag, compiler); + } + + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + if (!ClassDescriptorLoader.getClassDescriptor(JTabbedPane.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { + compiler.reportError("tab tag may only appear within JTabbedPane tag"); + return; + } + + JTabbedPaneHandler.CompiledTabbedPane tabs = (JTabbedPaneHandler.CompiledTabbedPane) compiler.getOpenComponent(); + + String id = tag.getAttribute("id"); + if (id == null || id.length() == 0) { + id = compiler.getAutoId(ClassDescriptorLoader.getClassDescriptor(TabInfo.class)); + } + TabInfo tabInfo = new TabInfo(id); + CompiledObject compiledTabInfo = new CompiledObject(id, ClassDescriptorLoader.getClassDescriptor(TabInfo.class), compiler); + compiler.registerCompiledObject(compiledTabInfo); + //id = tabInfo.getId(); + tabs.tabInfo = tabInfo; + setAttributes(compiledTabInfo, tabs, tag, compiler); + compileChildrenSecondPass(tag, compiler); + tabs.tabInfo = null; + } + + + public static void setAttribute(CompiledObject compiledTabInfo, JTabbedPaneHandler.CompiledTabbedPane tabs, String name, String value, JAXXCompiler compiler) throws CompilerException { + value = value.trim(); + TabInfo tabInfo = tabs.tabInfo; + String id = tabInfo.getId(); + String binding = compiler.processDataBindings(value, ClassDescriptorLoader.getClassDescriptor(Object.class)); + if (binding != null) { + compiler.registerDataBinding(binding, id + "." + name, id + ".set" + org.apache.commons.lang.StringUtils.capitalize(name) + "(" + binding + ");"); + return; + } + + String valueCode = TypeManager.getJavaCode(value); + + // add i18n support + if (I18nHelper.isI18nableAttribute(name, compiler)) { + value = valueCode = I18nHelper.addI18nInvocation(id, name, valueCode, compiler); + } + + if (name.equals("title")) { + tabInfo.setTitle(value); + compiledTabInfo.appendInitializationCode(id + ".setTitle(" + valueCode + ");"); + //compiledTabInfo.appendInitializationCode(id + ".setTitle(" + TypeManager.getJavaCode(value) + ");"); + } else if (name.equals("toolTipText")) { + tabInfo.setToolTipText(value); + compiledTabInfo.appendInitializationCode(id + ".setToolTipText(" + valueCode + ");"); + //compiledTabInfo.appendInitializationCode(id + ".setToolTipText(" + TypeManager.getJavaCode(value) + ");"); + } else if (name.equals("icon")) { + Icon icon = (Icon) TypeManager.convertFromString(value, Icon.class); + tabInfo.setIcon(icon); + compiledTabInfo.appendInitializationCode(id + ".setIcon(" + TypeManager.getJavaCode(icon) + ");"); + } else if (name.equals("enabled")) { + boolean enabled = (Boolean) TypeManager.convertFromString(value, Boolean.class); + tabInfo.setEnabled(enabled); + compiledTabInfo.appendInitializationCode(id + ".setEnabled(" + enabled + ");"); + } else if (name.equals("disabledIcon")) { + Icon disabledIcon = (Icon) TypeManager.convertFromString(value, Icon.class); + tabInfo.setDisabledIcon(disabledIcon); + compiledTabInfo.appendInitializationCode(id + ".setDisabledIcon(" + TypeManager.getJavaCode(disabledIcon) + ");"); + } else if (name.equals("mnemonic")) { + int mnemonic = (Character) TypeManager.convertFromString(value, char.class); + tabInfo.setMnemonic(mnemonic); + compiledTabInfo.appendInitializationCode(id + ".setMnemonic(" + mnemonic + ");"); + } else if (name.equals("displayedMnemonicIndex")) { + int displayedMnemonicIndex = (Integer) TypeManager.convertFromString(value, int.class); + tabInfo.setDisplayedMnemonicIndex(displayedMnemonicIndex); + compiledTabInfo.appendInitializationCode(id + ".setDisplayedMnemonicIndex(" + displayedMnemonicIndex + ");"); + } else if (name.equals("foreground")) { + Color foreground = (Color) TypeManager.convertFromString(value, Color.class); + tabInfo.setForeground(foreground); + compiledTabInfo.appendInitializationCode(id + ".setForeground(" + TypeManager.getJavaCode(foreground) + ");"); + } else if (name.equals("background")) { + Color background = (Color) TypeManager.convertFromString(value, Color.class); + tabInfo.setBackground(background); + compiledTabInfo.appendInitializationCode(id + ".setBackground(" + TypeManager.getJavaCode(background) + ");"); + } else if (name.equals("id")) { + // ignore, already handled + } else { + compiler.reportError("The <tab> tag does not support the attribute '" + name + "'"); + } + } + + + public void setAttributes(CompiledObject compiledTabInfo, JTabbedPaneHandler.CompiledTabbedPane tabs, Element tag, JAXXCompiler compiler) throws CompilerException { + NamedNodeMap children = tag.getAttributes(); + for (int i = 0; i < children.getLength(); i++) { + Attr attribute = (Attr) children.item(i); + String name = attribute.getName(); + String value = attribute.getValue(); + if (!name.startsWith("xmlns") && !JAXXCompiler.JAXX_INTERNAL_NAMESPACE.equals(attribute.getNamespaceURI())) { + setAttribute(compiledTabInfo, tabs, name, value, compiler); + } + } + } + + + protected void compileChildrenFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagFirstPass(child, compiler); + } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) { + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + } + + + protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileFirstPass(tag); + } + + + protected void compileChildrenSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + NodeList children = tag.getChildNodes(); + for (int i = 0; i < children.getLength(); i++) { + Node node = children.item(i); + int nodeType = node.getNodeType(); + if (nodeType == Node.ELEMENT_NODE) { + Element child = (Element) node; + compileChildTagSecondPass(child, compiler); + } else if (nodeType == Node.TEXT_NODE || nodeType == Node.CDATA_SECTION_NODE) { + String text = ((Text) node).getData().trim(); + if (text.length() > 0) { + compiler.reportError("tag '" + tag.getLocalName() + "' may not contain text ('" + ((Text) node).getData().trim() + "')"); + } + } + } + } + + + protected void compileChildTagSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + compiler.compileSecondPass(tag); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TableHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/TableHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TableHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/tags/swing/TableHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,124 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.swing; + +import jaxx.CompilerException; +import jaxx.UnsupportedAttributeException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.swing.Table; +import jaxx.tags.DefaultComponentHandler; +import jaxx.types.TypeManager; + +import java.awt.GridBagConstraints; +import java.awt.Insets; +import java.util.ArrayList; +import java.util.List; + +public class TableHandler extends DefaultComponentHandler { + public static final Insets DEFAULT_INSETS = new Insets(3, 3, 3, 3); + + public TableHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, Table.class); + } + + @Override + public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) throws CompilerException { + try { + if (object instanceof CompiledTable) { + CellHandler.setAttribute(((CompiledTable) object).getTableConstraints(), propertyName, stringValue); + } else { + super.setAttribute(object, propertyName, stringValue, inline, compiler); + } + } + catch (UnsupportedAttributeException e) { + super.setAttribute(object, propertyName, stringValue, inline, compiler); + } + } + + class CompiledTable extends CompiledObject { + private List<Integer> rowSpans = new ArrayList<Integer>(); + + private GridBagConstraints tableConstraints; + private GridBagConstraints rowConstraints = null; + private GridBagConstraints cellConstraints = null; + private boolean emptyCell; + + public CompiledTable(String id, ClassDescriptor objectClass, JAXXCompiler compiler) throws CompilerException { + super(id, objectClass, compiler); + tableConstraints = new GridBagConstraints(); + tableConstraints.gridx = -1; + tableConstraints.gridy = -1; + tableConstraints.insets = DEFAULT_INSETS; + } + + @Override + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + if (constraints != null) { + compiler.reportError("Table does not accept constraints"); + } + GridBagConstraints c = getCellConstraints(); + if (c == null) { + compiler.reportError("Table tag may only contain row tags"); + return; + } + if (!emptyCell) { + compiler.reportError("Table cells may only have one child component"); + } + while (rowSpans.size() < c.gridx + c.gridwidth) { + rowSpans.add(null); + } + for (int x = c.gridx; x < c.gridx + c.gridwidth; x++) { + rowSpans.set(x, c.gridheight); + } + + super.addChild(child, TypeManager.getJavaCode(c), compiler); + + emptyCell = false; + } + + public GridBagConstraints getTableConstraints() { + return tableConstraints; + } + + public GridBagConstraints getRowConstraints() { + return rowConstraints; + } + + public GridBagConstraints getCellConstraints() { + return cellConstraints; + } + + public void newRow() { + tableConstraints.gridy++; + tableConstraints.gridx = -1; + rowConstraints = (GridBagConstraints) tableConstraints.clone(); + + for (int x = 0; x < rowSpans.size(); x++) { + int rowSpan = rowSpans.get(x); + if (rowSpan > 0) { + rowSpans.set(x, rowSpan - 1); + } + } + } + + public void newCell() { + emptyCell = true; + rowConstraints.gridx++; + while (rowConstraints.gridx < rowSpans.size() && rowSpans.get(rowConstraints.gridx) > 0) { + rowConstraints.gridx++; + } + cellConstraints = (GridBagConstraints) rowConstraints.clone(); + } + } + + @Override + public CompiledObject createCompiledObject(String id, JAXXCompiler compiler) throws CompilerException { + return new CompiledTable(id, getBeanClass(), compiler); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/ColorConverter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/ColorConverter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/ColorConverter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/ColorConverter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,34 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +import java.awt.Color; +import java.lang.reflect.Field; + +public class ColorConverter implements TypeConverter { + public String getJavaCode(Object object) { + Color color = (Color) object; + return "new Color(" + color.getRed() + ", " + color.getGreen() + ", " + color.getBlue() + ")"; + } + + + public Object convertFromString(String string, Class type) { + if (type != Color.class) { + throw new IllegalArgumentException("unsupported type: " + type); + } + if (string.length() == 7 && string.charAt(0) == '#') { + return new Color(Integer.parseInt(string.substring(1), 16)); + } + try { + Field color = Color.class.getField(string); + return color.get(null); + } + catch (NoSuchFieldException e) { + throw new IllegalArgumentException("colors must be of the form #xxxxxx ('#' followed by six hexadecimal digits), or the name of a constant field in java.awt.Color (found: '" + string + "')"); + } catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/GridBagConstraintsConverter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/GridBagConstraintsConverter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/GridBagConstraintsConverter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/GridBagConstraintsConverter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,21 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +import java.awt.GridBagConstraints; + +public class GridBagConstraintsConverter implements TypeConverter { + public String getJavaCode(Object object) { + GridBagConstraints g = (GridBagConstraints) object; + return "new GridBagConstraints(" + g.gridx + ", " + g.gridy + ", " + g.gridwidth + ", " + g.gridheight + ", " + + g.weightx + ", " + g.weighty + ", " + g.anchor + ", " + g.fill + ", " + + TypeManager.getJavaCode(g.insets) + ", " + g.ipadx + ", " + g.ipady + ")"; + } + + + public Object convertFromString(String string, Class type) { + throw new UnsupportedOperationException("GridBagConstraints must be represented using Java code"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/InsetsConverter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/InsetsConverter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/InsetsConverter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/InsetsConverter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,36 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +import java.awt.Insets; +import java.util.StringTokenizer; + +public class InsetsConverter implements TypeConverter { + public String getJavaCode(Object object) { + Insets insets = (Insets) object; + return "new Insets(" + insets.top + ", " + insets.left + ", " + insets.bottom + ", " + insets.right + ")"; + } + + + public Object convertFromString(String string, Class type) { + if (type != Insets.class) { + throw new IllegalArgumentException("unsupported type: " + type); + } + StringTokenizer tokenizer = new StringTokenizer(string, ","); + int count = tokenizer.countTokens(); + if (count == 1) { + int i = Integer.parseInt(tokenizer.nextToken().trim()); + return new Insets(i, i, i, i); + } + if (count == 4) { + int[] insets = new int[count]; + for (int i = 0; tokenizer.hasMoreTokens(); i++) { + insets[i] = Integer.parseInt(tokenizer.nextToken().trim()); + } + return new Insets(insets[0], insets[1], insets[2], insets[3]); + } + throw new IllegalArgumentException("unable to convert string '" + string + "' to Insets"); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/KeyStrokeConverter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/KeyStrokeConverter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/KeyStrokeConverter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/java/jaxx/types/KeyStrokeConverter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,21 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +import javax.swing.KeyStroke; + +public class KeyStrokeConverter implements TypeConverter { + public String getJavaCode(Object object) { + return "KeyStroke.getKeyStroke(\"" + object.toString() + "\")"; + } + + + public Object convertFromString(String string, Class type) { + if (type != KeyStroke.class) { + throw new IllegalArgumentException("unsupported type: " + type); + } + return KeyStroke.getKeyStroke(string); + } +} \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.compiler.Generator =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.compiler.Generator (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.compiler.Generator 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1 @@ +jaxx.compiler.SwingGenerator Added: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.spi.Initializer =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.spi.Initializer (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/main/resources/META-INF/services/jaxx.spi.Initializer 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1 @@ +jaxx.tags.swing.SwingInitializer \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/ColorConverterTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/ColorConverterTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/ColorConverterTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/ColorConverterTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,51 @@ +package jaxx.junit; + +import jaxx.types.ColorConverter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.awt.Color; + +public class ColorConverterTest { + + ColorConverter converter; + + @Before + public void setUp() { + converter = new ColorConverter(); + } + + @Test + public void testHexValue() { + Color value = (Color) converter.convertFromString("#3000FF", Color.class); + Assert.assertEquals(value, new Color(48, 0, 255)); + } + + @Test + public void testUpperCaseConstant() { + Color value = (Color) converter.convertFromString("RED", Color.class); + Assert.assertEquals(value, Color.RED); + } + + @Test + public void testLowerCaseConstant() { + Color value = (Color) converter.convertFromString("blue", Color.class); + Assert.assertEquals(value, Color.blue); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingHash() { + converter.convertFromString("ABCDEF", Color.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidNumber() { + converter.convertFromString("#ABCDEG", Color.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidConstant() { + converter.convertFromString("rEd", Color.class); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/InsetsConverterTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/InsetsConverterTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/InsetsConverterTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/InsetsConverterTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,50 @@ +package jaxx.junit; + +import jaxx.types.InsetsConverter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.awt.Insets; + +public class InsetsConverterTest { + + InsetsConverter converter; + + @Before + public void setUp() { + converter = new InsetsConverter(); + } + + @Test + public void testSingleValue() { + Insets value = (Insets) converter.convertFromString("3", Insets.class); + Assert.assertEquals(value, new Insets(3, 3, 3, 3)); + } + + @Test + public void testFourValues() { + Insets value = (Insets) converter.convertFromString("3, 0, 12, 1000000", Insets.class); + Assert.assertEquals(value, new Insets(3, 0, 12, 1000000)); + } + + @Test(expected = IllegalArgumentException.class) + public void testTwoValues() { + converter.convertFromString("0, 4", Insets.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testThreeValues() { + converter.convertFromString("0, 4, 9", Insets.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testInvalidNumber() { + converter.convertFromString("0, 4, 9, A", Insets.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testBadFormatting() { + converter.convertFromString("0 - 1 - 2 - 3", Insets.class); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/TagManagerTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/TagManagerTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/TagManagerTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/junit/TagManagerTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,143 @@ +package jaxx.junit; + +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerLaunchor; +import jaxx.compiler.SwingCompiler; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.tags.DefaultComponentHandler; +import jaxx.tags.DefaultObjectHandler; +import jaxx.tags.TagHandler; +import jaxx.tags.TagManager; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.swing.JPopupMenu; +import java.io.ByteArrayOutputStream; +import java.io.FileInputStream; +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; + +public class TagManagerTest { + + protected JAXXCompiler compiler; + + public static class TestHandler extends DefaultObjectHandler { + public TestHandler(ClassDescriptor beanClass) { + super(beanClass); + } + } + + @BeforeClass + public static void initTagManaer() throws Exception { + + TagManager.reset(true); + + } + + @Before + public void setUp() { + JAXXCompilerLaunchor.newLaunchor(); + compiler = new SwingCompiler(SwingCompiler.class.getClassLoader()); + compiler.addImport("javax.swing.*"); + + } + + @Test + public void testRegisterBean() { + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(InputStream.class), TestHandler.class); + + Assert.assertTrue(TagManager.getTagHandler(ClassDescriptorLoader.getClassDescriptor(InputStream.class)) instanceof TestHandler); + Assert.assertTrue(TagManager.getTagHandler(ClassDescriptorLoader.getClassDescriptor(FileInputStream.class)) instanceof TestHandler); + } + + @Test + public void testRegisterDefaultNamespace() { + + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(OutputStream.class), TestHandler.class); + + TagManager.registerDefaultNamespace("OutputStream", "java.io.*"); + Assert.assertTrue("Could not find handler for OutputStream despite default namespace", TagManager.getTagHandler(null, "OutputStream", compiler) instanceof TestHandler); + + PrintStream oldErr = System.err; + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + System.setErr(new PrintStream(buffer)); + TagManager.registerDefaultNamespace("OutputStream", "java.dummy.*"); + Assert.assertNull("Found handler for OutputStream despite ambiguous default namespace", TagManager.getTagHandler(null, "OutputStream", compiler)); + System.setErr(oldErr); + Assert.assertTrue("No errors were produced with an ambiguous default namespace", buffer.size() > 0); + Assert.assertTrue(buffer.size() > 0); + } + + @Test + public void testResolveClassName() { + Assert.assertEquals("Could not resolve class name 'Object'", TagManager.resolveClassName("Object", compiler), "java.lang.Object"); + Assert.assertEquals("Could not resolve class name 'java.lang.Object'", TagManager.resolveClassName("java.lang.Object", compiler), "java.lang.Object"); + Assert.assertNull("Unexpectedly resolved class name 'java.awt.Object'", TagManager.resolveClassName("java.awt.Object", compiler)); + } + + @Test + public void testPackages() { + Assert.assertNull("Unexpectedly found handler for java.awt.JButton", TagManager.getTagHandler(null, "java.awt.JButton", compiler)); + Assert.assertNotNull("Did not find handler for JButton with default namespace of java.awt.*", TagManager.getTagHandler("java.awt.*", "JButton", compiler)); + Assert.assertNull("Unexpectedly found handler for java.awt.*:JButton", TagManager.getTagHandler("java.awt.*", "JButton", true, compiler)); + Assert.assertNotNull("Did not find handler for javax.swing.JButton", TagManager.getTagHandler(null, "javax.swing.JButton", compiler)); + Assert.assertNotNull("Did not find handler for JButton with default namespace of java.swing.*", TagManager.getTagHandler("java.swing.*", "JButton", compiler)); + Assert.assertNotNull("Did not find handler for javax.swing.*:JButton", TagManager.getTagHandler("javax.swing.*", "JButton", true, compiler)); + } + + @Test + public void testImport() throws Exception { + Assert.assertNull("Found handler for ActionListener despite no java.awt.event.* import", TagManager.getTagHandler(null, "ActionListener", compiler)); + + compiler.addImport("java.awt.event.*"); + + Assert.assertNotNull("Did not find ActionListener with java.awt.event.* import", TagManager.getTagHandler(null, "ActionListener", compiler)); + } + + @Test + public void testAmbiguousImport() throws Exception { + compiler.addImport("java.sql.*"); + Assert.assertNotNull("Did not find java.sql.Date with only java.sql.* imported", TagManager.getTagHandler(null, "Date", compiler)); + + PrintStream oldErr = System.err; + ByteArrayOutputStream buffer = new ByteArrayOutputStream(); + System.setErr(new PrintStream(buffer)); + compiler.addImport("java.util.*"); + TagManager.reset(true); + Assert.assertNull("Still found a handler for Date with an ambiguous import", TagManager.getTagHandler(null, "Date", compiler)); + System.setErr(oldErr); + Assert.assertTrue("No errors were produced with an ambiguous import", buffer.size() > 0); + + compiler.addImport("java.util.Date"); + Assert.assertNotNull("Did not find java.util.Date with a disambiguating import", TagManager.getTagHandler(null, "Date", compiler)); + } + + @Test + public void testInnerClass() { + TagHandler handler = TagManager.getTagHandler(null, "JPopupMenu.Separator", compiler); + Assert.assertTrue("Unable to resolve tag <JPopupMenu.Separator>", handler instanceof DefaultComponentHandler); + Assert.assertTrue(((DefaultComponentHandler) handler).getBeanClass().getName().equals(JPopupMenu.Separator.class.getName())); + + handler = TagManager.getTagHandler(null, "javax.swing.JPopupMenu.Separator", compiler); + Assert.assertTrue("Unable to resolve tag <javax.swing.JPopupMenu.Separator>", handler instanceof DefaultComponentHandler); + Assert.assertTrue(((DefaultComponentHandler) handler).getBeanClass().getName().equals(JPopupMenu.Separator.class.getName())); + } + + @Test + public void testWrongCase() { + Assert.assertNull("Unexpectedly found handler for 'object'", TagManager.getTagHandler(null, "object", compiler)); + Assert.assertNull("Unexpectedly found handler for 'tagmanagertest'", TagManager.getTagHandler(null, "tagmanagertest", compiler)); + } + + @Test + public void testAliasing() { + Assert.assertEquals("JComboBox is not aliased to jaxx.runtime.swing.JAXXComboBox", "jaxx.runtime.swing.JAXXComboBox", TagManager.resolveClassName("JComboBox", compiler)); + Assert.assertEquals("javax.swing.JComboBox is not aliased to jaxx.runtime.swing.JAXXComboBox", "jaxx.runtime.swing.JAXXComboBox", TagManager.resolveClassName("javax.swing.JComboBox", compiler)); + } + + +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/java/jaxx/runtime/swing/navigation/NavigationTreeModelTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,393 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.DefaultJAXXContext; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXContextEntryDef; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import org.junit.Assert; +import org.junit.Test; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + + +/** + * Test du model de navigation. + * + * @author chemit + */ +public class NavigationTreeModelTest { + + private static final String ROOT_CONTEXT = "$root"; + private static final String FAKE = "-fake"; + + private static final String separator = "/"; + + @Test + public void testFindNode() throws Exception { + + NavigationTreeModelBuilder builder = new NavigationTreeModelBuilder(separator); + + NavigationTreeNode rootNode = builder.build(null, (String) null, (String) null, ROOT_CONTEXT, null, null); + + for (int i = 0; i < 4; i++) { + NavigationTreeNode sonNode = builder.build(rootNode, (String) null, (String) null, getNodeContext(i), null, null); + for (int j = 0; j < 4; j++) { + NavigationTreeNode sonSonNode = builder.build(sonNode, (String) null, (String) null, getNodeContext(i, j), null, null); + for (int k = 0; k < 4; k++) { + builder.build(sonSonNode, (String) null, (String) null, getNodeContext(i, j, k), null, null); + } + } + } + + NavigationTreeModel model = builder.getModel(); + + NavigationTreeNode node; + String contextPath; + String currentNode; + + contextPath = ROOT_CONTEXT; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, ROOT_CONTEXT, 0, node, true); + + node = model.findNode(ROOT_CONTEXT + FAKE); + Assert.assertNull(node); + + for (int i = 0; i < 4; i++) { + currentNode = getNodeContext(i); + contextPath = ROOT_CONTEXT + separator + currentNode; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, currentNode, 1, node, false); + + for (int j = 0; j < 4; j++) { + currentNode = getNodeContext(i, j); + contextPath = ROOT_CONTEXT + separator + getNodeContext(i) + separator + currentNode; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, currentNode, 2, node, false); + + for (int k = 0; k < 4; k++) { + currentNode = getNodeContext(i, j, k); + contextPath = ROOT_CONTEXT + separator + getNodeContext(i) + separator + getNodeContext(i, j) + separator + currentNode; + node = model.findNode(contextPath); + assertNodeEquals(contextPath, currentNode, 3, node, false); + } + + node = model.findNode(ROOT_CONTEXT + separator + getNodeContext(i) + separator + getNodeContext(i, j) + separator + currentNode + FAKE); + Assert.assertNull(node); + } + + node = model.findNode(ROOT_CONTEXT + separator + getNodeContext(i) + separator + currentNode + FAKE); + Assert.assertNull(node); + + } + + } + + /** + * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point + * as a bean. + * <p/> + * Tree is like this + * <pre> + * $root + + * - name <-- attached to context entry : java.lang.String.class,"name" + * - name2 <-- attached to context entry : java.lang.String.class,"name2" + * - model + <-- attached to context entry : Model.class,null + * - name + * -integerValue + * - sons + + * - 0 + + * - name + * - integerValue + * - sons + * - 1 + + * - name + * - integerValue + * - sons + * - 2 + + * - name + * - integerValue + * - sons + * </pre> + * <p/> + * With this tree, we will have to results : + * <pre> + * $root.name => context.get(String.class,"name") + * $root.name2 => context.get(String.class,"name2") + * $root.model => context.get(Model.class) + * $root.model.name => context.get(Model.class).getName() + * $root.model.integerValue => context.get(Model.class).getIntegerValue() + * $root.model.sons => context.get(Model.class).getSons() + * $root.model.sons.0 => context.get(Model.class).getSons().get(0) + * </pre> + * + * @throws Exception if any pb + */ + @Test + public void testGetJAXXContextValue() throws Exception { + + NavigationTreeModelBuilder builder = new NavigationTreeModelBuilder(separator); + + NavigationTreeNode rootNode = builder.build(null, (String) null, (String) null, ROOT_CONTEXT, null, null); + + NavigationTreeNode sonNode; + NavigationTreeNode sonSonNode; + NavigationTreeNode sonSonSonNode; + + builder.build(rootNode, (String) null, JAXXContextEntryDef.newDef("name", String.class), "name", null, null); + builder.build(rootNode, (String) null, JAXXContextEntryDef.newDef("name2", String.class), "name2", null, null); + + sonNode = builder.build(rootNode, (String) null, JAXXContextEntryDef.newDef(Model.class), "model", null, null); + + builder.build(sonNode, (String) null, "../name", "name", null, null); + builder.build(sonNode, (String) null, "../integerValue", "integerValue", null, null); + + sonSonNode = builder.build(sonNode, (String) null, "../sons", "sons", null, null); + + sonSonSonNode = builder.build(sonSonNode, (String) null, "..[1]", 0 + "", null, null); + + builder.build(sonSonSonNode, (String) null, "../name", "name", null, null); + builder.build(sonSonSonNode, (String) null, "../integerValue", "integerValue", null, null); + builder.build(sonSonSonNode, (String) null, "../sons", "sons", null, null); + + sonSonSonNode = builder.build(sonSonNode, (String) null, "..[2]", 1 + "", null, null); + + builder.build(sonSonSonNode, (String) null, "../name", "name", null, null); + builder.build(sonSonSonNode, (String) null, "../integerValue", "integerValue", null, null); + builder.build(sonSonSonNode, (String) null, "../sons", "sons", null, null); + + sonSonSonNode = builder.build(sonSonNode, (String) null, (String) null, 2 + "", null, null); + //sonSonSonNode = model.new NavigationTreeNode(null, "..[3]", 2 + "", null, null); + sonSonNode.insert(sonSonSonNode, 2); + builder.build(sonSonSonNode, (String) null, "../..[3]/name", "name", null, null); + builder.build(sonSonSonNode, (String) null, "../..[3]/integerValue", "integerValue", null, null); + builder.build(sonSonSonNode, (String) null, "../..[3]/sons", "sons", null, null); + + NavigationTreeModel model = builder.getModel(); + + JAXXContext context = new DefaultJAXXContext(); + context.setContextValue("the name", "name"); + context.setContextValue("the name2", "name2"); + + + context.setContextValue( + new Model("modelName", 10, + Arrays.asList( + new Model("one", 1, Collections.<Model>emptyList()), + new Model("two", 2, Collections.<Model>emptyList()), + new Model("three", 3, Collections.<Model>emptyList()) + ) + ) + ); + + Assert.assertNull(model.getJAXXContextValue(context, "$root.name" + FAKE)); + + testBinding(model, context, "$root/name", context.getContextValue(String.class, "name")); + testBinding(model, context, "$root/name2", context.getContextValue(String.class, "name2")); + + Model bean = context.getContextValue(Model.class); + + testBinding(model, context, "$root/model", bean); + testBinding(model, context, "$root/model/name", bean.getName()); + testBinding(model, context, "$root/model/integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root/model/sons", bean.getSons()); + + testBinding(model, context, "$root/model/sons/0/name", bean.getSons().get(0).getName()); + testBinding(model, context, "$root/model/sons/0/integerValue", bean.getSons().get(0).getIntegerValue()); + testBinding(model, context, "$root/model/sons/0/sons", bean.getSons().get(0).getSons()); + + + testBinding(model, context, "$root/model/sons/1/name", bean.getSons().get(1).getName()); + testBinding(model, context, "$root/model/sons/1/integerValue", bean.getSons().get(1).getIntegerValue()); + testBinding(model, context, "$root/model/sons/1/sons", bean.getSons().get(1).getSons()); + + testBinding(model, context, "$root/model/sons/2/name", bean.getSons().get(2).getName()); + testBinding(model, context, "$root/model/sons/2/integerValue", bean.getSons().get(2).getIntegerValue()); + testBinding(model, context, "$root/model/sons/2/sons", bean.getSons().get(2).getSons()); + } + + /** + * Test the {@link NavigationTreeModel#getJAXXContextValue(jaxx.runtime.JAXXContext, String)} with an entry point + * as a list. + * <p/> + * Tree is like this + * <pre> + * $root + + * - models + <-- attached to context entry : java.util.List.class,"models" + * - 0 + + * - name + * -integerValue + * - sons + + * - 0 + + * - name + * - 1 + + * - name + * - integerValue + * - sons + * - 2 + + * - name + * - integerValue + * - sons + * </pre> + * <p/> + * With this tree, we will have to results : + * <pre> + * $root.models => context.get(List.class,"models") + * $root.models.0 => context.get(List.class,"models").get(0) + * $root.models.0.name => context.get(List.class,"models").get(0).getName() + * </pre> + * + * @throws Exception if any pb + */ + @Test + public void testGetJAXXContextValueFromList() throws Exception { + + NavigationTreeModelBuilder builder = new NavigationTreeModelBuilder(separator); + + NavigationTreeNode rootNode = builder.build(null, (String) null, (String) null, ROOT_CONTEXT, null, null); + + NavigationTreeNode sonNode; + NavigationTreeNode sonSonNode; + NavigationTreeNode sonSonSonNode; + + // first son is a list of models + sonNode = builder.build(rootNode, (String) null, JAXXContextEntryDef.newListDef("models"), "models", null, null); + + // first son son is a model + sonSonNode = builder.build(sonNode, (String) null, "..[1]", "0", null, null); + + builder.build(sonSonNode, (String) null, "../name", "name", null, null); + builder.build(sonSonNode, (String) null, "../integerValue", "integerValue", null, null); + sonSonNode = builder.build(sonSonNode, (String) null, "../sons", "sons", null, null); + + sonSonSonNode = builder.build(sonSonNode, (String) null, "..[1]", "0", null, null); + builder.build(sonSonSonNode, (String) null, "../name", "name", null, null); + + // second son son is a model + sonSonNode = builder.build(sonNode, (String) null, "..[2]", "1", null, null); + + builder.build(sonSonNode, (String) null, "../name", "name", null, null); + builder.build(sonSonNode, (String) null, "../integerValue", "integerValue", null, null); + builder.build(sonSonNode, (String) null, "../sons", "sons", null, null); + + // third son son is a model + sonSonNode = builder.build(sonNode, (String) null, "..[3]", "2", null, null); + + builder.build(sonSonNode, (String) null, "../name", "name", null, null); + builder.build(sonSonNode, (String) null, "../integerValue", "integerValue", null, null); + builder.build(sonSonNode, (String) null, "../sons", "sons", null, null); + + NavigationTreeModel model = builder.getModel(); + + + List<Model> list = Arrays.asList( + new Model("entryOne", 10, + Arrays.asList( + new Model("one", 1, Collections.<Model>emptyList()), + new Model("two", 2, Collections.<Model>emptyList()), + new Model("three", 3, Collections.<Model>emptyList()) + ) + ), + new Model("entryTwo", 20, + Arrays.asList( + new Model("2one", 1, Collections.<Model>emptyList()), + new Model("2two", 2, Collections.<Model>emptyList()), + new Model("2three", 3, Collections.<Model>emptyList()) + ) + ), + new Model("entryThree", 30, + Arrays.asList( + new Model("3one", 1, Collections.<Model>emptyList()), + new Model("3two", 2, Collections.<Model>emptyList()), + new Model("3three", 3, Collections.<Model>emptyList()) + ) + ) + ); + JAXXContext context = new DefaultJAXXContext(); + context.setContextValue(list, "models"); + + Model bean; + + testBinding(model, context, "$root/models", list); + + bean = list.get(0); + testBinding(model, context, "$root/models/0", bean); + testBinding(model, context, "$root/models/0/name", bean.getName()); + testBinding(model, context, "$root/models/0/integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root/models/0/sons", bean.getSons()); + testBinding(model, context, "$root/models/0/sons/0", bean.getSons().get(0)); + testBinding(model, context, "$root/models/0/sons/0/name", bean.getSons().get(0).getName()); + + bean = list.get(1); + testBinding(model, context, "$root/models/1", bean); + testBinding(model, context, "$root/models/1/name", bean.getName()); + testBinding(model, context, "$root/models/1/integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root/models/1/sons", bean.getSons()); + + bean = list.get(2); + testBinding(model, context, "$root/models/2", bean); + testBinding(model, context, "$root/models/2/name", bean.getName()); + testBinding(model, context, "$root/models/2/integerValue", bean.getIntegerValue()); + testBinding(model, context, "$root/models/2/sons", bean.getSons()); + + } + + protected void testBinding(NavigationTreeModel model, JAXXContext context, String contextPath, Object expected) throws Exception { + + Object value; + value = model.getJAXXContextValue(context, contextPath); + Assert.assertNotNull(value); + Assert.assertEquals(expected, value); + } + + protected String getNodeContext(int... context) { + String result = ""; + for (int i : context) { + result += i; + } + return result; + } + + protected void assertNodeEquals(String contextPath, String nodeContext, int level, NavigationTreeNode node, boolean root) { + //System.out.println(contextPath + " : " + (node == null ? null : node.getContextPath())); + Assert.assertNotNull(node); + Assert.assertEquals(root, node.isRoot()); + Assert.assertEquals(level, node.getLevel()); + Assert.assertEquals(nodeContext, node.getNavigationPath()); + Assert.assertEquals(contextPath, node.getContextPath()); + } + + public static class Model { + + protected String name; + + protected int integerValue; + + protected List<Model> sons; + + public Model(String name, int integerValue, List<Model> sons) { + this.name = name; + this.integerValue = integerValue; + this.sons = sons; + } + + public String getName() { + return name; + } + + public int getIntegerValue() { + return integerValue; + } + + public List<Model> getSons() { + return sons; + } + + @Override + public String toString() { + return super.toString() + "<name:" + name + ",integerValue:" + integerValue + ",sons: " + sons + ">"; + } + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/resources/log4j.properties (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/resources/log4j.properties) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/resources/log4j.properties (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/resources/log4j.properties 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,8 @@ +# Global logging configuration +log4j.rootLogger=ERROR, stdout +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n + +log4j.logger.jaxx=DEBUG Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-swing/src/test/resources/log4j.properties ___________________________________________________________________ Name: svn:mergeinfo + Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-validator ___________________________________________________________________ Name: svn:ignore + target *.log *.iml Added: lutinjaxx/branches/storm_1/jaxx-compiler-validator/LICENSE.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/LICENSE.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/LICENSE.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Added: lutinjaxx/branches/storm_1/jaxx-compiler-validator/README.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/README.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/README.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install Added: lutinjaxx/branches/storm_1/jaxx-compiler-validator/changelog.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/changelog.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/changelog.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,90 @@ +1.0 ???? 200812?? + +0.8 ??? 200812?? + * 20081228 [chemit] - generify ClassDescriptor + - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from + JAXXCompiler and make possible to extract compiler engine from runtime + + * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation + * 20081218 [chemit] - improve generation of methods + * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) + - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option) + - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection + - add addSourcesToClassPath property to add sources directories in class-path + - improve classloader managment + - keep in DataSource objetCode + - fix bug when processDataBinding on a null objectCode + - always clean node cached values when selected it + - add usefull databinding method in Util + +* 20081213 [chemit] - improve navigation tree node rendering with some caches + - introduce a ChildBuilder to simplify building of child nodes from a collection or array + +0.7 chemit 20081210 +* 20081210 [chemit] - fix bug 1751 +* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) +* 20081208 [chemit] - javabBean attribute use to initialize bean + - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) + - introduce MultiJXPathDecorator + - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers + + * 20081207 [chemit] use lutinproject 3.1 + - can exclude field from validator + * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter + - fix bug when searching for a inner class + + * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator + - add setcontextValue and removeContextValue on JAXXContextEntryDef + - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff + - only enter once in $initialize method in generated code + + 0.6 chemit 20081117 + * 20081118 [chemit] introduce NavigationUtil, save in context selected node + * 20081107 [chemit] improve data binding and code generation : + - make possible inheritance in binding + - add an attribute javaBean to an object : will generate a full java bean support property + - make possible binding to the javaBean added properties + - clean generated code + + * 20081105 [chemit] introduce a CardLayout2 to extends awt CardLayout + introduce a NavigationTreeModel + introduce a Decorator to render Object + propagate constructor JAXXContext(JAXXContext) in JAXXObject generation + begin of rst documentation + + * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer + * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor. + * 20081102 [chemit] improve JAXXContext : + - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext + - do javadoc in JAXXContext + - add logic in DefaultJAXXContext : seek in parent context if entry not found + * 20081102 [chemit] improve tests : + - fix the last failed test from Jaxx original version :) + - dumps tests to JUnit4 :) + * 20081030 [chemit] improve BeanValidator : + - add full PropertyChangeEvent java-bean support and a property valid + - when remove bean from validator, must remove errors from model + - make possible to have a dynamic errorListModel in jaxx files + * 20081030 [chemit] improve JAXXContext : + - fix setContextValue bug when setting twice a same type for a same key + - implements a DefaultJAXXContext + - use this default implementation with delegate pattern in JAXXObject + * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext + * 20081027 [chemit] fix bug 1722 + * 20081027 [chemit] add conversion support in validator + * 20081025 [chemit] improve BeanValidator tag : + - add a errorList attribute for set a ErrorListMouseListener on the errorList + - add a beanInitializer attribute for set the validator's bean at runtime + - add a default errorListModel value 'errors' + * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method + * 20081024 [chemit] fix validator context lost if UI is launched from another thread + ver-0-5 chemit 20081002 + * 20081017 [chemit] add validator support + * 20081013 [chemit] can generate logger on jaxx files + * 20081011 [chemit] improve site + * 20081011 [chemit] fix bug on JavaFileParser : works again + * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin + * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules) + * 20081002 [chemit] Introduce JAXXContext + * 20081002 [chemit] Fix bug on method creation via scripting + * 20081002 [chemit] Improve i18n integration (works now also for tabs) Added: lutinjaxx/branches/storm_1/jaxx-compiler-validator/pom.xml =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/pom.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,54 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.codelutin</groupId> + <artifactId>lutinjaxx</artifactId> + <version>0.8-SNAPSHOT</version> + </parent> + + <artifactId>jaxx-compiler-validator</artifactId> + + <dependencies> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-validator</artifactId> + </dependency> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-compiler-api</artifactId> + </dependency> + + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + <name>jaxx-compiler-validator</name> + <description>Jaxx compiler validation extension</description> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + <packaging>jar</packaging> + + <build> + <defaultGoal>install</defaultGoal> + </build> + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + <scm> + <connection>${maven.scm.connection.child}</connection> + <developerConnection>${maven.scm.developerConnection.child}</developerConnection> + <url>${maven.scm.url.child}</url> + </scm> +</project> Added: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/compiler/ValidatorGenerator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,90 @@ +package jaxx.compiler; + +import jaxx.compiler.CompiledObject.ChildRef; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.JAXXValidator; +import jaxx.runtime.validator.BeanValidator; +import jaxx.tags.validator.BeanValidatorHandler; +import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator; +import jaxx.types.TypeManager; + +import java.util.List; +import java.lang.*; + +/** @author chemit */ +public class ValidatorGenerator implements Generator { + + protected static final JavaField VALIDATOR_IDS_FIELD = JavaField.newField(java.lang.reflect.Modifier.PROTECTED, + "java.util.List<String>", "validatorIds", "new ArrayList<String>()" + ); + + protected static final JavaMethod GET_VALIDATOR_METHOD = JavaMethod.newMethod(java.lang.reflect.Modifier.PUBLIC, "BeanValidator<?>", "getValidator", + "return (BeanValidator) (validatorIds.contains(validatorId)?getObjectById(validatorId):null);", + new JavaArgument("String", "validatorId") + ); + + @Override + public void finalizeCompiler(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) { + + if (!BeanValidatorHandler.hasValidator(compiler)) { + return; + } + + for (CompiledObject object : compiler.getObjects().values()) { + List<ChildRef> childs = object.getChilds(); + if (childs == null || childs.isEmpty()) { + continue; + } + for (ChildRef child : childs) { + String javaCode = child.getChildJavaCode(); + // some validators are defined on this object + boolean found = BeanValidatorHandler.isComponentUsedByValidator(compiler, child.getChild().getId()); + if (found) { + // box the child component in a JxLayer + child.setChildJavaCode("jaxx.runtime.Util.boxComponentWithJxLayer(" + javaCode + ")"); + } + } + } + // register validator + for (CompiledBeanValidator validator : BeanValidatorHandler.getValidators(compiler)) { + String id = TypeManager.getJavaCode(validator.getId()); + compiler.appendLateInitializer("validatorIds.add(" + id + ");"); + compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); + compiler.appendLateInitializer("getValidator(" + id + ").installUIs();"); + compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); + compiler.appendLateInitializer("getValidator(" + id + ").validate();"); + compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); + } + compiler.appendLateInitializer("validatorIds = java.util.Collections.unmodifiableList(validatorIds);"); + compiler.appendLateInitializer(JAXXCompiler.getLineSeparator()); + } + + @Override + public void prepareJavaFile(CompiledObject root, JAXXCompiler compiler, JavaFile javaFile, String packageName, String className) throws ClassNotFoundException { + if (!BeanValidatorHandler.hasValidator(compiler)) { + return; + } + + javaFile.addImport(BeanValidator.class); + + if (javaFile.isSuperclassIsJAXXObject()) { + ClassDescriptor superClass = ClassDescriptorLoader.getClassDescriptor(javaFile.getSuperClass()); + boolean parentIsValidator = ClassDescriptorLoader.getClassDescriptor(JAXXValidator.class).isAssignableFrom(superClass); + + if (parentIsValidator) { + // nothing to generate (use the parent directly) + return; + } + } + + // add JAXXValidator interface + javaFile.addInterface(JAXXCompiler.getCanonicalName(JAXXValidator.class)); + + // implements JAXXValidator + javaFile.addField(VALIDATOR_IDS_FIELD); + javaFile.addMethod(GET_VALIDATOR_METHOD); + } + + +} Copied: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,696 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.validator; + +import jaxx.CompilerException; +import jaxx.compiler.CompiledObject; +import jaxx.compiler.JAXXCompiler; +import jaxx.introspection.JAXXBeanInfo; +import jaxx.introspection.JAXXPropertyDescriptor; +import jaxx.reflect.ClassDescriptor; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.BeanValidator.Scope; +import jaxx.runtime.validator.Util; +import jaxx.runtime.validator.ui.AbstractBeanValidatorUI; +import jaxx.tags.DefaultObjectHandler; +import jaxx.types.TypeManager; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; + +import java.beans.IntrospectionException; +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +public class BeanValidatorHandler extends DefaultObjectHandler { + + public static final String TAG = BeanValidator.class.getSimpleName(); + public static final String BEAN_ATTRIBUTE = "bean"; + public static final String BEAN_CLASS_ATTRIBUTE = "beanClass"; + public static final String BEAN_INITIALIZER_ATTRIBUTE = "beanInitializer"; + + public static final String ERROR_LIST_MODEL_ATTRIBUTE = "errorListModel"; + public static final String ERROR_TABLE_MODEL_ATTRIBUTE = "errorTableModel"; + public static final String ERROR_LIST_ATTRIBUTE = "errorList"; + public static final String ERROR_TABLE_ATTRIBUTE = "errorTable"; + + public static final String ERROR_LIST_MODEL_DEFAULT = "errors"; + public static final String ERROR_TABLE_MODEL_DEFAULT = "errors2"; + + public static final String ERROR_LIST_DEFAULT = "errorList"; + public static final String ERROR_TABLE_DEFAULT = "errorTable"; + + public static final String AUTOFIELD_ATTRIBUTE = "autoField"; + public static final String UI_CLASS_ATTRIBUTE = "uiClass"; + public static final String STRICT_MODE_ATTRIBUTE = "strictMode"; + + public static final String CONTEXT_NAME_ATTRIBUTE = "contextName"; + + public static final String SCOPE_ATTRIBUTE = "scope"; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static Log log = LogFactory.getLog(BeanValidatorHandler.class); + + protected static Map<JAXXCompiler, List<CompiledBeanValidator>> validators = new HashMap<JAXXCompiler, List<CompiledBeanValidator>>(); + + protected static Map<JAXXCompiler, List<String>> validatedComponents = new HashMap<JAXXCompiler, List<String>>(); + + public BeanValidatorHandler(ClassDescriptor beanClass) { + super(beanClass); + ClassDescriptorLoader.checkSupportClass(getClass(), beanClass, BeanValidator.class); + } + + @Override + protected CompiledObject createCompiledObject(String id, JAXXCompiler compiler) { + return new CompiledBeanValidator(id, getBeanClass(), compiler); + } + + @Override + protected void compileChildTagFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + if (compiler.getOptions().isVerbose()) { + log.info(tag); + } + if (!tag.getLocalName().equals(FieldValidatorHandler.TAG)) { + compiler.reportError("tag '" + tag.getParentNode().getLocalName() + "' may only contain " + FieldValidatorHandler.TAG + " as children, but found : " + tag.getLocalName()); + } else { + compiler.compileFirstPass(tag); + } + } + + @Override + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + + super.compileSecondPass(tag, compiler); + + CompiledBeanValidator info = (CompiledBeanValidator) objectMap.get(tag); + + boolean error = info.addErrorListModel(tag, this, compiler); + + if (!error) { + error = info.addErrorList(tag, compiler); + } + + if (!error) { + error = info.addErrorTableModel(tag, this, compiler); + } + + if (!error) { + error = info.addErrorTable(tag, compiler); + } + + if (!error) { + error = info.addUiClass(this, compiler); + } + + if (!error) { + error = info.addBean(tag, this, compiler); + } + + if (!error) { + error = info.addContextName(this, compiler); + } + + if (!error) { + error = info.addScope(this, compiler); + } + + if (error) { + log.warn("error were detected in second compile pass of CompiledObject [" + info + "]"); + } + + // close the compiled object + compiler.closeComponent(info); + } + + @Override + protected void setDefaults(CompiledObject object, Element tag, JAXXCompiler compiler) { + // open the compiled object + compiler.openInvisibleComponent(object); + } + + @Override + public void setAttribute(CompiledObject object, String propertyName, String stringValue, boolean inline, JAXXCompiler compiler) { + if (compiler.getOptions().isVerbose()) { + log.info(propertyName + " : " + stringValue + " for " + object); + } + // delegate to the compiled object with is statefull (but not the tag handler) + object.addProperty(propertyName, stringValue); + } + + /** + * The compiled objet representing a BeanValidator to be generated in JAXXObject + * + * @author chemit + */ + public static class CompiledBeanValidator extends CompiledObject { + + protected Map<String, String> fields; + protected Map<String, String> excludeFields; + protected String bean; + protected String beanClass; + protected String contextName; + protected String uiClass; + protected String errorListModel; + protected String errorList; + protected Boolean autoField; + protected Boolean strictMode; + protected JAXXBeanInfo beanDescriptor; + protected String errorTableModel; + protected String errorTable; + protected Scope scope; + + public CompiledBeanValidator(String id, ClassDescriptor objectClass, JAXXCompiler compiler) { + super(id, objectClass, compiler); + fields = new TreeMap<String, String>(); + excludeFields = new TreeMap<String, String>(); + } + + public Map<String, String> getFields() { + return fields; + } + + public Map<String, String> getExcludeFields() { + return excludeFields; + } + + public void setFields(Map<String, String> fields) { + this.fields = fields; + } + + public void setExcludeFields(Map<String, String> excludeFields) { + this.excludeFields = excludeFields; + } + + @Override + public void addProperty(String property, String value) { + + if (BEAN_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + bean = value.trim(); + } + return; + } + + if (CONTEXT_NAME_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + contextName = value.trim(); + } + return; + } + + if (BEAN_CLASS_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + beanClass = value.trim(); + } + return; + } + + if (ERROR_LIST_MODEL_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + errorListModel = value.trim(); + } + return; + } + + if (ERROR_LIST_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + errorList = value.trim(); + } + return; + } + + if (ERROR_TABLE_MODEL_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + errorTableModel = value.trim(); + } + return; + } + + if (ERROR_TABLE_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + errorTable = value.trim(); + } + return; + } + + if (UI_CLASS_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + uiClass = value.trim(); + } + return; + } + + if (AUTOFIELD_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + autoField = (Boolean) TypeManager.convertFromString(value.trim(), Boolean.class); + } + return; + } + + if (STRICT_MODE_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + strictMode = (Boolean) TypeManager.convertFromString(value.trim(), Boolean.class); + } + return; + } + + if (SCOPE_ATTRIBUTE.equals(property)) { + if (value != null && !value.trim().isEmpty()) { + scope = (Scope) TypeManager.convertFromString(value.trim(), Scope.class); + } + return; + } + + throw new CompilerException("property " + property + " is not allowed on object " + this); + + //todo should not allowed to find other attributes + //super.addProperty(property, value); + } + + public String getBean() { + return bean; + } + + public String getErrorListModel() { + return errorListModel; + } + + public boolean getAutoField() { + return autoField != null && autoField; + } + + public boolean getStrictMode() { + return strictMode != null && strictMode; + } + + public String getUiClass() { + return uiClass; + } + + public String getBeanClass() { + return beanClass; + } + + public String getContextName() { + return contextName; + } + + public Scope getScope() { + return scope; + } + + public JAXXBeanInfo getBeanDescriptor(JAXXCompiler compiler) { + if (beanDescriptor == null && foundBean()) { + + String beanClassName = null; + try { + // get the real bean class name (from bean or beanClass) + if (beanClass != null) { + beanClassName = beanClass; + } else { + beanClassName = compiler.getSymbolTable().getClassTagIds().get(bean); + if (beanClassName == null) { + compiler.reportError("could not find class of the bean '" + bean + "'"); + return null; + } + } + ClassDescriptor beanClassDescriptor = ClassDescriptorLoader.getClassDescriptor(beanClassName); + beanDescriptor = DefaultObjectHandler.getJAXXBeanInfo(beanClassDescriptor); + } catch (ClassNotFoundException e) { + compiler.reportError("could not load class " + beanClassName); + } catch (IntrospectionException e) { + compiler.reportError("could not load class " + beanClassName); + } + } + return beanDescriptor; + } + + @Override + public void addChild(CompiledObject child, String constraints, JAXXCompiler compiler) throws CompilerException { + // do nothing + compiler.reportError("can not add CompiledObject in the tag '" + TAG + " (only field tags)"); + } + + public boolean foundBean() { + return !(bean == null && beanClass == null); + } + + protected boolean addUiClass(BeanValidatorHandler handler, JAXXCompiler compiler) { + boolean withError = false; + if (uiClass == null && compiler.getOptions().getDefaultErrorUI() != null) { + uiClass = compiler.getOptions().getDefaultErrorUI().getName(); + } + if (uiClass != null) { + try { + ClassDescriptor uiClazz = ClassDescriptorLoader.getClassDescriptor(uiClass); + if (!ClassDescriptorLoader.getClassDescriptor(AbstractBeanValidatorUI.class).isAssignableFrom(uiClazz)) { + compiler.reportError("attribute 'ui' :'" + uiClass + "' is not assignable from class " + AbstractBeanValidatorUI.class); + withError = true; + } else { + String code = handler.getSetPropertyCode(getJavaCode(), UI_CLASS_ATTRIBUTE, uiClazz.getName() + ".class", compiler); + appendAdditionCode(code); + } + } catch (ClassNotFoundException e) { + compiler.reportError("class not found '" + uiClass + "'"); + withError = true; + } + } + + return withError; + } + + protected boolean addErrorListModel(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + if (errorListModel == null) { + // try with the default "errors" + if (!compiler.checkReference(tag, ERROR_LIST_MODEL_DEFAULT, false, ERROR_LIST_MODEL_ATTRIBUTE)) { + return false; + } + errorListModel = ERROR_LIST_MODEL_DEFAULT; + } else { + if (errorListModel.startsWith("{") && errorListModel.endsWith("}")) { + // this is a script, no check here + errorListModel = errorListModel.substring(1, errorListModel.length() - 1).trim(); + } else if (!compiler.checkReference(tag, errorListModel, true, ERROR_LIST_MODEL_ATTRIBUTE)) { + // errorListModel is not defined + return true; + } + } + + String code = handler.getSetPropertyCode(getJavaCode(), ERROR_LIST_MODEL_ATTRIBUTE, errorListModel, compiler); + appendAdditionCode(code); + + return false; + + } + + protected boolean addErrorTableModel(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + if (errorTableModel == null) { + // try with the default "errors" + if (!compiler.checkReference(tag, ERROR_TABLE_MODEL_DEFAULT, false, ERROR_LIST_MODEL_ATTRIBUTE)) { + return false; + } + errorTableModel = ERROR_TABLE_MODEL_DEFAULT; + } else { + if (errorTableModel.startsWith("{") && errorTableModel.endsWith("}")) { + // this is a script, no check here + errorTableModel = errorTableModel.substring(1, errorTableModel.length() - 1).trim(); + } else if (!compiler.checkReference(tag, errorTableModel, true, ERROR_TABLE_MODEL_ATTRIBUTE)) { + // errorListModel is not defined + return true; + } + } + + String code = handler.getSetPropertyCode(getJavaCode(), ERROR_TABLE_MODEL_ATTRIBUTE, errorTableModel, compiler); + appendAdditionCode(code); + + return false; + + } + + protected boolean addContextName(BeanValidatorHandler handler, JAXXCompiler compiler) { + if (contextName != null) { + String code = handler.getSetPropertyCode(getJavaCode(), CONTEXT_NAME_ATTRIBUTE, TypeManager.getJavaCode(contextName), compiler); + appendAdditionCode(code); + } + return false; + } + + protected boolean addScope(BeanValidatorHandler handler, JAXXCompiler compiler) { + if (scope != null) { + String code = handler.getSetPropertyCode(getJavaCode(), SCOPE_ATTRIBUTE, TypeManager.getJavaCode(scope), compiler); + appendAdditionCode(code); + } + return false; + } + + protected boolean addErrorList(Element tag, JAXXCompiler compiler) { + + if (errorList == null) { + // try with the default "errorList" + if (!compiler.checkReference(tag, ERROR_LIST_DEFAULT, false, ERROR_LIST_ATTRIBUTE)) { + return false; + } + errorList = ERROR_LIST_DEFAULT; + } else { + if (!compiler.checkReference(tag, errorList, true, ERROR_LIST_ATTRIBUTE)) { + return true; + } + } + + String code = Util.class.getName() + ".registerErrorListMouseListener(" + errorList + ");"; + appendAdditionCode(code); + + return false; + + } + + protected boolean addErrorTable(Element tag, JAXXCompiler compiler) { + + if (errorTable == null) { + // try with the default "errorList" + if (!compiler.checkReference(tag, ERROR_TABLE_DEFAULT, false, ERROR_TABLE_ATTRIBUTE)) { + return false; + } + errorTable = ERROR_TABLE_DEFAULT; + } else { + if (!compiler.checkReference(tag, errorTable, true, ERROR_TABLE_ATTRIBUTE)) { + return true; + } + } + + String code = Util.class.getName() + ".registerErrorTableMouseListener(" + errorTable + ");"; + appendAdditionCode(code); + + return false; + + } + + protected boolean addBean(Element tag, BeanValidatorHandler handler, JAXXCompiler compiler) { + + if (!foundBean()) { + compiler.reportError("tag '" + tag + "' requires a 'bean' or a 'beanClass' attribute"); + return true; + } + + String beanInitializer = null; + if (bean != null) { + + if (bean.startsWith("{") && bean.endsWith("}")) { + + // just has an intializer + beanInitializer = bean.substring(1, bean.length() - 1); + // this is not a real bean, so delete it + bean = null; + } else { + + if (!compiler.checkReference(tag, bean, true, BEAN_ATTRIBUTE)) { + // could not find bean in compiled object + return true; + } + + if (isBeanUsedByValidator(compiler, bean)) { + compiler.reportError("the bean '" + bean + "' is already used in another the validator, can not used it in '" + tag + "'"); + return true; + } + + /*if (beanInitializer != null) { + compiler.reportWarning("tag '" + tag + "' found a 'bean' and a 'beanInitializer' attributes, 'beanInitializer' is skipped"); + }*/ + beanInitializer = bean; + } + } + + if (beanInitializer != null) { + String code = handler.getSetPropertyCode(getJavaCode(), BEAN_ATTRIBUTE, compiler.checkJavaCode(beanInitializer), compiler); + appendAdditionCode(code); + } + + // add generic type to validator + JAXXBeanInfo beanInfo = getBeanDescriptor(compiler); + if (beanInfo == null) { + return true; + } + + setGenericTypes(new String[]{beanInfo.getJAXXBeanDescriptor().getClassDescriptor().getName()}); + + if (getAutoField()) { + registerAutoFieldBean(tag, compiler, beanInfo); + } + + if (getBeanDescriptor(compiler) != null) { + + // add fieldrepresentation invocations + addFieldRepresentations(tag, compiler); + + // register the validator in compiler + registerValidator(compiler, this); + + } + + return false; + } + + private void registerValidator(JAXXCompiler compiler, CompiledBeanValidator compiledBeanValidator) { + List<CompiledBeanValidator> vals = validators.get(compiler); + if (vals == null) { + vals = new ArrayList<CompiledBeanValidator>(); + validators.put(compiler, vals); + } + vals.add(compiledBeanValidator); + List<String> ids = validatedComponents.get(compiler); + if (ids == null) { + ids = new ArrayList<String>(); + validatedComponents.put(compiler, ids); + } + ids.addAll(compiledBeanValidator.getFields().values()); + } + + protected void addFieldRepresentations(Element tag, JAXXCompiler compiler) { + for (Entry<String, String> entry : fields.entrySet()) { + String propertyName = entry.getKey(); + String component = entry.getValue(); + if (!checkBeanProperty(compiler, propertyName)) { + // property not find on bean + continue; + } + if (!compiler.checkReference(tag, component, true, null)) { + // editor component not find on ui + continue; + } + /*if (compiler.isComponentUsedByValidator(component)) { + // component is already used by another validator + compiler.reportError("component '" + component + "' is already used by another validator."); + continue; + }*/ + String keyCode = TypeManager.getJavaCode(propertyName); + appendAdditionCode(getJavaCode() + ".setFieldRepresentation(" + keyCode + ", " + component + ");"); + + } + } + + protected void registerAutoFieldBean(Element tag, JAXXCompiler compiler, JAXXBeanInfo beanInfo) { + for (JAXXPropertyDescriptor beanProperty : beanInfo.getJAXXPropertyDescriptors()) { + String descriptionName = beanProperty.getName(); + if (compiler.getOptions().isVerbose()) { + log.info("try to bind on bean " + beanInfo.getJAXXBeanDescriptor().getName() + " property " + descriptionName); + } + if (beanProperty.getWriteMethodDescriptor() == null) { + // read-only property + continue; + } + if (fields.containsKey(descriptionName)) { + // already defined in field + continue; + } + if (excludeFields.containsKey(descriptionName)) { + // exclude field + continue; + } + if (!compiler.checkReference(tag, descriptionName, getStrictMode(), null)) { + // no editor component found + continue; + } + // ok add the field mapping + registerField(descriptionName, descriptionName, compiler); + } + + for (Entry<String, String> entry : excludeFields.entrySet()) { + String key = entry.getKey(); + if (fields.containsKey(key)) { + compiler.reportWarning("field '" + key + "' can not be used and excluded at same time ! (field is skipped) for validator " + this); + fields.remove(key); + } + } + } + + public void registerField(String id, String component, JAXXCompiler compiler) { + if (fields.containsKey(id)) { + compiler.reportError("duplicate field '" + id + "' for validator " + this); + } else { + if (compiler.getOptions().isVerbose()) { + log.info("add field <" + id + ":" + component + ">"); + } + fields.put(id, component); + } + } + + public void registerExcludeField(String id, String component, JAXXCompiler compiler) { + if (excludeFields.containsKey(id)) { + compiler.reportError("duplicate field '" + id + "' for validator " + this); + } else { + if (compiler.getOptions().isVerbose()) { + log.info("add excludeField <" + id + ":" + component + ">"); + } + excludeFields.put(id, component); + } + } + + protected boolean checkBeanProperty(JAXXCompiler compiler, String propertyName) { + + for (JAXXPropertyDescriptor beanProperty : getBeanDescriptor(compiler).getJAXXPropertyDescriptors()) { + if (beanProperty.getName().equals(propertyName)) { + if (beanProperty.getWriteMethodDescriptor() == null) { + // read-onlyproperty + compiler.reportError("could not bind the readonly property '" + propertyName + "' on bean [" + getBean() + "] "); + return false; + } + return true; + } + } + compiler.reportError("could not find the property '" + propertyName + "' on bean [" + getBean() + "] "); + return false; + } + } + + /** + * Test if a given bean is attached to a validator. + * + * @param compiler current compiler to use + * @param beanId the bean to test + * @return <code>true</code> if the given bean is attached to a validator, <code>false</code> otherwise + */ + public static boolean isBeanUsedByValidator(JAXXCompiler compiler, String beanId) { + List<CompiledBeanValidator> beanValidatorList = validators.get(compiler); + if (beanValidatorList != null) { + for (CompiledBeanValidator validator : beanValidatorList) { + if (beanId.equals(validator.getBean())) { + return true; + } + } + } + return false; + } + + /** + * @param compiler compiler to use + * @return <code>true</code> if some validators were detected, <code>false</code> otherwise + */ + public static boolean hasValidator(JAXXCompiler compiler) { + List<CompiledBeanValidator> beanValidatorList = validators.get(compiler); + return beanValidatorList != null && !beanValidatorList.isEmpty(); + } + + /** + * Test if a given CompiledObject is attached to a validator. + * + * @param compiler compiler to use + * @param componentId the compiled object to test + * @return <code>true</code> if the given compiled object is attached to a validator, <code>false</code> otherwise + */ + public static boolean isComponentUsedByValidator(JAXXCompiler compiler, String componentId) { + List<String> ids = validatedComponents.get(compiler); + return ids != null && ids.contains(componentId); + } + + public static List<CompiledBeanValidator> getValidators(JAXXCompiler compiler) { + return validators.get(compiler); + } +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,85 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.validator; + +import jaxx.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.validator.BeanValidator; +import jaxx.tags.TagHandler; +import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; + +import java.io.IOException; + +public class ExcludeFieldValidatorHandler implements TagHandler { + + public static final String TAG = "excludeField"; + public static final String NAME_ATTRIBUTE = "name"; + public static final String COMPONENT_ATTRIBUTE = "component"; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ExcludeFieldValidatorHandler.class); + + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + if (compiler.getOptions().isVerbose()) { + log.info(tag); + } + //todo check there is no child + } + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + if (compiler.getOptions().isVerbose()) { + log.debug(tag); + } + + if (!ClassDescriptorLoader.getClassDescriptor(BeanValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { + compiler.reportError(TAG + " tag may only appear within " + BeanValidatorHandler.TAG + " tag but was " + tag); + return; + } + + CompiledBeanValidator info = (CompiledBeanValidator) compiler.getOpenComponent(); + if (!info.getAutoField()) { + compiler.reportError(TAG + " tag can not be used without an 'autoField' validator : " + tag); + return; + } + String name = tag.getAttribute(NAME_ATTRIBUTE); + String component = tag.getAttribute(COMPONENT_ATTRIBUTE); + if (name == null || name.trim().isEmpty()) { + compiler.reportError(TAG + " tag requires a " + NAME_ATTRIBUTE + " attribute"); + return; + } + name = name.trim(); + if (component == null || component.trim().isEmpty()) { + // try to use the name as component + if (!compiler.checkReference(tag, name, false, name)) { + compiler.reportError(TAG + " tag requires a " + COMPONENT_ATTRIBUTE + " attribute, try to use the name attribute [" + name + "] for the component, but no such component found"); + return; + } + component = name; + } + component = component.trim(); + + // check component is not already used by this compiled object + if (info.getFields().containsValue(component)) { + compiler.reportError(TAG + " tag found a attribute " + COMPONENT_ATTRIBUTE + " [" + component + "] already used in this validator"); + return; + } + if (info.getExcludeFields().containsValue(component)) { + compiler.reportError(TAG + " tag found a attribute " + COMPONENT_ATTRIBUTE + " [" + component + "] already used in this validator"); + return; + } + // check component exist (again perharps, but let the error knows exactly which tag failed...) + if (compiler.checkReference(tag, component, true, COMPONENT_ATTRIBUTE)) { + // add a field + info.registerField(name, component, compiler); + } + + + } + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ExcludeFieldValidatorHandler.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,78 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.validator; + +import jaxx.CompilerException; +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.validator.BeanValidator; +import jaxx.tags.TagHandler; +import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.w3c.dom.Element; + +import java.io.IOException; + +public class FieldValidatorHandler implements TagHandler { + + public static final String TAG = "field"; + public static final String NAME_ATTRIBUTE = "name"; + public static final String COMPONENT_ATTRIBUTE = "component"; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(FieldValidatorHandler.class); + + public void compileFirstPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + if (compiler.getOptions().isVerbose()) { + log.info(tag); + } + //todo check there is no child + } + + public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException { + if (compiler.getOptions().isVerbose()) { + log.info(tag); + } + + if (!ClassDescriptorLoader.getClassDescriptor(BeanValidator.class).isAssignableFrom(compiler.getOpenComponent().getObjectClass())) { + compiler.reportError(TAG + " tag may only appear within " + BeanValidatorHandler.TAG + " tag but was " + tag); + return; + } + + CompiledBeanValidator info = (CompiledBeanValidator) compiler.getOpenComponent(); + + String name = tag.getAttribute(NAME_ATTRIBUTE); + String component = tag.getAttribute(COMPONENT_ATTRIBUTE); + if (name == null || name.trim().isEmpty()) { + compiler.reportError(TAG + " tag requires a " + NAME_ATTRIBUTE + " attribute"); + return; + } + name = name.trim(); + if (component == null || component.trim().isEmpty()) { + // try to use the name as component + if (!compiler.checkReference(tag, name, false, name)) { + compiler.reportError(TAG + " tag requires a " + COMPONENT_ATTRIBUTE + " attribute, try to use the name attribute [" + name + "] for the component, but no such component found"); + return; + } + component = name; + } + component = component.trim(); + + // check component is not already used by this compiled object + if (info.getFields().containsValue(component)) { + compiler.reportError(TAG + " tag found a attribute " + COMPONENT_ATTRIBUTE + " [" + component + "] already used in this validator"); + return; + } + // check component exist (again perharps, but let the error knows exactly which tag failed...) + if (compiler.checkReference(tag, component, true, COMPONENT_ATTRIBUTE)) { + // add a field + info.registerField(name, component, compiler); + } + + + } + +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/SwingInitializer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,25 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.tags.validator; + +import jaxx.compiler.JAXXCompiler; +import jaxx.reflect.ClassDescriptorLoader; +import jaxx.runtime.validator.BeanValidator; +import jaxx.tags.TagManager; +import jaxx.types.BeanValidatorScopeConverter; +import jaxx.types.TypeManager; + +public class ValidatorInitializer implements jaxx.spi.Initializer { + + @Override + public void initialize() { + + TypeManager.registerTypeConverter(BeanValidator.Scope.class, new BeanValidatorScopeConverter()); + + TagManager.registerBean(ClassDescriptorLoader.getClassDescriptor(BeanValidator.class), BeanValidatorHandler.class); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, FieldValidatorHandler.TAG, new FieldValidatorHandler()); + TagManager.registerTag(JAXXCompiler.JAXX_NAMESPACE, ExcludeFieldValidatorHandler.TAG, new FieldValidatorHandler()); + } +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/tags/validator/ValidatorInitializer.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/types/BeanValidatorScopeConverter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/types/BeanValidatorScopeConverter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/types/BeanValidatorScopeConverter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/types/BeanValidatorScopeConverter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,29 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.types; + +import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.BeanValidator.Scope; + +public class BeanValidatorScopeConverter implements TypeConverter { + + public String getJavaCode(Object object) { + Scope type = (Scope) object; + return BeanValidator.class.getName() + "." + Scope.class.getSimpleName() + "." + type.name(); + } + + public Object convertFromString(String string, Class type) { + if (type != Scope.class) { + throw new IllegalArgumentException("unsupported type: " + type); + } + try { + return Scope.valueOf(string); + } catch (IllegalArgumentException e) { + // do nothing + } + + throw new IllegalArgumentException("unable to convert string '" + string + "' to " + Scope.class); + } +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/java/jaxx/types/BeanValidatorScopeConverter.java ___________________________________________________________________ Name: svn:mergeinfo + Added: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.compiler.Generator =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.compiler.Generator (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.compiler.Generator 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1 @@ +jaxx.compiler.ValidatorGenerator Added: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.spi.Initializer =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.spi.Initializer (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/main/resources/META-INF/services/jaxx.spi.Initializer 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1 @@ +jaxx.tags.validator.ValidatorInitializer \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,46 @@ +package jaxx.junit; + +import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.BeanValidator.Scope; +import jaxx.types.BeanValidatorScopeConverter; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +public class BeanValidatorScopeConverterTest { + + BeanValidatorScopeConverter converter; + Scope value; + String strValue; + + @Before + public void before() { + converter = new BeanValidatorScopeConverter(); + } + + @Test + public void testConvertFromString() { + value = (Scope) converter.convertFromString("ERROR", Scope.class); + Assert.assertEquals(value, Scope.ERROR); + + value = (Scope) converter.convertFromString("WARNING", Scope.class); + Assert.assertEquals(value, Scope.WARNING); + } + + @Test + public void testGetJavaCode() { + value = Scope.ERROR; + strValue = converter.getJavaCode(value); + Assert.assertEquals(BeanValidator.class.getName() + "." + Scope.class.getSimpleName() + "." + value.name(), strValue); + + value = Scope.WARNING; + strValue = converter.getJavaCode(value); + Assert.assertEquals(BeanValidator.class.getName() + "." + Scope.class.getSimpleName() + "." + value.name(), strValue); + } + + @Test(expected = IllegalArgumentException.class) + public void testConvertFromStringError() { + converter.convertFromString("FAKE", Scope.class); + } + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-compiler-validator/src/test/java/jaxx/junit/BeanValidatorScopeConverterTest.java ___________________________________________________________________ Name: svn:mergeinfo + Property changes on: lutinjaxx/branches/storm_1/jaxx-example/Calculator ___________________________________________________________________ Name: svn:ignore - target LICENSE.txt + target *.log *.iml Copied: lutinjaxx/branches/storm_1/jaxx-example/Components (from rev 1100, lutinjaxx/trunk/jaxx-example/Components) Modified: lutinjaxx/branches/storm_1/jaxx-example/Validation/pom.xml =================================================================== --- lutinjaxx/trunk/jaxx-example/Validation/pom.xml 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/jaxx-example/Validation/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -15,6 +15,15 @@ <groupId>org.codelutin.jaxx-example</groupId> <artifactId>Validation</artifactId> + <dependencies> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-validator</artifactId> + <scope>compile</scope> + </dependency> + + </dependencies> <!-- ************************************************************* --> <!-- *** Project Information ************************************* --> <!-- ************************************************************* --> Modified: lutinjaxx/branches/storm_1/jaxx-example/pom.xml =================================================================== --- lutinjaxx/trunk/jaxx-example/pom.xml 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/jaxx-example/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -18,7 +18,7 @@ <dependency> <groupId>org.codelutin</groupId> - <artifactId>jaxx-core</artifactId> + <artifactId>jaxx-runtime-swing</artifactId> <scope>compile</scope> </dependency> @@ -128,13 +128,13 @@ </build> <profiles> - <!-- by default example are included, use -Ddoexample=false to disable examples --> + <!-- by default jnlp is only perform on a release stage when using the maven-release-plugin --> <profile> - <id>dojnlp</id> + <id>release-profile</id> <activation> <property> - <name>dojnlp</name> - <value>!false</value> + <name>performRelease</name> + <value>true</value> </property> </activation> <build> Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-api ___________________________________________________________________ Name: svn:ignore + target *.log *.iml Added: lutinjaxx/branches/storm_1/jaxx-runtime-api/LICENSE.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/LICENSE.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/LICENSE.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Added: lutinjaxx/branches/storm_1/jaxx-runtime-api/README.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/README.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/README.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install Added: lutinjaxx/branches/storm_1/jaxx-runtime-api/changelog.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/changelog.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/changelog.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,90 @@ +1.0 ???? 200812?? + +0.8 ??? 200812?? + * 20081228 [chemit] - generify ClassDescriptor + - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from + JAXXCompiler and make possible to extract compiler engine from runtime + + * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation + * 20081218 [chemit] - improve generation of methods + * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) + - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option) + - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection + - add addSourcesToClassPath property to add sources directories in class-path + - improve classloader managment + - keep in DataSource objetCode + - fix bug when processDataBinding on a null objectCode + - always clean node cached values when selected it + - add usefull databinding method in Util + +* 20081213 [chemit] - improve navigation tree node rendering with some caches + - introduce a ChildBuilder to simplify building of child nodes from a collection or array + +0.7 chemit 20081210 +* 20081210 [chemit] - fix bug 1751 +* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) +* 20081208 [chemit] - javabBean attribute use to initialize bean + - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) + - introduce MultiJXPathDecorator + - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers + + * 20081207 [chemit] use lutinproject 3.1 + - can exclude field from validator + * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter + - fix bug when searching for a inner class + + * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator + - add setcontextValue and removeContextValue on JAXXContextEntryDef + - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff + - only enter once in $initialize method in generated code + + 0.6 chemit 20081117 + * 20081118 [chemit] introduce NavigationUtil, save in context selected node + * 20081107 [chemit] improve data binding and code generation : + - make possible inheritance in binding + - add an attribute javaBean to an object : will generate a full java bean support property + - make possible binding to the javaBean added properties + - clean generated code + + * 20081105 [chemit] introduce a CardLayout2 to extends awt CardLayout + introduce a NavigationTreeModel + introduce a Decorator to render Object + propagate constructor JAXXContext(JAXXContext) in JAXXObject generation + begin of rst documentation + + * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer + * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor. + * 20081102 [chemit] improve JAXXContext : + - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext + - do javadoc in JAXXContext + - add logic in DefaultJAXXContext : seek in parent context if entry not found + * 20081102 [chemit] improve tests : + - fix the last failed test from Jaxx original version :) + - dumps tests to JUnit4 :) + * 20081030 [chemit] improve BeanValidator : + - add full PropertyChangeEvent java-bean support and a property valid + - when remove bean from validator, must remove errors from model + - make possible to have a dynamic errorListModel in jaxx files + * 20081030 [chemit] improve JAXXContext : + - fix setContextValue bug when setting twice a same type for a same key + - implements a DefaultJAXXContext + - use this default implementation with delegate pattern in JAXXObject + * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext + * 20081027 [chemit] fix bug 1722 + * 20081027 [chemit] add conversion support in validator + * 20081025 [chemit] improve BeanValidator tag : + - add a errorList attribute for set a ErrorListMouseListener on the errorList + - add a beanInitializer attribute for set the validator's bean at runtime + - add a default errorListModel value 'errors' + * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method + * 20081024 [chemit] fix validator context lost if UI is launched from another thread + ver-0-5 chemit 20081002 + * 20081017 [chemit] add validator support + * 20081013 [chemit] can generate logger on jaxx files + * 20081011 [chemit] improve site + * 20081011 [chemit] fix bug on JavaFileParser : works again + * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin + * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules) + * 20081002 [chemit] Introduce JAXXContext + * 20081002 [chemit] Fix bug on method creation via scripting + * 20081002 [chemit] Improve i18n integration (works now also for tabs) Added: lutinjaxx/branches/storm_1/jaxx-runtime-api/pom.xml =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/pom.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,66 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.codelutin</groupId> + <artifactId>lutinjaxx</artifactId> + <version>0.8-SNAPSHOT</version> + </parent> + + <artifactId>jaxx-runtime-api</artifactId> + + <dependencies> + + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + </dependency> + + <!-- pour utiliser javaHelp --> + <dependency> + <groupId>javax.help</groupId> + <artifactId>javahelp</artifactId> + </dependency> + + <dependency> + <groupId>org.swinglabs</groupId> + <artifactId>jxlayer</artifactId> + </dependency> + + <dependency> + <groupId>commons-jxpath</groupId> + <artifactId>commons-jxpath</artifactId> + </dependency> + + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + <name>jaxx-runtime-api</name> + <description>Jaxx runtime api</description> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + <packaging>jar</packaging> + + <build> + <defaultGoal>install</defaultGoal> + </build> + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + <scm> + <connection>${maven.scm.connection.child}</connection> + <developerConnection>${maven.scm.developerConnection.child}</developerConnection> + <url>${maven.scm.url.child}</url> + </scm> +</project> Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/Base64Coder.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/Base64Coder.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/Base64Coder.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/Base64Coder.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,240 @@ +package jaxx; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.util.zip.GZIPInputStream; +import java.util.zip.GZIPOutputStream; + +/** + * A Base64 Encoder/Decoder. + * <p/> + * <p/> + * This class is used to encode and decode data in Base64 format as described in RFC 1521. + * <p/> + * <p/> + * This is "Open Source" software and released under the <a href="http://www.gnu.org/licenses/lgpl.html">GNU/LGPL</a> license.<br> + * It is provided "as is" without warranty of any kind.<br> + * Copyright 2003: Christian d'Heureuse, Inventec Informatik AG, Switzerland.<br> + * Home page: <a href="http://www.source-code.biz">www.source-code.biz</a><br> + * <p/> + * <p/> + * Version history:<br> + * 2003-07-22 Christian d'Heureuse (chdh): Module created.<br> + * 2005-08-11 chdh: Lincense changed from GPL to LGPL.<br> + * 2006-11-21 chdh:<br> + * Method encode(String) renamed to encodeString(String).<br> + * Method decode(String) renamed to decodeString(String).<br> + * New method encode(byte[],int) added.<br> + * New method decode(String) added.<br> + */ + +public class Base64Coder { + + // Mapping table from 6-bit nibbles to Base64 characters. + private static char[] map1 = new char[64]; + + static { + int i = 0; + for (char c = 'A'; c <= 'Z'; c++) { + map1[i++] = c; + } + for (char c = 'a'; c <= 'z'; c++) { + map1[i++] = c; + } + for (char c = '0'; c <= '9'; c++) { + map1[i++] = c; + } + map1[i++] = '+'; + map1[i] = '/'; + } + + // Mapping table from Base64 characters to 6-bit nibbles. + private static byte[] map2 = new byte[128]; + + static { + for (int i = 0; i < map2.length; i++) { + map2[i] = -1; + } + for (int i = 0; i < 64; i++) { + map2[map1[i]] = (byte) i; + } + } + + /** + * Read the object from Base64 string. + * + * @param s the string representation of serialized object. + * @param gzip if gzip stream + * @return the deserialize object + * @throws java.io.IOException if any io pb + * @throws ClassNotFoundException if class not found ? + */ + public static Object deserialize(String s, boolean gzip) throws IOException, + ClassNotFoundException { + byte[] data = Base64Coder.decode(s); + InputStream stream = new ByteArrayInputStream(data); + if (gzip) { + stream = new GZIPInputStream(stream); + } + ObjectInputStream ois = new ObjectInputStream(stream); + Object o = ois.readObject(); + ois.close(); + return o; + } + + /** + * Write the object to a Base64 string. + * + * @param o the object to serialize + * @param gzip if gzip stream + * @return the string representation + * @throws java.io.IOException if any io pb + */ + public static String serialize(Object o, boolean gzip) throws IOException { + ByteArrayOutputStream stream = new ByteArrayOutputStream(); + ObjectOutputStream oos; + if (gzip) { + oos = new ObjectOutputStream(new GZIPOutputStream(stream)); + } else { + oos = new ObjectOutputStream(stream); + } + oos.writeObject(o); + oos.close(); + return new String(Base64Coder.encode(stream.toByteArray())); + } + + /** + * Encodes a string into Base64 format. + * No blanks or line breaks are inserted. + * + * @param s a String to be encoded. + * @return A String with the Base64 encoded data. + */ + public static String encodeString(String s) { + return new String(encode(s.getBytes())); + } + + /** + * Encodes a byte array into Base64 format. + * No blanks or line breaks are inserted. + * + * @param in an array containing the data bytes to be encoded. + * @return A character array with the Base64 encoded data. + */ + public static char[] encode(byte[] in) { + return encode(in, in.length); + } + + /** + * Encodes a byte array into Base64 format. + * No blanks or line breaks are inserted. + * + * @param in an array containing the data bytes to be encoded. + * @param iLen number of bytes to process in <code>in</code>. + * @return A character array with the Base64 encoded data. + */ + public static char[] encode(byte[] in, int iLen) { + int oDataLen = (iLen * 4 + 2) / 3; // output length without padding + int oLen = ((iLen + 2) / 3) * 4; // output length including padding + char[] out = new char[oLen]; + int ip = 0; + int op = 0; + while (ip < iLen) { + int i0 = in[ip++] & 0xff; + int i1 = ip < iLen ? in[ip++] & 0xff : 0; + int i2 = ip < iLen ? in[ip++] & 0xff : 0; + int o0 = i0 >>> 2; + int o1 = ((i0 & 3) << 4) | (i1 >>> 4); + int o2 = ((i1 & 0xf) << 2) | (i2 >>> 6); + int o3 = i2 & 0x3F; + out[op++] = map1[o0]; + out[op++] = map1[o1]; + out[op] = op < oDataLen ? map1[o2] : '='; + op++; + out[op] = op < oDataLen ? map1[o3] : '='; + op++; + } + return out; + } + + /** + * Decodes a string from Base64 format. + * + * @param s a Base64 String to be decoded. + * @return A String containing the decoded data. + * @throws IllegalArgumentException if the input is not valid Base64 encoded data. + */ + public static String decodeString(String s) { + return new String(decode(s)); + } + + /** + * Decodes a byte array from Base64 format. + * + * @param s a Base64 String to be decoded. + * @return An array containing the decoded data bytes. + * @throws IllegalArgumentException if the input is not valid Base64 encoded data. + */ + public static byte[] decode(String s) { + return decode(s.toCharArray()); + } + + /** + * Decodes a byte array from Base64 format. + * No blanks or line breaks are allowed within the Base64 encoded data. + * + * @param in a character array containing the Base64 encoded data. + * @return An array containing the decoded data bytes. + * @throws IllegalArgumentException if the input is not valid Base64 encoded data. + */ + public static byte[] decode(char[] in) { + int iLen = in.length; + if (iLen % 4 != 0) { + throw new IllegalArgumentException("Length of Base64 encoded input string is not a multiple of 4."); + } + while (iLen > 0 && in[iLen - 1] == '=') { + iLen--; + } + int oLen = (iLen * 3) / 4; + byte[] out = new byte[oLen]; + int ip = 0; + int op = 0; + while (ip < iLen) { + int i0 = in[ip++]; + int i1 = in[ip++]; + int i2 = ip < iLen ? in[ip++] : 'A'; + int i3 = ip < iLen ? in[ip++] : 'A'; + if (i0 > 127 || i1 > 127 || i2 > 127 || i3 > 127) { + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + } + int b0 = map2[i0]; + int b1 = map2[i1]; + int b2 = map2[i2]; + int b3 = map2[i3]; + if (b0 < 0 || b1 < 0 || b2 < 0 || b3 < 0) { + throw new IllegalArgumentException("Illegal character in Base64 encoded data."); + } + int o0 = (b0 << 2) | (b1 >>> 4); + int o1 = ((b1 & 0xf) << 4) | (b2 >>> 2); + int o2 = ((b2 & 3) << 6) | b3; + out[op++] = (byte) o0; + if (op < oLen) { + out[op++] = (byte) o1; + } + if (op < oLen) { + out[op++] = (byte) o2; + } + } + return out; + } + + // Dummy constructor. + private Base64Coder() { + } + +} // end class Base64Coder + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Rule.java (from rev 1097, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Rule.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Rule.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Rule.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,54 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.css; + +import java.util.Map; + +public class Rule implements java.io.Serializable, Comparable<Rule> { + public static final String INLINE_ATTRIBUTE = "<inline attribute>"; + public static final String DATA_BINDING = "<data binding>"; + + private Selector[] selectors; + private Map<String, String> properties; + private static final long serialVersionUID = 1L; + + + public Rule(Selector[] selectors, Map<String, String> properties) { + this.selectors = selectors; + java.util.Arrays.sort(selectors); + this.properties = properties; + } + + + public Rule(Selector[] selectors, String[] keys, String[] values) { + this.selectors = selectors; + java.util.Arrays.sort(selectors); + this.properties = new java.util.HashMap<String, String>(); + if (keys.length != values.length) { + throw new IllegalArgumentException("keys and values must have the same number of entries"); + } + for (int i = 0; i < keys.length; i++) { + properties.put(keys[i], values[i]); + } + } + + public Selector[] getSelectors() { + return selectors; + } + + public Map<String, String> getProperties() { + return properties; + } + + @Override + public int compareTo(Rule o) { + return selectors[0].compareTo(o.selectors[0]); // they are already sorted so we only need to compare the highest-ranked from each one + } + + @Override + public String toString() { + return "Rule[" + java.util.Arrays.asList(selectors) + ", " + properties + "]"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Selector.java (from rev 1097, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Selector.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Selector.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Selector.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,99 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.css; + +public class Selector implements java.io.Serializable, Comparable<Selector> { + public static final int NEVER_APPLIES = 0; + public static final int PSEUDOCLASS_APPLIES_INHERIT_ONLY = 1; + public static final int PSEUDOCLASS_APPLIES = 2; + public static final int ALWAYS_APPLIES_INHERIT_ONLY = 3; + public static final int ALWAYS_APPLIES = 4; + + private String javaClassName; + private String styleClass; + private String pseudoClass; + private String id; + private boolean inline; + private static final long serialVersionUID = 1L; + + + public Selector(String javaClassName, String styleClass, String pseudoClass, String id) { + this(javaClassName, styleClass, pseudoClass, id, false); + } + + + public Selector(String javaClassName, String styleClass, String pseudoClass, String id, boolean inline) { + this.javaClassName = javaClassName; + this.styleClass = styleClass; + this.pseudoClass = pseudoClass; + this.id = id; + this.inline = inline; + } + + + public String getJavaClassName() { + return javaClassName; + } + + + public String getStyleClass() { + return styleClass; + } + + + public String getPseudoClass() { + return pseudoClass; + } + + + public String getId() { + return id; + } + + + public boolean isInline() { + return inline; + } + + @Override + public int compareTo(Selector selector) { + if (inline && !selector.inline) { + return 1; + } + if (!inline && selector.inline) { + return -1; + } + if (pseudoClass != null && selector.pseudoClass == null) { + return 1; + } + if (pseudoClass == null && selector.pseudoClass != null) { + return -1; + } + if (id != null && selector.id == null) { + return 1; + } + if (id == null && selector.id != null) { + return -1; + } + if (styleClass != null && selector.styleClass == null) { + return 1; + } + if (styleClass == null && selector.styleClass != null) { + return -1; + } + if (javaClassName != null && selector.javaClassName == null) { + return 1; + } + if (javaClassName == null && selector.javaClassName != null) { + return -1; + } + return 0; + } + + @Override + public String toString() { + return "Selector[" + javaClassName + ", " + styleClass + ", " + pseudoClass + ", " + id + "]"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Stylesheet.java (from rev 1097, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Stylesheet.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/css/Stylesheet.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,45 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.css; + +public class Stylesheet implements java.io.Serializable { + private Rule[] rules; + private static final long serialVersionUID = 1L; + + + public Stylesheet() { + rules = new Rule[0]; + } + + public Stylesheet(Rule[] rules) { + this.rules = rules; + java.util.Arrays.sort(rules); + } + + public Rule[] getRules() { + return rules; + } + + public void add(Rule newRule) { + Rule[] oldRules = rules; + rules = new Rule[oldRules.length + 1]; + System.arraycopy(oldRules, 0, rules, 0, oldRules.length); + rules[rules.length - 1] = newRule; + java.util.Arrays.sort(rules); + } + + public void add(Rule[] newRules) { + Rule[] oldRules = rules; + rules = new Rule[oldRules.length + newRules.length]; + System.arraycopy(oldRules, 0, rules, 0, oldRules.length); + System.arraycopy(newRules, 0, rules, oldRules.length, newRules.length); + java.util.Arrays.sort(rules); + } + + @Override + public String toString() { + return "Stylesheet" + java.util.Arrays.asList(rules); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/ComponentDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/ComponentDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/ComponentDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/ComponentDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,49 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime; + +import java.io.Serializable; + +public class ComponentDescriptor implements Serializable { + String id; + String javaClassName; + String styleClass; + ComponentDescriptor parent; + private static final long serialVersionUID = 1L; + + + public ComponentDescriptor(String id, String javaClassName, String styleClass, ComponentDescriptor parent) { + this.id = id; + this.javaClassName = javaClassName; + this.styleClass = styleClass; + this.parent = parent; + } + + + public String getId() { + return id; + } + + + public String getJavaClassName() { + return javaClassName; + } + + + public String getStyleClass() { + return styleClass; + } + + + public ComponentDescriptor getParent() { + return parent; + } + + + @Override + public String toString() { + return "ComponentDescriptor[" + id + ", " + javaClassName + ", " + styleClass + "]"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingListener.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/DataBindingListener.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingListener.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingListener.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,46 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + + +/** + * A <code>PropertyChangeListener</code> which processes a data binding when it receives a + * <code>PropertyChangeEvent</code>. + */ +public class DataBindingListener implements PropertyChangeListener { + private JAXXObject object; + private String dest; + + /** + * Creates a new <code>DataBindingListener</code> which will run the given data binding + * when it receives a <code>PropertyChangeEvent</code>. + * + * @param object the object in which the data binding exists + * @param dest the name of the data binding to run + */ + public DataBindingListener(JAXXObject object, String dest) { + this.object = object; + this.dest = dest; + } + + + /** + * Processes the data binding in response to a <code>PropertyChangeEvent</code>. + * + * @param e the event which triggered the binding + */ + public void propertyChange(PropertyChangeEvent e) { + object.processDataBinding(dest); + + // for now, handle dependency changes by always removing & reapplying + // the binding. We should be more efficient and only do this when it's + // actually necessary + object.removeDataBinding(dest); + object.applyDataBinding(dest); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingUpdateListener.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/DataBindingUpdateListener.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingUpdateListener.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DataBindingUpdateListener.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,46 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime; + +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + + +/** + * A <code>PropertyChangeListener</code> which removes and re-applies a data binding + * when it receives a <code>PropertyChangeEvent</code>. + */ +public class DataBindingUpdateListener implements PropertyChangeListener { + private JAXXObject object; + private String dest; + + /** + * Creates a new <code>DataBindingUpdateListener</code> which will remove and re-apply a + * data binding when it receives a <code>PropertyChangeEvent</code>. + * + * @param object the object in which the data binding exists + * @param dest the name of the data binding to reapply + */ + public DataBindingUpdateListener(JAXXObject object, String dest) { + this.object = object; + this.dest = dest; + } + + + public String getBindingName() { + return dest; + } + + + /** + * Updates the data binding in response to a <code>PropertyChangeEvent</code>. + * + * @param e the event which triggered the binding + */ + public void propertyChange(PropertyChangeEvent e) { + object.removeDataBinding(dest); + object.applyDataBinding(dest); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Decorator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Decorator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,35 @@ +package jaxx.runtime; + +/** + * A simple contract to define a String decorator on any java objet. + * + * @author chemit + */ +public abstract class Decorator<O> implements java.io.Serializable { + + protected final Class<O> internalClass; + private static final long serialVersionUID = -1L; + + /** + * @param internalClass the class of objects to be decorated. + * @throws NullPointerException if internalClass parameter is null + */ + public Decorator(Class<O> internalClass) throws NullPointerException { + if (internalClass == null) { + throw new NullPointerException("internalClass can not be null."); + } + this.internalClass = internalClass; + } + + /** + * @param bean the bean to decorate + * @return the string value of the given bean + */ + public abstract String toString(Object bean); + + + public final Class<O> getInternalClass() { + return internalClass; + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/DefaultJAXXContext.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/DefaultJAXXContext.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,188 @@ +package jaxx.runtime; + +import static jaxx.runtime.JAXXContextEntryDef.newDef; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.awt.Container; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +/** + * The default {@link JAXXContext} to be used in a {@link JAXXObject} by delegation. + * <p/> + * The values are store in a {@link Map} but we can not use directly the values as key. + * <p/> + * Because, it does not work if we add for the same object multi entries (named and unamed)... + * <p/> + * We prefer use as entry the {@link JAXXContextEntryDef} associated with the value. + * + * @author chemit + */ +public class DefaultJAXXContext implements JAXXContext { + + protected static final JAXXContextEntryDef<JAXXContext> PARENT_CONTEXT_ENTRY = newDef(JAXXContext.class); + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(DefaultJAXXContext.class); + + /** l'ui auquel est rattache le context */ + protected JAXXObject ui; + + /** le context parent */ + protected JAXXContext parentContext; + + /** les données contenues dans le context */ + protected final Map<JAXXContextEntryDef, Object> data; + + public DefaultJAXXContext() { + data = new HashMap<JAXXContextEntryDef, Object>(); + } + + public DefaultJAXXContext(JAXXObject ui) { + this(); + this.ui = ui; + } + + public <T> void setContextValue(T o) { + setContextValue(o, null); + } + + public <T> void setContextValue(T o, String name) { + if (name == null && PARENT_CONTEXT_ENTRY.accept2(o.getClass(), null)) { + setParentContext((JAXXContext) o); + return; + } + JAXXContextEntryDef<?> entry = getKey(name, o.getClass()); + // first remove entry + Object oldValue = remove0(o.getClass(), name); + if (oldValue != null) { + if (log.isDebugEnabled()) { + log.debug("remove value " + oldValue.getClass() + " for " + entry); + } + } + // then can put safely + data.put(entry, o); + } + + public <T> T getContextValue(Class<T> clazz) { + return getContextValue(clazz, null); + } + + @SuppressWarnings({"unchecked"}) + public <T> T getContextValue(Class<T> clazz, String name) { + if (PARENT_CONTEXT_ENTRY.accept(clazz, name)) { + return (T) getParentContext(); + } + for (Entry<JAXXContextEntryDef, Object> entry : data.entrySet()) { + if (entry.getKey().accept(clazz, name)) { + return (T) entry.getValue(); + } + } + + // no value found in this context, will try in the parent context + if (JAXXContext.class == clazz) { + // no seek in the parent context, since we are already looking for it + return null; + } + + JAXXContext parentContext = getParentContext(); + if (parentContext == null) { + // no parent context, so no value find + return null; + } + // seek in parent context + return parentContext.getContextValue(clazz, name); + } + + public <T> void removeContextValue(Class<T> klazz) { + removeContextValue(klazz, null); + } + + public <T> void removeContextValue(Class<T> klazz, String name) { + remove0(klazz, name); + } + + public <O extends Container> O getParentContainer(Class<O> clazz) { + return this.getParentContainer(ui, clazz); + } + + @SuppressWarnings({"unchecked"}) + public <O extends Container> O getParentContainer(Object top, Class<O> clazz) { + if (ui == null) { + throw new IllegalStateException("no ui attached to this context"); + } + if (top == null) { + throw new IllegalArgumentException("top parameter can not be null"); + } + if (!Container.class.isAssignableFrom(top.getClass())) { + throw new IllegalArgumentException("top parameter " + top + " is not a " + Container.class); + } + Container parent = ((Container) top).getParent(); + if (parent != null && !clazz.isAssignableFrom(parent.getClass())) { + parent = getParentContainer(parent, clazz); + } + return (O) parent; + } + + protected JAXXObject getUi() { + return ui; + } + + protected void setUi(JAXXObject ui) { + this.ui = ui; + } + + protected JAXXContextEntryDef<?> getKey(String name, Class<?> klass) { + return JAXXContextEntryDef.newDef(name, klass); + } + + @SuppressWarnings({"unchecked"}) + protected <T> T remove0(Class<T> klazz, String name) { + if (PARENT_CONTEXT_ENTRY.accept(klazz, name)) { + JAXXContext old = getParentContext(); + setParentContext(null); + return (T) old; + } + JAXXContextEntryDef entry = null; + for (JAXXContextEntryDef entryDef : data.keySet()) { + if (entryDef.accept(klazz, name)) { + entry = entryDef; + break; + } + } + if (entry != null) { + return (T) data.remove(entry); + } + + if (JAXXContext.class == klazz) { + return null; + } + // try in parentContext + JAXXContext parentContext = getParentContext(); + + if (parentContext == null) { + return null; + } + + if (parentContext instanceof DefaultJAXXContext) { + return ((DefaultJAXXContext) parentContext).remove0(klazz, name); + } + + return null; + } + + protected JAXXContext getParentContext() { + return parentContext; + } + + protected void setParentContext(JAXXContext parentContext) { + if (parentContext instanceof JAXXObject) { + // keep the real context, not the ui + parentContext = ((JAXXObject) parentContext).getDelegateContext(); + } + this.parentContext = parentContext; + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXAction.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXAction.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXAction.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXAction.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,19 @@ +package jaxx.runtime; + +/** + * This is the contract to be realized by any class to be used as Action class for an ui. + * + * @author chemit + */ +public interface JAXXAction { + + /** + * Prepare the initial context of the ui. + * + * @param parentContent the context of the parent of the ui (can be null if no parent is required) + * @param datas other datas to inject in initial context + * @return the {@link jaxx.runtime.JAXXInitialContext} to be injected in the ui via the constructor of the {@link jaxx.runtime.JAXXObject} + */ + JAXXInitialContext init(JAXXContext parentContent, Object... datas); + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContext.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXContext.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContext.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContext.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,99 @@ +package jaxx.runtime; + +import java.awt.Container; + +/** + * The {@link jaxx.runtime.JAXXContext} contract defines a generic context. + * <p/> + * A context contains two king of entries : + * <p/> + * <h2>Unamed entry</h2> + * a such entry maps filter only on the clas of the object of the entry. + * <p/> + * To add a <b>unamed</b> entry, use {@link #setContextValue(Object)} and {@link #getContextValue(Class)} to reteave a + * such entry. + * <p/> + * <h2>named entry</h2> + * a such entry filter on class of the object and on the name of the entry. + * <p/> + * To add a <b>named</b> entry, use {@link #setContextValue(Object,String)} and {@link #getContextValue(Class,String)} + * to reteave a such entry. + * + * @author letellier + * @author chemit + */ +public interface JAXXContext { + + /** + * Push in the context a new unamed entry. + * <p/> + * If a previous entry exists in context (unamed and same class), it will be removed. + * + * @param o the value to push in context + */ + public <T> void setContextValue(T o); + + /** + * * Push in the context a new amed entry. + * <p/> + * If a previous entry exists in context (same name and class), it will be removed. + * + * @param o the value to push in context + * @param name the name of the new entry + */ + public <T> void setContextValue(T o, String name); + + /** + * Remove from context the value with the given klazz as an unamed entry + * + * @param klazz the klazz entry + */ + public <T> void removeContextValue(Class<T> klazz); + + /** + * Remove from context the value with the given klazz as an unamed (if name is null) or named entry + * + * @param klazz the klazz entry + * @param name extra name of the entry + */ + + public <T> void removeContextValue(Class<T> klazz, String name); + + /** + * Seek for a unamed entry in the context + * <p/> + * This is an exemple to call a method in JAXX : + * <p/> + * <code><JButton onActionPerformed='{getContextValue(Action.class).method(args[])}'/></code> + * + * @param clazz the class of unamed entry to seek in context + * @return the value of the unamed entry for the given class, or <code>null</code> if no such entry. + */ + public <T> T getContextValue(Class<T> clazz); + + /** + * Seek for a named entry in the context + * + * @param clazz the class of named entry to seek in context + * @param name the name of the entry to seek in context + * @return the value of the named entry for the given class, or <code>null</code> if no such entry. + */ + public <T> T getContextValue(Class<T> clazz, String name); + + /** + * Return parent's container corresponding to the Class clazz + * + * @param clazz clazz desired + * @return parent's container + */ + public <O extends Container> O getParentContainer(Class<O> clazz); + + /** + * Return parent's container corresponding to the Class clazz + * + * @param top the top container + * @param clazz desired + * @return parent's container + */ + public <O extends Container> O getParentContainer(Object top, Class<O> clazz); +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContextEntryDef.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXContextEntryDef.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContextEntryDef.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXContextEntryDef.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,118 @@ +package jaxx.runtime; + +import java.util.Collections; +import java.util.List; + +/** + * To qualify an entry in a {@link JAXXContext}. + * <p/> + * Use the factory methods <code>newDef</code> and <code>newListDef</code< to obtain new instances. + * + * @author chemit + */ +public class JAXXContextEntryDef<O> implements java.io.Serializable { + + /** name of the entry, can be nuill for a unamed entry. */ + protected String name; + + /** class of the entry, can not be null */ + protected Class<O> klass; + + private static final long serialVersionUID = 1L; + + public static <O> JAXXContextEntryDef<O> newDef(Class<O> klass) { + return newDef(null, klass); + } + + public static <O> JAXXContextEntryDef<O> newDef(String name, Class<O> klass) { + return new JAXXContextEntryDef<O>(name, klass); + } + + public static <O> JAXXContextEntryDef<List<O>> newListDef() { + return newListDef(null); + } + + @SuppressWarnings({"unchecked"}) + public static <O> JAXXContextEntryDef<List<O>> newListDef(String name) { + JAXXContextEntryDef contextEntryDef = new JAXXContextEntryDef<List<O>>(name, JAXXContextEntryDef.<O>castList()); + contextEntryDef.klass = List.class; + return contextEntryDef; + } + + + public String getName() { + return name; + } + + public Class<O> getKlass() { + return klass; + } + + public O getContextValue(JAXXContext context) { + return context.getContextValue(klass, name); + } + + public void removeContextValue(JAXXContext context) { + context.removeContextValue(klass, name); + } + + public void setContextValue(JAXXContext context, O value) { + context.setContextValue(value, name); + } + + @Override + public String toString() { + return super.toString() + "<" + klass + ":" + name + ">"; + } + + protected JAXXContextEntryDef(Class<O> klass) { + this(null, klass); + } + + protected JAXXContextEntryDef(String name, Class<O> klass) { + if (klass == null) { + throw new IllegalArgumentException("class can not be null"); + } + this.name = name; + this.klass = klass; + } + + @SuppressWarnings({"unchecked"}) + protected static <O> Class<List<O>> castList() { + return (Class<List<O>>) Collections.emptyList().getClass(); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof JAXXContextEntryDef)) { + return false; + } + JAXXContextEntryDef that = (JAXXContextEntryDef) o; + return klass.equals(that.klass) && !(name != null ? !name.equals(that.name) : that.name != null); + + } + + @Override + public int hashCode() { + int result = (name != null ? name.hashCode() : 0); + return 31 * result + klass.hashCode(); + } + + public boolean accept(Class<?> klass, String name) { + if (klass == Object.class && this.klass != Object.class) { + // try on name only + return (this.name != null && name != null && this.name.equals(name)); + } + return klass.isAssignableFrom(this.klass) && (this.name == null && name == null + || (this.name != null && name != null && this.name.equals(name))); + } + + public boolean accept2(Class<?> klass, String name) { + return !(klass == Object.class && this.klass != Object.class) && + this.klass.isAssignableFrom(klass) && (this.name == null && + name == null || (this.name != null && name != null && this.name.equals(name))); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXInitialContext.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXInitialContext.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXInitialContext.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXInitialContext.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,93 @@ +package jaxx.runtime; + +import java.awt.Container; +import java.util.Map.Entry; + +/** + * An initial context to be inject in a {@link JAXXObject}. + * <p/> + * The method {@link #add(Object)} register a simple value. + * <p/> + * The method {@link #add(String, Object)} register a named value. + * <p/> + * The method {@link #to(JAXXContext)} inject in the {@link JAXXObject} the values registred in the initial context. + * <p/> + * The initial context is also a "limited" {@link JAXXContext}, since we can only use the two methods + * <p/> + * {@link #getContextValue(Class)} or {@link #getContextValue(Class, String)}. + * + * @see JAXXContext + */ +public class JAXXInitialContext extends DefaultJAXXContext { + + public JAXXInitialContext() { + super(); + } + + /** + * Register a simple (none named) value in the context. + * + * @param value the value to be registred in the context + * @return the instance of the context + */ + public JAXXInitialContext add(Object value) { + return add(null, value); + } + + /** + * Register a named value in the context. + * + * @param name the name of the value + * @param value the value to registred + * @return the instance of the context + */ + public JAXXInitialContext add(String name, Object value) { + super.setContextValue(value, name); + return this; + } + + /** + * Inject all the registed values into the {@link JAXXObject} + * + * @param dst the object to fill. + */ + public void to(JAXXContext dst) { + if (parentContext != null) { + dst.setContextValue(parentContext); + } + for (Entry<JAXXContextEntryDef, Object> entry : data.entrySet()) { + dst.setContextValue(entry.getValue(), entry.getKey().getName()); + } + } + + @Override + public void setContextValue(Object o) { + throw new RuntimeException("not implemented"); + } + + @Override + public void setContextValue(Object o, String name) { + throw new RuntimeException("not implemented"); + } + + @Override + public <T> void removeContextValue(Class<T> klazz) { + throw new RuntimeException("not implemented"); + } + + @Override + public <T> void removeContextValue(Class<T> klazz, String name) { + throw new RuntimeException("not implemented"); + } + + @Override + public <O extends Container> O getParentContainer(Class<O> clazz) { + throw new RuntimeException("not implemented"); + } + + @Override + public <O extends Container> O getParentContainer(Object top, Class<O> clazz) { + throw new RuntimeException("not implemented"); + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObject.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXObject.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObject.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObject.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,52 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime; + +/** The <code>JAXXObject</code> interface is implemented by all classes produced by the JAXX compiler. */ +public interface JAXXObject extends JAXXContext { + /** + * Retrieves an object defined in an XML tag by its ID. + * + * @param id the id of the component to retrieve + * @return the object + */ + public Object getObjectById(String id); + + /** + * Pretrieves the dictonary of knwon objects indexed by their ids. + * + * @return the dictonary of objects. + */ + public java.util.Map<String, Object> get$objectMap(); + + public void applyDataBinding(String id); + + + public void removeDataBinding(String id); + + public jaxx.runtime.JAXXContext getDelegateContext(); + + /** + * Processes a data binding by name. Data binding names are comprised of an object ID and a property name: + * for example, the data binding in the tag <code><JLabel id='label' text='{foo.getText()}'/></code> is + * named <code>"label.text"</code>. Processing a data binding causes it to reevaluate its expression, in this + * case <code>foo.getText()</code>. + * + * @param dest the name of the data binding to run + */ + public void processDataBinding(String dest); + + + /** + * All <code>JAXXObject</code> implements are capable of broadcasting <code>PropertyChangeEvent</code>, and + * furthermore (for technical reasons) must allow code in outside packages, specifically the JAXX runtime, + * to trigger these events. + * + * @param name the name of the property which changed + * @param oldValue the old value of the property + * @param newValue the new value of the property + */ + public void firePropertyChange(String name, Object oldValue, Object newValue); +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JAXXObjectDescriptor.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,42 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime; + +import jaxx.css.Stylesheet; + +import java.io.Serializable; + +public class JAXXObjectDescriptor implements Serializable { + private ComponentDescriptor[] descriptors; + private Stylesheet stylesheet; + private static final long serialVersionUID = 1L; + + + public JAXXObjectDescriptor(ComponentDescriptor[] descriptors, + Stylesheet stylesheet) { + this.descriptors = descriptors; + this.stylesheet = stylesheet; + } + + + public ComponentDescriptor[] getComponentDescriptors() { + return descriptors; + } + + + public Stylesheet getStylesheet() { + return stylesheet; + } + + @Override + public String toString() { + StringBuilder buffer = new StringBuilder(); + for (ComponentDescriptor descriptor : descriptors) { + buffer.append("\n").append(descriptor); + } + buffer.append("\n").append(stylesheet); + return buffer.toString(); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JXPathDecorator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/JXPathDecorator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,273 @@ +package jaxx.runtime; + +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * JXPath decorator based on {@link String#format(String, Object[])} method. + * <p/> + * To use it, give to him a expression where all jxpath to apply on bean are boxed in <code>${}</code>. + * <p/> + * After the jxpath token you must specifiy the formatter to apply of the jxpath token. + * <p/> + * For example : + * <pre> + * Decorator<Object> d = JXPathDecorator.newDecorator(JXPathDecorator.class,"expr = ${expressions}$s"); + * assert "expr = %1$s" == d.getExpression(); + * assert 1 == d.getNbToken(); + * assert java.util.Arrays.asList("expression") == d.getTokens(); + * assert "expr = %1$s" == d.toString(d); + * </pre> + * + * @author chemit + * @see Decorator + */ +public class JXPathDecorator<O> extends Decorator<O> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static final Log log = LogFactory.getLog(JXPathDecorator.class); + + private static final long serialVersionUID = 1L; + + /** + * Factory method to instanciate a new {@link JXPathDecorator} for the given class {@link O} and expression. + * + * @param internalClass the class of the objects decorated by the new decorator + * @param expression the expression to use to decorated objects + * @param <O> the generic type of class to be decorated by the new decorator + * @return the new instanciated decorator + * @throws IllegalArgumentException if the expression is not valid, says: + * <p/> + * - a missing right brace was detected. + * <p/> + * - a ${ was found in a jxpath token. + * @throws NullPointerException if internalClass parameter is null. + */ + public static <O> JXPathDecorator<O> newDecorator(Class<O> internalClass, String expression) + throws IllegalArgumentException, NullPointerException { + return new JXPathDecorator<O>(internalClass, expression, true); + } + + /** + * Sort a list of data based on the first token property of a given context + * in a given decorator. + * + * @param decorator the decorator to use to sort + * @param datas the list of data to sort + * @param pos the index of context to used in decorator to obtain sorted property. + */ + public static <O> void sort(JXPathDecorator<O> decorator, List<O> datas, int pos) { + Comparator<O> c = decorator.getComparator(pos); + boolean cachedComparator = c instanceof JXPathComparator; + try { + if (cachedComparator) { + ((JXPathComparator<O>) c).init(decorator, datas); + } + Collections.sort(datas, c); + } finally { + if (cachedComparator) { + ((JXPathComparator) c).clear(); + } + } + } + + public static class JXPathComparator<O> implements Comparator<O> { + + protected Map<O, Comparable<Comparable>> valueCache; + + private final String expression; + + public JXPathComparator(String expression) { + this.expression = expression; + this.valueCache = new HashMap<O, Comparable<Comparable>>(); + } + + @Override + public int compare(O o1, O o2) { + Comparable<Comparable> c1 = valueCache.get(o1); + Comparable<Comparable> c2 = valueCache.get(o2); + return c1.compareTo(c2); + } + + public void clear() { + valueCache.clear(); + } + + public void init(JXPathDecorator<O> decorator, List<O> datas) { + clear(); + for (O data : datas) { + JXPathContext jxcontext = JXPathContext.newContext(data); + Comparable<Comparable> key = decorator.getTokenValue(jxcontext, expression); + valueCache.put(data, key); + } + } + } + + public static class Context<O> implements java.io.Serializable { + + /** + * expression to format using {@link String#format(String, Object[])}, all variables are compute + * using using the jxpath tokens. + */ + protected String expression; + + /** list of jxpath tokens to apply on expression */ + protected String[] tokens; + + protected transient Comparator<O> comparator; + + private static final long serialVersionUID = 1L; + + public Context(String expression, String[] tokens) { + this.expression = expression; + this.tokens = tokens; + } + + public String getFirstProperty() { + return tokens[0]; + } + + public Comparator<O> getComparator(int pos) { + if (comparator == null) { + comparator = new JXPathComparator<O>(tokens[pos]); + } + return comparator; + } + + public void setComparator(Comparator<O> comparator) { + this.comparator = comparator; + } + + @Override + public String toString() { + return "<expression:" + expression + ", tokens:" + Arrays.toString(tokens) + ">"; + } + } + + /** the computed context of the decorator */ + protected Context<O> context; + + /** nb jxpath tokens to compute */ + protected int nbToken; + + /** the initial expression used to compute the decorator context. */ + protected String initialExpression; + + public String toString(Object bean) { + if (bean == null) { + return null; + } + JXPathContext jxcontext = JXPathContext.newContext(bean); + Object[] args = new Object[nbToken]; + for (int i = 0; i < nbToken; i++) { + args[i] = getTokenValue(jxcontext, context.tokens[i]); + } + return String.format(context.expression, args); + } + + @SuppressWarnings({"unchecked"}) + protected Comparable<Comparable> getTokenValue(JXPathContext jxcontext, String token) { + // assume all values are comparable + return (Comparable<Comparable>) jxcontext.getValue(token); + } + + public String getProperty(int pos) { + return getTokens()[pos]; + } + + public String getExpression() { + return context.expression; + } + + public String[] getTokens() { + return context.tokens; + } + + public int getNbToken() { + return nbToken; + } + + public String getInitialExpression() { + return initialExpression; + } + + @Override + public String toString() { + return super.toString() + "<" + context + ">"; + } + + public void setContext(Context<O> context) { + this.context = context; + this.nbToken = context.tokens.length; + // always reset comparator + //this.context.comparator = null; + if (log.isDebugEnabled()) { + log.debug(context); + } + } + + public JXPathDecorator(Class<O> internalClass, String expression, boolean creatContext) throws IllegalArgumentException, NullPointerException { + super(internalClass); + this.initialExpression = expression; + if (creatContext) { + setContext(JXPathDecorator.<O>createInitialContext(expression)); + if (log.isDebugEnabled()) { + log.debug(expression + " --> " + this.context); + } + } + } + + @SuppressWarnings({"unchecked"}) + protected Comparator<O> getComparator(int pos) { + ensureTokenIndex(this, pos); + return context.getComparator(pos); + } + + public static <O> Context<O> createInitialContext(String expression) { + List<String> lTokens = new ArrayList<String>(); + StringBuilder buffer = new StringBuilder(); + int size = expression.length(); + int end = -1; + int start; + while ((start = expression.indexOf("${", end + 1)) > -1) { + if (start > end + 1) { + // prefix of next jxpath token + buffer.append(expression.substring(end + 1, start)); + } + // seek end of jxpath + end = expression.indexOf("}", start + 1); + if (end == -1) { + throw new IllegalArgumentException("could not find the rigth brace starting at car " + start + " : " + expression.substring(start + 2)); + } + String jxpath = expression.substring(start + 2, end); + // not allowed ${ inside a jxpath token + if (jxpath.indexOf("${") > -1) { + throw new IllegalArgumentException("could not find a ${ inside a jxpath expression at car " + (start + 2) + " : " + jxpath); + } + // save the jxpath token + lTokens.add(jxpath); + // replace jxpath token in expresion with a string format variable + buffer.append("%").append(lTokens.size()); + } + if (size > (end + 1)) { + // suffix after end jxpath (or all expression if no jxpath) + buffer.append(expression.substring(end + 1)); + } + return new Context<O>(buffer.toString(), lTokens.toArray(new String[lTokens.size()])); + } + + protected static void ensureTokenIndex(JXPathDecorator decorator, int pos) { + if (pos < -1 || pos > decorator.getNbToken()) { + throw new ArrayIndexOutOfBoundsException("token index " + pos + " is out of bound, can be inside [" + 0 + "," + decorator.nbToken + "]"); + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/MultiJXPathDecorator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/MultiJXPathDecorator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/MultiJXPathDecorator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/MultiJXPathDecorator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,128 @@ +package jaxx.runtime; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.util.ArrayList; +import java.util.Comparator; +import java.util.List; +import java.util.StringTokenizer; + +/** + * TODO + * + * @author chemit + * @see jaxx.runtime.Decorator + */ +public class MultiJXPathDecorator<O> extends JXPathDecorator<O> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static final Log log = LogFactory.getLog(MultiJXPathDecorator.class); + + private static final long serialVersionUID = 1L; + + public static <O> MultiJXPathDecorator<O> newDecorator(Class<O> internalClass, + String expression, + String separator) + throws IllegalArgumentException, NullPointerException { + + return newDecorator(internalClass, expression, separator, separator); + } + + public static <O> MultiJXPathDecorator<O> newDecorator(Class<O> internalClass, + String expression, + String separator, + String separatorReplacement) + throws IllegalArgumentException, NullPointerException { + + Context<O>[] contexts = createInitialContexts(expression, separator, separatorReplacement); + + return new MultiJXPathDecorator<O>(internalClass, expression, separator, separatorReplacement, contexts); + } + + protected Context<O>[] contexts; + protected String separator; + protected String separatorReplacement; + + + public MultiJXPathDecorator(Class<O> internalClass, String expression, + String separator, String separatorReplacement, + Context<O>[] contexts) throws IllegalArgumentException, NullPointerException { + super(internalClass, expression, false); + this.separator = separator; + this.separatorReplacement = separatorReplacement; + this.contexts = contexts; + + setContextIndex(0); + + if (log.isDebugEnabled()) { + log.debug(expression + " --> " + this.context); + } + } + + public void setContextIndex(int index) { + ensureContextIndex(this, index); + setContext(contexts[index]); + } + + public int getNbContext() { + return contexts.length; + } + + public String getSeparator() { + return separator; + } + + public String getSeparatorReplacement() { + return separatorReplacement; + } + + @Override + protected Comparator<O> getComparator(int pos) { + ensureContextIndex(this, pos); + Context<O> context1 = contexts[pos]; + return context1.getComparator(0); + } + + public static <O> Context<O>[] createInitialContexts(String expression, String separator, String separatorReplacement) { + int sep = expression.indexOf(separator); + if (sep == -1) { + Context<O>[] result = MultiJXPathDecorator.newInstance(1); + result[0] = createInitialContext(expression); + return result; + } + + List<String> tokens = new ArrayList<String>(); + StringTokenizer stk = new StringTokenizer(expression, separator); + while (stk.hasMoreTokens()) { + tokens.add(stk.nextToken()); + } + + int nbTokens = tokens.size(); + Context<O>[] contexts = newInstance(nbTokens); + for (int i = 0; i < nbTokens; i++) { + StringBuilder buffer = new StringBuilder(expression.length()); + for (int j = 0; j < nbTokens; j++) { + int index = (i + j) % nbTokens; + String str = tokens.get(index); + //todo replace %index with %j + buffer.append(separatorReplacement).append(str); + } + contexts[i] = createInitialContext(buffer.substring(separatorReplacement.length())); + } + return contexts; + } + + protected static void ensureContextIndex(MultiJXPathDecorator decorator, int pos) { + if (pos < -1 || pos > decorator.contexts.length) { + throw new ArrayIndexOutOfBoundsException("context index " + pos + " is out of bound, can be inside [" + 0 + "," + decorator.contexts.length + "]"); + } + } + + @SuppressWarnings({"unchecked"}) + protected static <O> Context<O>[] newInstance(int size) { + // fixme how to instanciate a typed array with no checking warning ? + return new Context[size]; + } + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/MultiJXPathDecorator.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/PropertyDecorator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/PropertyDecorator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/PropertyDecorator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/PropertyDecorator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,92 @@ +package jaxx.runtime; + +import org.apache.commons.beanutils.PropertyUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; + +/** + * Simple property decorator based on {@link String#format(String, Object[])} method. + * <p/> + * To use it, give him a class and the property name to render. + * <p/> + * For example : + * <pre> + * Decorator<Object> d = PropertyDecorator.newDecorator(PropertyDecorator.class,"expressions"); + * </pre> + * + * @author chemit + * @see Decorator + */ +public class PropertyDecorator<O> extends Decorator<O> { + + private static final long serialVersionUID = 1L; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(PropertyDecorator.class); + + /** + * Factory method to instanciate a new {@link jaxx.runtime.PropertyDecorator} for the given class {@link O} and a + * readable property name. + * + * @param internalClass the class of the objects decorated by the new decorator + * @param property the property + * @param <O> the generic type of class to be decorated by the new decorator + * @return the new instanciated decorator + * @throws IllegalArgumentException if the expression is not valid, says: + * <p/> + * - a missing right brace was detected. + * <p/> + * - a ${ was found in a jxpath token. + * @throws NullPointerException if internalClass parameter is null. + */ + public static <O> PropertyDecorator<O> newDecorator(Class<O> internalClass, String property) + throws IllegalArgumentException, NullPointerException { + return new PropertyDecorator<O>(internalClass, property); + } + + protected String property; + + protected transient Method m; + + public String toString(Object bean) { + try { + return getM().invoke(bean) + ""; + } catch (Exception e) { + log.error("could not convert for reason : " + e, e); + return ""; + } + } + + public String getProperty() { + return property; + } + + protected PropertyDecorator(Class<O> internalClass, String property) throws NullPointerException { + super(internalClass); + if (property == null) { + throw new NullPointerException("property can not be null."); + } + this.property = property; + // init method + getM(); + } + + + protected Method getM() { + if (m == null) { + for (PropertyDescriptor propertyDescriptor : PropertyUtils.getPropertyDescriptors(internalClass)) { + if (propertyDescriptor.getName().equals(property)) { + this.m = propertyDescriptor.getReadMethod(); + break; + } + } + if (m == null) { + throw new IllegalArgumentException("could not find the property " + property + " in " + internalClass); + } + } + return m; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Util.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/Util.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Util.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/Util.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,454 @@ +package jaxx.runtime; + +import jaxx.Base64Coder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.jxlayer.JXLayer; + +import javax.swing.DefaultListCellRenderer; +import javax.swing.JComponent; +import javax.swing.JList; +import javax.swing.ImageIcon; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.IOException; +import java.lang.ref.WeakReference; +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.EventListener; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import java.util.WeakHashMap; + +public class Util { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(Util.class); + + + // Maps root objects to lists of event listeners + private static Map<Object, WeakReference<List<EventListenerDescriptor>>> eventListeners = new WeakHashMap<Object, WeakReference<List<EventListenerDescriptor>>>(); + private static Map<JAXXObject, WeakReference<List<DataBindingUpdateListener>>> dataBindingUpdateListeners = new WeakHashMap<JAXXObject, WeakReference<List<DataBindingUpdateListener>>>(); + + + private static class EventListenerDescriptor { + Class listenerClass; + String listenerMethodName; + String methodName; + Object eventListener; + } + + + /** + * Decodes the serialized representation of a JAXXObjectDescriptor. The string must be a byte-to-character mapping + * of the binary serialization data for a JAXXObjectDescriptor. See the comments in JAXXCompiler.createJAXXObjectDescriptorField + * for the rationale behind this (admittedly ugly) approach. + * + * @param descriptor descriptor to decode + * @return the dedoced descriptor + */ + public static JAXXObjectDescriptor decodeJAXXObjectDescriptor(String descriptor) { + try { + return (JAXXObjectDescriptor) Base64Coder.deserialize(descriptor, false); + /*byte[] data = new byte[descriptor.length()]; + // copy low-order bytes into the array. The high-order bytes should all be zero. + System.arraycopy(descriptor.getBytes(), 0, data, 0, data.length); + //descriptor.getBytes(0, descriptor.length(), data, 0); + ObjectInputStream in = new ObjectInputStream(new ByteArrayInputStream(data)); + return (JAXXObjectDescriptor) in.readObject();*/ + } + catch (IOException e) { + throw new RuntimeException("Internal error: can't-happen error", e); + } + catch (ClassNotFoundException e) { + throw new RuntimeException("Internal error: can't-happen error", e); + } + } + + + public static JAXXObjectDescriptor decodeCompressedJAXXObjectDescriptor(String descriptor) { + try { + return (JAXXObjectDescriptor) Base64Coder.deserialize(descriptor, true); + + /*byte[] data = new byte[descriptor.length()]; + // copy low-order bytes into the array. The high-order bytes should all be zero. + System.arraycopy(descriptor.getBytes(), 0, data, 0, data.length); + //descriptor.getBytes(0, descriptor.length(), data, 0); + ObjectInputStream in = new ObjectInputStream(new GZIPInputStream(new ByteArrayInputStream(data))); + return (JAXXObjectDescriptor) in.readObject();*/ + } + catch (IOException e) { + throw new RuntimeException("Internal error: can't-happen error", e); + } + catch (ClassNotFoundException e) { + throw new RuntimeException("Internal error: can't-happen error", e); + } + } + + + public static Object getEventListener(Class<? extends EventListener> listenerClass, final String listenerMethodName, final Object methodContainer, final String methodName) { + WeakReference<List<EventListenerDescriptor>> ref = eventListeners.get(methodContainer); + List<EventListenerDescriptor> descriptors = ref != null ? ref.get() : null; + if (descriptors == null) { + descriptors = new ArrayList<EventListenerDescriptor>(); + eventListeners.put(methodContainer, new WeakReference<List<EventListenerDescriptor>>(descriptors)); + } else { + for (EventListenerDescriptor descriptor : descriptors) { + if (listenerClass == descriptor.listenerClass && + (listenerMethodName == null ? descriptor.listenerMethodName == null : listenerMethodName.equals(descriptor.listenerMethodName)) && + methodName.equals(descriptor.methodName)) { + return descriptor.eventListener; + } + } + } + + // else we need to create a new listener + final EventListenerDescriptor descriptor = new EventListenerDescriptor(); + descriptor.listenerClass = listenerClass; + descriptor.listenerMethodName = listenerMethodName; + descriptor.methodName = methodName; + try { + final List<Method> listenerMethods = Arrays.asList(listenerClass.getMethods()); + Method listenerMethod = null; + if (listenerMethodName != null) { + for (Method listenerMethod1 : listenerMethods) { + if ((listenerMethod1).getName().equals(listenerMethodName)) { + listenerMethod = listenerMethod1; + break; + } + } + } + if (listenerMethodName != null && listenerMethod == null) { + throw new IllegalArgumentException("no method named " + listenerMethodName + " found in class " + listenerClass.getName()); + } + Class[] parameterTypes = listenerMethods.get(0).getParameterTypes(); + Class<?> methodContainerClass = methodContainer.getClass(); + final Method targetMethod = methodContainerClass.getMethod(methodName, parameterTypes); + descriptor.eventListener = Proxy.newProxyInstance(listenerClass.getClassLoader(), + new Class[]{listenerClass}, + new InvocationHandler() { + public Object invoke(Object proxy, Method method, Object[] args) { + String methodName = method.getName(); + if ((listenerMethodName == null && listenerMethods.contains(method)) || methodName.equals(listenerMethodName)) { + try { + return targetMethod.invoke(methodContainer, args); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (InvocationTargetException e) { + throw new RuntimeException(e); + } + } + if (methodName.equals("toString")) { + return toString(); + } + if (methodName.equals("equals")) { + return descriptor.eventListener == args[0]; + } + if (methodName.equals("hashCode")) { + return hashCode(); + } + return null; + } + }); + descriptors.add(descriptor); + return descriptor.eventListener; + } + catch (NoSuchMethodException e) { + throw new RuntimeException(e); + } + } + + + public static Object getEventListener(Class<? extends EventListener> listenerClass, final Object methodContainer, final String methodName) { + return getEventListener(listenerClass, null, methodContainer, methodName); + } + + + public static DataBindingUpdateListener getDataBindingUpdateListener(JAXXObject object, String bindingName) { + WeakReference<List<DataBindingUpdateListener>> ref = dataBindingUpdateListeners.get(object); + List<DataBindingUpdateListener> listeners = ref == null ? null : ref.get(); + if (listeners == null) { + listeners = new ArrayList<DataBindingUpdateListener>(); + dataBindingUpdateListeners.put(object, new WeakReference<List<DataBindingUpdateListener>>(listeners)); + } else { + for (DataBindingUpdateListener listener : listeners) { + if (bindingName.equals(listener.getBindingName())) { + return listener; + } + } + } + DataBindingUpdateListener listener = new DataBindingUpdateListener(object, bindingName); + listeners.add(listener); + return listener; + } + + + public static void setComponentWidth(Component component, int width) { + component.setSize(width, component.getHeight()); + if (component instanceof JComponent) { + JComponent jcomponent = (JComponent) component; + jcomponent.setPreferredSize(new Dimension(width, jcomponent.getPreferredSize().height)); + jcomponent.setMinimumSize(new Dimension(width, jcomponent.getPreferredSize().height)); + if (jcomponent.isDisplayable()) { + jcomponent.revalidate(); + } + } + } + + + public static void setComponentHeight(Component component, int height) { + component.setSize(component.getWidth(), height); + if (component instanceof JComponent) { + JComponent jcomponent = (JComponent) component; + jcomponent.setPreferredSize(new Dimension(jcomponent.getPreferredSize().width, height)); + jcomponent.setMinimumSize(new Dimension(jcomponent.getPreferredSize().width, height)); + if (jcomponent.isDisplayable()) { + jcomponent.revalidate(); + } + } + } + + + public static boolean assignment(boolean value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static byte assignment(byte value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static short assignment(short value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static int assignment(int value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static long assignment(long value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static float assignment(float value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static double assignment(double value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static char assignment(char value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + + public static java.lang.Object assignment(java.lang.Object value, String name, JAXXObject src) { + src.firePropertyChange(name.trim(), null, "dummy value"); + return value; + } + + /** + * recherche les composants portant le meme nom que les champs de la classe + * clazz. Cette methode est statique pour pouvoir eventuellement l'utiliser + * dans un autre context (je pense par exemple a la generation jaxx). + * <p/> + * <p/> + * Si la recherche echoue pour quelque raison que se soit, aucune exception + * n'est leve, et la map retournee est tout simplement vide ou incomplete + * + * @param clazz la classe ou recherche les champs + * @param container le container ou rechercher les composants d'edition + * @return le dictionnaire des composants recherches. + */ + public static Map<String, JComponent> lookingForEditor(Class clazz, Container container) { + Map<String, JComponent> result = new HashMap<String, JComponent>(); + try { + // looking for all component with name set + Map<String, JComponent> allNamedComponent = new HashMap<String, JComponent>(); + List<Container> todo = new LinkedList<Container>(); + todo.add(container); + while (todo.size() > 0) { + for (ListIterator<Container> i = todo.listIterator(); i.hasNext();) { + Container parent = i.next(); + i.remove(); + for (Component c : parent.getComponents()) { + if (c instanceof Container) { + i.add((Container) c); + String name = c.getName(); + if (c instanceof JComponent && + name != null && !"".equals(name)) { + allNamedComponent.put(name, (JComponent) c); + } + } + } + } + } + + // looking for all properties on class + BeanInfo info = Introspector.getBeanInfo(clazz); + PropertyDescriptor[] props = info.getPropertyDescriptors(); + + // find if one properties have same name that component + for (PropertyDescriptor prop : props) { + String name = prop.getName(); + if (allNamedComponent.containsKey(name)) { + result.put(name, allNamedComponent.get(name)); + } + } + + } catch (IntrospectionException eee) { + log.warn("Can't introspect bean", eee); + } + + if (log.isDebugEnabled()) { + log.debug("Result: " + result); + } + + return result; + } + + /** + * Box a component in a {@link org.jdesktop.jxlayer.JXLayer}. + * + * @param component the component to box + * @return the {@link org.jdesktop.jxlayer.JXLayer} boxing the component + */ + public static JXLayer boxComponentWithJxLayer(JComponent component) { + JXLayer layer = new org.jdesktop.jxlayer.JXLayer(); + layer.add(component); + return layer; + } + + /** + * Compute the string representation of an object. + * <p/> + * Return empty string if given object is null + * + * @param value the value to write + * @return the string representation of the given object or an empty string if object is null. + */ + public static String getStringValue(Object value) { + String result; + result = value == null ? "" : value.toString(); + return result; + } + + /** + * Test if a type of entry exists in a given context and throw an IllegalArgumentException if not found. + * <p/> + * If entry is found, return his value in context. + * + * @param context the context to test + * @param def the definition of the entry to seek in context + * @return the value from the context + * @throws IllegalArgumentException if the entry is not found in context. + */ + public static <T> T checkJAXXContextEntry(JAXXContext context, JAXXContextEntryDef<T> def) throws IllegalArgumentException { + + T value = def.getContextValue(context); + + if (value == null) { + throw new IllegalArgumentException("the context entry [" + def + "] ] was not found in context " + context); + } + + return value; + } + + /** + * Convinient method to apply more than one binding on a JAXX ui. + * + * @param src the ui to treate + * @param bindings the list of binding to process. + */ + public static void applyDataBinding(JAXXObject src, String... bindings) { + for (String binding : bindings) { + src.applyDataBinding(binding); + } + } + + /** + * Convinient method to process more than one binding on a JAXX ui. + * + * @param src the ui to treate + * @param bindings the list of binding to process. + */ + public static void processDataBinding(JAXXObject src, String... bindings) { + for (String binding : bindings) { + src.processDataBinding(binding); + } + } + + /** + * Convinient method to remove more than one binding on a JAXX ui. + * + * @param src the ui to treate + * @param bindings the list of binding to process. + */ + public static void removeDataBinding(JAXXObject src, String... bindings) { + for (String binding : bindings) { + src.removeDataBinding(binding); + } + } + + public static <O> DefaultListCellRenderer newDecoratedListCellRenderer(final Decorator<O> decorator) { + return new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + String decorated; + if (value instanceof String) { + decorated = (String) value; + } else { + decorated = decorator.toString(value); + } + return super.getListCellRendererComponent(list, decorated, index, isSelected, cellHasFocus); + } + }; + } + + public static ImageIcon createImageIcon(String path) { + java.net.URL imgURL = Util.class.getResource("/icons/" + path); + if (imgURL != null) { + return new ImageIcon(imgURL); + } else { + throw new IllegalArgumentException("could not find icon " + path); + } + } + + public static ImageIcon createActionIcon(String name) { + return createImageIcon("action-" + name + ".png"); + } + + public static ImageIcon createI18nIcon(String name) { + return createImageIcon("i18n/" + name + ".png"); + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/DataBinding.java (from rev 1099, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/css/DataBinding.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/DataBinding.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/DataBinding.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,31 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.css; + +/** + * Represents a data binding bound to an attribute at runtime. Used by {@link Pseudoclasses} to keep + * track of which data bindings are in effect. + */ +public class DataBinding { + private String id; + + public DataBinding(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + @Override + public boolean equals(Object o) { + return o instanceof DataBinding && ((DataBinding) o).getId().equals(getId()); + } + + @Override + public int hashCode() { + return id.hashCode(); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/Pseudoclasses.java (from rev 1099, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/css/Pseudoclasses.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/Pseudoclasses.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/main/java/jaxx/runtime/css/Pseudoclasses.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,176 @@ +package jaxx.runtime.css; + +import jaxx.runtime.JAXXObject; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.WeakHashMap; + +public class Pseudoclasses { + public static final String NO_PSEUDOCLASS = "no pseudoclass"; + + private static Map<Object, Map<String, List<PropertyValue>>> properties = new WeakHashMap<Object, Map<String, List<PropertyValue>>>(); + + + private static class PropertyValue implements Comparable<PropertyValue> { + private Object value; + private int id; + + public PropertyValue(Object value, int id) { + this.value = value; + this.id = id; + } + + public Object getValue() { + return value; + } + + public int getId() { + return id; + } + + public int compareTo(PropertyValue o) { + return getId() - o.getId(); + } + + @Override + public boolean equals(Object o) { + if (!(o instanceof PropertyValue)) { + return false; + } + PropertyValue value = (PropertyValue) o; + if (value.getId() != getId()) { + return false; + } + if (value.getValue() == null) { + return getValue() == null; + } + return value.getValue().equals(getValue()); + } + + @Override + public int hashCode() { + return (value != null ? value.hashCode() : 0) ^ id; + } + + @Override + public String toString() { + return "PropertyValue[" + value + ", " + id + "]"; + } + } + + private static List<PropertyValue> getPropertyList(Object object, String property) { + Map<String, List<PropertyValue>> propertyMap = properties.get(object); + if (propertyMap == null) { + propertyMap = new HashMap<String, List<PropertyValue>>(); + properties.put(object, propertyMap); + } + + List<PropertyValue> propertyList = propertyMap.get(property); + if (propertyList == null) { + propertyList = new ArrayList<PropertyValue>(); + propertyMap.put(property, propertyList); + } + + return propertyList; + } + + public static boolean isPropertyApplied(Object object, String property, int id) { + for (PropertyValue aPropertyList : getPropertyList(object, property)) { + if (aPropertyList.getId() == id) { + return true; + } + } + return false; + } + + public static void propertyApplied(Object object, String property, Object value, int id) { + List<PropertyValue> propertyList = getPropertyList(object, property); + propertyList.add(new PropertyValue(value, id)); + Collections.sort(propertyList); + } + + public static void propertyRemoved(Object object, String property, Object value, int id) { + List<PropertyValue> propertyList = getPropertyList(object, property); + propertyList.remove(new PropertyValue(value, id)); + } + + public static Object getCurrentValue(Object object, String property) { + List<PropertyValue> propertyList = getPropertyList(object, property); + if (propertyList.size() > 0) { + return propertyList.get(propertyList.size() - 1).getValue(); + } + return NO_PSEUDOCLASS; + } + + public static Object applyProperty(JAXXObject parent, Object object, String property, Object newValue, Object currentValue, int id) { + if (!isPropertyApplied(object, property, id)) { + Object value = getCurrentValue(object, property); + if (value == NO_PSEUDOCLASS) { + propertyApplied(object, property, wrap(currentValue), -1); + } + propertyApplied(object, property, wrap(newValue), id); + value = getCurrentValue(object, property); + if (value instanceof DataBinding) { + parent.applyDataBinding(((DataBinding) value).getId()); + } + return value; + } else + return currentValue; + } + + public static Object removeProperty(JAXXObject parent, Object object, String property, Object oldValue, Object currentValue, int id) { + if (isPropertyApplied(object, property, id)) { + Object value = getCurrentValue(object, property); + if (value == NO_PSEUDOCLASS) { + throw new IllegalStateException("found NO_PSEUDOCLASS value for a property which does not have a default value"); + } + if (value instanceof DataBinding) { + parent.removeDataBinding(((DataBinding) value).getId()); + } + propertyRemoved(object, property, wrap(oldValue), id); + value = getCurrentValue(object, property); + return value; + } else + return currentValue; + } + + public static Object wrap(boolean value) { + return value; + } + + public static Object wrap(byte value) { + return value; + } + + public static Object wrap(short value) { + return value; + } + + public static Object wrap(int value) { + return value; + } + + public static Object wrap(long value) { + return value; + } + + public static Object wrap(float value) { + return value; + } + + public static Object wrap(double value) { + return value; + } + + public static Object wrap(char value) { + return value; + } + + public static Object wrap(Object value) { + return value; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/DefaultJAXXContextTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/DefaultJAXXContextTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/DefaultJAXXContextTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/DefaultJAXXContextTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,299 @@ +package jaxx.runtime; + +import org.junit.Assert; +import org.junit.Before; +import org.junit.Test; + +import java.awt.Container; +import java.util.Map; + +/** @author chemit */ +public class DefaultJAXXContextTest { + + DefaultJAXXContext ctxt; + + @Before + public void initContext() throws Exception { + + // instanciate a new empty context + ctxt = new DefaultJAXXContext(); + } + + @Test(expected = IllegalStateException.class) + public void testParentContainerFail_IllegalStateException() throws Exception { + ctxt.getParentContainer(Container.class); + } + + @Test(expected = IllegalStateException.class) + public void testParentContainerFail_IllegalStateException2() throws Exception { + ctxt.getParentContainer("null", Container.class); + } + + + @Test(expected = IllegalArgumentException.class) + public void testParentContainerFail_IllegalArgumentException() throws Exception { + + // attach a fake ui (which is NOT a Container) + ctxt.setUi(new MyJAXXObject()); + ctxt.getParentContainer(Container.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testParentContainerFail_IllegalArgumentException2() throws Exception { + + // attach a fake ui (which is NOT a Container) + ctxt.setUi(new MyJAXXObject()); + ctxt.getParentContainer(null, Container.class); + } + + @Test(expected = IllegalArgumentException.class) + public void testParentContainerFail_IllegalArgumentException3() throws Exception { + + // attach a fake ui (which is NOT a Container) + ctxt.setUi(new MyJAXXObject()); + ctxt.getParentContainer("null", Container.class); + } + + @Test + public void testGetParentContext() throws Exception { + JAXXContext expected, result; + expected = null; + result = ctxt.getContextValue(JAXXContext.class); + Assert.assertEquals(expected, result); + + DefaultJAXXContext parentContext = new DefaultJAXXContext(); + + ctxt.setContextValue(parentContext); + + expected = parentContext; + result = ctxt.getContextValue(JAXXContext.class); + Assert.assertEquals(expected, result); + } + + @Test + public void testSetGetContextValue() throws Exception { + String expected; + String result; + + result = ctxt.getContextValue(String.class); + Assert.assertNull(result); + + expected = "yo"; + ctxt.setContextValue(expected); + result = ctxt.getContextValue(String.class); + Assert.assertEquals(expected, result); + + expected = "ya"; + ctxt.setContextValue(expected, "second"); + result = ctxt.getContextValue(String.class, "second"); + Assert.assertEquals(expected, result); + + expected = "yi"; + ctxt.setContextValue(expected, "second"); + result = ctxt.getContextValue(String.class, "second"); + Assert.assertEquals(expected, result); + } + + @Test + public void testSetGetContextValueInParentContext() throws Exception { + + // attach parent context + JAXXContext parentContext = new DefaultJAXXContext(); + ctxt.setContextValue(parentContext); + + String expected; + String result; + + result = ctxt.getContextValue(String.class); + Assert.assertNull(result); + + expected = "yo"; + result = ctxt.getContextValue(String.class); + Assert.assertNull(result); + parentContext.setContextValue(expected); + result = ctxt.getContextValue(String.class); + Assert.assertEquals(expected, result); + + expected = "ya"; + result = ctxt.getContextValue(String.class, "second"); + Assert.assertNull(result); + parentContext.setContextValue(expected, "second"); + result = ctxt.getContextValue(String.class, "second"); + Assert.assertEquals(expected, result); + + expected = "yi"; + result = ctxt.getContextValue(String.class, "second"); + parentContext.setContextValue(expected, "second"); + Assert.assertEquals("ya", result); + result = ctxt.getContextValue(String.class, "second"); + Assert.assertEquals(expected, result); + } + + @Test + public void testSetGetContextValue2() throws Exception { + + // attach parent context + JAXXContext parentContext = new DefaultJAXXContext(); + ctxt.setContextValue(parentContext); + + String expected; + String result; + + result = ctxt.getContextValue(String.class); + Assert.assertNull(result); + result = ctxt.getContextValue(String.class, "yo"); + Assert.assertNull(result); + + expected = "yo"; + ctxt.setContextValue(expected, "yo"); + + result = ctxt.getContextValue(String.class); + Assert.assertNull(result); + result = ctxt.getContextValue(String.class, "yo"); + Assert.assertEquals(expected, result); + } + + @Test + public void testSetGetContextValueInParentParentContext() throws Exception { + + // attach parent parent context + JAXXContext parentParentContext = new DefaultJAXXContext(); + JAXXContext parentContext = new DefaultJAXXContext(); + parentContext.setContextValue(parentParentContext); + ctxt.setContextValue(parentContext); + + String expected; + String result; + + result = ctxt.getContextValue(String.class); + Assert.assertNull(result); + + expected = "yo"; + result = ctxt.getContextValue(String.class); + Assert.assertNull(result); + parentParentContext.setContextValue(expected); + result = ctxt.getContextValue(String.class); + Assert.assertEquals(expected, result); + + expected = "ya"; + result = ctxt.getContextValue(String.class, "second"); + Assert.assertNull(result); + parentParentContext.setContextValue(expected, "second"); + result = ctxt.getContextValue(String.class, "second"); + Assert.assertEquals(expected, result); + + expected = "yi"; + result = ctxt.getContextValue(String.class, "second"); + parentParentContext.setContextValue(expected, "second"); + Assert.assertEquals("ya", result); + result = ctxt.getContextValue(String.class, "second"); + Assert.assertEquals(expected, result); + } + + @Test + public void testEntrySet() throws Exception { + Object o = new Object(); + + ctxt.setContextValue(o); + + Assert.assertEquals(1, ctxt.data.size()); + Assert.assertEquals(o, ctxt.getContextValue(Object.class)); + Assert.assertEquals(null, ctxt.getContextValue(Object.class, "named")); + + ctxt.setContextValue(o, "named"); + + Assert.assertEquals(2, ctxt.data.size()); + Assert.assertEquals(o, ctxt.getContextValue(Object.class)); + Assert.assertEquals(o, ctxt.getContextValue(Object.class, "named")); + + ctxt.removeContextValue(Object.class); + Assert.assertEquals(1, ctxt.data.size()); + Assert.assertEquals(null, ctxt.getContextValue(Object.class)); + Assert.assertEquals(o, ctxt.getContextValue(Object.class, "named")); + + ctxt.removeContextValue(Object.class); + Assert.assertEquals(1, ctxt.data.size()); + Assert.assertEquals(null, ctxt.getContextValue(Object.class)); + Assert.assertEquals(o, ctxt.getContextValue(Object.class, "named")); + + ctxt.removeContextValue(Object.class, "named"); + Assert.assertEquals(0, ctxt.data.size()); + Assert.assertEquals(null, ctxt.getContextValue(Object.class)); + Assert.assertEquals(null, ctxt.getContextValue(Object.class, "named")); + + } + + @Test + public void testEntrySetWithParent() throws Exception { + + DefaultJAXXContext parentContext = new DefaultJAXXContext(); + + ctxt.setContextValue(parentContext); + + class Object2 { + + } + Object o = new Object2(); + + parentContext.setContextValue(o); + + Assert.assertEquals(0, ctxt.data.size()); + Assert.assertEquals(1, parentContext.data.size()); + Assert.assertEquals(o, ctxt.getContextValue(Object2.class)); + Assert.assertEquals(null, ctxt.getContextValue(Object2.class, "named")); + + parentContext.setContextValue(o, "named"); + + Assert.assertEquals(0, ctxt.data.size()); + Assert.assertEquals(2, parentContext.data.size()); + Assert.assertEquals(o, ctxt.getContextValue(Object2.class)); + Assert.assertEquals(o, ctxt.getContextValue(Object2.class, "named")); + + parentContext.removeContextValue(Object2.class); + Assert.assertEquals(0, ctxt.data.size()); + Assert.assertEquals(1, parentContext.data.size()); + Assert.assertEquals(null, ctxt.getContextValue(Object2.class)); + Assert.assertEquals(o, ctxt.getContextValue(Object2.class, "named")); + + parentContext.removeContextValue(Object2.class); + Assert.assertEquals(0, ctxt.data.size()); + Assert.assertEquals(1, parentContext.data.size()); + Assert.assertEquals(null, ctxt.getContextValue(Object2.class)); + Assert.assertEquals(o, ctxt.getContextValue(Object2.class, "named")); + + ctxt.removeContextValue(Object2.class, "named"); + Assert.assertEquals(0, ctxt.data.size()); + Assert.assertEquals(0, parentContext.data.size()); + Assert.assertEquals(null, ctxt.getContextValue(Object2.class)); + Assert.assertEquals(null, ctxt.getContextValue(Object2.class, "named")); + + } + + private static class MyJAXXObject extends DefaultJAXXContext implements JAXXObject { + + public Object getObjectById(String id) { + return null; + } + + public Map<String, Object> get$objectMap() { + return null; + } + + public void applyDataBinding(String id) { + } + + public void removeDataBinding(String id) { + } + + public JAXXContext getDelegateContext() { + return null; + } + + public void processDataBinding(String dest) { + } + + public void firePropertyChange(String name, Object oldValue, Object newValue) { + } + + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/JXPathDecoratorTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/JXPathDecoratorTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/JXPathDecoratorTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/JXPathDecoratorTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,163 @@ +package jaxx.runtime; + +import jaxx.runtime.JXPathDecorator.Context; +import org.junit.After; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** @author chemit */ +public class JXPathDecoratorTest { + + + protected JXPathDecorator<?> decorator; + protected String expected; + protected String result; + + @After + public void after() { + decorator = null; + } + + @Test(expected = NullPointerException.class) + public void testNullInternalClass() throws Exception { + decorator = JXPathDecorator.newDecorator(null, "hello"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace() throws Exception { + decorator = JXPathDecorator.newDecorator(Object.class, "${haha"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace2() throws Exception { + decorator = JXPathDecorator.newDecorator(Object.class, "${haha${hum}"); + } + + @Test + public void testNullBean() throws Exception { + decorator = JXPathDecorator.newDecorator(Object.class, "hello"); + expected = "hello"; + assertEquals(expected, decorator.getExpression()); + assertEquals(0, decorator.nbToken); + assertEquals(0, decorator.getTokens().length); + + result = decorator.toString(null); + assertEquals(null, result); + } + + @Test + public void testNoJXPath() throws Exception { + decorator = JXPathDecorator.newDecorator(Object.class, "hello"); + expected = "hello"; + assertEquals(expected, decorator.getExpression()); + assertEquals(0, decorator.nbToken); + assertEquals(0, decorator.getTokens().length); + + result = decorator.toString(this); + assertEquals(expected, result); + } + + @Test + public void testDecorator() throws Exception { + + decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s - ${nbToken}$d"); + assertEquals("%1$s - %2$d", decorator.getExpression()); + assertDecoratorInternal(); + + decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}${nbToken}"); + assertEquals("%1%2", decorator.getExpression()); + assertDecoratorInternal(); + + decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "before ${expression}$s - ${nbToken}$d after"); + assertEquals("before %1$s - %2$d after", decorator.getExpression()); + assertDecoratorInternal(); + + decorator = JXPathDecorator.newDecorator(JXPathDecorator.class, "before${expression}$s-${nbToken}$dafter"); + assertEquals("before%1$s-%2$dafter", decorator.getExpression()); + assertDecoratorInternal(); + } + + public static class Data { + int pos; + String name; + + protected static List<Data> generate(int nb) { + List<Data> datas = new ArrayList<Data>(nb); + for (int i = 0; i < nb; i++) { + datas.add(new Data(i, "name_" + (nb - i))); + } + return datas; + } + + Data(int pos, String name) { + this.pos = pos; + this.name = name; + } + + public int getPos() { + return pos; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + return "Data{pos=" + pos + ", name='" + name + '\'' + '}'; + } + } + + @Test + public void testSort() throws Exception { + + List<Data> datas = Data.generate(10); + JXPathDecorator<Data> decorator = JXPathDecorator.newDecorator(Data.class, "${pos}$d ${name}$s"); + + List<Data> sortData = new ArrayList<Data>(datas); + JXPathDecorator.sort(decorator, sortData, 0); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + Collections.sort(datas, new Comparator<Data>() { + @Override + public int compare(Data o1, Data o2) { + return o1.name.compareTo(o2.name); + } + }); + Context<Data> context = decorator.context; + context.setComparator(null); + JXPathDecorator.sort(decorator, sortData, 1); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + } + + + public void assertDecoratorInternal(String... tokens) { + assertTokens(tokens); + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + private void assertTokens(String... tokens) { + if (tokens.length == 0) { + tokens = new String[]{"expression", "nbToken"}; + } + assertEquals(2, decorator.nbToken); + assertEquals(2, decorator.getTokens().length); + assertEquals(tokens[0], decorator.getTokens()[0]); + assertEquals(tokens[1], decorator.getTokens()[1]); + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,184 @@ +package jaxx.runtime; + +import jaxx.runtime.JXPathDecoratorTest.Data; +import org.junit.After; +import static org.junit.Assert.assertEquals; +import org.junit.Test; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; + +/** @author chemit */ +public class MultiJXPathDecoratorTest { + + + protected MultiJXPathDecorator<?> decorator; + protected String expected; + protected String result; + + @After + public void after() { + decorator = null; + } + + @Test(expected = NullPointerException.class) + public void testNullInternalClass() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(null, "hello", "#"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(Object.class, "${haha", "#"); + } + + @Test(expected = IllegalArgumentException.class) + public void testMissingRightBrace2() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(Object.class, "${haha${hum}", "#"); + } + + @Test + public void testNullBean() throws Exception { + decorator = MultiJXPathDecorator.newDecorator(Object.class, "hello", ""); + expected = "hello"; + assertEquals(expected, decorator.getExpression()); + assertEquals(0, decorator.nbToken); + assertEquals(0, decorator.getTokens().length); + + result = decorator.toString(null); + assertEquals(null, result); + } + + @Test + public void testMultiDecorator() throws Exception { + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s#${nbToken}$d", "#", " - "); + assertEquals("%1$s - %2$d", decorator.getExpression()); + assertDecoratorInternal(); + assertEquals(2, decorator.contexts.length); + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s", decorator.getExpression()); + assertTokens("nbToken", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s ## ${nbToken}$d", " ## ", " - "); + assertEquals("%1$s - %2$d", decorator.getExpression()); + assertDecoratorInternal(); + assertEquals(2, decorator.contexts.length); + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s", decorator.getExpression()); + assertTokens("nbToken", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + @Test + public void testMultiDecorator2() throws Exception { + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s#${nbToken}$d#${separator}$s", "#", " - "); + + assertEquals("%1$s - %2$d - %3$s", decorator.getExpression()); + assertTokens("expression", "nbToken", "separator"); + assertEquals(3, decorator.contexts.length); + + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s - %3$s", decorator.getExpression()); + assertTokens("nbToken", "separator", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(2); + assertEquals("%1$s - %2$s - %3$d", decorator.getExpression()); + assertTokens("separator", "expression", "nbToken"); + + expected = String.format(decorator.getExpression(), decorator.getSeparator(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + @Test + public void testMultiDecoratorWithMultiRef() throws Exception { + + decorator = MultiJXPathDecorator.newDecorator(JXPathDecorator.class, "${expression}$s#${nbToken}$d#${separator}$s %3$s", "#", " - "); + + assertEquals("%1$s - %2$d - %3$s %3$s", decorator.getExpression()); + assertTokens("expression", "nbToken", "separator"); + assertEquals(3, decorator.contexts.length); + + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(1); + assertEquals("%1$d - %2$s %3$s - %3$s", decorator.getExpression()); + assertTokens("nbToken", "separator", "expression"); + expected = String.format(decorator.getExpression(), decorator.getNbToken(), decorator.getSeparator(), decorator.getExpression()); + result = decorator.toString(decorator); + assertEquals(expected, result); + + decorator.setContextIndex(2); + assertEquals("%1$s %3$s - %2$s - %3$d", decorator.getExpression()); + assertTokens("separator", "expression", "nbToken"); + + expected = String.format(decorator.getExpression(), decorator.getSeparator(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + @Test + public void testSort() throws Exception { + + List<Data> datas = Data.generate(10); + + MultiJXPathDecorator<Data> decorator = MultiJXPathDecorator.newDecorator(Data.class, "${pos}$d-${name}$s", "-"); + + List<Data> sortData = new ArrayList<Data>(datas); + JXPathDecorator.sort(decorator, sortData, 0); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + Collections.sort(datas, new Comparator<Data>() { + @Override + public int compare(Data o1, Data o2) { + return o1.name.compareTo(o2.name); + } + }); + decorator.setContextIndex(1); + JXPathDecorator.sort(decorator, sortData, 1); + for (int i = 0; i < datas.size(); i++) { + Data data = datas.get(i); + Data sData = sortData.get(i); + assertEquals(data, sData); + } + } + + public void assertDecoratorInternal(String... tokens) { + assertTokens(tokens); + expected = String.format(decorator.getExpression(), decorator.getExpression(), decorator.getNbToken()); + result = decorator.toString(decorator); + assertEquals(expected, result); + } + + private void assertTokens(String... tokens) { + if (tokens.length == 0) { + tokens = new String[]{"expression", "nbToken"}; + } + assertEquals(tokens.length, decorator.nbToken); + assertEquals(tokens.length, decorator.getTokens().length); + for (int i = 0; i < tokens.length; i++) { + assertEquals(tokens[i], decorator.getTokens()[i]); + } + } + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/MultiJXPathDecoratorTest.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/UtilTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/runtime/UtilTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/UtilTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/java/jaxx/runtime/UtilTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,29 @@ +package jaxx.runtime; + +import org.junit.Assert; +import org.junit.Test; + +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +public class UtilTest { + + int count; + + @Test + public void testGetEventListener() { + count = 0; + DocumentListener listener = (DocumentListener) jaxx.runtime.Util.getEventListener(javax.swing.event.DocumentListener.class, this, "incCount"); + listener.insertUpdate(null); + Assert.assertEquals(count, 1); + DocumentListener listener2 = (DocumentListener) jaxx.runtime.Util.getEventListener(javax.swing.event.DocumentListener.class, this, "incCount"); + listener2.removeUpdate(null); + Assert.assertEquals(count, 2); + //assertTrue("Received two different event listeners despite using identical parameters", listener == listener2); + } + + + public void incCount(DocumentEvent e) { + count++; + } +} \ No newline at end of file Added: lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/resources/log4j.properties =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/resources/log4j.properties (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-api/src/test/resources/log4j.properties 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,8 @@ +# Global logging configuration +log4j.rootLogger=ERROR, stdout +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n + +log4j.logger.jaxx=DEBUG Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-swing ___________________________________________________________________ Name: svn:ignore + target *.log *.iml Added: lutinjaxx/branches/storm_1/jaxx-runtime-swing/LICENSE.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/LICENSE.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/LICENSE.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Added: lutinjaxx/branches/storm_1/jaxx-runtime-swing/README.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/README.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/README.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install Added: lutinjaxx/branches/storm_1/jaxx-runtime-swing/changelog.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/changelog.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/changelog.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,90 @@ +1.0 ???? 200812?? + +0.8 ??? 200812?? + * 20081228 [chemit] - generify ClassDescriptor + - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from + JAXXCompiler and make possible to extract compiler engine from runtime + + * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation + * 20081218 [chemit] - improve generation of methods + * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) + - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option) + - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection + - add addSourcesToClassPath property to add sources directories in class-path + - improve classloader managment + - keep in DataSource objetCode + - fix bug when processDataBinding on a null objectCode + - always clean node cached values when selected it + - add usefull databinding method in Util + +* 20081213 [chemit] - improve navigation tree node rendering with some caches + - introduce a ChildBuilder to simplify building of child nodes from a collection or array + +0.7 chemit 20081210 +* 20081210 [chemit] - fix bug 1751 +* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) +* 20081208 [chemit] - javabBean attribute use to initialize bean + - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) + - introduce MultiJXPathDecorator + - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers + + * 20081207 [chemit] use lutinproject 3.1 + - can exclude field from validator + * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter + - fix bug when searching for a inner class + + * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator + - add setcontextValue and removeContextValue on JAXXContextEntryDef + - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff + - only enter once in $initialize method in generated code + + 0.6 chemit 20081117 + * 20081118 [chemit] introduce NavigationUtil, save in context selected node + * 20081107 [chemit] improve data binding and code generation : + - make possible inheritance in binding + - add an attribute javaBean to an object : will generate a full java bean support property + - make possible binding to the javaBean added properties + - clean generated code + + * 20081105 [chemit] introduce a CardLayout2 to extends awt CardLayout + introduce a NavigationTreeModel + introduce a Decorator to render Object + propagate constructor JAXXContext(JAXXContext) in JAXXObject generation + begin of rst documentation + + * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer + * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor. + * 20081102 [chemit] improve JAXXContext : + - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext + - do javadoc in JAXXContext + - add logic in DefaultJAXXContext : seek in parent context if entry not found + * 20081102 [chemit] improve tests : + - fix the last failed test from Jaxx original version :) + - dumps tests to JUnit4 :) + * 20081030 [chemit] improve BeanValidator : + - add full PropertyChangeEvent java-bean support and a property valid + - when remove bean from validator, must remove errors from model + - make possible to have a dynamic errorListModel in jaxx files + * 20081030 [chemit] improve JAXXContext : + - fix setContextValue bug when setting twice a same type for a same key + - implements a DefaultJAXXContext + - use this default implementation with delegate pattern in JAXXObject + * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext + * 20081027 [chemit] fix bug 1722 + * 20081027 [chemit] add conversion support in validator + * 20081025 [chemit] improve BeanValidator tag : + - add a errorList attribute for set a ErrorListMouseListener on the errorList + - add a beanInitializer attribute for set the validator's bean at runtime + - add a default errorListModel value 'errors' + * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method + * 20081024 [chemit] fix validator context lost if UI is launched from another thread + ver-0-5 chemit 20081002 + * 20081017 [chemit] add validator support + * 20081013 [chemit] can generate logger on jaxx files + * 20081011 [chemit] improve site + * 20081011 [chemit] fix bug on JavaFileParser : works again + * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin + * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules) + * 20081002 [chemit] Introduce JAXXContext + * 20081002 [chemit] Fix bug on method creation via scripting + * 20081002 [chemit] Improve i18n integration (works now also for tabs) Added: lutinjaxx/branches/storm_1/jaxx-runtime-swing/pom.xml =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/pom.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.codelutin</groupId> + <artifactId>lutinjaxx</artifactId> + <version>0.8-SNAPSHOT</version> + </parent> + + <artifactId>jaxx-runtime-swing</artifactId> + + <dependencies> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-api</artifactId> + </dependency> + + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + <name>jaxx-runtime-swing</name> + <description>Jaxx runtime swing extension</description> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + <packaging>jar</packaging> + + <build> + <defaultGoal>install</defaultGoal> + </build> + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + <scm> + <connection>${maven.scm.connection.child}</connection> + <developerConnection>${maven.scm.developerConnection.child}</developerConnection> + <url>${maven.scm.url.child}</url> + </scm> +</project> Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/HBoxBeanInfo.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,58 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.beaninfos; + +import jaxx.runtime.swing.HBox; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.beans.SimpleBeanInfo; + +public class HBoxBeanInfo extends SimpleBeanInfo { + public BeanInfo[] getAdditionalBeanInfo() { + try { + return new BeanInfo[]{Introspector.getBeanInfo(JPanel.class)}; + } + catch (IntrospectionException e) { + throw new RuntimeException(e); + } + } + + + public PropertyDescriptor[] getPropertyDescriptors() { + try { + PropertyDescriptor spacing = new PropertyDescriptor("spacing", HBox.class); + spacing.setBound(true); + + PropertyDescriptor margin = new PropertyDescriptor("margin", HBox.class); + margin.setBound(true); + + PropertyDescriptor horizontalAlignment = new PropertyDescriptor("horizontalAlignment", HBox.class); + horizontalAlignment.setBound(true); + horizontalAlignment.setValue("enumerationValues", new Object[]{ + "left", SwingConstants.LEFT, "SwingConstants.LEFT", + "center", SwingConstants.CENTER, "SwingConstants.CENTER", + "right", SwingConstants.RIGHT, "SwingConstants.RIGHT" + }); + + PropertyDescriptor verticalAlignment = new PropertyDescriptor("verticalAlignment", HBox.class); + verticalAlignment.setBound(true); + verticalAlignment.setValue("enumerationValues", new Object[]{ + "top", SwingConstants.TOP, "SwingConstants.TOP", + "middle", SwingConstants.CENTER, "SwingConstants.CENTER", + "bottom", SwingConstants.BOTTOM, "SwingConstants.BOTTOM" + }); + + return new PropertyDescriptor[]{spacing, margin, horizontalAlignment, verticalAlignment}; + } + catch (IntrospectionException e) { + throw new RuntimeException(e); + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/beaninfos/VBoxBeanInfo.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,58 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.beaninfos; + +import jaxx.runtime.swing.VBox; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.beans.SimpleBeanInfo; + +public class VBoxBeanInfo extends SimpleBeanInfo { + public BeanInfo[] getAdditionalBeanInfo() { + try { + return new BeanInfo[]{Introspector.getBeanInfo(JPanel.class)}; + } + catch (IntrospectionException e) { + throw new RuntimeException(e); + } + } + + + public PropertyDescriptor[] getPropertyDescriptors() { + try { + PropertyDescriptor spacing = new PropertyDescriptor("spacing", VBox.class); + spacing.setBound(true); + + PropertyDescriptor margin = new PropertyDescriptor("margin", VBox.class); + margin.setBound(true); + + PropertyDescriptor horizontalAlignment = new PropertyDescriptor("horizontalAlignment", VBox.class); + horizontalAlignment.setBound(true); + horizontalAlignment.setValue("enumerationValues", new Object[]{ + "left", SwingConstants.LEFT, "SwingConstants.LEFT", + "center", SwingConstants.CENTER, "SwingConstants.CENTER", + "right", SwingConstants.RIGHT, "SwingConstants.RIGHT" + }); + + PropertyDescriptor verticalAlignment = new PropertyDescriptor("verticalAlignment", VBox.class); + verticalAlignment.setBound(true); + verticalAlignment.setValue("enumerationValues", new Object[]{ + "top", SwingConstants.TOP, "SwingConstants.TOP", + "middle", SwingConstants.CENTER, "SwingConstants.CENTER", + "bottom", SwingConstants.BOTTOM, "SwingConstants.BOTTOM" + }); + + return new PropertyDescriptor[]{spacing, margin, horizontalAlignment, verticalAlignment}; + } + catch (IntrospectionException e) { + throw new RuntimeException(e); + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Application.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Application.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Application.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Application.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,56 @@ +package jaxx.runtime.swing; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.UIManager; +import javax.swing.UnsupportedLookAndFeelException; +import java.awt.GraphicsConfiguration; + +public class Application extends JFrame { + // Special: jaxxc will automatically add a main() method to any components which + // extend <Application> + + + public Application() { + } + + + public Application(GraphicsConfiguration gc) { + super(gc); + } + + + public Application(String title) { + super(title); + } + + + public Application(String title, GraphicsConfiguration gc) { + super(title, gc); + } + + + public void setLookAndFeel(String lookAndFeel) { + if (lookAndFeel.equals("system")) + lookAndFeel = UIManager.getSystemLookAndFeelClassName(); + else if (lookAndFeel.equals("cross_platform")) + lookAndFeel = UIManager.getCrossPlatformLookAndFeelClassName(); + try { + UIManager.setLookAndFeel(lookAndFeel); + if (isDisplayable()) + SwingUtilities.updateComponentTreeUI(this); + } + catch (ClassNotFoundException e) { + throw new RuntimeException(e); + } + catch (InstantiationException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (UnsupportedLookAndFeelException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/CardLayout2.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/CardLayout2.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,87 @@ +package jaxx.runtime.swing; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import java.awt.CardLayout; +import java.awt.Component; +import java.awt.Container; +import java.io.Serializable; +import java.util.LinkedList; +import java.util.List; + +/** + * An override of the awt {@link java.awt.CardLayout}. + * <p/> + * Because in the original layout is not overridable : everything is package level accessible. + * <p/> + * This new class offers to test if a constrains (as a Serializable) is actually dealed by the layout, + * via the method {@link #contains(java.io.Serializable)}. + * <p/> + * We had also another method to obtain the current visible component in a container layouted by the class, + * via the method {@link #getVisibleComponent(java.awt.Container)}. + * + * @author chemit + * @version 1.0 + */ +public class CardLayout2 extends CardLayout { + + /** log */ + static private Log log = LogFactory.getLog(CardLayout2.class); + + private static final long serialVersionUID = 1L; + + /** list of already loaded context (since the {@link #vector} attribute is package visible... */ + protected List<Serializable> contexts = new LinkedList<Serializable>(); + + @Override + public void addLayoutComponent(Component comp, Object constraints) { + super.addLayoutComponent(comp, constraints); + contexts.add((Serializable) constraints); + if (log.isDebugEnabled()) { + log.debug(this + " new constraints : " + constraints); + } + } + + /** + * Test if a constrains is contained in the layout. + * + * @param constraints l'identifiant a tester + * @return <code>true</code> si l'identifiant est deja present dans le layout, <code>false</code> autrement. + */ + public boolean contains(Serializable constraints) { + return contexts.contains(constraints); + } + + /** + * Obtain the visible component in the container. + * + * @param container the container using this layout + * @return the component visible in the container. + */ + public Component getVisibleComponent(Container container) { + if (container.getLayout() != this) { + throw new IllegalArgumentException("the container is not managed by the current layout"); + } + for (Component component : container.getComponents()) { + if (component.isVisible()) { + return component; + } + } + // no component actually visible + return null; + } + + public Component getComponent(Container container, String constraints) { + if (container.getLayout() != this) { + throw new IllegalArgumentException("the container is not manage by the current layout"); + } + if (!contexts.contains(constraints)) { + throw new IllegalArgumentException("the constraints '" + constraints + "' is not supported by this layout : " + contexts); + } + int index = contexts.indexOf(constraints); + return container.getComponents()[index]; + } + + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,33 @@ +package jaxx.runtime.swing; + +import jaxx.runtime.Decorator; + +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; +import java.awt.Component; + +/** + * A simple TableCellRenderer using a delegate TableCellRenderer to render everything elese thant the text : + * the text is I18nalize. + * + * @author chemit + */ +public class DecoratorTableCellRenderer implements TableCellRenderer { + + /** the delegate cell renderer */ + protected TableCellRenderer delegate; + + protected Decorator decorator; + + public DecoratorTableCellRenderer(TableCellRenderer delegate, Decorator decorator) { + this.delegate = delegate; + this.decorator = decorator; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasfocus, int row, int column) { + if (value != null) { + value = decorator.toString(value); + } + return delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column); + } +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/DecoratorTableCellRenderer.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBox.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/HBox.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBox.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBox.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,102 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.JPanel; +import java.awt.Insets; + +/** + * Panel which uses an {@link HBoxLayout} by default. + * + * @author Ethan Nicholas + */ +public class HBox extends JPanel { + public static final String SPACING_PROPERTY = "spacing"; + public static final String MARGIN_PROPERTY = "margin"; + public static final String HORIZONTAL_ALIGNMENT_PROPERTY = "horizontalAlignment"; + public static final String VERTICAL_ALIGNMENT_PROPERTY = "verticalAlignment"; + + private Insets margin; + + public HBox() { + super(new HBoxLayout()); + } + + + /** + * Returns the spacing between components, in pixels. Spacing is applied between components only, + * not to the top or bottom of the container. + * + * @return spacing between components + */ + public int getSpacing() { + return ((HBoxLayout) getLayout()).getSpacing(); + } + + + /** + * Sets the spacing between components. Spacing is applied between components only, + * not to the top or bottom of the container. + * + * @param spacing new spacing value + */ + public void setSpacing(int spacing) { + int oldValue = getSpacing(); + ((HBoxLayout) getLayout()).setSpacing(spacing); + firePropertyChange(SPACING_PROPERTY, oldValue, spacing); + revalidate(); + } + + + public int getHorizontalAlignment() { + return ((HBoxLayout) getLayout()).getHorizontalAlignment(); + } + + + public void setHorizontalAlignment(int horizontalAlignment) { + int oldValue = getHorizontalAlignment(); + ((HBoxLayout) getLayout()).setHorizontalAlignment(horizontalAlignment); + firePropertyChange(HORIZONTAL_ALIGNMENT_PROPERTY, oldValue, horizontalAlignment); + revalidate(); + } + + + public int getVerticalAlignment() { + return ((HBoxLayout) getLayout()).getVerticalAlignment(); + } + + + public void setVerticalAlignment(int verticalAlignment) { + int oldValue = getVerticalAlignment(); + ((HBoxLayout) getLayout()).setVerticalAlignment(verticalAlignment); + firePropertyChange(VERTICAL_ALIGNMENT_PROPERTY, oldValue, verticalAlignment); + revalidate(); + } + + + public Insets getMargin() { + return margin; + } + + + public void setMargin(Insets margin) { + Insets oldValue = this.margin; + this.margin = (Insets) margin.clone(); + firePropertyChange(MARGIN_PROPERTY, oldValue, margin); + } + + + @Override + public Insets getInsets() { + Insets result = super.getInsets(); + if (margin != null) { + result.top += margin.top; + result.left += margin.left; + result.right += margin.right; + result.bottom += margin.bottom; + } + return result; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBoxLayout.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/HBoxLayout.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBoxLayout.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/HBoxLayout.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,132 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.SwingConstants; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; + +/** + * Horizontal box layout. The layout rules followed by this class are quite different than the core BoxLayout class, + * and in general represent a more useful algorithm. + * + * @author Ethan Nicholas + */ +public class HBoxLayout implements LayoutManager { + private int spacing = 6; + private int horizontalAlignment = SwingConstants.LEFT; + private int verticalAlignment = SwingConstants.TOP; + + + public int getSpacing() { + return spacing; + } + + + public void setSpacing(int spacing) { + this.spacing = spacing; + } + + + public int getHorizontalAlignment() { + return horizontalAlignment; + } + + + public void setHorizontalAlignment(int horizontalAlignment) { + this.horizontalAlignment = horizontalAlignment; + } + + + public int getVerticalAlignment() { + return verticalAlignment; + } + + + public void setVerticalAlignment(int verticalAlignment) { + this.verticalAlignment = verticalAlignment; + } + + + public void addLayoutComponent(String name, Component comp) { + } + + + public void layoutContainer(Container parent) { + Insets insets = parent.getInsets(); + int parentHeight = parent.getSize().height - insets.top - insets.bottom; + int count = parent.getComponentCount(); + Dimension preferredSize = parent.getPreferredSize(); + int x; + switch (horizontalAlignment) { + case SwingConstants.LEFT: + x = insets.left; + break; + case SwingConstants.CENTER: + x = insets.left + (parent.getWidth() - preferredSize.width) / 2; + break; + case SwingConstants.RIGHT: + x = insets.left + (parent.getWidth() - preferredSize.width); + break; + default: + throw new IllegalArgumentException("invalid horizontal alignment: " + horizontalAlignment); + } + + for (int i = 0; i < count; i++) { + Component component = parent.getComponent(i); + Dimension childPreferredSize = component.getPreferredSize(); + int height = Math.min(childPreferredSize.height, parentHeight); + int y; + switch (verticalAlignment) { + case SwingConstants.TOP: + y = insets.top; + break; + case SwingConstants.CENTER: + y = insets.top + (parentHeight - childPreferredSize.height) / 2; + break; + case SwingConstants.BOTTOM: + y = insets.top + (parentHeight - childPreferredSize.height); + break; + default: + throw new IllegalArgumentException("invalid vertical alignment: " + verticalAlignment); + } + component.setBounds(x, y, childPreferredSize.width, height); + x += childPreferredSize.width + spacing; + } + } + + + public Dimension minimumLayoutSize(Container parent) { + int width = (parent.getComponentCount() - 1) * spacing; + int height = 0; + for (int i = parent.getComponentCount() - 1; i >= 0; i--) { + Dimension minimumSize = parent.getComponent(i).getMinimumSize(); + width += minimumSize.width; + height = Math.max(height, minimumSize.height); + } + Insets insets = parent.getInsets(); + return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom); + } + + + public Dimension preferredLayoutSize(Container parent) { + int width = (parent.getComponentCount() - 1) * spacing; + int height = 0; + for (int i = parent.getComponentCount() - 1; i >= 0; i--) { + Dimension preferredSize = parent.getComponent(i).getPreferredSize(); + width += preferredSize.width; + height = Math.max(height, preferredSize.height); + } + Insets insets = parent.getInsets(); + return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom); + } + + + public void removeLayoutComponent(Component comp) { + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/I18nTableCellRenderer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,42 @@ +package jaxx.runtime.swing; + +import static org.codelutin.i18n.I18n._; + +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import java.awt.Component; + +/** + * A simple TableCellRenderer using a delegate TableCellRenderer to render everything elese thant the text : + * the text is I18nalize. + * + * @author chemit + */ +public class I18nTableCellRenderer implements TableCellRenderer { + + /** the libelles to display */ + protected final String[] keys; + + /** the delegate cell renderer */ + protected TableCellRenderer delegate; + + public I18nTableCellRenderer(TableCellRenderer delegate, String... keys) { + this.delegate = delegate; + this.keys = keys; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasfocus, int row, int column) { + if (column > keys.length) { + throw new IndexOutOfBoundsException("colum can not be greater than " + keys.length); + } + TableColumn col = table.getColumn(table.getColumnName(column)); + value = _(keys[col.getModelIndex()]); + return delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column); + + /*JLabel rendererComponent = (JLabel) delegate.getTableCellRendererComponent(table, value, isSelected, hasfocus, row, column); + + rendererComponent.setText(_(keys[column])); + return rendererComponent;*/ + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Item.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Item.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Item.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Item.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,192 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.event.SwingPropertyChangeSupport; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.ArrayList; +import java.util.List; + +// This needs to be split into two classes, Item and TreeItem +/** + * An item in a component such as <code>JComboBox</code> or <code>JTree</code>. The <code>Item</code> + * class corresponds to the <code><item></code> tag in JAXX source files. + */ +public class Item { + public static final String LABEL_PROPERTY = "label"; + public static final String VALUE_PROPERTY = "value"; + public static final String SELECTED_PROPERTY = "selected"; + + private String id; + private String label; + private Object value; + private boolean selected; + private List<Item> children; + private Item parent; + private PropertyChangeSupport propertyChangeSupport; + + /** + * Creates a new Item. This should only be called from compiled JAXX files. + * + * @param id the item's ID + * @param label the string that should be used to represent the item visually + * @param value the item's actual value + * @param selected <code>true</code> if the item should be selected by default + */ + public Item(String id, String label, Object value, boolean selected) { + this.id = id; + this.label = label; + this.value = value; + this.selected = selected; + } + + /** + * Returns this item's ID. + * + * @return the JAXX ID attribute + */ + public String getId() { + return id; + } + + /** + * Returns the string that should be used to represent the item at display time. If <code>null</code>, + * <code>String.valueOf(getValue())</code> will be used instead. + * + * @return this item's display string + * @see #setLabel + */ + public String getLabel() { + return label; + } + + /** + * Sets the item's display string. If <code>null, String.valueOf(getValue())</code> will be used instead. + * + * @param label the new display string + * @see #getLabel + */ + public void setLabel(String label) { + String oldLabel = this.label; + this.label = label; + firePropertyChange(LABEL_PROPERTY, oldLabel, label); + } + + /** + * Returns the item's actual value as it appears in the component's model. The <code>Item</code> itself is not + * visible from the model, only the value. + * + * @return the item's value + * @see #setValue + */ + public Object getValue() { + return value; + } + + /** + * Sets the item's value as it appears in the component's model. The <code>Item</code> itself is not + * visible from the model, only the value. + * + * @param value the new value + * @see #getValue + */ + public void setValue(Object value) { + Object oldValue = this.value; + this.value = value; + firePropertyChange(VALUE_PROPERTY, oldValue, value); + } + + /** + * Returns <code>true</code> if this item is currently selected. This is a bound property. + * + * @return <code>true</code> if item is selected + * @see #setSelected + */ + public boolean isSelected() { + return selected; + } + + /** + * Sets the item's selection state. This is a bound property. + * + * @param selected the new selection state + * @see #isSelected + */ + public void setSelected(boolean selected) { + boolean oldSelected = this.selected; + this.selected = selected; + firePropertyChange(SELECTED_PROPERTY, oldSelected, selected); + } + + /** + * Adds a new child node (Items can be nested in trees). + * + * @param item the new child item + */ + public void addChild(Item item) { + if (children == null) { + children = new ArrayList<Item>(); + } + children.add(item); + item.parent = this; + } + + /** + * Returns a list of this item's children. + * + * @return a list of all nested child nodes + */ + public List<Item> getChildren() { + if (children == null) { + children = new ArrayList<Item>(); + } + return children; + } + + /** + * Returns the <code>Item</code> containing this <code>Item</code>, or <code>null</code> for a top-level + * <code>Item</code>. + * + * @return the item parent (or null) + */ + public Item getParent() { + return parent; + } + + private PropertyChangeSupport getPropertyChangeSupport() { + if (propertyChangeSupport == null) { + propertyChangeSupport = new SwingPropertyChangeSupport(this); + } + return propertyChangeSupport; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String property, PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(property, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String property, PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(property, listener); + } + + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + if (propertyChangeSupport != null) { + getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue); + } + } + + @Override + public String toString() { + return getClass().getName() + "[" + value + "]"; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXButtonGroup.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,215 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.AbstractButton; +import javax.swing.ButtonGroup; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.EventListenerList; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.util.Enumeration; + +public class JAXXButtonGroup extends ButtonGroup { + public static final String SELECTED_VALUE_PROPERTY = "selectedValue"; + + public static final String BUTTON8GROUP_CLIENT_PROPERTY = "$buttonGroup"; + + public static final String VALUE_CLIENT_PROPERTY = "$value"; + + public static final String SELECTED_TIP_CLIENT_PROPERTY = "$selected.toolTipText"; + + public static final String NOT_SELECTED_TIP_CLIENT_PROPERTY = "$not.selected.toolTipText"; + + protected EventListenerList listenerList = new EventListenerList(); + + private PropertyChangeSupport propertyChangeSupport; + private transient Object selectedValue; + + protected boolean useToolTipText; + + protected transient ChangeEvent changeEvent = new ChangeEvent(this); + + private transient ChangeListener changeListener = new ChangeListener() { + public void stateChanged(ChangeEvent e) { + updateSelectedValue(); + if (useToolTipText) { + updateToolTipText(); + } + } + }; + + private static final long serialVersionUID = 1L; + + @Override + public void add(AbstractButton button) { + super.add(button); + button.addChangeListener(changeListener); + updateSelectedValue(); + } + + @Override + public void remove(AbstractButton button) { + super.remove(button); + button.removeChangeListener(changeListener); + updateSelectedValue(); + } + + + public void updateSelectedValue() { + Enumeration<AbstractButton> e = getElements(); + while (e.hasMoreElements()) { + AbstractButton button = e.nextElement(); + if (button.isSelected()) { + Object selectedValue = button.getClientProperty(VALUE_CLIENT_PROPERTY ); + if (selectedValue != getSelectedValue()) { + setSelectedValue(selectedValue); + } + } + } + } + + public void updateToolTipText() { + Enumeration<AbstractButton> e = getElements(); + while (e.hasMoreElements()) { + AbstractButton button = e.nextElement(); + String key = button.isSelected() ? SELECTED_TIP_CLIENT_PROPERTY : NOT_SELECTED_TIP_CLIENT_PROPERTY; + button.setToolTipText((String) button.getClientProperty(key)); + } + } + + public boolean isUseToolTipText() { + return useToolTipText; + } + + public Object getSelectedValue() { + return selectedValue; + } + + + public void setSelectedValue(Object value) { + Object oldValue = getSelectedValue(); + this.selectedValue = value; + firePropertyChange(oldValue); + } + + public void setUseToolTipText(boolean useToolTipText) { + this.useToolTipText = useToolTipText; + } + + public void setSelectedButton(Object value) { + setSelectedValue(value); + if (value == null) { + Enumeration<AbstractButton> e = getElements(); + while (e.hasMoreElements()) { + AbstractButton button = e.nextElement(); + setSelected(button.getModel(), false); + } + return; + } + + Enumeration<AbstractButton> e = getElements(); + while (e.hasMoreElements()) { + AbstractButton button = e.nextElement(); + Object selectedValue = button.getClientProperty(VALUE_CLIENT_PROPERTY ); + if (value.equals(selectedValue)) { + button.setSelected(true); + break; + } + } + } + + protected PropertyChangeSupport getPropertyChangeSupport() { + if (propertyChangeSupport == null) { + propertyChangeSupport = new PropertyChangeSupport(this); + } + return propertyChangeSupport; + } + + + public void addPropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(listener); + } + + + public void addPropertyChangeListener(String property, PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(property, listener); + } + + + public void removePropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(listener); + } + + + public void removePropertyChangeListener(String property, PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(property, listener); + } + + + private void firePropertyChange(Object oldValue) { + if (propertyChangeSupport != null) { + getPropertyChangeSupport().firePropertyChange(SELECTED_VALUE_PROPERTY, + oldValue, getSelectedValue()); + } + fireStateChanged(); + } + + /** + * Adds a <code>ChangeListener</code> to the button. + * + * @param l the listener to be added + */ + public void addChangeListener(ChangeListener l) { + listenerList.add(ChangeListener.class, l); + } + + /** + * Removes a ChangeListener from the button. + * + * @param l the listener to be removed + */ + public void removeChangeListener(ChangeListener l) { + listenerList.remove(ChangeListener.class, l); + } + + /** + * Returns an array of all the <code>ChangeListener</code>s added + * to this AbstractButton with addChangeListener(). + * + * @return all of the <code>ChangeListener</code>s added or an empty + * array if no listeners have been added + * @since 1.4 + */ + public ChangeListener[] getChangeListeners() { + return listenerList.getListeners(ChangeListener.class); + } + + /** + * Notifies all listeners that have registered interest for + * notification on this event type. The event instance + * is lazily created. + * + * @see EventListenerList + */ + protected void fireStateChanged() { + // Guaranteed to return a non-null array + Object[] listeners = listenerList.getListenerList(); + // Process the listeners last to first, notifying + // those that are interested in this event + for (int i = listeners.length - 2; i >= 0; i -= 2) { + if (listeners[i] == ChangeListener.class) { + // Lazily create the event: + if (changeEvent == null) { + changeEvent = new ChangeEvent(this); + } + ((ChangeListener) listeners[i + 1]).stateChanged(changeEvent); + } + } + } + + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXComboBox.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXComboBox.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXComboBox.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXComboBox.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,176 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.AbstractListModel; +import javax.swing.ComboBoxModel; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JComboBox; +import javax.swing.JList; +import javax.swing.ListModel; +import java.awt.Component; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +public class JAXXComboBox extends JComboBox { + public class JAXXComboBoxModel extends AbstractListModel implements ComboBoxModel { + private List<Item> items; + private Object selectedItem; + private static final long serialVersionUID = -8940733376638766414L; + + public JAXXComboBoxModel(List<Item> items) { + this.items = items; + + PropertyChangeListener listener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + if (e.getPropertyName().equals(Item.SELECTED_PROPERTY)) { + Item item = (Item) e.getSource(); + int itemIndex = JAXXComboBoxModel.this.items.indexOf(item); + // TODO: fix cut-and-pasting badness + int[] oldSelection = new int[]{getSelectedIndex()}; + int[] newSelection; + int index = -1; + for (int i = 0; i < oldSelection.length; i++) { + if (oldSelection[i] == itemIndex) { + index = i; + break; + } + } + if (item.isSelected()) { + if (index != -1) // it was already selected + { + return; + } + newSelection = new int[oldSelection.length + 1]; + System.arraycopy(oldSelection, 0, newSelection, 0, oldSelection.length); + newSelection[newSelection.length - 1] = itemIndex; + } else { + if (index == -1) // it already wasn't selected + { + return; + } + newSelection = new int[oldSelection.length - 1]; + System.arraycopy(oldSelection, 0, newSelection, 0, index); + System.arraycopy(oldSelection, index + 1, newSelection, index, oldSelection.length - 1 - index); + } + setSelectedIndex(newSelection[0]); + } else { + // TODO: more cut-and-pasting badness + for (int i = 0; i < getSize(); i++) { + if (getElementAt(i) == ((Item) e.getSource()).getValue()) { + fireContentsChanged(JAXXComboBoxModel.this, i, i); + if (getSelectedIndex() == i) { + fireItemStateChanged(new ItemEvent(JAXXComboBox.this, ItemEvent.ITEM_STATE_CHANGED, getElementAt(i), ItemEvent.DESELECTED)); + } + return; + } + } + } + } + }; + for (Item item : items) { + item.addPropertyChangeListener(listener); + } + } + + + public Object getElementAt(int i) { + return items.get(i).getValue(); + } + + + public int getSize() { + return items.size(); + } + + + public Object getSelectedItem() { + return selectedItem; + } + + + public void setSelectedItem(Object selectedItem) { + if ((this.selectedItem != null && !this.selectedItem.equals(selectedItem)) || + this.selectedItem == null && selectedItem != null) { + this.selectedItem = selectedItem; + fireContentsChanged(this, -1, -1); + } + } + } + + + public JAXXComboBox() { + setRenderer(new DefaultListCellRenderer() { + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + ListModel model = list.getModel(); + if (model instanceof JAXXComboBoxModel) { + List/*<Item>*/ items = ((JAXXComboBoxModel) model).items; + Item item = null; + if (index == -1) { + for (Object item1 : items) { + Item testItem = (Item) item1; + if (testItem.getValue() == value) { + item = testItem; + break; + } + } + } else + item = (Item) items.get(index); + + if (item != null) { + String label = item.getLabel(); + if (label != null) { + value = label; + } + } + } + return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + } + }); + + addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + ListModel model = getModel(); + if (model instanceof JAXXComboBoxModel) { + List<Item> items = ((JAXXComboBoxModel) model).items; + for (int i = items.size() - 1; i >= 0; i--) { + boolean selected = getSelectedIndex() == i; + Item item = items.get(i); + if (selected != item.isSelected()) { + item.setSelected(selected); + } + } + } + } + }); + } + + + // this way we can keep it marked protected and still allow code in this file to call it + @Override + protected void fireItemStateChanged(ItemEvent e) { + super.fireItemStateChanged(e); + } + + public void setItems(List<Item> items) { + setModel(new JAXXComboBoxModel(items)); + List<Integer> selectedIndexList = new ArrayList<Integer>(); + for (int i = 0; i < items.size(); i++) + if (items.get(i).isSelected()) { + selectedIndexList.add(i); + } + int[] selectedIndices = new int[selectedIndexList.size()]; + for (int i = 0; i < selectedIndexList.size(); i++) { + selectedIndices[i] = selectedIndexList.get(i); + } + if (selectedIndices.length > 0) { + setSelectedIndex(selectedIndices[0]); + } + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXList.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXList.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXList.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXList.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,148 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.AbstractListModel; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JList; +import javax.swing.ListModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +public class JAXXList extends JList { + public class JAXXListModel extends AbstractListModel { + private List<Item> items; + private static final long serialVersionUID = -1598924187490122036L; + + public JAXXListModel(List<Item> items) { + this.items = items; + + PropertyChangeListener listener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + if (e.getPropertyName().equals(Item.SELECTED_PROPERTY)) { + Item item = (Item) e.getSource(); + int itemIndex = JAXXListModel.this.items.indexOf(item); + int[] oldSelection = getSelectedIndices(); + int[] newSelection; + int index = -1; + for (int i = 0; i < oldSelection.length; i++) { + if (oldSelection[i] == itemIndex) { + index = i; + break; + } + } + if (item.isSelected()) { + if (index != -1) // it was already selected + { + return; + } + newSelection = new int[oldSelection.length + 1]; + System.arraycopy(oldSelection, 0, newSelection, 0, oldSelection.length); + newSelection[newSelection.length - 1] = itemIndex; + } else { + if (index == -1) // it already wasn't selected + { + return; + } + newSelection = new int[oldSelection.length - 1]; + System.arraycopy(oldSelection, 0, newSelection, 0, index); + System.arraycopy(oldSelection, index + 1, newSelection, index, oldSelection.length - 1 - index); + } + setSelectedIndices(newSelection); + } else { + for (int i = 0; i < getSize(); i++) { + if (getElementAt(i) == ((Item) e.getSource()).getValue()) { + fireContentsChanged(JAXXListModel.this, i, i); + if (isSelectedIndex(i)) { + fireSelectionValueChanged(i, i, false); + } + return; + } + } + } + } + }; + for (Item item : items) { + item.addPropertyChangeListener(listener); + } + } + + + public Object getElementAt(int i) { + return items.get(i).getValue(); + } + + + public int getSize() { + return items.size(); + } + } + + public JAXXList() { + setCellRenderer(new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + ListModel model = list.getModel(); + if (model instanceof JAXXListModel) { + Item item = ((JAXXListModel) model).items.get(index); + String label = item.getLabel(); + if (label != null) { + value = label; + } + } + return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + } + }); + + addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent e) { + ListModel model = getModel(); + if (model instanceof JAXXListModel) { + List<Item> items = ((JAXXListModel) model).items; + for (int i = items.size() - 1; i >= 0; i--) { + boolean selected = isSelectedIndex(i); + Item item = items.get(i); + if (selected != item.isSelected()) { + item.setSelected(selected); + } + } + } + } + }); + } + + + // this way we can keep it marked protected and still allow code in this file to call it + @Override + protected void fireSelectionValueChanged(int firstIndex, int lastIndex, boolean isAdjusting) { + super.fireSelectionValueChanged(firstIndex, lastIndex, isAdjusting); + } + + + public void setSelectedValue(Object value) { + super.setSelectedValue(value, true); + } + + + public void setItems(List<Item> items) { + setModel(new JAXXListModel(items)); + List<Integer> selectedIndexList = new ArrayList<Integer>(); + for (int i = 0; i < items.size(); i++) { + if (items.get(i).isSelected()) { + selectedIndexList.add(i); + } + } + int[] selectedIndices = new int[selectedIndexList.size()]; + for (int i = 0; i < selectedIndexList.size(); i++) { + selectedIndices[i] = selectedIndexList.get(i); + } + setSelectedIndices(selectedIndices); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTab.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXTab.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTab.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTab.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,23 @@ +/* +* ##% Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 Code Lutin, +* Tony Chemit +* +* This program is free software; you can redistribute it and/or +* modify it under the terms of the GNU General Public License +* as published by the Free Software Foundation; either version 2 +* of the License, or (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +* ##% */ +package jaxx.runtime.swing; + +/** @author chemit */ +public class JAXXTab extends Table { +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXToggleButton.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXToggleButton.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXToggleButton.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXToggleButton.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,94 @@ +package jaxx.runtime.swing; + +public class JAXXToggleButton extends javax.swing.JToggleButton { + + protected String glueText; + protected String normalText; + protected String glueTooltipText; + protected String normalTooltipText; + protected int normalMnemonic; + protected int glueMnemonic; + + protected boolean _init; + + + public String getGlueText() { + return glueText; + } + + public String getNormalText() { + return normalText; + } + + public String getGlueTooltipText() { + return glueTooltipText; + } + + public String getNormalTooltipText() { + return normalTooltipText; + } + + public void setGlueText(String glueText) { + this.glueText = glueText; + + } + + public void setNormalText(String normalText) { + this.normalText = normalText; + + } + + public void setGlueTooltipText(String glueTooltipText) { + this.glueTooltipText = glueTooltipText; + } + + public int getNormalMnemonic() { + return normalMnemonic; + } + + public void setNormalMnemonic(int normalMnemonic) { + this.normalMnemonic = normalMnemonic; + } + + public int getGlueMnemonic() { + return glueMnemonic; + } + + public void setGlueMnemonic(int glueMnemonic) { + this.glueMnemonic = glueMnemonic; + } + + public void setNormalTooltipText(String normalTooltipText) { + this.normalTooltipText = normalTooltipText; + if (!_init) { + init(); + _init = true; + } + } + + @Override + public void setSelected(boolean b) { + super.setSelected(b); + if (isSelected()) { + setText(getGlueText()); + setToolTipText(getGlueTooltipText()); + setMnemonic(getGlueMnemonic()); + } else { + setText(getNormalText()); + setToolTipText(getNormalTooltipText()); + setMnemonic(getNormalMnemonic()); + } + revalidate(); + } + + public void init() { + setSelected(false); + } + + /* end raw body code */ + public JAXXToggleButton() { + super(); + _init = false; + } + +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTree.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/JAXXTree.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTree.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/JAXXTree.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,213 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.JTree; +import javax.swing.event.TreeModelEvent; +import javax.swing.event.TreeModelListener; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeModel; +import javax.swing.tree.TreePath; +import java.awt.Component; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.util.ArrayList; +import java.util.List; + +public class JAXXTree extends JTree { + private static final String SYNTHETIC = "<synthetic root node>"; + + public class JAXXTreeModel implements TreeModel { + private Item root; + private List<TreeModelListener> listeners = new ArrayList<TreeModelListener>(); + + public JAXXTreeModel(List<Item> items) { + if (items.size() == 1) { + this.root = items.get(0); + } + else { + this.root = new Item(null, null, SYNTHETIC, false); + for (Item item : items) { + root.addChild(item); + } + } + + PropertyChangeListener listener = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent e) { + if (e.getPropertyName().equals(Item.SELECTED_PROPERTY)) { + Item item = (Item) e.getSource(); + if (item.isSelected()) { + addSelectionPath(getTreePath(item)); + } + else { + removeSelectionPath(getTreePath(item)); + } + } else { + Item item = (Item) e.getSource(); + boolean root = item.getParent() == null; + TreePath path = !root ? getTreePath(item.getParent()) : null; + fireTreeNodesChanged(new TreeModelEvent(JAXXTreeModel.this, path, + !root ? new int[]{item.getParent().getChildren().indexOf(item)} : null, + new Object[]{item.getValue()})); + } + } + }; + addPropertyChangeListener(root, listener); + } + + + private void addPropertyChangeListener(Item item, PropertyChangeListener listener) { + item.addPropertyChangeListener(listener); + List<Item> children = item.getChildren(); + for (Item aChildren : children) { + addPropertyChangeListener(aChildren, listener); + } + } + + + public void addTreeModelListener(TreeModelListener listener) { + listeners.add(listener); + } + + + /* This is an inefficient implementation, but hand-coded tree structures are unlikely to contain +enough nodes for that to really matter. This could be sped up with caching. */ + private Item findItem(Object value) { + return findItem(root, value); + } + + + private Item findItem(Item node, Object value) { + if (node.getValue() == value) + return node; + else { + List<Item> children = node.getChildren(); + for (Item aChildren : children) { + Item result = findItem(aChildren, value); + if (result != null) + return result; + } + return null; + } + } + + + private TreePath getTreePath(Item node) { + List<Object> path = new ArrayList<Object>(); + while (node != null) { + path.add(0, node.getValue()); + node = node.getParent(); + } + return new TreePath(path.toArray()); + } + + + public Object getChild(Object parent, int index) { + Item node = findItem(parent); + return node.getChildren().get(index).getValue(); + } + + + public int getChildCount(Object parent) { + Item node = findItem(parent); + return node.getChildren().size(); + } + + + public int getIndexOfChild(Object parent, Object child) { + Item node = findItem(parent); + List<Item> children = node.getChildren(); + for (int i = 0,j = children.size();i<j; i++) + if (children.get(i).getValue() == child) { + return i; + } + return -1; + } + + + public Object getRoot() { + return root.getValue(); + } + + + public boolean isLeaf(Object node) { + Item item = findItem(node); + return item != null && item.getChildren().size() == 0; + } + + + public void removeTreeModelListener(TreeModelListener listener) { + listeners.remove(listener); + } + + + public void fireTreeNodesChanged(TreeModelEvent e) { + for (TreeModelListener listener : listeners) { + listener.treeNodesChanged(e); + } + } + + + public void valueForPathChanged(TreePath path, Object newValue) { + } + } + + public JAXXTree() { + setCellRenderer(new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + TreeModel model = tree.getModel(); + if (model instanceof JAXXTreeModel) { + Item item = ((JAXXTreeModel) model).findItem(value); + if (item != null) { + String label = item.getLabel(); + if (label != null) { + value = label; + } + } + } + return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + } + }); + + addTreeSelectionListener(new TreeSelectionListener() { + public void valueChanged(TreeSelectionEvent e) { + TreeModel model = getModel(); + if (model instanceof JAXXTreeModel) { + scan((JAXXTreeModel) model, ((JAXXTreeModel) model).root); + } + } + + + private void scan(JAXXTreeModel model, Item item) { + TreePath path = model.getTreePath(item); + if (item.isSelected() != isPathSelected(path)) { + item.setSelected(!item.isSelected()); + } + List<Item> children = item.getChildren(); + for (Item aChildren : children) { + scan(model, aChildren); + } + } + }); + } + + + public void setItems(List<Item> items) { + JAXXTreeModel model = new JAXXTreeModel(items); + if (model.getRoot() != null) { + setRootVisible(model.getRoot() != SYNTHETIC); + } + setModel(model); + } + + + public Object getSelectionValue() { + TreePath selectionPath = getSelectionPath(); + return selectionPath != null ? selectionPath.getLastPathComponent() : null; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Spacer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Spacer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Spacer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Spacer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,10 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.JComponent; + +public class Spacer extends JComponent { +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfo.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/TabInfo.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfo.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfo.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,165 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.Icon; +import javax.swing.event.SwingPropertyChangeSupport; +import java.awt.Color; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +public class TabInfo { + public static String BACKGROUND_PROPERTY = "background"; + public static String DISABLED_ICON_PROPERTY = "disabledIcon"; + public static String DISPLAYED_MNEMONIC_INDEX_PROPERTY = "displayedMnemonicIndex"; + public static String ENABLED_PROPERTY = "enabled"; + public static String FOREGROUND_PROPERTY = "foreground"; + public static String ICON_PROPERTY = "icon"; + public static String MNEMONIC_PROPERTY = "mnemonic"; + public static String TITLE_PROPERTY = "title"; + public static String TOOL_TIP_TEXT_PROPERTY = "toolTipText"; + + private String id; + private Color background; + private Icon disabledIcon; + private int displayedMnemonicIndex = -1; + private boolean enabled = true; + private Color foreground; + private Icon icon; + private int mnemonic = -1; + private String title; + private String toolTipText; + + private PropertyChangeSupport propertyChangeSupport; + + public TabInfo() { + } + + public TabInfo(String id) { + this.id = id; + } + + public String getId() { + return id; + } + + public Color getBackground() { + return background; + } + + public void setBackground(Color background) { + Color oldValue = this.background; + this.background = background; + firePropertyChange(BACKGROUND_PROPERTY, oldValue, background); + } + + public Icon getDisabledIcon() { + return disabledIcon; + } + + public void setDisabledIcon(Icon disabledIcon) { + Icon oldValue = this.disabledIcon; + this.disabledIcon = disabledIcon; + firePropertyChange(DISABLED_ICON_PROPERTY, oldValue, disabledIcon); + } + + public int getDisplayedMnemonicIndex() { + return displayedMnemonicIndex; + } + + public void setDisplayedMnemonicIndex(int displayedMnemonicIndex) { + int oldValue = this.displayedMnemonicIndex; + this.displayedMnemonicIndex = displayedMnemonicIndex; + firePropertyChange(DISPLAYED_MNEMONIC_INDEX_PROPERTY, oldValue, displayedMnemonicIndex); + } + + public boolean isEnabled() { + return enabled; + } + + public void setEnabled(boolean enabled) { + boolean oldValue = this.enabled; + this.enabled = enabled; + firePropertyChange(ENABLED_PROPERTY, oldValue, enabled); + } + + public Color getForeground() { + return foreground; + } + + public void setForeground(Color foreground) { + Color oldValue = this.foreground; + this.foreground = foreground; + firePropertyChange(FOREGROUND_PROPERTY, oldValue, foreground); + } + + public Icon getIcon() { + return icon; + } + + public void setIcon(Icon icon) { + Icon oldValue = this.icon; + this.icon = icon; + firePropertyChange(ICON_PROPERTY, oldValue, icon); + } + + public int getMnemonic() { + return mnemonic; + } + + public void setMnemonic(int mnemonic) { + int oldValue = this.mnemonic; + this.mnemonic = mnemonic; + firePropertyChange(MNEMONIC_PROPERTY, oldValue, mnemonic); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + String oldValue = this.title; + this.title = title; + firePropertyChange(TITLE_PROPERTY, oldValue, title); + } + + public String getToolTipText() { + return toolTipText; + } + + public void setToolTipText(String toolTipText) { + String oldValue = this.toolTipText; + this.toolTipText = toolTipText; + firePropertyChange(TOOL_TIP_TEXT_PROPERTY, oldValue, toolTipText); + } + + private PropertyChangeSupport getPropertyChangeSupport() { + if (propertyChangeSupport == null) { + propertyChangeSupport = new SwingPropertyChangeSupport(this); + } + return propertyChangeSupport; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String property, PropertyChangeListener listener) { + getPropertyChangeSupport().addPropertyChangeListener(property, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String property, PropertyChangeListener listener) { + getPropertyChangeSupport().removePropertyChangeListener(property, listener); + } + + protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) { + if (propertyChangeSupport != null) + getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfoPropertyChangeListener.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/TabInfoPropertyChangeListener.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfoPropertyChangeListener.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/TabInfoPropertyChangeListener.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,41 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.Icon; +import javax.swing.JTabbedPane; +import java.awt.Color; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; + +public class TabInfoPropertyChangeListener implements PropertyChangeListener { + private JTabbedPane tabs; + private int tabIndex; + + public TabInfoPropertyChangeListener(JTabbedPane tabs, int tabIndex) { + this.tabs = tabs; + this.tabIndex = tabIndex; + } + + public void propertyChange(PropertyChangeEvent e) { + String name = e.getPropertyName(); + if (name.equals(TabInfo.TITLE_PROPERTY)) + tabs.setTitleAt(tabIndex, (String) e.getNewValue()); + else if (name.equals(TabInfo.TOOL_TIP_TEXT_PROPERTY)) + tabs.setToolTipTextAt(tabIndex, (String) e.getNewValue()); + else if (name.equals(TabInfo.FOREGROUND_PROPERTY)) + tabs.setForegroundAt(tabIndex, (Color) e.getNewValue()); + else if (name.equals(TabInfo.BACKGROUND_PROPERTY)) + tabs.setBackgroundAt(tabIndex, (Color) e.getNewValue()); + else if (name.equals(TabInfo.MNEMONIC_PROPERTY)) + tabs.setMnemonicAt(tabIndex, (Integer) e.getNewValue()); + else if (name.equals(TabInfo.DISPLAYED_MNEMONIC_INDEX_PROPERTY)) + tabs.setDisplayedMnemonicIndexAt(tabIndex, (Integer) e.getNewValue()); + else if (name.equals(TabInfo.ICON_PROPERTY)) + tabs.setIconAt(tabIndex, (Icon) e.getNewValue()); + else if (name.equals(TabInfo.DISABLED_ICON_PROPERTY)) + tabs.setDisabledIconAt(tabIndex, (Icon) e.getNewValue()); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Table.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Table.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Table.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Table.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,63 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.JPanel; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.LayoutManager; + +/** + * Panel which uses a {@link GridBagLayout} by default. + * + * @author Ethan Nicholas + */ +public class Table extends JPanel { + public static final Insets DEFAULT_INSETS = new Insets(3, 3, 3, 3); + + private GridBagConstraints tableConstraints = new GridBagConstraints(); + private GridBagConstraints rowConstraints = null; + private GridBagConstraints cellConstraints = null; + + + public Table() { + super.setLayout(new GridBagLayout()); + + tableConstraints.insets = DEFAULT_INSETS; + } + + + public void setLayout(LayoutManager layout) { + // do nothing + } + + + public GridBagConstraints getTableConstraints() { + return tableConstraints; + } + + + public GridBagConstraints getRowConstraints() { + return rowConstraints; + } + + + public GridBagConstraints getCellConstraints() { + return cellConstraints; + } + + + public void newRow() { + tableConstraints.gridy++; + rowConstraints = (GridBagConstraints) tableConstraints.clone(); + } + + + public void newCell() { + rowConstraints.gridx++; + cellConstraints = (GridBagConstraints) rowConstraints.clone(); + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Utils.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/Utils.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Utils.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/Utils.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,153 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.DefaultComboBoxModel; +import javax.swing.ImageIcon; +import javax.swing.JComboBox; +import javax.swing.JTable; +import javax.swing.SwingUtilities; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import javax.swing.text.AbstractDocument; +import javax.swing.text.JTextComponent; +import java.lang.reflect.Field; +import java.util.Collection; + +public class Utils { + private static Field numReaders; + private static Field notifyingListeners; + + public static void setText(final JTextComponent c, final String text) { + try { + // AbstractDocument deadlocks if we try to acquire a write lock while a read lock is held by the current thread + // If there are any readers, dispatch an invokeLater. This should only happen in the event of circular bindings. + // Similarly, circular bindings can result in an "Attempt to mutate in notification" error, which we deal with + // by checking for the 'notifyingListeners' property. + AbstractDocument document = (AbstractDocument) c.getDocument(); + if (numReaders == null) { + numReaders = AbstractDocument.class.getDeclaredField("numReaders"); + numReaders.setAccessible(true); + } + if (notifyingListeners == null) { + notifyingListeners = AbstractDocument.class.getDeclaredField("notifyingListeners"); + notifyingListeners.setAccessible(true); + } + + if (notifyingListeners.get(document).equals(Boolean.TRUE)) { + return; + } + + if ((Integer) numReaders.get(document) > 0) { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (!c.getText().equals(text)) { + c.setText(text); + } + } + }); + return; + } + + String oldText = c.getText(); + if (oldText == null || !oldText.equals(text)) { + c.setText(text); + } + } + catch (NoSuchFieldException e) { + throw new RuntimeException(e); + } + catch (IllegalAccessException e) { + throw new RuntimeException(e); + } + catch (SecurityException e) { + c.setText(text); + } + } + + /** + * + * @param path icones from path /icons + * @return the icone + * @deprecated prefer use {@link jaxx.runtime.Util#createImageIcon(String)} + */ + @Deprecated + public static ImageIcon createImageIcon(String path) { + java.net.URL imgURL = Utils.class.getResource("/icons/" + path); + if (imgURL != null) { + return new ImageIcon(imgURL); + } else { + throw new IllegalArgumentException("could not find icon " + path); + } + } + + /** + * + * @param name icones from path /icons/action-xx.png + * @return the icone + * @deprecated prefer use {@link jaxx.runtime.Util#createActionIcon(String)} + */ + @Deprecated + public static ImageIcon createActionIcon(String name) { + return createImageIcon("action-" + name + ".png"); + } + + /** + * + * @param name icones from path /icons/i18n/xx-.png icones + * @return the icone + * @deprecated prefer use {@link jaxx.runtime.Util#createI18nIcon(String)} + */ + @Deprecated + public static ImageIcon createI18nIcon(String name) { + return createImageIcon("i18n/" + name + ".png"); + } + + /** + * Fill a combo box model with some datas, and select after all the given object + * + * @param combo the combo to fill + * @param data data ot inject in combo + * @param select the object to select in combo after reflling his model + */ + public static void fillComboBox(JComboBox combo, Collection<?> data, Object select) { + if (!(combo.getModel() instanceof DefaultComboBoxModel)) { + throw new IllegalArgumentException("this method need a DefaultComboBoxModel for this model but was " + combo.getModel().getClass()); + } + DefaultComboBoxModel model = (DefaultComboBoxModel) combo.getModel(); + // evince the model + model.removeListDataListener(combo); + model.removeAllElements(); + for (Object o : data) { + model.addElement(o); + } + // attach the model + model.addListDataListener(combo); + model.setSelectedItem(select); + } + + public static void fixTableColumnWidth(JTable table, int columnIndex, int width) { + TableColumn column = table.getColumnModel().getColumn(columnIndex); + column.setMaxWidth(width); + column.setMinWidth(width); + column.setWidth(width); + column.setPreferredWidth(width); + } + + public static void setTableColumnEditor(JTable table, int columnIndex, TableCellEditor editor) { + TableColumn column = table.getColumnModel().getColumn(columnIndex); + column.setCellEditor(editor); + } + + public static void setTableColumnRenderer(JTable table, int columnIndex, TableCellRenderer editor) { + TableColumn column = table.getColumnModel().getColumn(columnIndex); + column.setCellRenderer(editor); + } + + public static void setI18nTableHeaderRenderer(JTable table, String... libelles) { + table.getTableHeader().setDefaultRenderer(new I18nTableCellRenderer(table.getTableHeader().getDefaultRenderer(), libelles)); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBox.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/VBox.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBox.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBox.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,101 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.JPanel; +import java.awt.Insets; + +/** + * Panel which uses a {@link VBoxLayout} by default. + * + * @author Ethan Nicholas + */ +public class VBox extends JPanel { + public static final String SPACING_PROPERTY = "spacing"; + public static final String MARGIN_PROPERTY = "margin"; + public static final String HORIZONTAL_ALIGNMENT_PROPERTY = "horizontalAlignment"; + public static final String VERTICAL_ALIGNMENT_PROPERTY = "verticalAlignment"; + + private Insets margin; + + public VBox() { + super(new VBoxLayout()); + } + + + /** + * Returns the spacing between components, in pixels. Spacing is applied between components only, + * not to the top or bottom of the container. + * + * @return spacing between components + */ + public int getSpacing() { + return ((VBoxLayout) getLayout()).getSpacing(); + } + + + /** + * Sets the spacing between components. Spacing is applied between components only, + * not to the top or bottom of the container. + * + * @param spacing new spacing value + */ + public void setSpacing(int spacing) { + int oldValue = getSpacing(); + ((VBoxLayout) getLayout()).setSpacing(spacing); + firePropertyChange(SPACING_PROPERTY, oldValue, spacing); + revalidate(); + } + + + public int getHorizontalAlignment() { + return ((VBoxLayout) getLayout()).getHorizontalAlignment(); + } + + + public void setHorizontalAlignment(int horizontalAlignment) { + int oldValue = getHorizontalAlignment(); + ((VBoxLayout) getLayout()).setHorizontalAlignment(horizontalAlignment); + firePropertyChange(HORIZONTAL_ALIGNMENT_PROPERTY, oldValue, horizontalAlignment); + revalidate(); + } + + + public int getVerticalAlignment() { + return ((VBoxLayout) getLayout()).getVerticalAlignment(); + } + + + public void setVerticalAlignment(int verticalAlignment) { + int oldValue = getVerticalAlignment(); + ((VBoxLayout) getLayout()).setVerticalAlignment(verticalAlignment); + firePropertyChange(VERTICAL_ALIGNMENT_PROPERTY, oldValue, verticalAlignment); + revalidate(); + } + + + public Insets getMargin() { + return margin; + } + + + public void setMargin(Insets margin) { + Insets oldValue = this.margin; + this.margin = (Insets) margin.clone(); + firePropertyChange(MARGIN_PROPERTY, oldValue, margin); + } + + + public Insets getInsets() { + Insets result = super.getInsets(); + if (margin != null) { + result.top += margin.top; + result.left += margin.left; + result.right += margin.right; + result.bottom += margin.bottom; + } + return result; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBoxLayout.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/VBoxLayout.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBoxLayout.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/VBoxLayout.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,132 @@ +/* + * Copyright 2006 Ethan Nicholas. All rights reserved. + * Use is subject to license terms. + */ +package jaxx.runtime.swing; + +import javax.swing.SwingConstants; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; + +/** + * Vertical box layout. The layout rules followed by this class are quite different than the core BoxLayout class, + * and in general represent a more useful algorithm. + * + * @author Ethan Nicholas + */ +public class VBoxLayout implements LayoutManager { + private int spacing = 6; + private int horizontalAlignment = SwingConstants.LEFT; + private int verticalAlignment = SwingConstants.TOP; + + + public int getSpacing() { + return spacing; + } + + + public void setSpacing(int spacing) { + this.spacing = spacing; + } + + + public int getHorizontalAlignment() { + return horizontalAlignment; + } + + + public void setHorizontalAlignment(int horizontalAlignment) { + this.horizontalAlignment = horizontalAlignment; + } + + + public int getVerticalAlignment() { + return verticalAlignment; + } + + + public void setVerticalAlignment(int verticalAlignment) { + this.verticalAlignment = verticalAlignment; + } + + + public void addLayoutComponent(String name, Component comp) { + } + + + public void layoutContainer(Container parent) { + Insets insets = parent.getInsets(); + int parentWidth = parent.getSize().width - insets.left - insets.right; + int count = parent.getComponentCount(); + Dimension preferredSize = parent.getPreferredSize(); + int y; + switch (verticalAlignment) { + case SwingConstants.TOP: + y = insets.top; + break; + case SwingConstants.CENTER: + y = insets.top + (parent.getHeight() - preferredSize.height) / 2; + break; + case SwingConstants.BOTTOM: + y = insets.top + (parent.getHeight() - preferredSize.height); + break; + default: + throw new IllegalArgumentException("invalid vertical alignment: " + verticalAlignment); + } + + for (int i = 0; i < count; i++) { + Component component = parent.getComponent(i); + Dimension childPreferredSize = component.getPreferredSize(); + int width = Math.min(childPreferredSize.width, parentWidth); + int x; + switch (horizontalAlignment) { + case SwingConstants.LEFT: + x = insets.left; + break; + case SwingConstants.CENTER: + x = insets.left + (parentWidth - childPreferredSize.width) / 2; + break; + case SwingConstants.RIGHT: + x = insets.left + (parentWidth - childPreferredSize.width); + break; + default: + throw new IllegalArgumentException("invalid horizontal alignment: " + horizontalAlignment); + } + component.setBounds(x, y, width, childPreferredSize.height); + y += childPreferredSize.height + spacing; + } + } + + + public Dimension minimumLayoutSize(Container parent) { + int width = 0; + int height = (parent.getComponentCount() - 1) * spacing; + for (int i = parent.getComponentCount() - 1; i >= 0; i--) { + Dimension minimumSize = parent.getComponent(i).getMinimumSize(); + width = Math.max(width, minimumSize.width); + height += minimumSize.height; + } + Insets insets = parent.getInsets(); + return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom); + } + + + public Dimension preferredLayoutSize(Container parent) { + int width = 0; + int height = (parent.getComponentCount() - 1) * spacing; + for (int i = parent.getComponentCount() - 1; i >= 0; i--) { + Dimension preferredSize = parent.getComponent(i).getPreferredSize(); + width = Math.max(width, preferredSize.width); + height += preferredSize.height; + } + Insets insets = parent.getInsets(); + return new Dimension(width + insets.left + insets.right, height + insets.top + insets.bottom); + } + + + public void removeLayoutComponent(Component comp) { + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeCellRenderer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeCellRenderer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeCellRenderer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeCellRenderer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,69 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXContext; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import jaxx.runtime.swing.navigation.NavigationUtil.NodeRenderer; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.util.StringUtil; + +import javax.swing.JTree; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreePath; +import java.awt.Component; + +/** + * A simple cell renderer which use the {@link NavigationTreeNode#renderer} to display node. + * + * @author chemit + */ +public class NavigationTreeCellRenderer extends DefaultTreeCellRenderer { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationTreeCellRenderer.class); + + protected JAXXContext context; + + protected static long t = 0; + + public NavigationTreeCellRenderer(JAXXContext context) { + this.context = context; + } + + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + TreePath path = tree.getPathForRow(row); + if (path == null) { + return this; + } + + if (value != null) { + long t0 = System.nanoTime(); + NodeRenderer renderer = getNodeRenderer(value); + long t1 = System.nanoTime(); + if (renderer != null) { + value = renderer.toString(context); + long t2 = System.nanoTime(); + if (log.isDebugEnabled()) { + log.debug("use renderer [" + (t++) + "]<" + row + ">" + renderer.decorator + " <" + StringUtil.convertTime(t0, t1) + "/" + StringUtil.convertTime(t1, t2) + ">"); + } + } + } + + return super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + } + + protected NodeRenderer getNodeRenderer(Object value) { + NodeRenderer render = null; + + if (value != null && value instanceof NavigationTreeNode && ((NavigationTreeNode) value).getUserObject() instanceof NodeRenderer) { + + // NodeRenderer used as userObject + NavigationTreeNode navigationTreeNode = (NavigationTreeNode) value; + + render = (NodeRenderer) navigationTreeNode.getUserObject(); + } + return render; + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModel.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,546 @@ +package jaxx.runtime.swing.navigation; + + +import jaxx.runtime.JAXXAction; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXContextEntryDef; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.swing.navigation.NavigationUtil.NodeRenderer; +import org.apache.commons.jxpath.JXPathContext; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeNode; +import java.util.Enumeration; +import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Le modele utilisé pour un arbre de navigation. + * <p/> + * Il est composé de {@link NavigationTreeModel.NavigationTreeNode} + * + * @author chemit + */ +public class NavigationTreeModel extends DefaultTreeModel { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationTreeModel.class); + + static private final long serialVersionUID = 1L; + + /** the separator char used to produce the navigation path of a node. */ + protected final String navigationPathSeparator; + + public NavigationTreeModel(TreeNode root, String navigationPathSeparator) { + super(root); + this.navigationPathSeparator = navigationPathSeparator; + } + + @Override + public NavigationTreeNode getRoot() { + return (NavigationTreeNode) super.getRoot(); + } + + /** + * Search from the root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#navigationPath} valued separated by dot. + * <p/> + * Example : + * <p/> + * <pre>$root.child1.leaf1</pre> + * + * @param path the fully path of the searched node. + * @return the node matching the fully context from the root node, or <code>null</code> if not find. + */ + public NavigationTreeNode findNode(String path) { + return findNode(getRoot(), path, (Pattern) null); + } + + /** + * Apply first the regex pattern to obtain the searched node fi the given <code>regex</code> is not null. + * <p/> + * Search then from the root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}. + * <p/> + * <p/> + * Example : + * <p/> + * <pre>$root.child1.leaf1</pre> + * + * @param path the fully path of the searched node. + * @param regex a optional regex to apply to path before searching + * @return the node matching the fully context from the root node, or <code>null</code> if not found. + */ + public NavigationTreeNode findNode(String path, String regex) { + return findNode(getRoot(), path, regex); + } + + /** + * Apply first the regex pattern to obtain the searched node. + * <p/> + * Search then from the root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}. + * <p/> + * Example : + * <p/> + * <pre>$root.child1.leaf1</pre> + * + * @param path the fully path of the searched node. + * @param regex a optional regex to apply to path before searching + * @return the node matching the fully context from the root node, or <code>null</code> if not found. + */ + public NavigationTreeNode findNode(String path, Pattern regex) { + return findNode(getRoot(), path, regex); + } + + + /** + * Search from a given root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}. + * + * @param root root node to be used + * @param path the fully path of the searched node. + * @return the node matching the fully context from the given root node, or <code>null</code> if not found. + */ + public NavigationTreeNode findNode(NavigationTreeNode root, String path) { + return findNode(root, path, (Pattern) null); + } + + /** + * Apply first the regex pattern to obtain the searched node. + * <p/> + * Search then from a given root node a node named by his fully path (concatenation of nodes) + * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}. + * + * @param root root node to be used + * @param path the fully path of the searched node. + * @param regex a previous regex to apply to path : must have a matches + * @return the node matching the fully context from the given root node, or <code>null</code> if not found. + */ + public NavigationTreeNode findNode(NavigationTreeNode root, String path, String regex) { + return findNode(root, path, regex == null ? null : Pattern.compile(regex)); + } + + /** + * Apply first the regex pattern to obtain the searched node. + * <p/> + * Search then from a given root node a node named by his fully path (concatenation of nodes + * {@link NavigationTreeNode#navigationPath} valued separated by {@link #navigationPathSeparator}. + * + * @param root root node to be used + * @param path the fully path of the searched node. + * @param regex a previous regex to apply to path : must have a matches + * @return the node matching the fully context from the given root node, or <code>null</code> if not found. + */ + public NavigationTreeNode findNode(NavigationTreeNode root, String path, Pattern regex) { + if (regex != null) { + Matcher matcher = regex.matcher(path); + if (!matcher.matches() || matcher.groupCount() < 1) { + log.warn("no matching regex " + regex + " to " + path); + return null; + } + path = matcher.group(1); + if (log.isDebugEnabled()) { + log.debug("matching regex " + regex + " : " + path); + } + } + StringTokenizer stk = new StringTokenizer(path, navigationPathSeparator); + NavigationTreeNode result = root; + // pas the first token (matches the root node) + if (root.isRoot() && stk.hasMoreTokens()) { + String rootPath = stk.nextToken(); + if (!rootPath.equals(root.getNavigationPath())) { + return null; + } + } + while (stk.hasMoreTokens()) { + result = result.getChild(stk.nextToken()); + } + return result; + } + + + /** + * Obtain the associated bean value from context corresponding to node from given navigation path. + * + * @param context the context where to seek value + * @param navigationPath the current context path of the node + * @return the value associated in context with the given navigation path + */ + public Object getJAXXContextValue(JAXXContext context, String navigationPath) { + Object result; + NavigationTreeNode node = findNode(navigationPath, (Pattern) null); + result = getJAXXContextValue(context, node); + return result; + } + + /** + * Obtain the associated bean value from context corresponding to node + * + * @param context the context where to seek value + * @param node the current node + * @return the value associated in context with the given node. + */ + public Object getJAXXContextValue(JAXXContext context, NavigationTreeNode node) { + if (node == null) { + return null; + //fixme should throw a NPE exception + //throw new NullPointerException("node can not be null"); + } + return node.getJAXXContextValue(context); + } + + + @Override + public void nodeChanged(TreeNode node) { + NavigationTreeNode n = (NavigationTreeNode) node; + n.clearCache(); + super.nodeChanged(node); + } + + /** + * la représentation d'un noeud dans le modele {@link NavigationTreeModel} + * + * @author chemit + */ + public class NavigationTreeNode extends DefaultMutableTreeNode { + + private static final long serialVersionUID = 1L; + + /** pour representer le context du noeud. */ + protected String navigationPath; + + /** the JAXXObject class associated with this node (can be null) */ + protected Class<? extends JAXXObject> jaxxClass; + + /** the JAXXAction class associated with this node and will be put in ui context */ + protected Class<? extends JAXXAction> jaxxActionClass; + + /** the definition of the JAXXContext entry associated to this node, if null will seek in parent */ + protected JAXXContextEntryDef jaxxContextEntryDef; + + /** jxPath to process to obtain real value associated from context with the node (can be null) */ + protected String jaxxContextEntryPath; + + /** cache of bean associated with bean to improve performance */ + protected transient Object cachedBean; + + /** renderer of the node */ + protected NodeRenderer renderer; + + public NavigationTreeNode(Object renderer, + Object jaxxContextEntryDef, + String navigationPath, + Class<? extends JAXXObject> jaxxClass, + Class<? extends JAXXAction> jaxxActionClass) { + super(renderer); + if (renderer instanceof NodeRenderer) { + // the renderer must keep a reference of the node + this.renderer = (NodeRenderer) renderer; + this.renderer.setNode(this); + } else if (renderer instanceof String) { + // nothing special to be done + } else if (renderer != null) { + // wrong renderer type + throw new IllegalArgumentException("to define a renderer, must be a String (simple libelle) or a " + NodeRenderer.class + ", but was " + renderer); + } + this.navigationPath = navigationPath; + this.jaxxClass = jaxxClass; + this.jaxxActionClass = jaxxActionClass; + + if (jaxxContextEntryDef instanceof JAXXContextEntryDef) { + this.jaxxContextEntryDef = ((JAXXContextEntryDef) jaxxContextEntryDef); + } else if (jaxxContextEntryDef instanceof String) { + this.jaxxContextEntryPath = (String) jaxxContextEntryDef; + } else if (jaxxContextEntryDef != null) { + // wrong context definition type + throw new IllegalArgumentException("to define a context link, must be a String (jxpath) or a " + JAXXContextEntryDef.class + ", but was " + jaxxContextEntryDef); + } + } + + public NavigationTreeNode(Object renderer, + JAXXContextEntryDef jaxxContextEntryDef, + String jaxxContextEntryPath, + String navigationPath, + Class<? extends JAXXObject> jaxxClass, + Class<? extends JAXXAction> jaxxActionClass) { + super(renderer); + if (renderer instanceof NodeRenderer) { + // the renderer must keep a reference of the node + this.renderer = (NodeRenderer) renderer; + this.renderer.setNode(this); + } else if (renderer instanceof String) { + // nothing special to be done + } else if (renderer != null) { + // wrong renderer type + throw new IllegalArgumentException("to define a renderer, must be a String (simple libelle) or a " + NodeRenderer.class + ", but was " + renderer); + } + this.navigationPath = navigationPath; + this.jaxxClass = jaxxClass; + this.jaxxActionClass = jaxxActionClass; + this.jaxxContextEntryDef = jaxxContextEntryDef; + this.jaxxContextEntryPath = jaxxContextEntryPath; + } + + public String getNavigationPath() { + return navigationPath; + } + + public void setNavigationPath(String navigationPath) { + this.navigationPath = navigationPath; + } + + public Class<? extends JAXXObject> getJaxxClass() { + return jaxxClass; + } + + public void setJaxxClass(Class<? extends JAXXObject> jaxxClass) { + this.jaxxClass = jaxxClass; + } + + public Class<? extends JAXXAction> getJaxxActionClass() { + return jaxxActionClass; + } + + public void setJaxxActionClass(Class<? extends JAXXAction> jaxxActionClass) { + this.jaxxActionClass = jaxxActionClass; + } + + public JAXXContextEntryDef getJaxxContextEntryDef() { + return jaxxContextEntryDef; + } + + public void setJaxxContextEntryDef(JAXXContextEntryDef jaxxContextEntryDef) { + this.jaxxContextEntryDef = jaxxContextEntryDef; + } + + public String getJaxxContextEntryPath() { + return jaxxContextEntryPath; + } + + public void setJaxxContextEntryPath(String jaxxContextEntryPath) { + this.jaxxContextEntryPath = jaxxContextEntryPath; + } + + public Class<?> getInternalClass() { + return renderer.getInternalClass(); + } + + /** @return the fully context pathof the node from the root node to this. */ + public String getContextPath() { + TreeNode[] path = getPath(); + StringBuilder sb = new StringBuilder(); + for (TreeNode treeNode : path) { + NavigationTreeNode myNode = (NavigationTreeNode) treeNode; + sb.append(navigationPathSeparator).append(myNode.getNavigationPath()); + } + return sb.substring(1); + } + + @Override + public NavigationTreeNode getChildAt(int index) { + return (NavigationTreeNode) super.getChildAt(index); + } + + @Override + public NavigationTreeNode getParent() { + return (NavigationTreeNode) super.getParent(); + } + + /** + * @param navigationPath the name of the {@link #navigationPath} to be matched in the cild of this node. + * @return the child of this node with given {@link # navigationPath} value. + */ + public NavigationTreeNode getChild(String navigationPath) { + for (int i = 0, max = getChildCount(); i < max; i++) { + NavigationTreeNode son = getChildAt(i); + if (navigationPath.equals(son.getNavigationPath())) { + return son; + } + } + return null; + } + + /** + * Obtain the associated bean value from context corresponding to node + * + * @param context the context to seek + * @return the value associated in context with the given context path + */ + public Object getJAXXContextValue(JAXXContext context) { + Object result; + + if (cachedBean != null) { + // use cached bean + return cachedBean; + } + + if (getJaxxContextEntryDef() != null && jaxxContextEntryPath == null) { + // the node maps directly a value in context, with no jxpath resolving + result = getJaxxContextEntryDef().getContextValue(context); + // save in cache + setCachedBean(result); + return result; + } + // find the first ancestor node with a context def + NavigationTreeNode parentNode = getFirstAncestorWithDef(); + if (parentNode == null) { + log.warn("could not find a ancestor node with a definition of a context entry from node (" + this + ")"); + // todo must be an error + // no parent found + return null; + } + + Object parentBean = parentNode.getJaxxContextEntryDef().getContextValue(context); + + if (parentBean == null) { + // must be an error no bean found + log.warn("culd not find a bean attached in context from context entry definition " + parentNode.getJaxxContextEntryDef()); + return null; + } + + if (parentNode.jaxxContextEntryPath != null) { + // apply the jxpath on parentBean + JXPathContext jxcontext = JXPathContext.newContext(parentBean); + + parentBean = jxcontext.getValue(parentNode.jaxxContextEntryPath); + } + + // save in cache + parentNode.setCachedBean(parentBean); + + if (this == parentNode) { + // current node is the node matching the context entry value and no jxpath is found + return parentBean; + } + + if (jaxxContextEntryPath == null) { + // todo must be an error + log.warn("must find a jaxxContextEntryPath on node (" + this + ")"); + return null; + } + + String jxpathExpression = computeJXPath(jaxxContextEntryPath, parentNode); + + if (jxpathExpression == null) { + /// todo must be an error + log.warn("could not build jxpath from node " + parentNode + " to " + this); + // could not retreave the jxpath... + return null; + } + if (jxpathExpression.startsWith("[")) { + // special case when we want to access a collection + jxpathExpression = '.' + jxpathExpression; + } + if (log.isDebugEnabled()) { + log.debug("jxpath : " + jxpathExpression); + } + + JXPathContext jxcontext = JXPathContext.newContext(parentBean); + + result = jxcontext.getValue(jxpathExpression); + + // save in cache + setCachedBean(result); + + return result; + } + + /** + * @return the first ancestor with a none null {@link #jaxxContextEntryDef} + * or <code>null</code> if none find.. + */ + protected NavigationTreeNode getFirstAncestorWithDef() { + if (jaxxContextEntryDef != null) { + return this; + } + return getParent() == null ? null : getParent().getFirstAncestorWithDef(); + } + + protected String computeJXPath(String expr, NavigationTreeNode parentNode) { + if (parentNode == this) { + // reach the parent limit node, return the expr computed + return expr; + } + int firstIndex = expr.indexOf(".."); + int lastIndex = expr.lastIndexOf(".."); + + if (firstIndex == -1) { + // this is a error, since current node is not parent limit node, + // we must find somewhere a way to go up in nodes + throw new IllegalArgumentException(expr + " should contains at least one \"..\""); + } + + if (firstIndex != 0) { + // this is a error, the ../ must be at the beginning of the expression + throw new IllegalArgumentException("\"..\" must be at the beginning but was : " + expr); + } + + NavigationTreeNode ancestor = getParent(); + + if (firstIndex == lastIndex) { + // found only one go up, so must be substitute by the parent node context + + String newExpr = expr.substring(2); + //String newExpr = expr.substring(expr.startsWith("../") ? 3 : 2); + + if (getParent().equals(parentNode)) { + + // parent node is the final parent node, so no substitution needed + return newExpr; + //return parentNode.computeJXPath(newExpr, parentNode); + } + + // ancestor must have a jaxxContextEntryPath + if (ancestor.jaxxContextEntryPath == null) { + throw new IllegalArgumentException("with the expression " + expr + ", the ancestor node (" + ancestor + ") must have a jaxxContextEntryPath definition, but was not "); + } + + newExpr = ancestor.jaxxContextEntryPath + newExpr; + + return ancestor.computeJXPath(newExpr, parentNode); + } + + // have more than one go up, so the ancestor node can not have a jaxxContextEntryPath + if (ancestor.jaxxContextEntryPath != null) { + throw new IllegalArgumentException("with the expression " + expr + ", the ancestor node can not have a jaxxContextEntryPath definition"); + } + + // substitute the last ..[/] and delegate to ancestor + String newExpr = expr.substring(0, lastIndex - 1) + expr.substring(lastIndex + (expr.charAt(lastIndex + 3) == '/' ? 3 : 2)); + + return ancestor.computeJXPath(newExpr, parentNode); + } + + public void clearCache() { + + // clear bean cache + cachedBean = null; + + // clear render cache + if (renderer != null) { + renderer.setRendererCachedValue(null); + } + + // clear cache in childs + Enumeration childs = this.children(); + while (childs.hasMoreElements()) { + NavigationTreeNode o = (NavigationTreeNode) childs.nextElement(); + o.clearCache(); + } + } + + public Object getCachedBean() { + return cachedBean; + } + + public void setCachedBean(Object cachedBean) { + this.cachedBean = cachedBean; + } + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeModelBuilder.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,155 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.Decorator; +import jaxx.runtime.JAXXAction; +import jaxx.runtime.JAXXContextEntryDef; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import jaxx.runtime.swing.navigation.NavigationUtil.NodeRenderer; + +/** @author chemit */ +public class NavigationTreeModelBuilder { + + protected NavigationTreeModel model; + + public NavigationTreeModelBuilder(String navigationSeparator) { + model = new NavigationTreeModel(null, navigationSeparator); + } + + public NavigationTreeModel getModel() { + return model; + } + + public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, + JAXXContextEntryDef entryDef, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(libelle), entryDef, entryPath, contextName, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, + JAXXContextEntryDef entryDef, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(libelle), entryDef, contextName, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public NavigationTreeNode build(NavigationTreeNode parentNode, String libelle, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(libelle), entryPath, contextName, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, + JAXXContextEntryDef entryDef, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(decorator), entryDef, entryPath, contextName, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, + JAXXContextEntryDef entryDef, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(decorator), entryDef, contextName, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + public NavigationTreeNode build(NavigationTreeNode parentNode, Decorator<?> decorator, + String entryPath, + String contextName, + Class<? extends JAXXObject> uiClass, + Class<? extends JAXXAction> actionClass) { + NavigationTreeNode node = model.new NavigationTreeNode(new NodeRenderer(decorator), entryPath, contextName, uiClass, actionClass); + return addChildNode(parentNode, node); + } + + protected NavigationTreeNode addChildNode(NavigationTreeNode parentNode, NavigationTreeNode node) { + if (parentNode == null) { + model.setRoot(node); + } else { + parentNode.add(node); + } + model.nodeStructureChanged(parentNode); + return node; + } + + public NavigationTreeNode removeChildNode(NavigationTreeNode node) { + NavigationTreeNode parentNode = node.getParent(); + /*if (parentNode != null) { + parentNode.remove(node); + }*/ + model.removeNodeFromParent(node); + return parentNode; + } + + public static abstract class ChildBuilder<O> { + + protected NavigationTreeModelBuilder builder; + + protected ChildBuilder(NavigationTreeModelBuilder builder) { + this.builder = builder; + } + + protected abstract void init(Class<? extends O> klass); + + protected abstract Decorator<? extends O> getDecorator(O child); + + protected abstract String getJXPath(O child); + + protected abstract String getNavigationPath(O child); + + public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, java.util.Collection<? extends O> beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { + + if (beans == null || beans.isEmpty()) { + // no bean to treate + return; + } + + init(klass); + + NavigationTreeNode node; + + for (O o : beans) { + node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); + if (cacheValues) { + // cache the bean value to improve performance + node.setCachedBean(o); + } + } + } + + public void build(NavigationTreeNode parent, boolean cacheValues, Class<? extends O> klass, O[] beans, Class<? extends JAXXObject> ui, Class<? extends JAXXAction> actionClass) { + + if (beans == null || beans.length == 0) { + // no bean to treate + return; + } + + init(klass); + + NavigationTreeNode node; + + for (O o : beans) { + node = builder.build(parent, getDecorator(o), getJXPath(o), getNavigationPath(o), ui, actionClass); + if (cacheValues) { + // cache the bean value to improve performance + node.setCachedBean(o); + } + } + } + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapter.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,238 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXAction; +import jaxx.runtime.JAXXContextEntryDef; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JTree; +import javax.swing.event.TreeSelectionEvent; +import javax.swing.event.TreeSelectionListener; +import javax.swing.tree.TreePath; +import java.awt.Component; + +/** A {@link javax.swing.event.TreeSelectionListener} implementation@author chemit */ +public abstract class NavigationTreeSelectionAdapter implements TreeSelectionListener { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationTreeSelectionAdapter.class); + + static public final String NAVIGATION_CONTEXT_PATH = "navigation-context-path"; + + static public final String NAVIGATION_SELECTED_NODE = "navigation-selected-node"; + + static public final String NAVIGATION_SELECTED_BEAN = "navigation-selected-bean"; + + static public final JAXXContextEntryDef<Boolean> GO_BACK_DEF = JAXXContextEntryDef.newDef("goBack", Boolean.class); + + /** defined the stategy of instanciation of ui */ + public enum Strategy { + /** instanciate a ui for a node */ + PER_NODE, + /** instanciate only one a ui for a type,nodes will share the instanciation */ + PER_UI_TYPE + } + + /** la classe d'ui par defaut, associé à un noeud de l'arbe */ + protected Class<? extends JAXXObject> defaultUIClass; + + protected Class<? extends JAXXAction> defaultUIHandlerClass; + + /** l'ui contenant l'arbre de navigation */ + protected JAXXObject context; + + protected Strategy strategy; + + protected NavigationTreeSelectionAdapter(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context, Strategy strategy) { + this.defaultUIClass = defaultUIClass; + this.defaultUIHandlerClass = defaultUIHandlerClass; + this.context = context; + this.strategy = strategy; + } + + + protected abstract NavigationTreeModel getNavigationTreeModel(); + + /** + * @return le composent actuellement visible associé au noeud courant ou au noeud précédent + * lors d'un changement de noeud. + */ + protected abstract Component getCurrentUI(); + + /** + * @param node le noeud associé à l'ui à retrouver + * @return l'ui associé au novueau noeud sélectionné + */ + protected abstract Component getUI(NavigationTreeNode node); + + /** + * @param event l'evenement de selection de noeud + * @param component le composent actuellement visible + * @return <code>true</code> si le composent a bien été fermé, <code>false</code> sinon + * @throws Exception if any + */ + protected abstract boolean closeUI(TreeSelectionEvent event, Component component) throws Exception; + + /** + * Instancie une nouvelle ui associé à un noeud de l'arbre de navigation + * + * @param node le noeud associé à l'ui à créer + * @return la nouvelle ui associée au noeud + * @throws Exception if any + */ + protected abstract Component createUI(NavigationTreeNode node) throws Exception; + + /** + * Ouvre l'ui associée au noeud sélectionné dans l'arbre de navigation. + * + * @param newUI l'ui associé au noeud sélectionné à ouvrir + * @param node le node de l'ui a ouvrir + * @throws Exception if any + */ + protected abstract void openUI(Component newUI, NavigationTreeNode node) throws Exception; + + /** + * Retourne au noeud précdemment sélectionné dans l'arbre de navigation, avec la possibilité de notifier + * une erreure survenue. + * + * @param event l'évènement de changement de noeud sélectionné. + * @param e l'erreur recontrée (ou null si pas d"erreur) + */ + protected abstract void goBackToPreviousNode(TreeSelectionEvent event, Exception e); + + /** + * Prepare le nouveau noeud sélectionné. + * + * @param event l'évènement de selection du noeud + * @return le noeud selectionné et preparé + */ + protected NavigationTreeNode prepareNode(TreeSelectionEvent event) { + NavigationTreeNode node = (NavigationTreeNode) event.getPath().getLastPathComponent(); + + if (node.getJaxxClass() == null) { + // no ui is associated with this node, display a empty content + node.setJaxxClass(defaultUIClass); + } + + if (node.getJaxxActionClass() == null) { + node.setJaxxActionClass(defaultUIHandlerClass); + } + return node; + } + + public void valueChanged(TreeSelectionEvent event) { + if (event.getOldLeadSelectionPath() != null && event.getOldLeadSelectionPath().equals(event.getPath())) { + // do not treate this if no path changed + return; + } + + Boolean goBack = GO_BACK_DEF.getContextValue(context); + if (goBack != null && goBack) { + // do not treate this, apsecial flag told us :) + GO_BACK_DEF.removeContextValue(context); + return; + } + + try { + + NavigationTreeNode node = prepareNode(event); + + String path = node.getContextPath(); + + if (log.isTraceEnabled()) { + log.trace(path); + } + + Component newUI = getUI(node); + Component component = getCurrentUI(); + + if (newUI != null && strategy == Strategy.PER_NODE && newUI.equals(component)) { + // call back from goto back to previous node, do nothing + return; + } + + if (!closeUI(event, component)) { + GO_BACK_DEF.setContextValue(context, Boolean.TRUE); + // previous ui was not closed, so reselect the previous node in navigation + goBackToPreviousNode(event, null); + // and quit + return; + } + + // now, we are free to open the ui associated with the selected node in navigation + + // always clean cache on the node before all + node.cachedBean = null; + if (node.renderer != null) { + node.renderer.setRendererCachedValue(null); + } + // before all, attach bean in context associated with the selected node in naivgation tree + Object data = getNavigationTreeModel().getJAXXContextValue(context, path); + + addSelectedBeanInContext(node, data); + + if (newUI == null) { + // instanciate a new ui associated with the selected node + newUI = createUI(node); + } + + // save in context current node context path + context.setContextValue(node.getContextPath(), NAVIGATION_CONTEXT_PATH); + + // save in context current node + context.setContextValue(node, NAVIGATION_SELECTED_NODE); + + // really open the ui associated with the selected node + openUI(newUI, node); + + } catch (Exception e) { + // remove data from context + + // if any error, go back to previvous node + goBackToPreviousNode(event, e); + } + } + + protected void addSelectedBeanInContext(NavigationTreeNode node, Object data) { + + if (log.isDebugEnabled()) { + log.debug("find data for contextPath <" + node.getContextPath() + "> : " + (data == null ? null : data.getClass())); + } + + context.removeContextValue(Object.class, NAVIGATION_SELECTED_BEAN); + + if (data != null) { + context.setContextValue(data, NAVIGATION_SELECTED_BEAN); + //todo should we not use this to avoid conflict in context ? + context.setContextValue(data); + } + } + + protected String getNodeConstraints(NavigationTreeNode node) { + String constraints; + switch (strategy) { + case PER_NODE: + constraints = node.getContextPath(); + break; + case PER_UI_TYPE: + constraints = node.getJaxxClass().getName(); + break; + default: + throw new IllegalArgumentException("could not find constraint for node : " + node); + } + return constraints; + } + + protected void returnToPreviousNode(JTree tree, TreeSelectionEvent event) { + // go back to previous node + // put in context a tag to not come back again here + TreePath oldPath = event.getOldLeadSelectionPath(); + //NavigationTreeNode oldNode = (NavigationTreeNode) oldPath.getLastPathComponent(); + if (oldPath != null) { + tree.setSelectionPath(oldPath); + } + } + +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapterWithCardLayout.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapterWithCardLayout.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapterWithCardLayout.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationTreeSelectionAdapterWithCardLayout.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,108 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.JAXXAction; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.JAXXInitialContext; +import jaxx.runtime.JAXXObject; +import jaxx.runtime.swing.CardLayout2; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JPanel; +import javax.swing.event.TreeSelectionEvent; +import java.awt.Component; + +/** + * Simple {@link NavigationTreeSelectionAdapter} implementation with a {@link jaxx.runtime.swing.CardLayout2} to manage components to + * associated with tree's nodes. + * <p/> + * For each node, the ui associated has a constraints in a cardlayout which is the node context path. + * <p/> + * A single container managed by the cardlayout is used to display the components associated with tree's nodes. + * + * @author chemit + */ +public abstract class NavigationTreeSelectionAdapterWithCardLayout extends NavigationTreeSelectionAdapter { + + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationTreeSelectionAdapterWithCardLayout.class); + + /** + * All components associated with a tree's node is displayed in a single container. + * + * @return the containter of components + */ + protected abstract JPanel getContentContainer(); + + /** + * the cardlayout managing components associated with tree node. The constraints + * of each component is the node contextPath. + * + * @return the layout used to display components associated with tree's nodes. + */ + protected abstract CardLayout2 getContentLayout(); + + public NavigationTreeSelectionAdapterWithCardLayout(Class<? extends JAXXObject> defaultUIClass, Class<? extends JAXXAction> defaultUIHandlerClass, JAXXObject context, Strategy strategy) { + super(defaultUIClass, defaultUIHandlerClass, context,strategy); + + if (getContentContainer() == null) { + throw new IllegalArgumentException("could not have a null 'contentContainer' in ui " + context); + } + if (getContentLayout() == null) { + throw new IllegalArgumentException("could not have a null 'contentLayout' in ui " + context); + } + } + + protected Component getCurrentUI() { + CardLayout2 layout = getContentLayout(); + JPanel container = getContentContainer(); + return layout.getVisibleComponent(container); + } + + protected Component getUI(NavigationTreeNode node) { + CardLayout2 layout = getContentLayout(); + JPanel container = getContentContainer(); + String path = getNodeConstraints(node); + return layout.contains(path) ? layout.getComponent(container, path) : null; + } + + protected void openUI(Component newUI, NavigationTreeNode node) throws Exception { + + CardLayout2 layout = getContentLayout(); + JPanel container = getContentContainer(); + // switch layout + layout.show(container, getNodeConstraints(node)); + } + + protected boolean closeUI(TreeSelectionEvent event, Component component) throws Exception { + // by default, we says that component was succesfull closed + return true; + } + + protected Component createUI(NavigationTreeNode node) throws Exception { + JAXXObject newUI; + + if (node.getJaxxActionClass() != null) { + JAXXAction action = node.getJaxxActionClass().newInstance(); + // init context with + JAXXInitialContext context = action.init(this.context); + // must instanciate the ui with an JAXXInitialContext + newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(context); + } else { + if (log.isWarnEnabled()) { + log.warn("no action associated with ui " + node.getJaxxClass()); + } + // no action associated, just + newUI = node.getJaxxClass().getConstructor(JAXXContext.class).newInstance(this.context); + } + if (log.isDebugEnabled()) { + log.debug("instanciate new ui " + newUI); + } + + getContentContainer().add((Component) newUI, getNodeConstraints(node)); + return (Component) newUI; + } +} + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-swing/src/main/java/jaxx/runtime/swing/navigation/NavigationUtil.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,154 @@ +package jaxx.runtime.swing.navigation; + +import jaxx.runtime.Decorator; +import jaxx.runtime.JAXXContext; +import jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import static org.codelutin.i18n.I18n._; + +import java.lang.reflect.InvocationTargetException; +import java.util.regex.Pattern; + +/** + * Usefull methods on {@link NavigationTreeModel} and others. + * + * @author chemit + * @see jaxx.runtime.swing.navigation.NavigationTreeModel + * @see jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode + */ +public class NavigationUtil { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(NavigationUtil.class); + + public static String getCurrentNavigationNath(JAXXContext context) { + return context.getContextValue(String.class, NavigationTreeSelectionAdapter.NAVIGATION_CONTEXT_PATH); + } + + public static NavigationTreeNode getSelectedNode(JAXXContext context) { + return context.getContextValue(NavigationTreeNode.class, NavigationTreeSelectionAdapter.NAVIGATION_SELECTED_NODE); + } + + public static <O> O getSelectedBean(JAXXContext context, Class<O> clazz) { + return context.getContextValue(clazz, NavigationTreeSelectionAdapter.NAVIGATION_SELECTED_BEAN); + } + + public static Object getContextValue(JAXXContext context, String contextKey, String navigationPath) throws InvocationTargetException, NoSuchMethodException, IllegalAccessException { + + NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey); + + return navigationModel.getJAXXContextValue(context, navigationPath); + } + + public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath) { + + NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey); + + return navigationModel.findNode(navigationPath); + } + + public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, String regex) { + + NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey); + + return navigationModel.findNode(navigationPath, regex); + } + + + public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, Pattern regex) { + + NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey); + + return navigationModel.findNode(navigationPath, regex); + } + + public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, String regex, String suffix) { + + NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey); + + NavigationTreeNode navigationTreeNode = navigationModel.findNode(navigationPath, regex); + if (navigationTreeNode != null && suffix != null) { + navigationTreeNode = navigationModel.findNode(navigationTreeNode, suffix); + } + return navigationTreeNode; + } + + public static NavigationTreeNode findNode(JAXXContext context, String contextKey, String navigationPath, Pattern regex, String suffix) { + + NavigationTreeModel navigationModel = context.getContextValue(NavigationTreeModel.class, contextKey); + + NavigationTreeNode navigationTreeNode = navigationModel.findNode(navigationPath, regex); + if (navigationTreeNode != null && suffix != null) { + navigationTreeNode = navigationModel.findNode(navigationTreeNode, suffix); + } + return navigationTreeNode; + } + + public static class NodeRenderer implements java.io.Serializable { + + protected String libelle; + + protected Decorator decorator; + + protected NavigationTreeNode node; + + protected Class<?> internalClass; + + protected String rendererCachedValue; + + private static final long serialVersionUID = -1238962588426200861L; + + public NodeRenderer(String libelle) { + this.libelle = libelle; + this.internalClass = String.class; + } + + public NodeRenderer(Decorator decorator) { + this.decorator = decorator; + this.internalClass = decorator.getInternalClass(); + } + + public String toString(JAXXContext context) { + if (rendererCachedValue != null) { + return rendererCachedValue; + } + + String result; + + if (libelle != null) { + // simple libelle renderer + result = _(libelle); + } else { + + // with decorator renderer + + try { + Object bean = node.getJAXXContextValue(context); + result = decorator.toString(bean); + + } catch (Exception e) { + result = ""; + } + } + setRendererCachedValue(result); + return result; + } + + public void setNode(NavigationTreeNode node) { + this.node = node; + } + + public Class<?> getInternalClass() { + return internalClass; + } + + public void setRendererCachedValue(String rendererCachedValue) { + this.rendererCachedValue = rendererCachedValue; + if (log.isDebugEnabled()) { + log.debug(rendererCachedValue); + } + } + } + +} Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator ___________________________________________________________________ Name: svn:ignore + *.iml target *.log Added: lutinjaxx/branches/storm_1/jaxx-runtime-validator/LICENSE.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/LICENSE.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/LICENSE.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,166 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/> + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. + + Each version is given a distinguishing version number. If the +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. + Added: lutinjaxx/branches/storm_1/jaxx-runtime-validator/README.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/README.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/README.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,2 @@ +To deploy new version of pom: mvn deploy +To install localy: mvn install Added: lutinjaxx/branches/storm_1/jaxx-runtime-validator/changelog.txt =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/changelog.txt (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/changelog.txt 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,90 @@ +1.0 ???? 200812?? + +0.8 ??? 200812?? + * 20081228 [chemit] - generify ClassDescriptor + - introduce StylesheetHelper helper class to detach Stylesheet, Rule and Selector classes from + JAXXCompiler and make possible to extract compiler engine from runtime + + * 20081227 [chemit] - add PCS on ValidatorErrorTable to be used by table validation + * 20081218 [chemit] - improve generation of methods + * 20081214 [chemit] - can now in validation, put error with args (all args must be separated by a ##) + - improve event naming : replace the $evXXX by doMEthodName__on__field (except with optimize option) + - add jaww.runtime.swing.Utils.fillComboBox to fill a combobox model from a collection + - add addSourcesToClassPath property to add sources directories in class-path + - improve classloader managment + - keep in DataSource objetCode + - fix bug when processDataBinding on a null objectCode + - always clean node cached values when selected it + - add usefull databinding method in Util + +* 20081213 [chemit] - improve navigation tree node rendering with some caches + - introduce a ChildBuilder to simplify building of child nodes from a collection or array + +0.7 chemit 20081210 +* 20081210 [chemit] - fix bug 1751 +* 20081210 [chemit] - improve JAXXButtonGroup (add ActionChangeListener and toolTipText mecanism) +* 20081208 [chemit] - javabBean attribute use to initialize bean + - introduce Base64Coder to fix bug 1750 and control serailVersionUI (put them to 1L for the moment) + - introduce MultiJXPathDecorator + - add a resetAfterCompile parameter toCompilerOption to keep in test used compilers + + * 20081207 [chemit] use lutinproject 3.1 + - can exclude field from validator + * 20081202 [chemit] - add strategy for loading ui in NavigationTreeSelectionAdapter + - fix bug when searching for a inner class + + * 20081201 [chemit] - implements jaxx.runtime.JXPathDecorator + - add setcontextValue and removeContextValue on JAXXContextEntryDef + - introduce scope in BeanValidator (ERROR or WARNING) and related swing stuff + - only enter once in $initialize method in generated code + + 0.6 chemit 20081117 + * 20081118 [chemit] introduce NavigationUtil, save in context selected node + * 20081107 [chemit] improve data binding and code generation : + - make possible inheritance in binding + - add an attribute javaBean to an object : will generate a full java bean support property + - make possible binding to the javaBean added properties + - clean generated code + + * 20081105 [chemit] introduce a CardLayout2 to extends awt CardLayout + introduce a NavigationTreeModel + introduce a Decorator to render Object + propagate constructor JAXXContext(JAXXContext) in JAXXObject generation + begin of rst documentation + + * 20081104 [chemit] can add extra beanInfoSearchPath in SwingInitializer + * 20081104 [chemit] add jaxxContextImplementorClass in option to make possible use of other JAXXContext implementor. + * 20081102 [chemit] improve JAXXContext : + - introduce a JAXXContextEntryDef to qualify an entry of a JAXXContext + - do javadoc in JAXXContext + - add logic in DefaultJAXXContext : seek in parent context if entry not found + * 20081102 [chemit] improve tests : + - fix the last failed test from Jaxx original version :) + - dumps tests to JUnit4 :) + * 20081030 [chemit] improve BeanValidator : + - add full PropertyChangeEvent java-bean support and a property valid + - when remove bean from validator, must remove errors from model + - make possible to have a dynamic errorListModel in jaxx files + * 20081030 [chemit] improve JAXXContext : + - fix setContextValue bug when setting twice a same type for a same key + - implements a DefaultJAXXContext + - use this default implementation with delegate pattern in JAXXObject + * 20081030 [chemit] add JAXXAction contract to simplify init of ui with JAXXInitialContext + * 20081027 [chemit] fix bug 1722 + * 20081027 [chemit] add conversion support in validator + * 20081025 [chemit] improve BeanValidator tag : + - add a errorList attribute for set a ErrorListMouseListener on the errorList + - add a beanInitializer attribute for set the validator's bean at runtime + - add a default errorListModel value 'errors' + * 20081025 [chemit] introduce JAXXInitialContext to fill JAXXContext at runtime before $initialize() method + * 20081024 [chemit] fix validator context lost if UI is launched from another thread + ver-0-5 chemit 20081002 + * 20081017 [chemit] add validator support + * 20081013 [chemit] can generate logger on jaxx files + * 20081011 [chemit] improve site + * 20081011 [chemit] fix bug on JavaFileParser : works again + * 20081002 [chemit] Using lutinproject 3.0, changing groupId to org.codelutin + * 20081002 [chemit] use a single module jaxx-core (no more core, runtime and jaxx-swing modules) + * 20081002 [chemit] Introduce JAXXContext + * 20081002 [chemit] Fix bug on method creation via scripting + * 20081002 [chemit] Improve i18n integration (works now also for tabs) Added: lutinjaxx/branches/storm_1/jaxx-runtime-validator/pom.xml =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/pom.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,59 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> + + <modelVersion>4.0.0</modelVersion> + + <!-- ************************************************************* --> + <!-- *** POM Relationships *************************************** --> + <!-- ************************************************************* --> + + <parent> + <groupId>org.codelutin</groupId> + <artifactId>lutinjaxx</artifactId> + <version>0.8-SNAPSHOT</version> + </parent> + + <artifactId>jaxx-runtime-validator</artifactId> + + <dependencies> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-api</artifactId> + </dependency> + + <!--dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-swing</artifactId> + </dependency--> + + <dependency> + <groupId>com.opensymphony</groupId> + <artifactId>xwork</artifactId> + </dependency> + + </dependencies> + + <!-- ************************************************************* --> + <!-- *** Project Information ************************************* --> + <!-- ************************************************************* --> + <name>jaxx-runtime-validator</name> + <description>Jaxx runtime validation</description> + + <!-- ************************************************************* --> + <!-- *** Build Settings ****************************************** --> + <!-- ************************************************************* --> + <packaging>jar</packaging> + + <build> + <defaultGoal>install</defaultGoal> + </build> + <!-- ************************************************************* --> + <!-- *** Build Environment ************************************** --> + <!-- ************************************************************* --> + <scm> + <connection>${maven.scm.connection.child}</connection> + <developerConnection>${maven.scm.developerConnection.child}</developerConnection> + <url>${maven.scm.url.child}</url> + </scm> +</project> Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/JAXXValidator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,25 @@ +package jaxx.runtime; + +import jaxx.runtime.validator.BeanValidator; + +import java.util.List; + +/** + * The contract of a validator-able object. + * + * @author chemit + */ +public interface JAXXValidator { + + /** + * Obtain a validator from his id + * + * @param validatorId validator id + * @return the associated validator, or <code>null</code> if not find + */ + BeanValidator<?> getValidator(String validatorId); + + /** @return the list of ids of all registred validator */ + List<String> getValidatorIds(); + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/JAXXValidator.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,609 @@ +/* *##% + * Copyright (C) 2002-2008 Code Lutin, Benjamin Poussin + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, + * USA. + *##%*/ + +package jaxx.runtime.validator; + + +import com.opensymphony.xwork2.ActionContext; +import com.opensymphony.xwork2.ValidationAware; +import com.opensymphony.xwork2.ValidationAwareSupport; +import com.opensymphony.xwork2.config.Configuration; +import com.opensymphony.xwork2.config.ConfigurationManager; +import com.opensymphony.xwork2.util.ValueStack; +import com.opensymphony.xwork2.util.ValueStackFactory; +import com.opensymphony.xwork2.validator.ActionValidatorManager; +import com.opensymphony.xwork2.validator.DelegatingValidatorContext; +import com.opensymphony.xwork2.validator.ValidationException; +import jaxx.runtime.validator.ui.AbstractBeanValidatorUI; +import jaxx.runtime.validator.ui.IconValidationUI; +import org.apache.commons.beanutils.ConversionException; +import org.apache.commons.beanutils.Converter; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codelutin.util.ConverterUtil; +import org.jdesktop.jxlayer.JXLayer; + +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import java.awt.Container; +import java.beans.Introspector; +import java.beans.PropertyChangeEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.TreeMap; + +/** + * <p/> + * Permet d'ajouter facilement le support de la validation des champs d'un + * bean et de le relier a une interface graphique. + * Utilise xwork pour la validation et JXLayer pour la visualisation. + * <p/> + * <p/> + * Le mieux pour son integration dans Jaxx est de faire de la generation pour + * force la compilation du code suivant: + * <p/> + * <pre> + * myValidor.getBean().get<field>(); + * </pre> + * <p/> + * et ceci pour chaque field ajoute a la map fieldRepresentation. De cette + * facon meme si le champs field est en texte on a une verification de son + * existance a la compilation. + * <p/> + * <p/> + * La representation en tag pourrait etre + * <pre> + * <validator id="myValidator" beanClass="{Personne.class}" errorList="$list"> + * <field name="name" component="$name"/> + * <field name="firstName" component="$firstName"/> + * <field name="birthDate" component="$birthDate"/> + * </validator> + * <validator beanClass="{Personne.class}" autoField="true" errorList="$list"> + * <fieldRepresentation name="name" component="$lastName"/> + * </validator> + * </pre> + * <p/> + * dans le premier exemple on fait un mapping explicite des champs, mais on voit + * que le nom du composant graphique est le meme que celui du champs. Pour eviter + * de longue saisie, il est possible d'utiliser le flag <b>autoField</b> + * qui pour chaque champs du ayant une methode get du bean recherche un composant + * avec cet Id. Il est aussi possible de surcharge un champs explicitement + * comme ici name, dans le cas ou le composant qui porterait ce nom serait + * utilise pour autre chose. + * <p/> + * <p/> + * Il faut un handler particulier pour ce composant car les attributs + * <b>beanClass</b> et <b>autoField</b> ne sont present que dans le XML jaxx et + * servent a la generation. Il faut aussi prendre en compte les elements + * fieldRepresentation fils du tag validator. + * <p/> + * <p/> + * Voici ce que pourrait etre le code genere par jaxx + * <pre> + * // declaration du bean + * BeanValidator<beanClass> $myValidator; + * // init du bean + * protected void createMyValidator() { + * $myValidator = new BeanValidator<beanClass>(); + * // genere seulement si autoField = true + * for (Method m : beanClass.getMethod()) { + * if (m.getName().startsWith("get")) { + * String fieldName = m.getName().substring(3).toLowerCase(); + * $myValidator.setFieldRepresentation(fieldName, $objectMap.get(fieldName)); + * } + * } + * // pour chaque tag fieldRepresentation + * myValidator.setFieldRepresentation("name", $lastName); + * // si beanClass est specifie et n'est pas Object, on force l'acces au champs + * // pour validation a la compilation + * $myValidator.getBean().getName(); + * $objectMap.put("myValidator", $myValidator); + * } + * </pre> + * + * @author poussin + * @author chemit + * @version 1.0 + * <p/> + * Last update: $Date$ + * by : chemit + */ +public class BeanValidator<T> { + + /** + * Pour definir le niveau de validation. + * <p/> + * Par défaut, le validateur est supposé géré des erreurs, mais on peut aussi l'utiliser + * pour consigner des warnings sur le bean surveiller. + */ + public enum Scope { + ERROR, + WARNING + } + + static public final String BEAN_PROERTY = "bean"; + + private static final String CONTEXT_NAME_PROPERTY = "contextName"; + + static public final String VALID_PROERTY = "valid"; + + static public final String CHANGED_PROERTY = "changed"; + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(BeanValidator.class); + + /** Constant name of the default ui renderer to be used. */ + static private final Class<? extends AbstractBeanValidatorUI> DEFAULT_UI_CLASS = IconValidationUI.class; + + /** delgate property change support */ + protected PropertyChangeSupport pcs; + + protected ValidationAwareSupport validationSupport; + + protected DelegatingValidatorContext validationContext; + + protected transient ActionValidatorManager validator; + + /** indique si le bean a ete modifie depuis son arrivee */ + protected boolean changed = false; + + /** state of the validator */ + protected boolean valid; + + /** le bean a surveiller */ + protected T bean = null; + + /** l'objet qui recoit les notifications de modification du bean */ + protected PropertyChangeListener l; + + /** permet de faire le lien en un champs du bean et l'objet qui permet de l'editer */ + protected Map<String, JComponent> fieldRepresentation; + + /** Object servant a contenir la liste des erreurs */ + protected BeanValidatorErrorListModel errorListModel; + + /** Object servant a contenir la liste des erreurs */ + protected BeanValidatorErrorTableModel errorTableModel; + + /** ui renderer class */ + protected Class<? extends AbstractBeanValidatorUI> uiClass; + + /** validator context */ + protected ActionContext context; + + /** map of conversion errors detected by this validator */ + protected Map<String, String> conversionErrors; + + /** the validation named context */ + protected String contextName; + + protected Scope scope = Scope.ERROR; + + public BeanValidator() { + pcs = new PropertyChangeSupport(this); + validationSupport = new ValidationAwareSupport(); + validationContext = new DelegatingValidatorContext(validationSupport); + fieldRepresentation = new HashMap<String, JComponent>(); + conversionErrors = new TreeMap<String, String>(); + l = new PropertyChangeListener() { + public void propertyChange(PropertyChangeEvent evt) { + validate(); + setValid(!hasErrors()); + setChanged(true); + } + }; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + + public BeanValidatorErrorListModel getErrorListModel() { + return errorListModel; + } + + public BeanValidatorErrorTableModel getErrorTableModel() { + return errorTableModel; + } + + public JComponent getFieldRepresentation(String fieldname) { + return fieldRepresentation.get(fieldname); + } + + public Scope getScope() { + return scope; + } + + /** + * Retourne vrai si l'objet bean a ete modifie depuis le dernier + * {@link #setBean} + * + * @return <code>true</code> if bean was modify since last {@link #setBean(Object)} invocation + */ + public boolean isChanged() { + return changed; + } + + public boolean isValid() { + return valid; + } + + public T getBean() { + return bean; + } + + public Class<? extends AbstractBeanValidatorUI> getUiClass() { + return uiClass; + } + + public Map getFieldErrors() { + return validationContext.getFieldErrors(); + } + + public Collection getActionErrors() { + return validationContext.getActionErrors(); + } + + public Collection getActionMessages() { + return validationContext.getActionMessages(); + } + + public Map<String, String> getConversionErrors() { + return conversionErrors; + } + + public void setErrorListModel(BeanValidatorErrorListModel errorListModel) { + this.errorListModel = errorListModel; + if (errorListModel != null) { + // register the validator in the model list + errorListModel.registerValidator(this); + } + } + + public void setErrorTableModel(BeanValidatorErrorTableModel errorTableModel) { + this.errorTableModel = errorTableModel; + if (errorTableModel != null) { + // register the validator in the model table + errorTableModel.registerValidator(this); + } + } + + /** + * Permet d'indiquer le composant graphique responsable de l'affichage + * d'un attribut du bean + * + * @param fieldname the field name in the bean + * @param c the editor component for the field + */ + public void setFieldRepresentation(String fieldname, JComponent c) { + fieldRepresentation.put(fieldname, c); + //todo we do not want at this moment to add something in ui, since ui is perharps not useable + //todo prefer to use the method installUIs + //JComponent old = fieldRepresentation.put(fieldname, c); + //setErrorRepresentation(fieldname, old, c, uiClass); + } + + public void setFieldRepresentation(Map<String, JComponent> fieldRepresentation) { + for (Map.Entry<String, JComponent> e : fieldRepresentation.entrySet()) { + setFieldRepresentation(e.getKey(), e.getValue()); + } + } + + /** + * Permet de force la remise a false de l'etat de changement du bean + * + * @param changed flag to force reset of property {@link #changed} + */ + public void setChanged(boolean changed) { + boolean oldChanged = this.changed; + this.changed = changed; + pcs.firePropertyChange(CHANGED_PROERTY, oldChanged, changed); + } + + public void setValid(boolean valid) { + boolean oldValid = this.valid; + this.valid = valid; + if (oldValid != valid) { + pcs.firePropertyChange(VALID_PROERTY, oldValid, valid); + } + } + + public void setBean(T bean) { + T oldBean = this.bean; + + // clean conversions of previous bean + conversionErrors.clear(); + if (oldBean != null) { + try { + Method method = this.bean.getClass().getMethod("removePropertyChangeListener", PropertyChangeListener.class); + method.invoke(oldBean, l); + } catch (Exception eee) { + log.info("Can't register as listener", eee); + } + } + this.bean = bean; + if (bean != null) { + try { + Method method = this.bean.getClass().getMethod("addPropertyChangeListener", PropertyChangeListener.class); + method.invoke(bean, l); + } catch (Exception eee) { + log.info("Can't register as listener", eee); + } + validate(); + } else { + // must remove all errors from this validator on errorListModel + validationSupport.clearErrorsAndMessages(); + addErrors(); + } + setValid(!hasErrors()); + setChanged(false); + pcs.firePropertyChange(BEAN_PROERTY, oldBean, bean); + } + + public void setContextName(String contextName) { + String oldValidationContextName = this.contextName; + this.contextName = contextName; + pcs.firePropertyChange(CONTEXT_NAME_PROPERTY, oldValidationContextName, contextName); + } + + public void setUiClass(Class<? extends AbstractBeanValidatorUI> uiClass) { + this.uiClass = uiClass; + } + + public void setScope(Scope scope) { + this.scope = scope; + } + + /** @return <code>true</code> if errors are detected, <code>false</code> otherwise */ + public boolean hasErrors() { + //todo should also detecte actionErrors ? + return scope == Scope.ERROR && (validationContext.hasFieldErrors() || !conversionErrors.isEmpty()); + //return validationContext.hasFieldErrors() || validationContext.hasActionErrors(); + } + + public boolean hasWarnings() { + return scope == Scope.WARNING && (validationContext.hasFieldErrors() || !conversionErrors.isEmpty()); + } + + /** install ui on required components */ + public void installUIs() { + SwingUtilities.invokeLater(new Runnable() { + public void run() { + if (uiClass == null) { + // use the default one + uiClass = DEFAULT_UI_CLASS; + } + for (String fieldname : fieldRepresentation.keySet()) { + try { + setErrorRepresentation(fieldname, null, fieldRepresentation.get(fieldname), uiClass); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + }); + + } + + /** + * Convert a value. + * <p/> + * If an error occurs, then add an error in validator. + * + * @param fieldName the name of the bean property + * @param value the value to convert + * @param valueClass the type of converted value + * @return the converted value, or null if conversion was not ok + */ + public <T> T convert(String fieldName, String value, Class<T> valueClass) { + if (fieldName == null) { + throw new IllegalArgumentException("fieldName can not be null"); + } + if (valueClass == null) { + throw new IllegalArgumentException("valueClass can not be null"); + } + + // on ne convertit pas si il y a un bean et que le resultat de la validation + // pourra etre affiche quelque part + if (checkState() || value == null) { + return null; + } + + // remove the previous conversion error for the field + conversionErrors.remove(fieldName); + + T result; + try { + Converter converter = ConverterUtil.getConverter(valueClass); + if (converter == null) { + throw new RuntimeException("could not find converter for the type " + valueClass); + } + result = (T) converter.convert(valueClass, value); + /* Why this test ? if (result != null && !value.equals(result.toString())) { + conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); + result = null; + validate(); + }*/ + } catch (ConversionException e) { + // get + conversionErrors.put(fieldName, "error.convertor." + Introspector.decapitalize(valueClass.getSimpleName())); + result = null; + validate(); + } + + return result; + } + + /** + * il faut eviter le code re-intrant (durant une validation, une autre est + * demandee). Pour cela on fait la validation dans un thread, et tant + * que la premiere validation n'est pas fini, on ne repond pas aux + * solicitations. + * Cette method est public pour permettre de force une validation par + * programmation, ce qui est utile par exemple si le bean ne supporte + * pas les {@link PropertyChangeListener} + */ + public void validate() { + // on ne valide que si il y a un bean et que le resultat de la validation + // pourra etre affiche quelque part + if (checkState()) { + return; + } + + try { + + validationSupport.clearErrorsAndMessages(); + + getValidator().validate(bean, contextName, validationContext); + + // add the registred conversion errors + transfertConversionErrorsToFieldErrors(); + + if (log.isTraceEnabled()) { + log.trace("Action errors: " + validationContext.getActionErrors()); + log.trace("Action messages: " + validationContext.getActionMessages()); + log.trace("Field errors: " + validationContext.getFieldErrors()); + } + + if (log.isDebugEnabled()) { + log.debug(this + " : " + validationContext.getFieldErrors()); + } + // add errors + addErrors(); + + for (String fieldname : fieldRepresentation.keySet()) { + JComponent c = fieldRepresentation.get(fieldname); + //todo: a supprimer mais actuellemnt le layer ne se repaint pas bien, cela n'est pas normal + if (c.getParent() != null) { + c.getParent().repaint(); + } + } + } catch (ValidationException eee) { + log.warn("Error during validation", eee); + } + } + + @Override + public String toString() { + return super.toString() + "<contextName:" + contextName + ">"; + } + + /** @return <code>true</code> if validation is not active , <code>false</code> otherwise. */ + protected boolean checkState() { + return bean == null || (getErrorListModel() == null && getErrorTableModel() == null) || fieldRepresentation.size() == 0; + } + + protected ActionValidatorManager getValidator() { + if (validator == null) { + ConfigurationManager confManager = new ConfigurationManager(); + Configuration conf = confManager.getConfiguration(); + + ValueStackFactory vsf = conf.getContainer().getInstance( + ValueStackFactory.class); + ValueStack vs = vsf.createValueStack(); + context = new ActionContext(vs.getContext()); + ActionContext.setContext(context); + + validator = conf.getContainer().getInstance( + ActionValidatorManager.class, "no-annotations"); + } + //TC - 20081024 : since context is in a ThreadLocal variable, we must do the check + if (ActionContext.getContext() == null) { + ActionContext.setContext(context); + } + return validator; + } + + protected void setErrorRepresentation(String fieldname, JComponent old, JComponent c, Class<? extends AbstractBeanValidatorUI> uiClass) throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { + if (old != c) { + if (old != null) { + // suppression du jxlayer sous l'ancien composant + Container container = old.getParent(); + if (container instanceof JXLayer) { + JXLayer<?> jx = (JXLayer<?>) container; + jx.setUI(null); + } + } + if (c != null) { + // ajout du jxlayer sous ce composant + Container container = c.getParent(); + if (container instanceof JXLayer) { + Constructor<? extends AbstractBeanValidatorUI> cons = uiClass.getConstructor(String.class, String.class,Scope.class, ValidationAware.class); + AbstractBeanValidatorUI ui = cons.newInstance(fieldname, c.getName(), scope, validationSupport); + ui.setEnabled(true); + JXLayer<JComponent> jx = (JXLayer<JComponent>) container; + jx.setUI(ui); + } + } + } + } + + /** + * Transfer the registred conversion errors to fieldErrors. + * <p/> + * The previously filed errors of a given field where a conversion error occurs will be removed. + */ + protected void transfertConversionErrorsToFieldErrors() { + Map map = getFieldErrors(); + for (Entry<String, String> entry : conversionErrors.entrySet()) { + // remove from validation, errors occurs on this field + List errors = (List) map.get(entry.getKey()); + if (errors != null) { + errors.clear(); + errors.add(entry.getValue()); + } else { + errors = Collections.singletonList(entry.getValue()); + } + // add the concrete conversion error + map.put(entry.getKey(), errors); + } + validationContext.setFieldErrors(map); + } + + protected void addErrors() { + if (errorListModel != null) { + errorListModel.addErrors(this); + } + if (errorTableModel != null) { + errorTableModel.addErrors(this); + } + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidatorError.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorError.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,89 @@ +package jaxx.runtime.validator; + +import org.codelutin.i18n.I18n; + +import javax.swing.JComponent; + +import jaxx.runtime.validator.BeanValidator.Scope; + +/** + * The model of an error. + * + * @author chemit + */ +public class BeanValidatorError<T> { + + protected BeanValidator<T> validator; + + protected String fieldName; + + protected String error; + + protected JComponent component; + + public BeanValidator<T> getValidator() { + return validator; + } + + public String getFieldName() { + return fieldName; + } + + public String getError() { + return error; + } + + public JComponent getComponent() { + return component; + } + + public void setValidator(BeanValidator<T> validator) { + this.validator = validator; + } + + public void setFieldName(String fieldName) { + this.fieldName = fieldName; + } + + public void setError(String error) { + this.error = error; + } + + public void setComponent(JComponent component) { + this.component = component; + } + + public Scope getScope() { + return validator.getScope(); + } + + @Override + public String toString() { + return component.getName() + " : " + I18n._(error); + } + + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (!(o instanceof BeanValidatorError)) { + return false; + } + + BeanValidatorError that = (BeanValidatorError) o; + + return component.equals(that.component) && error.equals(that.error) && fieldName.equals(that.fieldName) && validator.equals(that.validator); + + } + + @Override + public int hashCode() { + int result; + result = validator.hashCode(); + result = 31 * result + fieldName.hashCode(); + result = 31 * result + error.hashCode(); + result = 31 * result + component.hashCode(); + return result; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorListModel.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,139 @@ +package jaxx.runtime.validator; + +import javax.swing.DefaultListModel; +import javax.swing.JComponent; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Enumeration; +import java.util.List; +import java.util.Map; + +/** + * The model of the list of errors + * + * @author chemit + */ +public class BeanValidatorErrorListModel extends DefaultListModel { + private static final long serialVersionUID = 1L; + + /** list of registred validators */ + protected transient List<BeanValidator<?>> validators; + + /** comporator of errors */ + protected transient Comparator<BeanValidatorError> comparator; + + public BeanValidatorErrorListModel() { + validators = new ArrayList<BeanValidator<?>>(); + } + + public void registerValidator(BeanValidator<?> validator) { + if (validators.contains(validator)) { + throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); + } + validators.add(validator); + } + + public <T> void addErrors(BeanValidator<T> validator) { + if (!validators.contains(validator)) { + throw new IllegalArgumentException("the validator " + validator + " is not registred in " + this); + } + + // new errors for the given validator + List<BeanValidatorError> newErrors = new ArrayList<BeanValidatorError>(); + // old errors for the given validator + List<BeanValidatorError> oldErrors = new ArrayList<BeanValidatorError>(); + // old errors for other validators + List<BeanValidatorError> oldOtherErrors = new ArrayList<BeanValidatorError>(); + + // split old errors from other validators + splitOldErrors(validator, oldErrors, oldOtherErrors); + + // fill new errors + fillNewErrors(validator, newErrors); + + // check if something has changed for the given validator + if (hasChanged(oldErrors, newErrors)) { + + // reinject other errors + newErrors.addAll(oldOtherErrors); + + // sort errors + Collections.sort(newErrors, getComparator()); + + // clean errors in model + clear(); + + // reinject in list model, all the errors + for (BeanValidatorError error : newErrors) { + addElement(error); + } + + // notify thaht the model has changed + fireContentsChanged(this, 0, getSize() - 1); + } + } + + protected boolean hasChanged(List<BeanValidatorError> oldErrors, List<BeanValidatorError> newErrors) { + if (oldErrors.size() != newErrors.size()) { + return true; + } + for (BeanValidatorError oldError : oldErrors) { + if (!newErrors.contains(oldError)) { + return true; + } + } + return false; + } + + protected <T> void fillNewErrors(BeanValidator<T> validator, List<BeanValidatorError> newErrors) { + if (validator.hasErrors()) { + // inject this validator errors + for (Object o : validator.getFieldErrors().entrySet()) { + Map.Entry<?, ?> r = (Map.Entry<?, ?>) o; + BeanValidatorError<T> error; + String field = (String) r.getKey(); + JComponent component = validator.getFieldRepresentation(field); + if (component!=null) { + for (Object errorString : (List<?>) r.getValue()) { + String error1 = (String) errorString; + error = new BeanValidatorError<T>(); + error.setComponent(component); + error.setValidator(validator); + error.setError(error1); + error.setFieldName(field); + newErrors.add(error); + } + } + } + //todo should also do actionErrors + } + } + + protected <T> void splitOldErrors(BeanValidator<T> validator, List<BeanValidatorError> oldErrors, List<BeanValidatorError> oldOtherErrors) { + Enumeration enumeration = elements(); + + while (enumeration.hasMoreElements()) { + Object o = enumeration.nextElement(); + BeanValidatorError<?> error = (BeanValidatorError) o; + if (!error.getValidator().equals(validator)) { + // error from another validator, keep it + oldOtherErrors.add(error); + } else { + oldErrors.add(error); + } + } + } + + protected Comparator<BeanValidatorError> getComparator() { + if (comparator == null) { + comparator = new Comparator<BeanValidatorError>() { + public int compare(BeanValidatorError o1, BeanValidatorError o2) { + return o1.toString().compareTo(o2.toString()); + } + }; + } + return comparator; + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,161 @@ +package jaxx.runtime.validator; + +import javax.swing.JComponent; +import javax.swing.table.DefaultTableModel; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.List; +import java.util.Map; +import java.util.Vector; + +/** + * The model of the list of errors + * + * @author chemit + */ +public class BeanValidatorErrorTableModel extends DefaultTableModel { + + private static final long serialVersionUID = 1L; + + public static final String[] columnNames = {"validator.scope", "validator.field", "validator.message"}; + + /** list of registred validators */ + protected transient List<BeanValidator<?>> validators; + + /** comporator of errors */ + protected transient Comparator<BeanValidatorError> comparator; + + public BeanValidatorErrorTableModel() { + super(columnNames, 0); + validators = new ArrayList<BeanValidator<?>>(); + } + + public int getErrorColumn() { + return findColumn(BeanValidatorErrorTableModel.columnNames[2]); + } + + @Override + public boolean isCellEditable(int row, int column) { + // cells are never editable in this model + return false; + } + + public void registerValidator(BeanValidator<?> validator) { + if (validators.contains(validator)) { + throw new IllegalArgumentException("the validator " + validator + " is already registred in " + this); + } + validators.add(validator); + } + + public <T> void addErrors(BeanValidator<T> validator) { + if (!validators.contains(validator)) { + throw new IllegalArgumentException("the validator " + validator + " is not registred in " + this); + } + + // new errors for the given validator + List<BeanValidatorError> newErrors = new ArrayList<BeanValidatorError>(); + // old errors for the given validator + List<BeanValidatorError> oldErrors = new ArrayList<BeanValidatorError>(); + // old errors for other validators + List<BeanValidatorError> oldOtherErrors = new ArrayList<BeanValidatorError>(); + + // split old errors from other validators + splitOldErrors(validator, oldErrors, oldOtherErrors); + + // fill new errors + fillNewErrors(validator, newErrors); + + // check if something has changed for the given validator + if (hasChanged(oldErrors, newErrors)) { + + // reinject other errors + newErrors.addAll(oldOtherErrors); + + // sort errors + Collections.sort(newErrors, getComparator()); + + // clean errors in model + getDataVector().clear(); + // reinject in list model, all the errors + for (BeanValidatorError error : newErrors) { + addRow(new Object[]{error.getScope(), error.getFieldName(), error}); + } + + // notify thaht the model has changed + fireTableDataChanged(); + } + } + + protected boolean hasChanged(List<BeanValidatorError> oldErrors, List<BeanValidatorError> newErrors) { + if (oldErrors.size() != newErrors.size()) { + return true; + } + for (BeanValidatorError oldError : oldErrors) { + if (!newErrors.contains(oldError)) { + return true; + } + } + return false; + } + + protected <T> void fillNewErrors(BeanValidator<T> validator, List<BeanValidatorError> newErrors) { + if (validator.hasErrors() || validator.hasWarnings()) { + // inject this validator errors + for (Object o : validator.getFieldErrors().entrySet()) { + Map.Entry<?, ?> r = (Map.Entry<?, ?>) o; + BeanValidatorError<T> error; + String field = (String) r.getKey(); + JComponent component = validator.getFieldRepresentation(field); + if (component != null) { + for (Object errorString : (List<?>) r.getValue()) { + String error1 = (String) errorString; + error = new BeanValidatorError<T>(); + error.setComponent(component); + error.setValidator(validator); + error.setError(error1); + error.setFieldName(field); + newErrors.add(error); + } + } + } + //todo should also do actionErrors + } + } + + protected <T> void splitOldErrors(BeanValidator<T> validator, List<BeanValidatorError> oldErrors, List<BeanValidatorError> oldOtherErrors) { + + int col = getErrorColumn(); + for (Object o : super.getDataVector()) { + Vector row = (Vector) o; + BeanValidatorError<?> error = (BeanValidatorError<?>) row.get(col); + if (!error.getValidator().equals(validator)) { + // error from another validator, keep it + oldOtherErrors.add(error); + } else { + oldErrors.add(error); + } + } + } + + protected Comparator<BeanValidatorError> getComparator() { + if (comparator == null) { + comparator = new Comparator<BeanValidatorError>() { + public int compare(BeanValidatorError o1, BeanValidatorError o2) { + // first sort on scope + int scope = o1.getScope().ordinal() - o2.getScope().ordinal(); + if (scope != 0) { + return scope; + } + int field = o1.getFieldName().compareTo(o2.getFieldName()); + if (field != 0) { + return field; + } + return o1.getError().compareTo(o2.getError()); + } + }; + } + return comparator; + } + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/BeanValidatorErrorTableModel.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorListMouseListener.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,61 @@ +package jaxx.runtime.validator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JComponent; +import javax.swing.JList; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * A mouse listener to put on a {@link JList} with a {@link BeanValidatorErrorListModel} as a model. + * <p/> + * When a double click occurs, find the selected error in model and then focus to the associated component of error. + * + * @author chemit + */ +public class ErrorListMouseListener extends MouseAdapter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private Log log = LogFactory.getLog(ErrorListMouseListener.class); + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (e.getClickCount() == 2) { + + BeanValidatorError<?> entry = getSelectedError(e); + if (entry == null) { + // no entry found + return; + } + JComponent component = entry.getComponent(); + if (component != null) { + component.requestFocus(); + } + } + } + + + protected BeanValidatorError<?> getSelectedError(MouseEvent e) { + JList list = (JList) e.getSource(); + if (!(list.getModel() instanceof BeanValidatorErrorListModel)) { + log.warn("model must be a " + BeanValidatorErrorListModel.class + ", but was " + list.getModel()); + return null; + } + + BeanValidatorErrorListModel model = (BeanValidatorErrorListModel) list.getModel(); + int index = list.getSelectionModel().getMinSelectionIndex(); + if (index == -1) { + // nothing is selected + return null; + } + BeanValidatorError<?> entry = (BeanValidatorError) model.getElementAt(index); + if (log.isDebugEnabled()) { + log.debug("selected index: " + index + " : error: " + entry); + } + return entry; + } + +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java (from rev 1093, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,92 @@ +package jaxx.runtime.validator; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +import javax.swing.JComponent; +import javax.swing.JTable; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; + +/** + * A mouse listener to put on a {@link javax.swing.JList} with a {@link jaxx.runtime.validator.BeanValidatorErrorListModel} as a model. + * <p/> + * When a double click occurs, find the selected error in model and then focus to the associated component of error. + * + * @author chemit + */ +public class ErrorTableMouseListener extends MouseAdapter { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + private static Log log = LogFactory.getLog(ErrorTableMouseListener.class); + + public static final String HIGHLIGHT_ERROR_PROPERTY = "highlightError"; + + /** delgate property change support */ + protected PropertyChangeSupport pcs; + + public ErrorTableMouseListener() { + pcs = new PropertyChangeSupport(this); + } + + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + if (e.getClickCount() == 2) { + + BeanValidatorError<?> entry = getSelectedError(e); + if (entry == null) { + // no entry found + return; + } + JComponent component = entry.getComponent(); + if (component != null) { + pcs.firePropertyChange(HIGHLIGHT_ERROR_PROPERTY, null, entry); + if (component.isVisible()) { + component.requestFocus(); + } + } + } + } + + + protected BeanValidatorError<?> getSelectedError(MouseEvent e) { + JTable table = (JTable) e.getSource(); + if (!(table.getModel() instanceof BeanValidatorErrorTableModel)) { + log.warn("model must be a " + BeanValidatorErrorTableModel.class + ", but was " + table.getModel()); + return null; + } + + BeanValidatorErrorTableModel model = (BeanValidatorErrorTableModel) table.getModel(); + int index = table.getSelectionModel().getMinSelectionIndex(); + if (index == -1) { + // nothing is selected + return null; + } + int col = model.getErrorColumn(); + BeanValidatorError<?> entry = (BeanValidatorError) model.getValueAt(index, col); + if (log.isDebugEnabled()) { + log.debug("selected index: " + index + " : error: " + entry); + } + return entry; + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + pcs.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + pcs.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + pcs.removePropertyChangeListener(propertyName, listener); + } + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableMouseListener.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ErrorTableRenderer.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,68 @@ +package jaxx.runtime.validator; + +import jaxx.runtime.validator.BeanValidator.Scope; +import static org.codelutin.i18n.I18n._; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.DefaultTableCellRenderer; +import java.awt.Component; +import java.util.ArrayList; +import java.util.List; +import java.util.StringTokenizer; + +/** @author chemit */ +public class ErrorTableRenderer extends DefaultTableCellRenderer { + + ImageIcon errorIcon; + ImageIcon warningIcon; + + public ErrorTableRenderer() { + errorIcon = jaxx.runtime.Util.createImageIcon("error.png"); + warningIcon = jaxx.runtime.Util.createImageIcon("warning.png"); + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + JLabel rendererComponent = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + + ImageIcon icon = null; + String text = null; + if (value instanceof Scope) { + + Scope scope = (Scope) value; + switch (scope) { + case ERROR: + icon = errorIcon; + break; + case WARNING: + icon = warningIcon; + break; + } + } else if (value instanceof BeanValidatorError) { + String error = ((BeanValidatorError) value).getError(); + if (error.indexOf("##") == -1) { + text = _(error); + } else { + StringTokenizer stk = new StringTokenizer(error, "##"); + String errorName = stk.nextToken(); + List<String> args = new ArrayList<String>(); + while (stk.hasMoreTokens()) { + args.add(stk.nextToken()); + } + text = _(errorName, args.toArray(new String[args.size()])); + } + } else { + // keep text rendered + text = rendererComponent.getText(); + } + rendererComponent.setText(text); + rendererComponent.setIcon(icon); + return rendererComponent; + } + + @Override + protected void setValue(Object value) { + super.setValue(value); + } +} Added: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/Util.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,155 @@ +package jaxx.runtime.validator; + +import jaxx.runtime.JAXXObject; +import jaxx.runtime.JAXXValidator; + +import javax.swing.JList; +import javax.swing.JTable; +import java.awt.event.MouseListener; +import java.util.List; +import java.util.ArrayList; +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.beans.IntrospectionException; +import java.lang.reflect.InvocationTargetException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** @author chemit */ +public class Util { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + static private final Log log = LogFactory.getLog(Util.class); + + public static void registerErrorListMouseListener(JList list) { + if (list == null) { + return; + } + for (MouseListener listener : list.getMouseListeners()) { + if (listener instanceof ErrorListMouseListener) { + // already have a such listener + log.info("already registered a such MouseListener : " + listener); + return; + } + } + list.addMouseListener(new ErrorListMouseListener()); + } + + public static void registerErrorTableMouseListener(JTable table) { + if (table == null) { + return; + } + for (MouseListener listener : table.getMouseListeners()) { + if (listener instanceof ErrorTableMouseListener) { + // already have a such listener + log.info("already registered a such MouseListener : " + listener); + return; + } + } + table.addMouseListener(new ErrorTableMouseListener()); + } + + public static ErrorTableMouseListener getErrorTableMouseListener(JTable table) { + if (table != null) { + for (MouseListener listener : table.getMouseListeners()) { + if (listener instanceof ErrorTableMouseListener) { + return (ErrorTableMouseListener) listener; + } + } + } + return null; + } + + /** + * Convinient method to attach a bean to all validators of an JAXXObject. + * <p/> + * It is possible to exclude some validator to be treated. + * + * @param ui the ui containing the validatros to treate + * @param bean the bean to attach in validators (can be null) + * @param excludeIds the list of validator id to exclude + */ + @SuppressWarnings({"unchecked"}) + public static void setValidatorBean(JAXXObject ui, Object bean, String... excludeIds) { + if (!JAXXValidator.class.isAssignableFrom(ui.getClass()) ) { + return; + } + JAXXValidator jaxxValidator = (JAXXValidator) ui; + List<String> validatorIds = jaxxValidator.getValidatorIds(); + if (excludeIds.length > 0) { + validatorIds = new ArrayList<String>(validatorIds); + for (String excludeId : excludeIds) { + validatorIds.remove(excludeId); + } + } + for (String validatorId : validatorIds) { + BeanValidator beanValidator = jaxxValidator.getValidator(validatorId); + beanValidator.setBean(bean); + } + } + + /** + * Convinient method to set the changed property to all validators of an JAXXObject. + * <p/> + * It is possible to exclude some validator to be treated. + * + * @param ui the ui containing the validatros to treate + * @param newValue the new value to set in changed validator property + * @param excludeIds the list of validator id to exclude + */ + @SuppressWarnings({"unchecked"}) + public static void setValidatorChanged(JAXXObject ui, boolean newValue, String... excludeIds) { + if (!JAXXValidator.class.isAssignableFrom(ui.getClass()) ) { + return; + } + JAXXValidator jaxxValidator = (JAXXValidator) ui; + List<String> validatorIds = jaxxValidator.getValidatorIds(); + if (excludeIds.length > 0) { + validatorIds = new ArrayList<String>(validatorIds); + for (String excludeId : excludeIds) { + validatorIds.remove(excludeId); + } + } + for (String validatorId : validatorIds) { + BeanValidator beanValidator = jaxxValidator.getValidator(validatorId); + beanValidator.setChanged(newValue); + } + } + + /** + * Convert a value to a given type and then if was succesffull try to set it in the bean manage by the validator. + * + * @param validator validator to be involved + * @param fieldName the name of the bean property + * @param value the actual value to convert + * @param valueClass the type of the conversion + */ + public static void convert(BeanValidator<?> validator, String fieldName, String value, Class<?> valueClass) { + + Object result = validator.convert(fieldName, value, valueClass); + if (result != null) { + try { + BeanInfo info = Introspector.getBeanInfo(validator.getBean().getClass()); + + for (PropertyDescriptor descriptor : info.getPropertyDescriptors()) { + if (fieldName.equals(descriptor.getName()) && descriptor.getWriteMethod() != null) { + + descriptor.getWriteMethod().invoke(validator.getBean(), result); + break; + } + } + } catch (IntrospectionException e) { + log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e); + } catch (InvocationTargetException e) { + log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e); + } catch (IllegalAccessException e) { + log.error("could not obtain beanInfo for " + valueClass.getClass() + ", reason : " + e.getMessage(), e); + } + } else { + //fixme : conversion failed, we should be able to notify ui that values has changed ? + // otherwise, bean value has not changed,... + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingDirectoryFieldValidator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,72 @@ +package jaxx.runtime.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * ExistingDirectoryFieldValidator checks that a File field exists and is a directory. + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="existingDirectory"> + * <param name="fieldName">tmp</param> + * <message>tmp is not an existing directory</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="existingDirectory"> + * <message>tmp is not an existing directory</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author chemit + */ +public class ExistingDirectoryFieldValidator extends FieldValidatorSupport { + + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = this.getFieldValue(fieldName, object); + if (value==null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (!(f.isDirectory() && f.exists())) { + // f is not a directory, nor exists + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "existingDirectory"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingFileFieldValidator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/field/ExistingFileFieldValidator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingFileFieldValidator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/ExistingFileFieldValidator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,72 @@ +package jaxx.runtime.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * ExistingFileFieldValidator checks that a File field exists. * + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="fileExisting"> + * <param name="fieldName">tmp</param> + * <message>tmp is not an existing file</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="fileExisting"> + * <message>tmp is not an existing file</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author chemit + */ +public class ExistingFileFieldValidator extends FieldValidatorSupport { + + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = this.getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (!(f.isFile() && f.exists())) { + // f is not a file nor exists + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "existingFile"; + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingDirectoryFieldValidator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,72 @@ +package jaxx.runtime.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * NotExistingDirectoryFieldValidator checks that a File field as a directory does not exist. * + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="notExistingDirectory"> + * <param name="fieldName">tmp</param> + * <message>tmp is an existing directory</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="notExistingDirectory"> + * <message>tmp is an existing directory</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author chemit + */ +public class NotExistingDirectoryFieldValidator extends FieldValidatorSupport { + + @Override + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = this.getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (f.exists() || f.isFile()) { + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "notExistingDirectory"; + } +} \ No newline at end of file Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingFileFieldValidator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/field/NotExistingFileFieldValidator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingFileFieldValidator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingFileFieldValidator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,73 @@ +package jaxx.runtime.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * NotExistingFileFieldValidator checks that a File field as a file does not exist. * + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="notExistingFile"> + * <param name="fieldName">tmp</param> + * <message>tmp is an existing file</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="notExistingFile"> + * <message>tmp is an existing file</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author chemit + */ +public class NotExistingFileFieldValidator extends FieldValidatorSupport { + + @Override + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = this.getFieldValue(fieldName, object); + if (value==null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (f.exists() || f.isDirectory()) { + // f is not a file and exist + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "notExistingFile"; + } +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/NotExistingFileFieldValidator.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/RequiredFileFieldValidator.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/field/RequiredFileFieldValidator.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/RequiredFileFieldValidator.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/RequiredFileFieldValidator.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,72 @@ +package jaxx.runtime.validator.field; + +import com.opensymphony.xwork2.validator.ValidationException; +import com.opensymphony.xwork2.validator.validators.FieldValidatorSupport; + +import java.io.File; + +/** + * <!-- START SNIPPET: javadoc --> + * RequiredFileFieldValidator checks that a File field is not null nor have an empty filename. + * <!-- END SNIPPET: javadoc --> + * <p/> + * <p/> + * <!-- START SNIPPET: parameters --> + * <ul> + * <li>fieldName - The field name this validator is validating. Required if using Plain-Validator Syntax otherwise not required</li> + * </ul> + * <!-- END SNIPPET: parameters --> + * <p/> + * <p/> + * <pre> + * <!-- START SNIPPET: examples --> + * <validators> + * <!-- Plain-Validator Syntax --> + * <validator type="requiredFile"> + * <param name="fieldName">tmp</param> + * <message>tmp is required</message> + * </validator> + * <p/> + * <!-- Field-Validator Syntax --> + * <field name="tmp"> + * <field-validator type="requiredFile"> + * <message>tmp is required</message> + * </field-validator> + * </field> + * </validators> + * <!-- END SNIPPET: examples --> + * </pre> + * + * @author chemit + */ +public class RequiredFileFieldValidator extends FieldValidatorSupport { + + public void validate(Object object) throws ValidationException { + String fieldName = getFieldName(); + Object value = this.getFieldValue(fieldName, object); + if (value == null) { + // no value defined + addFieldError(fieldName, object); + return; + } + File f; + if (value instanceof File) { + f = (File) value; + } else if (value instanceof String) { + f = new File((String) value); + } else { + addFieldError(fieldName, object); + return; + } + + if (f.getPath().trim().isEmpty()) { + // f is not a directory nor exists + addFieldError(fieldName, object); + } + } + + @Override + public String getValidatorType() { + return "requiredFile"; + } +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/field/RequiredFileFieldValidator.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/AbstractBeanValidatorUI.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,38 @@ +package jaxx.runtime.validator.ui; + +import com.opensymphony.xwork2.ValidationAware; +import jaxx.runtime.validator.BeanValidator.Scope; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.jdesktop.jxlayer.plaf.AbstractLayerUI; + +/** + * Abstract renderer + * + * @author chemit + */ +public abstract class AbstractBeanValidatorUI extends AbstractLayerUI<javax.swing.JComponent> { + + /** to use log facility, just put in your code: log.info(\"...\"); */ + protected static Log log = LogFactory.getLog(AbstractBeanValidatorUI.class); + + /** scope */ + protected Scope scope; + + /** bean field */ + protected String field; + + /** component id */ + protected String componentId; + + /** validation context */ + protected ValidationAware validationContext; + + public AbstractBeanValidatorUI(String field, String componentId, Scope scope, ValidationAware validationContext) { + this.componentId = componentId; + this.field = field; + this.scope = scope; + this.validationContext = validationContext; + log.info("install " + this + "<field:" + field + ", componentId:" + componentId + ">"); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/IconValidationUI.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,59 @@ +package jaxx.runtime.validator.ui; + +import com.opensymphony.xwork2.ValidationAware; +import jaxx.runtime.validator.BeanValidator.Scope; +import org.jdesktop.jxlayer.JXLayer; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +/** @author chemit */ +public class IconValidationUI extends AbstractBeanValidatorUI { + + // The icon to be shown at the layer's corner + protected BufferedImage invalidIcon; + + protected Color hightlight; + + public IconValidationUI(String field, String componentId, Scope scope, ValidationAware validationContext) { + super(field, componentId, scope, validationContext); + int width = 7; + int height = 8; + hightlight = scope == Scope.ERROR ? Color.RED : Color.YELLOW; + invalidIcon = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2 = (Graphics2D) invalidIcon.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); + g2.setColor(hightlight); + g2.fillRect(0, 0, width, height); + g2.setColor(Color.WHITE); + g2.drawLine(0, 0, width, height); + g2.drawLine(0, height, width, 0); + g2.dispose(); + } + + @Override + public void installUI(JComponent c) { + super.installUI(c); + c.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 3)); + } + + @Override + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + c.setBorder(null); + } + + @Override + protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { + super.paintLayer(g2, l); + // There is no need to take insets into account for this painter + if (validationContext.getFieldErrors().containsKey(field)) { + g2.drawImage(invalidIcon, l.getWidth() - invalidIcon.getWidth() - 1, 0, null); + } + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,68 @@ +package jaxx.runtime.validator.ui; + +import com.opensymphony.xwork2.ValidationAware; +import jaxx.runtime.validator.BeanValidator.Scope; +import org.jdesktop.jxlayer.JXLayer; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; + +/** @author chemit */ +public class ImageValidationUI extends AbstractBeanValidatorUI { + + // The icon to be shown at the layer's corner + protected BufferedImage invalidIcon; + + protected Color hightlight; + + public ImageValidationUI(String field, String componentId, Scope scope, ValidationAware validationContext) { + super(field, componentId, scope, validationContext); + + hightlight = scope == Scope.ERROR ? Color.RED : Color.YELLOW; + ImageIcon image = null; + switch (scope) { + + case ERROR: + image = jaxx.runtime.Util.createImageIcon("error.png"); + break; + case WARNING: + image = jaxx.runtime.Util.createImageIcon("warning.png"); + break; + } + //int width = 7; + //int height = 8; + invalidIcon = new BufferedImage(image.getIconWidth(), image.getIconHeight(), BufferedImage.TYPE_INT_ARGB); + + Graphics2D g2 = (Graphics2D) invalidIcon.getGraphics(); + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE); + g2.drawImage(image.getImage(), 0, 0, null); + g2.dispose(); + } + + @Override + public void installUI(JComponent c) { + super.installUI(c); + c.setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 3)); + } + + @Override + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + c.setBorder(null); + } + + @Override + protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { + super.paintLayer(g2, l); + // There is no need to take insets into account for this painter + if (validationContext.getFieldErrors().containsKey(field)) { + g2.drawImage(invalidIcon, l.getWidth() - invalidIcon.getWidth() - 1, 0, null); + } + } +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/ImageValidationUI.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/java/jaxx/runtime/validator/ui/TranslucentValidationUI.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,45 @@ +package jaxx.runtime.validator.ui; + +import com.opensymphony.xwork2.ValidationAware; +import jaxx.runtime.validator.BeanValidator.Scope; +import org.jdesktop.jxlayer.JXLayer; + +import javax.swing.JComponent; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Rectangle; + +/** @author chemit */ +public class TranslucentValidationUI extends AbstractBeanValidatorUI { + + protected Color hightlight; + + public TranslucentValidationUI(String field, String componentId, Scope scope, ValidationAware validationContext) { + super(field, componentId, scope, validationContext); + hightlight = scope == Scope.ERROR ? Color.RED : Color.YELLOW; + } + + @Override + protected void paintLayer(Graphics2D g2, JXLayer<JComponent> l) { + // paints the layer as is + super.paintLayer(g2, l); + + // to be in sync with the view if the layer has a border + Insets layerInsets = l.getInsets(); + g2.translate(layerInsets.left, layerInsets.top); + + JComponent view = l.getView(); + // To prevent painting on view's border + Insets insets = view.getInsets(); + g2.clip(new Rectangle(insets.left, insets.top, + view.getWidth() - insets.left - insets.right, + view.getHeight() - insets.top - insets.bottom)); + + g2.setColor(!validationContext.getFieldErrors().containsKey(field) ? + Color.GREEN : Color.RED); + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .2f)); + g2.fillRect(0, 0, l.getWidth(), l.getHeight()); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/icons/error.png (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/resources/icons/error.png) =================================================================== (Binary files differ) Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/icons/error.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/icons/warning.png (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/resources/icons/warning.png) =================================================================== (Binary files differ) Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/icons/warning.png ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/validators.xml (from rev 1092, lutinjaxx/trunk/jaxx-core/src/main/resources/validators.xml) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/validators.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/main/resources/validators.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator Config 1.0//EN" + "http://www.opensymphony.com/xwork/xwork-validator-config-1.0.dtd"> + +<!-- START SNIPPET: validators --> +<validators> + <validator name="requiredFile" class="jaxx.runtime.validator.field.RequiredFileFieldValidator"/> + <validator name="existingFile" class="jaxx.runtime.validator.field.ExistingFileFieldValidator"/> + <validator name="notExistingFile" class="jaxx.runtime.validator.field.NotExistingFileFieldValidator"/> + <validator name="existingDirectory" class="jaxx.runtime.validator.field.ExistingDirectoryFieldValidator"/> + <validator name="notExistingDirectory" class="jaxx.runtime.validator.field.NotExistingDirectoryFieldValidator"/> +</validators> +<!-- END SNIPPET: validators --> Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorBean.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/ValidatorBean.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorBean.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorBean.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,78 @@ +package jaxx.junit; + +import java.beans.PropertyChangeListener; +import java.beans.PropertyChangeSupport; +import java.io.File; + +public class ValidatorBean { + + protected File existingFile; + protected File notExistingFile; + + protected File existingDirectory; + protected File notExistingDirectory; + + PropertyChangeSupport p; + + public ValidatorBean() { + p = new PropertyChangeSupport(this); + } + + public void addPropertyChangeListener(PropertyChangeListener listener) { + p.addPropertyChangeListener(listener); + } + + public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) { + p.addPropertyChangeListener(propertyName, listener); + } + + public void removePropertyChangeListener(PropertyChangeListener listener) { + p.removePropertyChangeListener(listener); + } + + public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) { + p.removePropertyChangeListener(propertyName, listener); + } + + + public File getExistingFile() { + return existingFile; + } + + public File getNotExistingFile() { + return notExistingFile; + } + + public File getExistingDirectory() { + return existingDirectory; + } + + public File getNotExistingDirectory() { + return notExistingDirectory; + } + + public void setExistingFile(File existingFile) { + File old = this.existingFile; + this.existingFile = existingFile; + p.firePropertyChange("existingFile", old, existingFile); + } + + public void setNotExistingFile(File notExistingFile) { + File old = this.notExistingFile; + this.notExistingFile = notExistingFile; + p.firePropertyChange("notExistingFile", old, notExistingFile); + } + + public void setExistingDirectory(File existingDirectory) { + File old = this.existingDirectory; + this.existingDirectory = existingDirectory; + p.firePropertyChange("existingDirectory", old, existingDirectory); + } + + public void setNotExistingDirectory(File notExistingDirectory) { + File old = this.notExistingDirectory; + this.notExistingDirectory = notExistingDirectory; + p.firePropertyChange("notExistingDirectory", old, notExistingDirectory); + } + +} \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorBean.java ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorTest.java (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/java/jaxx/junit/ValidatorTest.java) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorTest.java (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/java/jaxx/junit/ValidatorTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,173 @@ +package jaxx.junit; + +import jaxx.runtime.validator.BeanValidator; +import jaxx.runtime.validator.BeanValidatorError; +import jaxx.runtime.validator.BeanValidatorErrorListModel; +import org.junit.Assert; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import javax.swing.JLabel; +import java.io.File; +import java.util.Enumeration; + +/** @author chemit */ +public class ValidatorTest { + + ValidatorBean bean; + + static protected BeanValidator<ValidatorBean> validator; + static protected BeanValidatorErrorListModel errors; + static protected File basedir; + + @BeforeClass + public static void initValidator() throws Exception { + + String b = System.getenv("basedir"); + if (b == null) { + b = new File("").getAbsolutePath(); + } + basedir = new File(b); + validator = new BeanValidator<ValidatorBean>(); + validator.setErrorListModel(errors = new BeanValidatorErrorListModel()); + JLabel label = new JLabel(); + validator.setFieldRepresentation("existingFile", label); + validator.setFieldRepresentation("existingDirectory", label); + validator.setFieldRepresentation("notExistingFile", label); + validator.setFieldRepresentation("notExistingDirectory", label); + + } + + @Before + public void setUp() throws Exception { + validator.setBean(bean = new ValidatorBean()); + } + + @Test + public void testRequiredFileFieldValidator() throws Exception { + + Assert.assertNull(bean.getExistingFile()); + assertFieldInError("existingFile", "existingFile.required", true); + + bean.setExistingFile(new File("")); + assertFieldInError("existingFile", "existingFile.required", true); + + bean.setExistingFile(basedir); + assertFieldInError("existingFile", "existingFile.required", false); + + assertFieldInError("existingFile", "existingFile.not.exist", true); + + bean.setExistingFile(new File(basedir, "pom.xml")); + assertFieldInError("existingFile", "existingFile.required", false); + assertFieldInError("existingFile", "existingFile.not.exist", false); + + } + + @Test + public void testExistingFileFieldValidator() throws Exception { + + Assert.assertNull(bean.getExistingFile()); + assertFieldInError("existingFile", "existingFile.required", true); + + bean.setExistingFile(new File("")); + assertFieldInError("existingFile", "existingFile.required", true); + + // existing directory + bean.setExistingFile(basedir); + assertFieldInError("existingFile", "existingFile.required", false); + assertFieldInError("existingFile", "existingFile.not.exist", true); + + // existing file + bean.setExistingFile(new File(basedir, "pom.xml")); + assertFieldInError("existingFile", "existingFile.required", false); + assertFieldInError("existingFile", "existingFile.not.exist", false); + + } + + @Test + public void testNotExistingFileFieldValidator() throws Exception { + + Assert.assertNull(bean.getNotExistingFile()); + assertFieldInError("notExistingFile", "notExistingFile.required", true); + + bean.setNotExistingFile(new File("")); + assertFieldInError("notExistingFile", "notExistingFile.required", true); + + // existing directory + bean.setNotExistingFile(basedir); + assertFieldInError("notExistingFile", "notExistingFile.required", false); + assertFieldInError("notExistingFile", "notExistingFile.exist", true); + + // existing file + bean.setNotExistingFile(new File(basedir, "pom.xml")); + assertFieldInError("notExistingFile", "notExistingFile.required", false); + assertFieldInError("notExistingFile", "notExistingFile.exist", true); + + // none existing file + bean.setNotExistingFile(new File(basedir, "pom.xml-" + System.currentTimeMillis())); + assertFieldInError("notExistingFile", "notEexistingFile.required", false); + assertFieldInError("notExistingFile", "notExistingFile.exist", false); + + + } + + @Test + public void testExistingDirectoryFieldValidator() throws Exception { + + Assert.assertNull(bean.getExistingDirectory()); + assertFieldInError("existingDirectory", "existingDirectory.required", true); + + bean.setExistingDirectory(new File("")); + assertFieldInError("existingDirectory", "existingDirectory.required", true); + + // existing file + bean.setExistingDirectory(new File(basedir, "pom.xml")); + assertFieldInError("existingDirectory", "existingDirectory.required", false); + assertFieldInError("existingDirectory", "existingDirectory.not.exist", true); + + // existing directory + bean.setExistingDirectory(basedir); + assertFieldInError("existingDirectory", "existingDirectory.required", false); + assertFieldInError("existingDirectory", "existingDirectory.not.exist", false); + + } + + @Test + public void testNotExistingDirectoryFieldValidator() throws Exception { + Assert.assertNull(bean.getNotExistingDirectory()); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", true); + + bean.setNotExistingDirectory(new File("")); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", true); + + // existing directory + bean.setNotExistingDirectory(basedir); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", false); + assertFieldInError("notExistingDirectory", "notExistingDirectory.exist", true); + + // existing file + bean.setNotExistingDirectory(new File(basedir, "pom.xml")); + assertFieldInError("notExistingDirectory", "notExistingDirectory.required", false); + assertFieldInError("notExistingDirectory", "notExistingDirectory.exist", true); + + // none existing directory + bean.setNotExistingDirectory(new File(basedir, "pom.xml-" + System.currentTimeMillis())); + assertFieldInError("notExistingDirectory", "notEexistingFile.required", false); + assertFieldInError("notExistingDirectory", "notExistingDirectory.exist", false); + } + + + protected void assertFieldInError(String s, String error, boolean required) { + Enumeration<?> myErrors = errors.elements(); + while (myErrors.hasMoreElements()) { + BeanValidatorError o = (BeanValidatorError) myErrors.nextElement(); + if (o.getFieldName().equals(s) && o.getError().equals(error)) { + Assert.assertTrue(required); + return; + } + } + // error was not found + Assert.assertFalse(required); + } +} Copied: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/jaxx/junit/ValidatorBean-validation.xml (from rev 1092, lutinjaxx/trunk/jaxx-core/src/test/resources/jaxx/junit/ValidatorBean-validation.xml) =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/jaxx/junit/ValidatorBean-validation.xml (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/jaxx/junit/ValidatorBean-validation.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,44 @@ +<!DOCTYPE validators PUBLIC + "-//OpenSymphony Group//XWork Validator 1.0.2//EN" + "http://www.opensymphony.com/xwork/xwork-validator-1.0.2.dtd"> +<validators> + + <field name="existingFile"> + <field-validator type="requiredFile" short-circuit="true"> + <message>existingFile.required</message> + </field-validator> + <field-validator type="existingFile" short-circuit="true"> + <message>existingFile.not.exist</message> + </field-validator> + </field> + + <field name="notExistingFile"> + <field-validator type="requiredFile" short-circuit="true"> + <message>notExistingFile.required</message> + </field-validator> + <field-validator type="notExistingFile" short-circuit="true"> + <message>notExistingFile.exist</message> + </field-validator> + </field> + + <field name="existingDirectory"> + <field-validator type="requiredFile" short-circuit="true"> + <message>existingDirectory.required</message> + </field-validator> + + <field-validator type="existingDirectory" short-circuit="true"> + <message>existingDirectory.not.exist</message> + </field-validator> + </field> + + <field name="notExistingDirectory"> + <field-validator type="requiredFile" short-circuit="true"> + <message>notExistingDirectory.required</message> + </field-validator> + + <field-validator type="notExistingDirectory" short-circuit="true"> + <message>notExistingDirectory.exist</message> + </field-validator> + </field> + +</validators> \ No newline at end of file Property changes on: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/jaxx/junit/ValidatorBean-validation.xml ___________________________________________________________________ Name: svn:mergeinfo + Added: lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/log4j.properties =================================================================== --- lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/log4j.properties (rev 0) +++ lutinjaxx/branches/storm_1/jaxx-runtime-validator/src/test/resources/log4j.properties 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,8 @@ +# Global logging configuration +log4j.rootLogger=ERROR, stdout +# Console output... +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) %M - %m%n + +log4j.logger.jaxx=DEBUG Modified: lutinjaxx/branches/storm_1/jaxx-swing-action/pom.xml =================================================================== --- lutinjaxx/trunk/jaxx-swing-action/pom.xml 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/jaxx-swing-action/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -25,7 +25,7 @@ <dependency> <groupId>org.codelutin</groupId> - <artifactId>jaxx-core</artifactId> + <artifactId>jaxx-runtime-swing</artifactId> <scope>compile</scope> </dependency> Modified: lutinjaxx/branches/storm_1/maven-jaxx-plugin/pom.xml =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/pom.xml 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/maven-jaxx-plugin/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,4 +1,5 @@ -<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> @@ -24,14 +25,23 @@ <dependency> <groupId>org.codelutin</groupId> - <artifactId>jaxx-core</artifactId> - <scope>compile</scope> + <artifactId>jaxx-compiler-api</artifactId> </dependency> <dependency> <groupId>org.codelutin</groupId> + <artifactId>jaxx-compiler-validator</artifactId> + </dependency> + + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-compiler-swing</artifactId> + </dependency> + + + <dependency> + <groupId>org.codelutin</groupId> <artifactId>jaxx-swing-action</artifactId> - <scope>compile</scope> </dependency> <!-- maven plugin project dependencies --> Modified: lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -19,11 +19,12 @@ package org.codelutin.jaxx; +import jaxx.beaninfos.BeanInfoUtil; +import jaxx.compiler.JAXXCompiler; +import jaxx.compiler.JAXXCompilerLaunchor; import jaxx.compiler.CompilerOptions; -import jaxx.compiler.JAXXCompiler; import jaxx.runtime.JAXXContext; import jaxx.tags.TagManager; -import jaxx.tags.swing.SwingInitializer; import org.apache.maven.artifact.DependencyResolutionRequiredException; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; @@ -62,6 +63,13 @@ protected MavenProject project; /** + * Le compilateur à utiliser (par défaut celui de Swing) + * + * @parameter expression="${jaxx.compilerFQN}" default-value="jaxx.compiler.SwingCompiler" + */ + protected String compilerFQN; + + /** * Repertoire de destination des fichiers java a generer. * * @parameter expression="${jaxx.outJava}" default-value="${basedir}/target/generated-sources/java" @@ -191,7 +199,7 @@ /** * extra path to be added in {@link java.beans.Introspector#setBeanInfoSearchPath(String[])}. * <p/> - * add beanInfoSearchPath to be registred by {@link SwingInitializer#setExtraBeanInfoSearchPath(String[])} + * add beanInfoSearchPath to be registred by {@link BeanInfoUtil#addJaxxBeanInfoPath(String[])} * <p/> * and then will be use by {@link jaxx.tags.swing.SwingInitializer#initialize()}. * <p/> @@ -232,8 +240,9 @@ private Class<?> defaultErrorUIClass; protected ClassLoader cl; + private Class<? extends JAXXCompiler> compilerClass; - protected void init() throws ClassNotFoundException { + protected void init() throws ClassNotFoundException, MalformedURLException { if (project != null && ("pom".equals(project.getPackaging()) || "site".equals(project.getPackaging()))) { // nothing to be done for this type of packaging @@ -242,6 +251,8 @@ return; } + compilerClass = (Class<? extends JAXXCompiler>) Class.forName(compilerFQN); + if (defaultErrorUIFQN != null && !defaultErrorUIFQN.trim().isEmpty()) { defaultErrorUIClass = Class.forName(defaultErrorUIFQN); } @@ -251,7 +262,7 @@ if (beanInfoSearchPath != null && beanInfoSearchPath.length > 0) { // regisre extra path - SwingInitializer.setExtraBeanInfoSearchPath(beanInfoSearchPath); + BeanInfoUtil.addJaxxBeanInfoPath(beanInfoSearchPath); } if (!outResource.exists()) { outResource.mkdirs(); @@ -322,6 +333,7 @@ if (javaOpts != null && !"".equals(javaOpts)) { result.setJavacOpts(javaOpts); } + result.setCompilerClass(compilerClass); result.setKeepJavaFiles(true); result.setOptimize(optimize); result.setJavacTargetDirectory(outClass); @@ -347,6 +359,8 @@ init(); } catch (ClassNotFoundException e) { throw new MojoExecutionException("error in init : " + e.getMessage(), e); + } catch (MalformedURLException e) { + throw new MojoExecutionException("error in init : " + e.getMessage(), e); } if (skip) { @@ -373,10 +387,16 @@ // force compiler init from here, not in a static block TagManager.reset(verbose); - if (!JAXXCompiler.compile(src, files, options)) { + JAXXCompilerLaunchor launchor = JAXXCompilerLaunchor.newLaunchor(src, files, options); + + if (!launchor.compile()) { throw new MojoFailureException("Aborting due to errors reported by jaxxc"); } + /*if (!JAXXCompiler.compile(src, files, options)) { + throw new MojoFailureException("Aborting due to errors reported by jaxxc"); + }*/ + } catch (Exception e) { getLog().error(e); Throwable e2 = e; @@ -399,7 +419,7 @@ } @SuppressWarnings({"unchecked"}) - protected URLClassLoader initClassLoader(MavenProject project, Log log) { + protected URLClassLoader initClassLoader(MavenProject project, Log log) throws MalformedURLException { URLClassLoader loader = null; if (project != null) { @@ -430,14 +450,18 @@ result = new URLClassLoader(lUrls.toArray(new URL[lUrls.size()]), getClass().getClassLoader()); - } catch (MalformedURLException eee) { - throw new RuntimeException("Can't create ClassLoader for script, bad directory: " + outClass + " for reason " + eee.getMessage(), eee); } catch (IOException e) { throw new RuntimeException("Can't create ClassLoader for script, bad directory: " + outClass + " for reason " + e.getMessage(), e); } catch (DependencyResolutionRequiredException e) { throw new RuntimeException(e); } loader = result; + } else { + List<URL> lUrls = new ArrayList<URL>(); + if (addSourcesToClassPath) { + lUrls.add(src.toURI().toURL()); + } + loader = new URLClassLoader(lUrls.toArray(new URL[lUrls.size()]), getClass().getClassLoader()); } if (loader != null && isVerbose()) { for (URL entry : loader.getURLs()) { @@ -603,4 +627,16 @@ public void setBeanInfoSearchPath(String[] beanInfoSearchPath) { this.beanInfoSearchPath = beanInfoSearchPath; } + + public String getCompilerFQN() { + return compilerFQN; + } + + public void setCompilerFQN(String compilerFQN) { + this.compilerFQN = compilerFQN; + } + + public Class<? extends JAXXCompiler> getCompilerClass() { + return compilerClass; + } } \ No newline at end of file Modified: lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1750Test.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -2,7 +2,7 @@ import jaxx.Base64Coder; import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXCompilerHelper; +import jaxx.compiler.JAXXCompilerLaunchor; import jaxx.runtime.JAXXObjectDescriptor; import jaxx.runtime.Util; @@ -13,7 +13,7 @@ mojo.execute(); assertEquals(1, mojo.getFiles().length); - JAXXCompiler compiler = JAXXCompilerHelper.getJAXXCompiler("testcases.bug_1750.ComboBox"); + JAXXCompiler compiler = JAXXCompilerLaunchor.get().getJAXXCompiler("testcases.bug_1750.ComboBox"); assertNotNull(compiler); JAXXObjectDescriptor descriptor = compiler.getJAXXObjectDescriptor(); Modified: lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1751Test.java =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1751Test.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/Bug1751Test.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,11 +1,5 @@ package org.codelutin.jaxx; -import jaxx.Base64Coder; -import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXCompilerHelper; -import jaxx.runtime.JAXXObjectDescriptor; -import jaxx.runtime.Util; - /** @author chemit */ public class Bug1751Test extends JaxxBaseTest { Modified: lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,12 +1,11 @@ package org.codelutin.jaxx; import jaxx.compiler.JAXXCompiler; -import jaxx.compiler.JAXXCompilerHelper; +import jaxx.compiler.JAXXCompilerLaunchor; import jaxx.runtime.DefaultJAXXContext; import jaxx.runtime.JAXXContext; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugin.logging.SystemStreamLog; -import org.junit.Assert; import java.io.File; import java.lang.reflect.Field; @@ -61,6 +60,7 @@ checkPattern(mojo, "import org.apache.commons.logging.LogFactory;", false, files); } + @SuppressWarnings({"unchecked"}) public void testErrors() throws Exception { // init mojo to get alls files to treate mojo.init(); @@ -87,8 +87,8 @@ //do nothing } }); - Field fieldCompilers = JAXXCompilerHelper.class.getDeclaredField("compilers"); - Field fieldErrorCount = JAXXCompilerHelper.class.getDeclaredField("errorCount"); + Field fieldCompilers = JAXXCompilerLaunchor.class.getDeclaredField("compilers"); + Field fieldErrorCount = JAXXCompilerLaunchor.class.getDeclaredField("errorCount"); fieldCompilers.setAccessible(true); fieldErrorCount.setAccessible(true); @@ -105,11 +105,13 @@ // ok jaxx compiler failed assertTrue(true); - Map<String, JAXXCompiler> compilers = (Map<String, JAXXCompiler>) fieldCompilers.get(null); + JAXXCompilerLaunchor launchor = JAXXCompilerLaunchor.get(); + Map<String, JAXXCompiler> compilers = (Map<String, JAXXCompiler>) fieldCompilers.get(launchor); assertEquals(1, compilers.size()); - JAXXCompiler compiler = compilers.values().iterator().next(); - Integer nberrors = (Integer) fieldErrorCount.get(compiler); - assertTrue(nberrors > 0); + //JAXXCompiler compiler; + //compiler = compilers.values().iterator().next(); + Integer nberrors = (Integer) fieldErrorCount.get(launchor); + assertTrue(nberrors != null && nberrors > 0); } } } @@ -125,7 +127,7 @@ mojo.init(); fail(); } catch (IllegalArgumentException e) { - Assert.assertTrue(true); + assertTrue(true); } mojo.setJaxxContextImplementorClass(String.class.getName()); @@ -133,7 +135,7 @@ mojo.init(); fail(); } catch (IllegalArgumentException e) { - Assert.assertTrue(true); + assertTrue(true); } mojo.setJaxxContextImplementorClass(JAXXContext.class.getName()); @@ -141,12 +143,12 @@ mojo.init(); fail(); } catch (IllegalArgumentException e) { - Assert.assertTrue(true); + assertTrue(true); } mojo.setJaxxContextImplementorClass(DefaultJAXXContext.class.getName()); mojo.init(); - Assert.assertTrue(true); + assertTrue(true); } @@ -188,7 +190,9 @@ assertEquals(oldTime, mojo.getUpdater().getMirrorFile(srcFile).lastModified()); // three round : modify a source with no force option - srcFile.setLastModified(System.currentTimeMillis()); + if (!srcFile.setLastModified(System.currentTimeMillis())) { + log.warn("failed to set LastModified for file " + srcFile); + } mojo.execute(); files = mojo.getFiles(); @@ -210,6 +214,7 @@ } + @SuppressWarnings({"unchecked"}) public void testValidatorErrors() throws Exception { // init mojo to get alls files to treate mojo.init(); @@ -236,8 +241,8 @@ //do nothing } }); - Field fieldCompilers = JAXXCompilerHelper.class.getDeclaredField("compilers"); - Field fieldErrorCount = JAXXCompilerHelper.class.getDeclaredField("errorCount"); + Field fieldCompilers = JAXXCompilerLaunchor.class.getDeclaredField("compilers"); + Field fieldErrorCount = JAXXCompilerLaunchor.class.getDeclaredField("errorCount"); fieldCompilers.setAccessible(true); fieldErrorCount.setAccessible(true); @@ -253,11 +258,11 @@ } catch (MojoExecutionException e) { // ok jaxx compiler failed assertTrue(true); - - Map<String, JAXXCompiler> compilers = (Map<String, JAXXCompiler>) fieldCompilers.get(null); + JAXXCompilerLaunchor launchor = JAXXCompilerLaunchor.get(); + Map<String, Compiler> compilers = (Map<String, Compiler>) fieldCompilers.get(launchor); assertEquals(1, compilers.size()); - JAXXCompiler compiler = compilers.values().iterator().next(); - Integer nberrors = (Integer) fieldErrorCount.get(compiler); + //Compiler compiler = compilers.values().iterator().next(); + Integer nberrors = (Integer) fieldErrorCount.get(launchor); assertEquals(1, nberrors.intValue()); } } Modified: lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/JaxxBaseTest.java 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,5 +1,6 @@ package org.codelutin.jaxx; +import jaxx.runtime.DefaultJAXXContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.maven.plugin.testing.AbstractMojoTestCase; @@ -8,8 +9,6 @@ import java.io.File; import java.io.IOException; -import jaxx.runtime.DefaultJAXXContext; - /** @author chemit */ public abstract class JaxxBaseTest extends AbstractMojoTestCase { @@ -33,6 +32,7 @@ pomFile = getPomFile(); mojo = (JaxxGeneratorMojo) lookupMojo("generate", pomFile); mojo.setJaxxContextImplementorClass(DefaultJAXXContext.class.getName()); + mojo.setCompilerFQN(jaxx.compiler.SwingCompiler.class.getName()); assertNotNull(mojo); } Modified: lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/resources/testcases/Bug_1751.xml =================================================================== --- lutinjaxx/trunk/maven-jaxx-plugin/src/test/resources/testcases/Bug_1751.xml 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/maven-jaxx-plugin/src/test/resources/testcases/Bug_1751.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -9,8 +9,8 @@ <artifactId>maven-jaxx-plugin</artifactId> <configuration> <src>${basedir}/src/test/resources</src> - <outJava>${basedir}/target/generated-sources/it-1751/java</outJava> - <outResource>${basedir}/target/generated-sources/it-1751/resources</outResource> + <outJava>${basedir}/target/it-generated-source/it-1751/java</outJava> + <outResource>${basedir}/target/it-generated-source/it-1751/resources</outResource> <i18nable>true</i18nable> <force>true</force> <verbose>true</verbose> Modified: lutinjaxx/branches/storm_1/pom.xml =================================================================== --- lutinjaxx/trunk/pom.xml 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/pom.xml 2008-12-30 09:05:37 UTC (rev 1101) @@ -9,14 +9,22 @@ <parent> <groupId>org.codelutin</groupId> <artifactId>lutinproject</artifactId> - <version>3.2</version> + <version>3.3-SNAPSHOT</version> </parent> <artifactId>lutinjaxx</artifactId> <modules> <module>jaxx-util</module> - <module>jaxx-core</module> + <module>jaxx-runtime-api</module> + <module>jaxx-runtime-swing</module> + <module>jaxx-runtime-validator</module> + + <module>jaxx-compiler-api</module> + <module>jaxx-compiler-swing</module> + <module>jaxx-compiler-validator</module> + + <!--module>jaxx-core</module--> <module>jaxx-swing-action</module> <module>maven-jaxx-plugin</module> </modules> @@ -52,6 +60,8 @@ <!-- lutinutil version --> <lutinutil.version>1.0</lutinutil.version> + <jaxx.version>${project.version}</jaxx.version> + <!-- multi-module level two son pom scm properties --> <maven.scm.url.child.child> http://${labs.host}/plugins/scmsvn/viewcvs.php/lutinjaxx/trunk/${project.parent.artifactId}/${project.artifactId}?root=${labs.project} @@ -85,7 +95,7 @@ </plugins> </pluginManagement> - <plugins> + <!--plugins> <plugin> <artifactId>maven-javadoc-plugin</artifactId> @@ -96,7 +106,7 @@ </executions> </plugin> - </plugins> + </plugins--> </build> @@ -114,13 +124,48 @@ <version>${project.version}</version> </dependency> + <!-- api extension --> <dependency> <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-api</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-compiler-api</artifactId> + <version>${project.version}</version> + </dependency> <dependency> + <groupId>org.codelutin</groupId> <artifactId>jaxx-core</artifactId> <version>${project.version}</version> </dependency> + + <!-- swing extension --> <dependency> <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-swing</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-compiler-swing</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- validator extension --> + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-runtime-validator</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>org.codelutin</groupId> + <artifactId>jaxx-compiler-validator</artifactId> + <version>${project.version}</version> + </dependency> + + <dependency> + <groupId>org.codelutin</groupId> <artifactId>jaxx-swing-action</artifactId> <version>${project.version}</version> </dependency> @@ -184,6 +229,12 @@ <version>1.3</version> </dependency> + <dependency> + <groupId>commons-lang</groupId> + <artifactId>commons-lang</artifactId> + <version>2.4</version> + </dependency> + </dependencies> </dependencyManagement> Copied: lutinjaxx/branches/storm_1/src/site/fr/rst/BeanValidator.rst (from rev 1092, lutinjaxx/trunk/jaxx-core/src/site/fr/rst/BeanValidator.rst) =================================================================== --- lutinjaxx/branches/storm_1/src/site/fr/rst/BeanValidator.rst (rev 0) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/BeanValidator.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,179 @@ +------------- +BeanValidator +------------- + +.. contents:: + + +Présentation +============ + +Ajout du support de validation dans JAXX. + +La techonologie utilisée est celle de Struts 2 (XWorks 2). + + +Configuration +============= + +La configuration des validateurs se font via des fichier xml (on peut aussi utiliser des annotations,...). + +Ajout d'un validateur +********************* + +Pour enregister un nouveau validateur sur un bean, il suffit de placer dans le même paquetage que le bean un fichier *XXX-validation.xml* où XXX est le nom non qualifié du bean. + +On peut de plus affecter un context de validation, dans ce cas le fichier doit s'appeler *XXX-YYY-validation.xml*, où YYY est le nom du context de validation. + +Ainsi on peut valider de différentes manières un bean (par exemple selon son cycle de vie :création, modification, ...). + +Ajout d'un nouveau type de validateur +************************************* + +Il est aussi possible de définir de nouveau type de validateurs : + + * créer une classe qui étend FieldValidator + * ajouter un fichier validators.xml (ou ajouter dans un tel fichier la définition du nouveau validator) à la racine du class-path. + +I18n +**** + +Afin de rendre le mécanisme multi-langue, on propose dans les fichiers de validations d'utiliser des clef i18n pour les messages. + +Un nouveau parseur dans notre plugin i18n a été ajouté pour détecter ces clefs. (*maven-i18n-plugin:0.7:parserValidation*) + + +Intégration dans JAXX +===================== + +Deux nouveaux tags ont été conçus pour pouvoir décrire un validateur dans les fichiers JAXX. + +Ce développement est dans le paquetage *jaxx.tags.validator*. + +tag BeanValidator +***************** + +Permet de définir un nouveau validateur dans une classe JAXX. + +Les attributs autorisés sont les suivants : + + * *id* : le nom du validateur + + * *bean* : l'id d'un bean connu par la classe JAXX. On ne peut pas utiliser ici une expression car on n'est pas sûr de pouvoir déterminer le type de cette expression pendant le parsing ? (a verifier). + + * *beanClass* : le FQN de classe du bean à valider. Peut-être non présent si l'attribut *bean* est renseigné. + + * *beanInitializer* : une expression pour initialiser le bean à valider. TODO a revoir : on devrait utiliser uniquement un seul attribut *bean*... + + * *contextName* : le nom du contexte de validation. + + * *autoField* : flag pour indiquer l'inscription implicite des validateurs de champs du bean. Pour ce faire on parcourt l'ensemble des champs du bean et on ne considère uniquement ceux dont on connait dans la classe JAXX un composent d'édition du champ (id=nom du champ). Il est possible de surcharger ce configuration implicite en rajoutant explicitement des champs (voir le tag *field*). + + * *errorList* : le composant graphique pour afficher la liste des erreurs, doit étendre *javax.swing.JList*. Si non présent, on essayera le component d'id *errorList*. + + * *errorListModel* : le modèle qui contient la liste des erreurs (et est liée au composant *errorList*), doit étendre *jaxx.runtime.validator.BeanValidatorErrorListModel*. Si non présent on essayera le composent d'id *errorListModel*. + + * *uiClass* : le FQN de la classe utilisé pour le rendu des erreurs sur les wigets d'édition. La classe doit étendre *jaxx.runtime.validator.ui.AbstractBeanValidatorUI*. Si non présent, on utilise par défaut le render *jaxx.runtime.validator.ui.IconValidationUI*. + + +Le tag supporte aussi l'ajout de tag *field* comme fils pour définir explicitement des champs à validater. + +tag field +********* + +Le tag *field* définit une entrée dans le validateur, on définit une correspondance entre le champ à valider et le composant d'édition de ce champ. + +Le tag supporte les attributs suivants : + + * *name* : le nom de la propriété du bean associée. + Cet attribut est obligatoire. + + * *component* : l'id du composant graphique d'édition associé à la propriété du bean. + Cet attribut peut être omis si le nom de la propriété du bean est identique à celui du composent graphique d'édition. + + +Les classes du runtime +====================== + +Ce développement est dans le paquetage *jaxx.runtime.validator* (sauf pour l'interface *jaxx.runtime.JAXXValidator*). + +Il s'agit de l'ensemble des classes ajoutées dans le module *jaxx-core* pour encapsuler la validation dans les fichiers java générés à partir des fichiers JAXX. + + +interface jaxx.runtime.JAXXValidator +************************************ + +Ce contrat a été ajouté à tous les objets JAXX générés (donc l'interface JAXXObject étend JAXXValidator). + +On définit ici uniquement des méthodes d'accès aux validateurs enregistrés dans le JAXXObject. + +TODO on pourrait ajouter des méthodes pour savoir l'état de validation d'un validateur ? + + +classe jaxx.runtime.validator.BeanValidator +******************************************* + +Il s'agit de la classe principale d'encapsulation d'un validateur XWorks 2. + +Le principe est simple : le validateur écoute les modifications sur le bean associé et revalide le bean à chaque modification. La validation met à jour la liste des erreurs asociées. + +On se base sur les PropertyChangeListener pour écouter les modification des beans. Il faut donc que les beans supporte ces listeners. + +Pour les entités de ToPIA, il suffit de positionner un contexte (topia) au bean pour profiter des listeners liés. + +Pour les DTO de ToPIA, les générateurs ont été modifiés pour gérer ce support. + +Les méthodes à retenir sont : + + * *setBean* pour affecter un bean au validateur (pour déasactiver passer null). Lors de la désactivation d'un bean, les erreurs associés sont retirées de la liste des erreurs. + + * *setContextName* pour affecter un nouveau nom de context de validation (par défaut on utilise pas de context de validation). + + * *validate* pour lancer une validation sur le bean liée (ne sera opérant uniquement si un bean est liée et qu'une liste d'erreur est liée). + + * *isValid* pour connaitre l'état du validateur à un moment donné. + +Normalement la méthode *validate* ne devrait pas être appelée directement. : elle est automatiquement invoquée lorsqu'une propriété du bean est modifiée. + +classe jaxx.runtime.validator.BeanValidatorError +************************************************ + +Modélisation d'une erreur renvoyé par le validateur, on conserve ici : + + * le validateur qui a provoqué l'erreur + + * la propriété du bean en faute + + * le composent graphique d'édtion de la propriété + +classe jaxx.runtime.validator.BeanValidatorErrorListModel +********************************************************* + +Le modèle de la liste des erreurs renvoyées par le validateur. Il s'agit d'une extension d'un *javax.swing.DefaultListModel* qui permet de gérer une liste d'erreurs provenant de plusieurs validateurs en même temps. + +classe jaxx.runtime.validator.ErrorListMouseListener +**************************************************** + +Un listener écoutant les double clics sur une liste d'erreurs et qui donne le focus au composent graphique d'édition associée à la propriété dont l'erreur est sélectionné. + + +Les conversions +=============== + +Pour l'édition de proriétés qui ne sont pas des chaines de caractères, des erreurs de conversions peuvent survenir (conversion de la valeur de l'édtieur graphique vers le bean), avant que l'on utilise +réellement la mécanique de la validation. + +Pour palier à ce problème on a intégré la gestion des erreurs de conversion dans le validateur. +Pour ce faire, il suffit de faire appel à la méthode suivante pour injecter dans un bean une propriété : + + :: + + jaxx.runtime.Util.convert(validator,"nomDeLaPropriété",widget.getText(),TypeDeLaProriete.class); + + +On obtiendra si une erreur de conversion intervient, une erreur dont le libellé est de la forme *error.convertor.XXX* +où XXX est nom simple en minuscule du type de la propruité. (par exemple : *error.convertor.integer*). + + + + Copied: lutinjaxx/branches/storm_1/src/site/fr/rst/I18n.rst (from rev 1092, lutinjaxx/trunk/jaxx-core/src/site/fr/rst/I18n.rst) =================================================================== --- lutinjaxx/branches/storm_1/src/site/fr/rst/I18n.rst (rev 0) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/I18n.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,56 @@ +---- +I18n +---- + +.. contents:: + + +Présentation +============ + +Ajout du support i18n dans JAXX. + +On utilise la système i18n développé dans la librairie des lutins (*lutinlib*). + +Configuration +============= + +Une option a été ajoutée dans le plugin maven de JAXX : *i18nable* pour permettre ou non l'utilisation de ce système. + +Par défaut, l'option est active (donc aucune configuration supplémentaire n'est nécessaire pour utiliser i18n dans JAXX). + + +Fonctionnement +============== + +Le fonctionnement est simple : lors de la compilation JAXX, lorsque l'on rencontre certains attributs on encapsule la +valeur de l'attribution par un appel à la méthode + +:: + + org.codelutin.i18n.I18n._(String) + + +La liste des attributs en question sont les suivants : + + - title + - text + - toolTipText + + +Ensuite l'utilisation du *parserJava* du plugin i18n permet la détection des clefs i18n. + + +Pourquoi ne plus utiliser l'ancien parserJaxx du plugin i18n +============================================================ + +Un parseur avait été développé initialement pour détecter dans les fichiers JAXX (*parserJaxx*), les appels à la méthode de traduction +i18n dans les attributs. + +Ce parseur n'est plus d'actualité car on ne doit plus avoir d'appel explicite à cette méthode dans les fichiers JAXX. + +De plus, même sans avoir mis en place le mécanisme i18n dans JAXX, ce parseur n'était plus d'actualité : il se base +sur une liste prédéfinie d'attributs xml à scanner pour détecter des appels i18n; ce qui n'était pas acceptable à terme +car si on ajoute un nouveau composent dans JAXX, le plugin i18n n'est pas capable de détecter les nouvelles clefs. + +Donc on préconise l'utilisation du *parserJava* du plugin i18n qui lui est capable de détecter tous les appels i18n. Property changes on: lutinjaxx/branches/storm_1/src/site/fr/rst/I18n.rst ___________________________________________________________________ Name: svn:mergeinfo + Copied: lutinjaxx/branches/storm_1/src/site/fr/rst/Interface.rst (from rev 1092, lutinjaxx/trunk/jaxx-core/src/site/fr/rst/Interface.rst) =================================================================== --- lutinjaxx/branches/storm_1/src/site/fr/rst/Interface.rst (rev 0) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/Interface.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,38 @@ +--------- +Interface +--------- + +.. contents:: + + +Présentation +============ + +Ajout de contrats sur le code généré dans JAXX. + +Mécanisme +========= + +Le compilateur JAXX génère des classes à partir de fichiers JAXX mais n'est pas capable d'ajouter des contrats sur +les objets générés, donc interdit en quelque sorte la programmation par contrat. + +Pour palier à cette limitation, on a ajouté un attribut spécial *implements*. + +Cette attribut ne doit être placé que sur le tag racine d'un fichier JAXX et son contenu est le nom qualifié d'un ou +plusieurs contrats séparaés par des virgules. + +:: + + <JPanel implements='java.lang.Comparable'> + + <script>public int compareTo(JPanel o) { return getName().compareTo(o.getName()); }</script> + + </JPanel> + +La classe générée aura bien le contrat *java.lang.Comparable*. + +TODO +==== + +Il serait intéressant lors de l'injection de contrats sur un objet jaxx de pouvoir vérifier si toutes les méthodes du +contrat sont bien implantées dans la classe, et si ce n'est pas le cas de rendre la classe abstraite. Copied: lutinjaxx/branches/storm_1/src/site/fr/rst/JAXXContext.rst (from rev 1092, lutinjaxx/trunk/jaxx-core/src/site/fr/rst/JAXXContext.rst) =================================================================== --- lutinjaxx/branches/storm_1/src/site/fr/rst/JAXXContext.rst (rev 0) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/JAXXContext.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,161 @@ +----------- +JAXXContext +----------- + +.. contents:: + + +Présentation +============ + +Ajout d'un context applicatif dans JAXX. + +Le besoin initial de ce développement est de pouvoir facilement intégrer un context applicatif dans JAXX et de pouvoir +l'utiliser dans les fichiers JAXX pour injecter par exemple des données dans les widgets. + +jaxx.runtime.JAXXContext +======================== + +Il s'agit du contrat de base du context applicatif. + +Les entrées dans le context +*************************** + +Chaque donnée utilisable dans le context est caractérisée par deux propriétés : + + * la type de l'objet + + * un nom (facultatif) associé à la donnée + +Le type de l'objet correspondant en fait à la classe de la donnée. + +Le nom qui est facultatif permet de pouvoir distinguer plusieurs données d'un même type dans le context. Si le nom +n'est pas utilisé pour caractériser une données on fixera alors sa valeur à *null*. + +Afin de pouvoir caractériser les entrées dans le context, une classe a été définie *jaxx.runtime.JAXXContextEntryDef*. + +Les méthodes de lecture +*********************** + +On a définit deux méthodes de lecture de données dans le context : + + * *getContextValue(Class)* récupère la donnée *non nommée* dont le type correspond à celui passé. + + * *getContextValue(Class,String)* récupère la donnée nommé dont le type correspond à celui passé. + +Les méthodes d'écriture +*********************** + +On a définit quatre méthodes d'écriture de données dans le context : + + * *setContextValue(Object)* enregistre dans le context la donnée *non nommée*. + + * *setContextValue(Object,String)* enregistre dans le context la donnée *nommée*. + + * *removeContextValue(Class)* supprime du context, la donnée *non nommée* dont le type est passé. + + * *removeContextValue(Class, String)* supprime du context, la donnée *nommée* dont le type est passé. + +Afin de pouvoir assurer une cohérence dans le context, chaque injection de donnée, sera toujours précédée par une +suppression d'un éventuellement ancienne valeur qui aurait la même définition d'entrée. + +L'héritage +********** + +Il est possible d'avoir une hériarchie de context qui s'enchaînent. Ce mécanisme a été mis en place pour répondre à un +besion précis : chaque fichier JAXX donne lieu à une nouvelle classe qui possède son propre context. + +On peut avoir des fichiers JAXX qui utilisent d'autres fichiers JAXX, il faut donc être capable de lier le context du +composent parent avec ses fils. + +La mise en place de l'héritage est transparente pour l'utilisateur : aucune méthode supplémentaire n'est requise. + +Les implantations de context +============================ + +jaxx.runtime.DefaultJAXXContext +******************************* + +Il s'agit de l'implantation par défaut utilisée par les objects *JAXXObject* (objets générés). + +A noter que pour les opérations d'injection ou de suppression, on effectuera les opérations sur le context qui contient +réellement la donnée, ce qui est important pour conserver la cohérence des contexts dans les contexts chaînés. + +Pour traiter le context parent, aucune méthode publique supplémentaire n'a été rajoutée, il suffit d'injecter un objet +de type *JAXXContext* *non nommé* qui le context courant qui sera détecté comme une entrée de type context. + +Cette entrée spéciale ne sera pas stockée avec les autres entrées afin d'optimiser les algorithmes d'injection et de +restitution. + +jaxx.runtime.JAXXInitialContext +******************************* + +On a implanté un second type de context qui lui peut servir à l'initialisation des JAXXObject. + +Ce second type de context ajoute des méthodes pour préparer le context avant l'instanciation des JAXXObject. + +Ce context admet certaine limitation (pas de suppression dans le context), et apporte trois nouvelles méthodes : + + * add(Object) : injecte dans le context une entrée non nommée et retourne l'instance du context. + + * add(String,Object) : injecte dans le context une entrée nommé et retourne l'instance du context. + + * to(JAXXContext) : injecte dans le context passé toutes les entrée du context. + +Les méthodes *add* peuvent être chaînées comme dans l'exemple suivant : + +:: + + JAXXInitialContext context = new JAXXInitialContext().add("string").add(0).add("currentDate",new Date()); + + +Intégration dans les JAXXObject +=============================== + +Le traitement d'un fichier JAXX donne lieu à une classe qui possède le contrat *jaxx.runtime.JAXXObject*. + +Ce contrat hérite donc du contrat *JAXXContext* (afin de pouvoir l'utiliser de manière transparente dans les fichiers JAXX). + +Afin de simplifier la génération et les évolutions du context indépendemment des évolutions des JAXXObject, on utilise +un pattern de délégation au sein des object générés. + +Paramétrage de l'implantation du context +**************************************** + +Une propriété a été rajoutée sur le plugin JAXX, afin de pouvoir préciser l'implantation de context à utiliser : + +:: + + jaxx.jaxxContextImplementorClass + +Il s'agit du nom qualifié de la classe d'implantation à utiliser. + +Par défaut, si rien n'est renseigné, on utilisera un *jaxx.runtime.DefaultJAXXContext*. + + +Initialisation d'un JAXXObject +****************************** + +Un nouveau constructeur a été ajouté dans les JAXXObjet générés afin de pouvoir facilement initialisé un tel objet à +partir d'un context parent, son unique paramètre est le context parent. Ce constructeur est capable de différencer le +type de context passé : + + * s'il s'agit d'un *JAXXInitialContext*, on recopie alors dans le context réel de l'objet toutes les entrées du context passé. + + * sinon le context passé est simplement injecté dans le context de l'objet (et donc sera utilisé comme le context parent de celui de l'objet). + +Voici un exemple d'initialisation d'un JAXXObject : + +:: + + java.util.Date currentDate = new java.util.Date(); + JAXXInitialContext context = new JAXXInitialContext().add("string").add(0).add("currentDate",currentDate); + JAXXObject ui = new MyUI(context); + + assert "string".equals(myUI.getContextValue(String.class)); + assert 0 == myUI.getContextValue(Integer.class); + assert currentDate.equals(myUI.getContextValue(java.util.Date.class,"currentDate")); + +A noter, que l'initialisation du context d'un *JAXXObject* sera toujours effectuée avant la méthode *$initialize* générée +par le compilateur JAXX, ce qui permet de pouvoir utiliser le context pour l'initialisation des widgets dans les fichiers JAXX. + Copied: lutinjaxx/branches/storm_1/src/site/fr/rst/JavaBean.rst (from rev 1092, lutinjaxx/trunk/jaxx-core/src/site/fr/rst/JavaBean.rst) =================================================================== --- lutinjaxx/branches/storm_1/src/site/fr/rst/JavaBean.rst (rev 0) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/JavaBean.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,50 @@ +-------- +JavaBean +-------- + +.. contents:: + + +Présentation +============ + +Ajout du support complêt des javaBean dans JAXX. + +Mécanisme +========= + +Il est possible dans JAXX de rajouter des objets quelconques via leur nom qualifié de classe : + +:: + + <JPanel> + <java.lang.Boolean id='myState' constructorParams='true'/> + <JLabel text='text' visible='{isMySate()}'/> + </JPanel> + +Avant l'ajout de la fonctionnalité, le code généré possèdait : + + * une propriété en lecture seul nommé *myState*. + +Aucun support javaBean n'était présent et le databinding sur la propriété *visible* du label n'est pas créé. Cela veut +dire que le label sera initialisé avec la valeur initiale du boolean et c'est tout... + +Avec l'ajout du support javaBean, on peut maintenant faire ces bindings, pour ce faire il suffit d'ajouter un attribut +*javaBean* sur l'objet : + +:: + + <JPanel> + <java.lang.Boolean id='myState' constructorParams='true' javaBean='anyValue'/> + <JLabel text='text' visible='{isMySate()}'/> + </JPanel> + +On aura donc en plus : + + * un mutateur sur la propriété *myState* qui déclanchera l'envoie d'un *PropertyChange* sur la propriété lors de modification de valeur. + +Ainsi le compilateur JAXX sera capable d'enregistrer un novueau dataBindig sur la propriété *visible* du label et la +modification de l'état *myState* sera automatiquement répercuté sur la propriété. + + + Copied: lutinjaxx/branches/storm_1/src/site/fr/rst/NavigationTreeModel.rst (from rev 1092, lutinjaxx/trunk/jaxx-core/src/site/fr/rst/NavigationTreeModel.rst) =================================================================== --- lutinjaxx/branches/storm_1/src/site/fr/rst/NavigationTreeModel.rst (rev 0) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/NavigationTreeModel.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -0,0 +1,168 @@ +------------------- +NavigationTreeModel +------------------- + +.. contents:: + + +Présentation +============ + +Ajout d'un modèle d'arbre de navigation. + +Le but de cette fonctionnalité est de pouvoir créer un arbre de navigation lié au context de JAXX, de définir des UI +rattachés à chaque noeud. + +Le développement est effectué dans le paquetage *jaxx.runtime.swing.navigation*. + +jaxx.runtime.swing.navigation.NavigationTreeModel +================================================= + +Il s'agit du modèle de l'arbre utilisé, c'est une extension d'un *javax.swing.tree.DefaultTreeModel*. + +Les noeuds présents dans ce modèle sont aussi typés en *jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode*. + +L'idée principale est de pouvoir associé à un noeud précis un chemin depuis la racine, ce que l'on appele *chemin de navigation*. + +Pour obtenir le chemin de navigation d'un noeud donné, on récupère l'enmseble des neoud depuis la racine vers ce noeud +et les concatène en suffixant par le caractère séparateur défini. + +Définition d'un noeud +===================== + +Le noeud (*jaxx.runtime.swing.navigation.NavigationTreeModel.NavigationTreeNode*) est une extension d'un *javax.swing.tree.DefaultMutableTreeNode*. + +Il apporte les nouvelles propriétés suivantes : + + * *navigationPAth* : nom de chemin de navigation de ce noeud. + + * *jaxxClass* : nom qualifié de la classe d'ui associé à ce noeud (doit être obligatoirement un *JAXXObject*) + + * *jaxxActionClass* : nom qualifié de la classe d'handler d'ui associé à ce noeud (doit être obligatoirement un *JAXXAction*). + + * *jaxxContextEntryDef* : définition de l'entrée dans le context JAXX associé à ce noeud. + + * *jaxxContextEntryJXPath* : définition d'une expression JXPath à appliquer sur le bean associé au noeud. + + +Retrouver un noeud à partir du chemin de navigation +*************************************************** + +Il est possible en connaissant le chemin de navigation d'un noued de récupérer le noeud dans l'arbre via la méthode + +:: + + model.findNode("chemin.de.navigation") + +Trouver la valeur associée dans le context JAXX à partir du chemin de navigation +******************************************************************************** + +Il est possible en connaissant le chemin de navigation d'un noued de récupérer la valeur associée dans le context JAXX. + +:: + + model.getJAXXContextValue(myJAXXContext, "chemin.de.navigation")* . + +L'algrotihme est le suivant : + + * récupération du noeud associé au chemin de navigation + + * recherche du premier noeud (dans les noeuds qui remontent vers la racine de l'arbre) dont la propriété *jaxxContextEntry* est non nulle, il s'agit du point d'entré dans le context JAXX. + + * redescendre à partir de ce noeud vers le noeud d'origine (si ce noeud était différent) et en descendant conjointement dans l'objet du context JAXX : + + - on utilise l'expression JXPath pour obtenir l'objet associé au noeud + +Exemple : + +:: + + "$root" + <-- la racine de l'abre + | + + "string" <-- attaché au context JAXX <java.lang.String,"string"> + | + + "liste" + <-- attaché au context JAXX <java.util.List.class,"liste"> + | | + | + "0" <-- le premier élément de la liste + | | + | + "1" <-- le second élément de la liste + | | + | + "2" <-- le troisième élément de la liste + | + + "locale" + <-- attaché au context JAXX <java.util.Locale> + | + + country + | + + language + + // preparation du context + java.util.List myList = java.util.Arrays.asList("one","two","three"); + java.util.Locale myLocale = java.util.Locale.FRENCH; + context.setContextValue(myList, "liste"); + context.setContextValue("stringValue","string"); + context.setContextValue(myLocale); + + + // récupération des valeurs dans le context à partir de chemin de navigation + assert model.getJAXXContextValue(context, "$root") == null; + assert model.getJAXXContextValue(context, "$root.string") == "stringValue"; + assert model.getJAXXContextValue(context, "$root.liste") == myList; + assert model.getJAXXContextValue(context, "$root.liste.0") == "one"; + assert model.getJAXXContextValue(context, "$root.liste.1") == "two"; + assert model.getJAXXContextValue(context, "$root.liste.2") == "three"; + assert model.getJAXXContextValue(context, "$root.locale") == myLocale; + assert model.getJAXXContextValue(context, "$root.locale.country") == myLocale.getCountry(); + assert model.getJAXXContextValue(context, "$root.locale.language") == myLocale.getLanguage(); + +TODO mettre à jour cet exemple suite à l'utilisation de JXPath pour naviguer dans les objets. + +A noter qu'une seconde méthode de récupération de valeur du context JAXX est disponible pour pouvoir récupérer cette +valeur en connaissant le noeud : + +:: + + model.getJAXXContextValue(context, myNode); + +jaxx.runtime.swing.navigation.NavigationTreeSelectionAdapter +============================================================ + +Il s'agit d'un listener sur la sélection d'un noeud dans l'arbre de navigation basé sur notre modèle de navigation. Il +étend *javax.swing.event.TreeSelectionListener*. + +Ce listener contient la gestion de passage d'un noeud à un autre avec interaction avec le context JAXX et affichage automatique de l'ui associé au noeud sélectionné. + +**Attention : la mécanique ne fonctionne que pour un arbre à selection unique.** + +Algorithme +********** + +Voici l'algorithme utilisé lors de la sélection d'un nouveau noeud : + + * *closeUI* : tentative de fermeture de l'ui lié au noeud précédemment selectionné, si cela n'aboutit pas on retourne sur le noeud précédent. + + * *attachBeanFromNodeToContext* : injection dans le context JAXX de la valeur associée au nouveau noeud + + * *createUI* : création de la nouvelle ui (si elle n'existe pas) + + * *openUI* : ouverture de la nouvelle ui + +Si une erreur survient lors de ces opérations, on entre dans la méthode *goBackToPreviousNode* qui est abstraite et permet de notifier les erreur de retourner au noeud précdent. + +jaxx.runtime.swing.navigation.NavigationTreeSelectionAdapterWithCardLayout +************************************************************************** + +Il s'agit d'une implantation du listener précédent qui suppose que les uis associées aux noeuds sont affichées dans un +unique container en utilisant le layout *jaxx.runtime.swing.CardLayout2*. + +La contrainte de chaque ui sera extactement le chemin de navigation du noeud associé. + +Il possède deux méthodes abstraites : + + * *getContentContainer* : qui indique le container d'ui. + + * *getContentLayout* : qui indique le layout utilisé. + +Pour pouvoir utilisé cet *adapter*, il vous suffit de définir la méthode suivante (en plus des deux méthodes abstraites) : + + * *goBackToPreviousNode* : comment gérer les erreurs et retourner au noeud précedent. + Modified: lutinjaxx/branches/storm_1/src/site/fr/rst/Todo.rst =================================================================== --- lutinjaxx/trunk/src/site/fr/rst/Todo.rst 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/Todo.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,4 +1,15 @@ +==== TODO ==== -a faire \ No newline at end of file + - réorganiser ce module maven en deux modules : + + * un premier module de runtime + + * un second module contenant uniquement le compilateur et non nécessaire au runtime. + + Le second module pourrait être facultatif et le code pourrait directement être placé dans le module du plugin. + + Cependant cela n'est pas possible actuelement car certains objets du runtime contiennent aussi du code utilisé + par le compilateur JAXX (par exemple StyleSheet). Il faut avant tout cloisonner le code non runtime. + \ No newline at end of file Modified: lutinjaxx/branches/storm_1/src/site/fr/rst/index.rst =================================================================== --- lutinjaxx/trunk/src/site/fr/rst/index.rst 2008-12-27 14:19:59 UTC (rev 1092) +++ lutinjaxx/branches/storm_1/src/site/fr/rst/index.rst 2008-12-30 09:05:37 UTC (rev 1101) @@ -1,4 +1,4 @@ -lutinjaxx +jaxx-core ========= .. contents:: @@ -7,7 +7,35 @@ Présentation ------------ -Super pom du projet jaxx. +Le compilateur Jaxx TODO **Veuillez consulter la JavaDoc pour de plus ample détails sur les différentes librairies.** + +Nouvelles fonctionnalités +------------------------- + + * I18n_ + + * JAXXContext_ + + * BeanValidator_ + + * NavigationTreeModel_ + + * JavaBean_ + + * Interface_ + + +.. _I18n: I18n.html + +.. _JAXXContext: JAXXContext.html + +.. _BeanValidator: BeanValidator.html + +.. _NavigationTreeModel: NavigationTreeModel.html + +.. _Javabean: JavaBean.html + +.. _Interface: Interface.html \ No newline at end of file
participants (1)
-
tchemit@users.labs.libre-entreprise.org