Jaxx-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2005 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2004 -----
- December
- November
- October
- September
- August
October 2008
- 2 participants
- 150 discussions
[Buix-commits] r980 - lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator
by tchemit@users.labs.libre-entreprise.org 20 Oct '08
by tchemit@users.labs.libre-entreprise.org 20 Oct '08
20 Oct '08
Author: tchemit
Date: 2008-10-20 13:49:00 +0000 (Mon, 20 Oct 2008)
New Revision: 980
Removed:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java
Log:
test if parent is not null from a component to use it with no ui...
clean code, remove unsued FileFieldValidator
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java 2008-10-19 21:56:45 UTC (rev 979)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java 2008-10-20 13:49:00 UTC (rev 980)
@@ -25,7 +25,6 @@
import com.opensymphony.xwork2.ValidationAwareSupport;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationManager;
-import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.validator.ActionValidatorManager;
@@ -330,7 +329,9 @@
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
- c.getParent().repaint();
+ if (c.getParent() != null) {
+ c.getParent().repaint();
+ }
}
} catch (ValidationException eee) {
log.warn("Error during validation", eee);
@@ -340,8 +341,6 @@
protected ActionValidatorManager getValidator() {
if (validator == null) {
ConfigurationManager confManager = new ConfigurationManager();
- //confManager.addContainerProvider(new XmlConfigurationProvider("my-xworks.xml"));
- //confManager.addContainerProvider(new XmlConfigurationProvider("my-validators.xml"));
Configuration conf = confManager.getConfiguration();
ValueStackFactory vsf = conf.getContainer().getInstance(
@@ -372,8 +371,6 @@
if (container instanceof JXLayer) {
Constructor<? extends AbstractBeanValidatorUI> cons = uiClass.getConstructor(String.class, String.class, ValidationAware.class);
AbstractBeanValidatorUI ui = cons.newInstance(fieldname, c.getName(), validationSupport);
- //IconValidationUI ui = new IconValidationUI(fieldname, c.getName(), validationSupport);
- //TranslucentValidationUI ui = new TranslucentValidationUI(fieldname, c.getName(), validationSupport);
ui.setEnabled(true);
JXLayer<JComponent> jx = (JXLayer<JComponent>) container;
jx.setUI(ui);
Deleted: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java 2008-10-19 21:56:45 UTC (rev 979)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java 2008-10-20 13:49:00 UTC (rev 980)
@@ -1,70 +0,0 @@
-package jaxx.runtime.validator;
-
-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="directoryExisting">
- * <param name="fieldName">tmp</param>
- * <message>tmp is not an existing directory</message>
- * </validator>
- * <p/>
- * <!-- Field-Validator Syntax -->
- * <field name="tmp">
- * <field-validator type="directoryExisting">
- * <message>tmp is not an existing directory</message>
- * </field-validator>
- * </field>
- * </validators>
- * <!-- END SNIPPET: examples -->
- * </pre>
- *
- * @author chemit
- */
-public class DirectoryFieldValidator extends FieldValidatorSupport {
-
- public void validate(Object object) throws ValidationException {
- String fieldName = getFieldName();
- Object value = this.getFieldValue(fieldName, object);
- if (value==null) {
- 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()) {
- addFieldError(fieldName, object);
- }
- }
-
- @Override
- public String getValidatorType() {
- return "directory";
- }
-}
\ No newline at end of file
Deleted: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java 2008-10-19 21:56:45 UTC (rev 979)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java 2008-10-20 13:49:00 UTC (rev 980)
@@ -1,70 +0,0 @@
-package jaxx.runtime.validator;
-
-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 FileFieldValidator extends FieldValidatorSupport {
-
- public void validate(Object object) throws ValidationException {
- String fieldName = getFieldName();
- Object value = this.getFieldValue(fieldName, object);
- if (value == null) {
- 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()) {
- addFieldError(fieldName, object);
- }
- }
-
- @Override
- public String getValidatorType() {
- return "file";
- }
-}
\ No newline at end of file
1
0
[Buix-commits] r979 - in lutinjaxx/trunk: jaxx-core/src/main/java/jaxx/runtime/validator jaxx-core/src/main/resources jaxx-example/Validation/src/main/java/examples/Validation jaxx-example/Validation/src/main/resources/examples/Validation
by tchemit@users.labs.libre-entreprise.org 19 Oct '08
by tchemit@users.labs.libre-entreprise.org 19 Oct '08
19 Oct '08
Author: tchemit
Date: 2008-10-19 21:56:45 +0000 (Sun, 19 Oct 2008)
New Revision: 979
Added:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingDirectoryFieldValidator.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingFileFieldValidator.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java
lutinjaxx/trunk/jaxx-core/src/main/resources/validators.xml
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java
lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Identity.java
lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Validation.jaxx
lutinjaxx/trunk/jaxx-example/Validation/src/main/resources/examples/Validation/Identity-validation.xml
Log:
adding validator on files and directories
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java 2008-10-19 20:15:06 UTC (rev 978)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/BeanValidator.java 2008-10-19 21:56:45 UTC (rev 979)
@@ -25,6 +25,7 @@
import com.opensymphony.xwork2.ValidationAwareSupport;
import com.opensymphony.xwork2.config.Configuration;
import com.opensymphony.xwork2.config.ConfigurationManager;
+import com.opensymphony.xwork2.config.providers.XmlConfigurationProvider;
import com.opensymphony.xwork2.util.ValueStack;
import com.opensymphony.xwork2.util.ValueStackFactory;
import com.opensymphony.xwork2.validator.ActionValidatorManager;
@@ -339,6 +340,8 @@
protected ActionValidatorManager getValidator() {
if (validator == null) {
ConfigurationManager confManager = new ConfigurationManager();
+ //confManager.addContainerProvider(new XmlConfigurationProvider("my-xworks.xml"));
+ //confManager.addContainerProvider(new XmlConfigurationProvider("my-validators.xml"));
Configuration conf = confManager.getConfiguration();
ValueStackFactory vsf = conf.getContainer().getInstance(
Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/DirectoryFieldValidator.java 2008-10-19 21:56:45 UTC (rev 979)
@@ -0,0 +1,70 @@
+package jaxx.runtime.validator;
+
+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="directoryExisting">
+ * <param name="fieldName">tmp</param>
+ * <message>tmp is not an existing directory</message>
+ * </validator>
+ * <p/>
+ * <!-- Field-Validator Syntax -->
+ * <field name="tmp">
+ * <field-validator type="directoryExisting">
+ * <message>tmp is not an existing directory</message>
+ * </field-validator>
+ * </field>
+ * </validators>
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ *
+ * @author chemit
+ */
+public class DirectoryFieldValidator extends FieldValidatorSupport {
+
+ public void validate(Object object) throws ValidationException {
+ String fieldName = getFieldName();
+ Object value = this.getFieldValue(fieldName, object);
+ if (value==null) {
+ 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()) {
+ addFieldError(fieldName, object);
+ }
+ }
+
+ @Override
+ public String getValidatorType() {
+ return "directory";
+ }
+}
\ No newline at end of file
Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingDirectoryFieldValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingDirectoryFieldValidator.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingDirectoryFieldValidator.java 2008-10-19 21:56:45 UTC (rev 979)
@@ -0,0 +1,72 @@
+package jaxx.runtime.validator;
+
+import com.opensymphony.xwork2.validator.ValidationException;
+
+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="directoryExisting">
+ * <param name="fieldName">tmp</param>
+ * <message>tmp is not an existing directory</message>
+ * </validator>
+ * <p/>
+ * <!-- Field-Validator Syntax -->
+ * <field name="tmp">
+ * <field-validator type="directoryExisting">
+ * <message>tmp is not an existing directory</message>
+ * </field-validator>
+ * </field>
+ * </validators>
+ * <!-- END SNIPPET: examples -->
+ * </pre>
+ *
+ * @author chemit
+ */
+public class ExistingDirectoryFieldValidator extends DirectoryFieldValidator {
+
+ @Override
+ public void validate(Object object) throws ValidationException {
+ super.validate(object);
+ if (getValidatorContext().getFieldErrors().containsKey(getFieldName())) {
+ // error already detected
+ return;
+ }
+ String fieldName = getFieldName();
+ Object value = this.getFieldValue(fieldName, object);
+
+ 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()) {
+ addFieldError(fieldName, object);
+ }
+ }
+
+ @Override
+ public String getValidatorType() {
+ return "existingDirectory";
+ }
+}
\ No newline at end of file
Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingFileFieldValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingFileFieldValidator.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/ExistingFileFieldValidator.java 2008-10-19 21:56:45 UTC (rev 979)
@@ -0,0 +1,72 @@
+package jaxx.runtime.validator;
+
+import com.opensymphony.xwork2.validator.ValidationException;
+
+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 FileFieldValidator {
+
+ @Override
+ public void validate(Object object) throws ValidationException {
+ super.validate(object);
+ if (getValidatorContext().getFieldErrors().containsKey(getFieldName())) {
+ // error already detected
+ return;
+ }
+ String fieldName = getFieldName();
+ Object value = this.getFieldValue(fieldName, object);
+
+ 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()) {
+ addFieldError(fieldName, object);
+ }
+ }
+
+ @Override
+ public String getValidatorType() {
+ return "existingFile";
+ }
+}
Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/runtime/validator/FileFieldValidator.java 2008-10-19 21:56:45 UTC (rev 979)
@@ -0,0 +1,70 @@
+package jaxx.runtime.validator;
+
+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 FileFieldValidator extends FieldValidatorSupport {
+
+ public void validate(Object object) throws ValidationException {
+ String fieldName = getFieldName();
+ Object value = this.getFieldValue(fieldName, object);
+ if (value == null) {
+ 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()) {
+ addFieldError(fieldName, object);
+ }
+ }
+
+ @Override
+ public String getValidatorType() {
+ return "file";
+ }
+}
\ No newline at end of file
Added: lutinjaxx/trunk/jaxx-core/src/main/resources/validators.xml
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/resources/validators.xml (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/resources/validators.xml 2008-10-19 21:56:45 UTC (rev 979)
@@ -0,0 +1,13 @@
+<?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="file" class="jaxx.runtime.validator.FileFieldValidator"/>
+ <validator name="directory" class="jaxx.runtime.validator.DirectoryFieldValidator"/>
+ <validator name="existingFile" class="jaxx.runtime.validator.ExistingFileFieldValidator"/>
+ <validator name="existingDirectory" class="jaxx.runtime.validator.ExistingDirectoryFieldValidator"/>
+</validators>
+<!-- END SNIPPET: validators -->
Modified: lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Identity.java
===================================================================
--- lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Identity.java 2008-10-19 20:15:06 UTC (rev 978)
+++ lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Identity.java 2008-10-19 21:56:45 UTC (rev 979)
@@ -2,6 +2,7 @@
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
+import java.io.File;
public class Identity {
@@ -13,7 +14,10 @@
protected int age = 51;
+ protected File config = new File("/tmp");
+ protected File dir = new File("/tmp");
+
PropertyChangeSupport p;
public Identity() {
@@ -53,6 +57,14 @@
return age;
}
+ public File getConfig() {
+ return config;
+ }
+
+ public File getDir() {
+ return dir;
+ }
+
public void setFirstName(String firstName) {
String oldFirstName = this.firstName;
this.firstName = firstName;
@@ -66,7 +78,7 @@
}
public void setEmail(String email) {
- String oldEmail =this.email;
+ String oldEmail = this.email;
this.email = email;
p.firePropertyChange("email", oldEmail, email);
}
@@ -76,4 +88,16 @@
this.age = age;
p.firePropertyChange("age", oldAge, age);
}
+
+ public void setConfig(File config) {
+ File oldConfig = this.config;
+ this.config = config;
+ p.firePropertyChange("config", oldConfig, config);
+ }
+
+ public void setDir(File dir) {
+ File oldDir = this.dir;
+ this.dir = dir;
+ p.firePropertyChange("dir", oldDir, dir);
+ }
}
\ No newline at end of file
Modified: lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Validation.jaxx
===================================================================
--- lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Validation.jaxx 2008-10-19 20:15:06 UTC (rev 978)
+++ lutinjaxx/trunk/jaxx-example/Validation/src/main/java/examples/Validation/Validation.jaxx 2008-10-19 21:56:45 UTC (rev 979)
@@ -166,7 +166,7 @@
<row>
<cell weightx='1' weighty='1' insets='6, 3, 0, 0'>
<JPanel border='{BorderFactory.createTitledBorder("Identify Form")}'
- layout='{new GridLayout()}' width='250' height='140'>
+ layout='{new GridLayout()}' width='250' height='180'>
<Table anchor='west' fill='both'>
<row>
<cell>
@@ -205,6 +205,24 @@
onStateChanged='identity.setAge(age.getValue())'/>
</cell>
</row>
+ <row>
+ <cell>
+ <JLabel text='Config file :'/>
+ </cell>
+ <cell>
+ <JTextField id='config' text='{identity.getConfig()}'
+ onKeyReleased='identity.setConfig(new java.io.File(config.getText()))'/>
+ </cell>
+ </row>
+ <row>
+ <cell>
+ <JLabel text='Working directory:'/>
+ </cell>
+ <cell>
+ <JTextField id='dir' text='{identity.getDir()}'
+ onKeyReleased='identity.setDir(new java.io.File(dir.getText()))'/>
+ </cell>
+ </row>
</Table>
</JPanel>
</cell>
@@ -236,7 +254,6 @@
<JLabel text='{identity.getEmail()}'/>
</cell>
</row>
-
<row>
<cell>
<JLabel text='Age:'/>
@@ -245,6 +262,22 @@
<JLabel text='{identity.getAge()}'/>
</cell>
</row>
+ <row>
+ <cell>
+ <JLabel text='Config file:'/>
+ </cell>
+ <cell>
+ <JLabel text='{identity.getConfig()}'/>
+ </cell>
+ </row>
+ <row>
+ <cell>
+ <JLabel text='Directory file:'/>
+ </cell>
+ <cell>
+ <JLabel text='{identity.getDir()}'/>
+ </cell>
+ </row>
</Table>
</JPanel>
</cell>
Modified: lutinjaxx/trunk/jaxx-example/Validation/src/main/resources/examples/Validation/Identity-validation.xml
===================================================================
--- lutinjaxx/trunk/jaxx-example/Validation/src/main/resources/examples/Validation/Identity-validation.xml 2008-10-19 20:15:06 UTC (rev 978)
+++ lutinjaxx/trunk/jaxx-example/Validation/src/main/resources/examples/Validation/Identity-validation.xml 2008-10-19 21:56:45 UTC (rev 979)
@@ -22,6 +22,24 @@
</field-validator>
</field>
+ <field name="config">
+ <field-validator type="file" short-circuit="true">
+ <message>${config} is not a file.</message>
+ </field-validator>
+ <field-validator type="existingFile" short-circuit="true">
+ <message>The configuration file ${config} does not exist.</message>
+ </field-validator>
+ </field>
+
+ <field name="dir">
+ <field-validator type="directory" short-circuit="true">
+ <message>${dir} is not a directory.</message>
+ </field-validator>
+ <field-validator type="existingDirectory" short-circuit="true">
+ <message>The directory ${dir} does not exist.</message>
+ </field-validator>
+ </field>
+
<field name="age">
<field-validator type="int">
<param name="min">18</param>
1
0
[Buix-commits] r978 - lutinjaxx/trunk/jaxx-core/src/main/java/jaxx
by tchemit@users.labs.libre-entreprise.org 19 Oct '08
by tchemit@users.labs.libre-entreprise.org 19 Oct '08
19 Oct '08
Author: tchemit
Date: 2008-10-19 20:15:06 +0000 (Sun, 19 Oct 2008)
New Revision: 978
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/PrintTagInfo.java
Log:
begin of refactor of this tools to make it works with rst... to be finished
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/PrintTagInfo.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/PrintTagInfo.java 2008-10-19 19:44:06 UTC (rev 977)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/PrintTagInfo.java 2008-10-19 20:15:06 UTC (rev 978)
@@ -8,6 +8,11 @@
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 {
/**
@@ -17,20 +22,48 @@
* @throws Exception if an error occurs
*/
public static void main(String[] arg) throws Exception {
- JAXXCompiler.init();
+ 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));
+ }
- ClassDescriptor beanClass = ClassDescriptorLoader.getClassDescriptor(arg[0]);
+ try {
+ JAXXCompiler.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
- System.out.println("Properties in " + beanClass);
+ 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)
+ if (property.getWriteMethodDescriptor() == null) {
continue;
+ }
boolean found = false;
String name = property.getName();
@@ -41,29 +74,42 @@
}
}
if (!found) {
- if (property.getPropertyType() == null)
+ if (property.getPropertyType() == null) {
System.err.println(name + " has null type");
- else {
- System.out.println("{{EquivalentAttribute|" + name + "|" + arg[0].replace('.', '/') +
- "|set" + JAXXCompiler.capitalize(name) + "|" +
- JAXXCompiler.getCanonicalName(property.getPropertyType()) + "}}");
- System.out.println("|-");
+ } else {
+ w.append("{{EquivalentAttribute|");
+ w.append(name);
+ w.append("|");
+ w.append(className.replace('.', '/'));
+ w.append("|set");
+ w.append(JAXXCompiler.capitalize(name));
+ w.append("|");
+ w.append(JAXXCompiler.getCanonicalName(property.getPropertyType()));
+ w.append("}}");
+ w.append("|-");
+ w.newLine();
}
}
}
- System.out.println();
- System.out.println();
+ 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();
- System.out.println("Bound methods in " + beanClass);
+ w.append("Bound methods in ").append(String.valueOf(beanClass));
+ w.newLine();
for (MethodDescriptor method : methods) {
try {
- if (handler.isMemberBound(method.getName()))
- System.out.println("* <tt>" + method.getName() + "()</tt>");
- }
- catch (Throwable e) {
+ if (handler.isMemberBound(method.getName())) {
+ w.append("* <tt>").append(method.getName()).append("()</tt>");
+ w.newLine();
+ }
+ } catch (Throwable e) {
// ignore ?
}
}
1
0
[Buix-commits] r977 - in lutinjaxx/trunk: jaxx-core/src/main/java/jaxx/compiler jaxx-core/src/main/java/jaxx/css jaxx-core/src/main/java/jaxx/tags jaxx-core/src/main/java/jaxx/tags/swing maven-jaxx-plugin/src/test/java/org/codelutin/jaxx
by tchemit@users.labs.libre-entreprise.org 19 Oct '08
by tchemit@users.labs.libre-entreprise.org 19 Oct '08
19 Oct '08
Author: tchemit
Date: 2008-10-19 19:44:06 +0000 (Sun, 19 Oct 2008)
New Revision: 977
Added:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataBinding.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataSource.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/ScriptManager.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/ApplicationHandler.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JWindowHandler.java
lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java
Log:
refactor JAXXCompiler :
now use two others class :
- JAXXCompilerHelper which contains all static methods
- JAXXObjectGenerator which manage the generation of the java file
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/CompiledObject.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -420,7 +420,7 @@
eventHandlers.add(handler);
if (getJavaCode().indexOf(".") != -1) { // object lives in another JAXX file and consequently its initialization code won't be output
- compiler.initializer.append(getInitializationCode(handler, compiler));
+ compiler.appendInitializerCode(getInitializationCode(handler, compiler));
}
}
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataBinding.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataBinding.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataBinding.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -66,13 +66,13 @@
if (!result && quickNoDependencies) {
if (!dest.endsWith(".layout")) // layout is specially handled early in the chain
- compiler.initDataBindings.append(assignment).append(JAXXCompiler.getLineSeparator());
+ compiler.appendInitDataBindings(assignment+ JAXXCompiler.getLineSeparator());
return false; // no dependencies, just a static expression
- } else {
- if (compiler.processDataBinding.length() > 0)
- compiler.processDataBinding.append("else ");
- compiler.processDataBinding.append("if ($dest.equals(").append(TypeManager.getJavaCode(id)).append(")) { ").append(assignment).append("}\n").append(JAXXCompiler.getLineSeparator());
- return true;
}
+ if (compiler.haveProcessDataBinding()) {
+ compiler.appendProcessDataBinding("else ");
+ }
+ compiler.appendProcessDataBinding("if ($dest.equals(" + TypeManager.getJavaCode(id) + ")) { " + assignment + "}\n" + JAXXCompiler.getLineSeparator());
+ return true;
}
}
\ No newline at end of file
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataSource.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataSource.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/DataSource.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -82,8 +82,9 @@
* @throws CompilerException if a compilation error occurs
*/
public boolean compile(String propertyChangeListenerCode) throws CompilerException {
- if (compiled)
+ 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()) {
@@ -91,8 +92,9 @@
scanNode(node, id);
}
- if (dependencySymbols.size() > 0)
- compiler.bodyCode.append("private PropertyChangeListener ").append(id).append(" = ").append(propertyChangeListenerCode).append(";\n");
+ if (dependencySymbols.size() > 0) {
+ compiler.appendBodyCode("private PropertyChangeListener " + id + " = " + propertyChangeListenerCode + ";\n");
+ }
compileListeners();
compiled = true;
@@ -121,8 +123,9 @@
default:
int count = node.jjtGetNumChildren();
- for (int i = 0; i < count; i++)
+ for (int i = 0; i < count; i++) {
scanNode(node.getChild(i), listenerId);
+ }
determineNodeType(node, listenerId);
}
}
@@ -131,33 +134,33 @@
assert node.getId() == JavaParserTreeConstants.JJTLITERAL;
if (node.jjtGetNumChildren() == 1) {
int id = node.getChild(0).getId();
- if (id == JavaParserTreeConstants.JJTBOOLEANLITERAL)
+ if (id == JavaParserTreeConstants.JJTBOOLEANLITERAL) {
return ClassDescriptorLoader.getClassDescriptor(boolean.class);
- else if (id == JavaParserTreeConstants.JJTNULLLITERAL)
+ }
+ if (id == JavaParserTreeConstants.JJTNULLLITERAL) {
return ClassDescriptorLoader.getClassDescriptor(NULL.class);
- else
- throw new RuntimeException("Expected BooleanLiteral or NullLiteral, found " + JavaParserTreeConstants.jjtNodeName[id]);
- } else {
- int id = node.firstToken.kind;
- switch (id) {
- case JavaParserConstants.INTEGER_LITERAL:
- if (node.firstToken.image.toLowerCase().endsWith("l"))
- return ClassDescriptorLoader.getClassDescriptor(long.class);
- else
- 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);
- else
- 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]);
}
+ 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]);
+ }
}
/**
@@ -179,11 +182,13 @@
for (int j = 0; j < tokens.length - (isMethod ? 1 : 0); j++) {
accepted = false;
- if (tokensSeenSoFar.length() > 0)
+ if (tokensSeenSoFar.length() > 0) {
tokensSeenSoFar.append('.');
+ }
tokensSeenSoFar.append(tokens[j]);
- if (currentSymbol.length() > 0)
+ if (currentSymbol.length() > 0) {
currentSymbol.append('.');
+ }
currentSymbol.append(tokens[j]);
if (currentSymbol.indexOf(".") == -1) {
@@ -234,8 +239,9 @@
return null;
}
}
- if (!accepted)
+ if (!accepted) {
return null;
+ }
}
return contextClass;
@@ -254,11 +260,13 @@
SimpleNode prefix = expression.getChild(0);
if (prefix.jjtGetNumChildren() == 1) {
int type = prefix.getChild(0).getId();
- if (type == JavaParserTreeConstants.JJTLITERAL || type == JavaParserTreeConstants.JJTEXPRESSION)
+ if (type == JavaParserTreeConstants.JJTLITERAL || type == JavaParserTreeConstants.JJTEXPRESSION) {
prefix.setJavaType(prefix.getChild(0).getJavaType());
- else
+ } 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) {
@@ -266,8 +274,9 @@
}
ClassDescriptor contextClass = prefix.getJavaType();
- if (contextClass == null)
+ if (contextClass == null) {
contextClass = compiler.getRootObject().getObjectClass();
+ }
String lastNode = prefix.getText().trim();
for (int i = 1; i < expression.jjtGetNumChildren(); i++) {
@@ -275,14 +284,17 @@
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)
+ 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--)
+ for (int j = i - 2; j >= 0; j--) {
objectCode = expression.getChild(j).getText() + objectCode;
- if (objectCode.length() == 0)
+ }
+ if (objectCode.length() == 0) {
objectCode = compiler.getRootObject().getJavaCode();
+ }
String methodName = lastNode.substring(dotPos + 1).trim();
try {
MethodDescriptor method = contextClass.getMethodDescriptor(methodName, new ClassDescriptor[0]);
@@ -292,10 +304,11 @@
catch (NoSuchMethodException e) {
// happens for methods defined in the current JAXX file via scripts
String propertyName = null;
- if (methodName.startsWith("is"))
+ if (methodName.startsWith("is")) {
propertyName = Introspector.decapitalize(methodName.substring("is".length()));
- else if (methodName.startsWith("get"))
+ } else if (methodName.startsWith("get")) {
propertyName = Introspector.decapitalize(methodName.substring("get".length()));
+ }
if (propertyName != null) {
MethodDescriptor[] newMethods = compiler.getScriptMethods();
for (MethodDescriptor newMethod : newMethods) {
@@ -313,8 +326,9 @@
}
}
lastNode = suffix.getText().trim();
- if (lastNode.startsWith("."))
+ if (lastNode.startsWith(".")) {
lastNode = lastNode.substring(1);
+ }
}
return null;
@@ -322,7 +336,9 @@
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 {
@@ -344,12 +360,13 @@
* can be tracked.
*
* @param node node to scan
- * @param listenerId
+ * @param listenerId the listener id
*/
private void determineNodeType(SimpleNode node, String listenerId) {
ClassDescriptor type = null;
- if (node.jjtGetNumChildren() == 1)
+ if (node.jjtGetNumChildren() == 1) {
type = node.getChild(0).getJavaType();
+ }
switch (node.getId()) {
case JavaParserTreeConstants.JJTCLASSORINTERFACETYPE:
type = ClassDescriptorLoader.getClassDescriptor(Class.class);
@@ -375,34 +392,48 @@
addListenerCode.append(" ");
}
addListenerCode.append(addCode);
- if (objectCode != null)
+ if (objectCode != null) {
addListenerCode.append("}");
+ }
if (objectCode != null) {
removeListenerCode.append("if (").append(objectCode).append(" != null) {").append(JAXXCompiler.getLineSeparator());
removeListenerCode.append(" ");
}
removeListenerCode.append(removeCode);
- if (objectCode != null)
+ if (objectCode != null) {
removeListenerCode.append("}");
+ }
}
}
private void compileListeners() {
if (addListenerCode.length() > 0) {
- 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 (compiler.haveApplyDataBinding()) {
+ compiler.appendApplyDataBinding("else ");
+ }
+ compiler.appendApplyDataBinding("if ($binding.equals(" + TypeManager.getJavaCode(id) + ")) {" + JAXXCompiler.getLineSeparator());
+ compiler.appendApplyDataBinding(" " + addListenerCode + JAXXCompiler.getLineSeparator());
+ compiler.appendApplyDataBinding("}" + JAXXCompiler.getLineSeparator());
+ //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.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());
+ if (compiler.haveRemoveDataBinding()) {
+ compiler.appendRemoveDataBinding("else ");
+ }
+ compiler.appendRemoveDataBinding("if ($binding.equals(" + TypeManager.getJavaCode(id) + ")) {" + JAXXCompiler.getLineSeparator());
+ compiler.appendRemoveDataBinding(" " + removeListenerCode + JAXXCompiler.getLineSeparator());
+ compiler.appendRemoveDataBinding("}" + JAXXCompiler.getLineSeparator());
+ //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());
}
}
}
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -15,265 +15,141 @@
import jaxx.reflect.FieldDescriptor;
import jaxx.reflect.MethodDescriptor;
import jaxx.runtime.ComponentDescriptor;
-import jaxx.runtime.JAXXObject;
import jaxx.runtime.JAXXObjectDescriptor;
-import jaxx.runtime.swing.Application;
-import jaxx.spi.Initializer;
import jaxx.tags.DefaultObjectHandler;
import jaxx.tags.TagHandler;
import jaxx.tags.TagManager;
import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator;
-import jaxx.types.TypeManager;
-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.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
-import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
-import java.io.ObjectOutputStream;
-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.ServiceLoader;
import java.util.Set;
import java.util.Stack;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import java.util.zip.GZIPOutputStream;
-/** Compiles JAXX files into Java classes. */
-public class JAXXCompiler {
- /** log */
- protected static final Log log = LogFactory.getLog(JAXXCompiler.class);
+/**
+ * Compiles JAXX files into Java classes.
+ * <p/>
+ * extends the {@link JAXXCompilerHelper} class wich contains all static usefull method.
+ * <p/>
+ * In that way, this class should not contains any static code, but use by inheritance the ones defined in the {@link JAXXCompilerHelper}
+ * <p/>
+ * use also a {@link #generator} ({@link JAXXObjectGenerator} to generate the java file,
+ * after the compilation.
+ */
+public class JAXXCompiler extends JAXXCompilerHelper {
- /**
- * 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;
+ /*---------------------------------------------------------------------------------*/
+ /*-- compiler fields --------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
- public static final String JAXX_NAMESPACE = "http://www.jaxxframework.org/";
- public static final String JAXX_INTERNAL_NAMESPACE = "http://www.jaxxframework.org/internal";
+ /** flag to detec if an error occurs while compiling jaxx file */
+ protected boolean failed;
- /** Maximum length of an inlinable creation method. */
- private static final int INLINE_THRESHOLD = 300;
-
- /** Contains import declarations (of the form "javax.swing.") which are always imported in all compiler instances. */
- private static List<String> staticImports = new ArrayList<String>();
-
- static {
- //TODO humm, we should be able to import only what is needed
- staticImports.add("java.awt.*");
- staticImports.add("java.awt.event.*");
- staticImports.add("java.beans.*");
- staticImports.add("java.io.*");
- staticImports.add("java.lang.*");
- staticImports.add("java.util.*");
- staticImports.add("javax.swing.*");
- staticImports.add("javax.swing.border.*");
- staticImports.add("javax.swing.event.*");
- staticImports.add("jaxx.runtime.swing.JAXXButtonGroup");
- staticImports.add("jaxx.runtime.swing.HBox");
- staticImports.add("jaxx.runtime.swing.VBox");
- staticImports.add("jaxx.runtime.swing.Table");
- staticImports.add("static org.codelutin.i18n.I18n._");
- staticImports.add("static org.codelutin.jaxx.util.UIHelper.createImageIcon");
- }
-
- private static DefaultObjectHandler firstPassClassTagHandler = new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(Object.class));
-
- /**
- * 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.
- */
- private List<Runnable> initializers = new ArrayList<Runnable>();
-
- /** Files being compiled during the compilation session, may be modified as compilation progresses and additional dependencies are found. */
- private static List<File> jaxxFiles = new ArrayList<File>();
-
- /** Class names corresponding to the files in the jaxxFiles list. */
- private static List<String> jaxxFileClassNames = new ArrayList<String>();
-
- /** Maps the names of classes being compiled to the compiler instance handling the compilation. */
- private static 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). */
- private static Map<File, SymbolTable> symbolTables = new HashMap<File, SymbolTable>();
-
- private CompilerOptions options;
-
- /** Used for error reporting purposes, so we can report the right line number. */
- private Stack<Element> tagsBeingCompiled = new Stack<Element>();
-
- /** Used for error reporting purposes, so we can report the right source file. */
- private Stack<File> sourceFiles = new Stack<File>();
-
- /** Maps object ID strings to the objects themselves. These are created during the second compilation pass. */
- private Map<String, CompiledObject> objects = new LinkedHashMap<String, CompiledObject>();
-
- /** Maps objects to their ID strings. These are created during the second compilation pass. */
- private Map<CompiledObject, String> ids = new LinkedHashMap<CompiledObject, String>();
-
- private static int errorCount;
- private static int warningCount;
-
- private boolean failed;
-
/** Object corresponding to the root tag in the document. */
- private CompiledObject root;
+ protected CompiledObject root;
/** Contains strings of the form "javax.swing." */
- private Set<String> importedPackages = new HashSet<String>();
+ protected Set<String> importedPackages = new HashSet<String>();
/** Contains strings of the form "javax.swing.Timer" */
- private Set<String> importedClasses = new HashSet<String>();
+ protected Set<String> importedClasses = new HashSet<String>();
/** Keeps track of open components (components still having children added). */
- private Stack<CompiledObject> openComponents = new Stack<CompiledObject>();
+ protected Stack<CompiledObject> openComponents = new Stack<CompiledObject>();
/** Sequence number used to create automatic variable names. */
- private int autogenID = 0;
+ protected int autogenID = 0;
- private List<DataBinding> dataBindings = new ArrayList<DataBinding>();
+ protected List<DataBinding> dataBindings = new ArrayList<DataBinding>();
- private JavaFile javaFile = new JavaFile();
-
- // true if a main() method has been declared in a script
- boolean mainDeclared;
-
/** list of validators */
protected List<CompiledBeanValidator> validators = new ArrayList<CompiledBeanValidator>();
/** list of objectId attached to a validator * */
protected List<String> validatedComponents = new ArrayList<String>();
- private SymbolTable symbolTable = new SymbolTable();
+ protected SymbolTable symbolTable = new SymbolTable();
- // TODO: replace these public StringBuffers with something a little less stupid
-
- /** Extra code to be added to the instance initializer. */
- public StringBuffer initializer = new StringBuffer();
-
- /** Extra code to be added at the end of the instance initializer. */
- public StringBuffer lateInitializer = new StringBuffer();
-
- /** Extra code to be added to the class body. */
- public StringBuffer bodyCode = new StringBuffer();
-
- /** Code to initialize data bindings. */
- public StringBuffer initDataBindings = new StringBuffer();
-
- /** Body of the applyDataBinding method. */
- public StringBuffer applyDataBinding = new StringBuffer();
-
- /** Body of the removeDataBinding method. */
- public StringBuffer removeDataBinding = new StringBuffer();
-
- /** Body of the processDataBinding method. */
- public StringBuffer processDataBinding = new StringBuffer();
-
/** Base directory used for path resolution (normally the directory in which the .jaxx file resides). */
- private File baseDir;
+ protected File baseDir;
/** .jaxx file being compiled. */
- private File src;
+ protected File src;
- /** Generated .java file. */
- private File dest;
-
/** Parsed XML of src file. */
- private Document document;
+ protected Document document;
/** Name of class being compiled. */
- private String outputClassName;
+ protected String outputClassName;
- private ScriptManager scriptManager = new ScriptManager(this);
+ protected ScriptManager scriptManager = new ScriptManager(this);
/** Combination of all stylesheets registered using {@link #registerStylesheet}. */
- private Stylesheet stylesheet;
+ protected Stylesheet stylesheet;
/** Contains all attributes defined inline on class tags. */
- private List<Rule> inlineStyles = new ArrayList<Rule>();
+ 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).
*/
- private Map<String, Map<ClassDescriptor, List<EventHandler>>> eventHandlers = new HashMap<String, Map<ClassDescriptor, List<EventHandler>>>();
+ protected Map<String, Map<ClassDescriptor, List<EventHandler>>> eventHandlers = new HashMap<String, Map<ClassDescriptor, List<EventHandler>>>();
- private Map<Object, String> uniqueIds = new HashMap<Object, String>();
+ /** Maps of uniqued id for objects used in compiler */
+ protected Map<Object, String> uniqueIds = new HashMap<Object, String>();
- private Map<EventHandler, String> eventHandlerMethodNames = new HashMap<EventHandler, 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 */
- private ClassLoader classLoader;
+ protected ClassLoader classLoader;
- private static final int PASS_1 = 0;
- private static final int PASS_2 = 1;
- private static int currentPass;
+ /** the generator of the java file */
+ protected final JAXXObjectGenerator generator;
- public static void init() {
- // forces static initializer to run if it hasn't yet
- }
+ /**
+ * 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>();
- public static void loadLibraries(boolean verbose) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
- 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();
- }
- }
+ /** left brace matcher */
+ protected Matcher leftBraceMatcher = Pattern.compile("^(\\{)|[^\\\\](\\{)").matcher("");
- private JAXXCompiler(ClassLoader classLoader) {
+ /** right brace matcher */
+ protected Matcher rightBraceMatcher = Pattern.compile("^(\\})|[^\\\\](\\})").matcher("");
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Constructor methods ----------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ protected JAXXCompiler(ClassLoader classLoader) {
this.options = new CompilerOptions();
this.classLoader = classLoader;
+ this.generator = new JAXXObjectGenerator(this);
addImport("java.lang.*");
}
-
/**
* Creates a new JAXXCompiler.
*
@@ -288,61 +164,18 @@
sourceFiles.push(src);
this.outputClassName = outputClassName;
this.options = options;
+ this.generator = new JAXXObjectGenerator(this);
addImport(outputClassName.substring(0, outputClassName.lastIndexOf(".") + 1) + "*");
for (Object staticImport : staticImports) {
addImport((String) staticImport);
}
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- Initializer methods -----------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
- /**
- * Creates a dummy JAXXCompiler for use in unit testing.
- *
- * @return the compiler
- */
- public static JAXXCompiler createDummyCompiler() {
- return createDummyCompiler(JAXXCompiler.class.getClassLoader());
- }
-
-
- /**
- * Creates a dummy JAXXCompiler for use in unit testing.
- *
- * @param classLoader class loader to use
- * @return the compiler
- */
- public static JAXXCompiler createDummyCompiler(ClassLoader classLoader) {
- return new JAXXCompiler(classLoader);
- }
-
-
- public CompilerOptions getOptions() {
- return options;
- }
-
-
- public JavaFile getJavaFile() {
- return javaFile;
- }
-
-
- private 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);
- }
- }
-
-
- private void runInitializers() {
+ protected void runInitializers() {
for (Runnable runnable : initializers) {
if (log.isDebugEnabled()) {
log.debug(runnable);
@@ -369,735 +202,10 @@
initializers.add(r);
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- Compile methods --------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
- private void compileSecondPass() throws IOException {
- if (!tagsBeingCompiled.isEmpty()) {
- throw new RuntimeException("Internal error: starting pass two, but tagsBeingCompiled is not empty: " + tagsBeingCompiled);
- }
- compileSecondPass(document.getDocumentElement());
- }
-
-
- private void applyStylesheets() {
- for (Object o : new ArrayList<CompiledObject>(objects.values())) {
- CompiledObject object = (CompiledObject) o;
- TagManager.getTagHandler(object.getObjectClass()).applyStylesheets(object, this);
- }
- }
-
-
- private void generateCode() throws IOException {
- if (options.getTargetDirectory() != null) {
- dest = new File(options.getTargetDirectory(), outputClassName.replace('.', File.separatorChar) + ".java");
- } else {
- dest = new File(baseDir, outputClassName.substring(outputClassName.lastIndexOf(".") + 1) + ".java");
- }
- if (dest.exists() && !dest.setLastModified(System.currentTimeMillis())) {
- log.warn("could not touch file " + dest);
- }
- PrintWriter out = new PrintWriter(new FileWriter(dest));
- createJavaSource(out);
- out.close();
- }
-
- private void createJavaSource(PrintWriter out) throws IOException {
- int dotPos = outputClassName.lastIndexOf(".");
- String packageName = dotPos != -1 ? outputClassName.substring(0, dotPos) : null;
- String simpleClassName = outputClassName.substring(dotPos + 1);
- outputClass(packageName, simpleClassName, out);
- }
-
-
- public String getOutputClassName() {
- return outputClassName;
- }
-
- 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);
- }
- }
-
-
- public File getBaseDir() {
- return baseDir;
- }
-
-
- public Set<String> getImportedClasses() {
- return importedClasses;
- }
-
-
- public Set<String> getImportedPackages() {
- return importedPackages;
- }
-
-
- private 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);
- break;
- }
- catch (NoSuchFieldException e) {
- ancestor = ancestor.getSuperclass();
- }
- }
- }
-
-
- private Iterator<CompiledObject> getObjectCreationOrder() {
- return objects.values().iterator();
- }
-
-
- protected JavaMethod createConstructor(String className) throws CompilerException {
- StringBuffer code = new StringBuffer();
- String constructorParams = root.getConstructorParams();
- if (constructorParams != null) {
- code.append(" super(").append(constructorParams).append(");");
- code.append(getLineSeparator());
- }
- code.append("$initialize();");
- code.append(getLineSeparator());
- return new JavaMethod(Modifier.PUBLIC, null, className, null, null, code.toString());
- }
-
-
- protected JavaMethod createInitializer(String className) throws CompilerException {
- StringBuffer code = new StringBuffer();
- code.append("$objectMap.put(").append(TypeManager.getJavaCode(root.getId())).append(", this);");
- code.append(getLineSeparator());
-
- Iterator<CompiledObject> i = getObjectCreationOrder();
- boolean lastWasMethodCall = false;
- while (i.hasNext()) {
- CompiledObject object = i.next();
- if (object != root && !object.isOverride()) {
- if (inlineCreation(object)) {
- if (lastWasMethodCall) {
- lastWasMethodCall = false;
- code.append(getLineSeparator());
- }
- code.append(getCreationCode(object));
- code.append(getLineSeparator());
- } else {
- code.append(object.getCreationMethodName()).append("();");
- code.append(getLineSeparator());
- lastWasMethodCall = true;
- }
- }
- }
- String rootCode = root.getInitializationCode(this);
- if (rootCode != null && rootCode.length() > 0) {
- code.append(rootCode);
- code.append(getLineSeparator());
- }
- code.append(getLineSeparator());
- if (initializer.length() > 0) {
- code.append(initializer);
- code.append(getLineSeparator());
- }
- code.append("$completeSetup();");
- code.append(getLineSeparator());
- return new JavaMethod(Modifier.PRIVATE, "void", "$initialize", null, null, code.toString());
- }
-
-
- protected JavaMethod createCompleteSetupMethod() {
- StringBuffer code = new StringBuffer();
- code.append("allComponentsCreated = true;");
- code.append(getLineSeparator());
- for (CompiledObject object : objects.values()) {
- //TC - 20081017 only generate the method if not empty ?
- if (object.getId().startsWith("$")) {
- code.append(object.getAdditionCode()).append(getLineSeparator());
- } else {
- String additionCode = object.getAdditionCode();
- if (additionCode.length() > 0) {
- code.append(object.getAdditionMethodName()).append("();").append(getLineSeparator());
- additionCode = "if (allComponentsCreated) {" + getLineSeparator() + additionCode + "}";
- javaFile.addMethod(new JavaMethod(Modifier.PROTECTED, "void", object.getAdditionMethodName(), null, null, additionCode));
- }
- }
- //code.append(getLineSeparator());
- }
-
- code.append(initDataBindings);
-
- if (lateInitializer.length() > 0) {
- code.append(lateInitializer);
- code.append(getLineSeparator());
- }
-
- if (hasValidator()) {
- // register validator
- for (CompiledBeanValidator validator : validators) {
- String id = TypeManager.getJavaCode(validator.getId());
- code.append("validatorIds.add(").append(id).append(");");
- code.append(getLineSeparator());
- code.append("getValidator(").append(id).append(").installUIs();");
- code.append("getValidator(").append(id).append(").validate();");
- code.append(getLineSeparator());
- }
- }
- return new JavaMethod(Modifier.PRIVATE, "void", "$completeSetup", null, null, code.toString());
- }
-
-
- protected JavaMethod createProcessDataBindingMethod() {
- StringBuffer code = new StringBuffer();
- boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(root.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 (processDataBinding.length() > 0) {
- code.append(" if (!$force && $activeBindings.contains($dest)) return;");
- code.append(getLineSeparator());
- code.append(" $activeBindings.add($dest);");
- code.append(getLineSeparator());
- code.append(" try {");
- code.append(getLineSeparator());
- if (processDataBinding.length() > 0) {
- code.append(processDataBinding);
- code.append(getLineSeparator());
- }
- if (superclassIsJAXXObject) {
- code.append(" else");
- code.append(getLineSeparator());
- code.append(" super.processDataBinding($dest, true);");
- code.append(getLineSeparator());
- }
- code.append(" }");
- code.append(getLineSeparator());
- code.append(" finally {");
- code.append(getLineSeparator());
- code.append(" $activeBindings.remove($dest);");
- code.append(getLineSeparator());
- code.append(" }");
- code.append(getLineSeparator());
- } else if (superclassIsJAXXObject) {
- code.append(" super.processDataBinding($dest, true);");
- code.append(getLineSeparator());
- }
- return new JavaMethod(Modifier.PUBLIC, "void", "processDataBinding",
- new JavaArgument[]{new JavaArgument("String", "$dest"), new JavaArgument("boolean", "$force")},
- null, code.toString());
- }
-
-
- protected void createJavaFile(String packageName, String className) throws CompilerException {
- String fullClassName = packageName != null ? packageName + "." + className : className;
- if (root == null) {
- throw new CompilerException("root tag must be a class tag");
- }
- ClassDescriptor superclass = root.getObjectClass();
- boolean superclassIsJAXXObject = ClassDescriptorLoader.getClassDescriptor(JAXXObject.class).isAssignableFrom(superclass);
- javaFile.setModifiers(Modifier.PUBLIC);
- javaFile.setClassName(fullClassName);
- javaFile.setSuperClass(getCanonicalName(superclass));
- javaFile.setInterfaces(new String[]{getCanonicalName(JAXXObject.class)});
-
- for (CompiledObject object : objects.values()) {
- if (!object.isOverride() && !(object instanceof ScriptInitializer)) {
- int access = object.getId().startsWith("$") ? Modifier.PRIVATE : Modifier.PROTECTED;
- if (object == root) {
- javaFile.addField(new JavaField(access, fullClassName, object.getId(), "this"));
- } else {
- //TC -20081017 can have generic on compiled Object
- javaFile.addField(new JavaField(access, getCanonicalName(object), object.getId()));
- //javaFile.addField(new JavaField(access, getCanonicalName(object.getObjectClass()), object.getId()));
- }
- }
- }
-
- if (!superclassIsJAXXObject) {
- // add logger
- if (getOptions().isAddLogger()) {
- javaFile.addImport("org.apache.commons.logging.Log");
- javaFile.addImport("org.apache.commons.logging.LogFactory");
- javaFile.addField(createLoggerField(fullClassName));
- }
-
- javaFile.addField(new JavaField(Modifier.PROTECTED, "java.util.List<Object>", "$activeBindings", "new ArrayList<Object>()"));
- javaFile.addField(new JavaField(Modifier.PROTECTED, "java.util.Map<String,Object>", "$bindingSources", "new HashMap<String,Object>()"));
- }
-
- javaFile.addImport("jaxx.runtime.validator.BeanValidator");
- javaFile.addField(new JavaField(Modifier.PROTECTED, "java.util.List<String>", "validatorIds", "new ArrayList<String>()"));
-
- if (stylesheet != null) {
- javaFile.addField(new JavaField(0, "java.util.Map", "$previousValues", "new java.util.HashMap()"));
- }
-
- javaFile.addMethod(createConstructor(className));
- javaFile.addMethod(createInitializer(className));
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "BeanValidator<?>", "getValidator", new JavaArgument[]{new JavaArgument("String", "validatorId")},
- null, "return (BeanValidator)(validatorIds.contains(validatorId)?getObjectById(validatorId):null);"));
-
- for (DataBinding dataBinding : dataBindings) {
- if (dataBinding.compile(true)) {
- initDataBindings.append("applyDataBinding(").append(TypeManager.getJavaCode(dataBinding.getId())).append(");").append(JAXXCompiler.getLineSeparator());
- }
- }
-
- javaFile.addBodyCode(bodyCode.toString());
-
- for (CompiledObject object : objects.values()) {
- if (!inlineCreation(object) && object != root) {
- javaFile.addMethod(new JavaMethod(Modifier.PROTECTED, "void", object.getCreationMethodName(), null, null, getCreationCode(object)));
- }
- }
-
- javaFile.addField(new JavaField(Modifier.PRIVATE, "boolean", "allComponentsCreated"));
-
- javaFile.addMethod(createCompleteSetupMethod());
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "applyDataBinding", new JavaArgument[]{new JavaArgument("String", "$binding")},
- null, applyDataBinding.toString() + getLineSeparator() + " processDataBinding($binding);"));
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "removeDataBinding", new JavaArgument[]{new JavaArgument("String", "$binding")},
- null, removeDataBinding.toString()));
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "processDataBinding", new JavaArgument[]{new JavaArgument("String", "dest")},
- null, "processDataBinding(dest, false);"));
-
- javaFile.addMethod(createProcessDataBindingMethod());
-
- if (!superclassIsJAXXObject) {
- javaFile.addField(createObjectMap());
- javaFile.addMethod(createGetObjectByIdMethod());
- }
-
- javaFile.addField(createJAXXObjectDescriptorField());
- javaFile.addMethod(createGetJAXXObjectDescriptorMethod());
-
- /*
- * Gestion du context
- */
- javaFile.addField(createContextField());
- javaFile.addMethod(createSetContextValueMethod());
- javaFile.addMethod(createSetContextValueNameMethod());
- javaFile.addMethod(createGetContextValueMethod());
- javaFile.addMethod(createGetContextValueNameMethod());
- javaFile.addMethod(createGetParentContainer());
- javaFile.addMethod(createGetParentContainerMore());
- ClassDescriptor currentClass = root.getObjectClass();
- MethodDescriptor firePropertyChange = null;
- while (firePropertyChange == null && currentClass != null) {
- try {
- firePropertyChange = currentClass.getDeclaredMethodDescriptor("firePropertyChange", new ClassDescriptor[]{
- 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(new JavaMethod(Modifier.PUBLIC, "void", "firePropertyChange", new JavaArgument[]{
- new JavaArgument("java.lang.String", "propertyName"), new JavaArgument("java.lang.Object", "oldValue"), new JavaArgument("java.lang.Object", "newValue")},
- null, "super.firePropertyChange(propertyName, oldValue, newValue);"));
- } else {
- // either no support at all or firePropertyChange isn't accessible
- addPropertyChangeSupport(javaFile);
- }
-
- addEventHandlers(javaFile);
-
- if (ClassDescriptorLoader.getClassDescriptor(Application.class).isAssignableFrom(root.getObjectClass()) && !mainDeclared) {
- // TODO: check for existing main method first
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC | Modifier.STATIC, "void", "main",
- new JavaArgument[]{new JavaArgument("String[]", "arg")}, null,
- "SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });"));
- }
- }
-
-
- protected void outputClass(String packageName, String className, PrintWriter out) throws CompilerException {
- createJavaFile(packageName, className);
- out.println(javaFile.toString());
- }
-
-
- 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);
- }
- }
-
- private JavaField createLoggerField(String className) {
- return new JavaField(Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL, "Log", "log", "LogFactory.getLog(" + className + ".class)");
- }
-
- /*
- * Gestion du context
- */
- private JavaField createContextField() {
- return new JavaField(Modifier.PROTECTED, "Map<Object,String>", "$contextMap", "new HashMap<Object,String>()");
- }
-
- private JavaMethod createSetContextValueMethod() {
-
- return new JavaMethod(Modifier.PUBLIC, "void", "setContextValue",
- new JavaArgument[]{new JavaArgument("Object", "clazz")}, null, getSetContextValueMethodCode());
- }
-
- private JavaMethod createSetContextValueNameMethod() {
- return new JavaMethod(Modifier.PUBLIC, "void", "setContextValue",
- new JavaArgument[]{new JavaArgument("Object", "clazz"), new JavaArgument("String", "name")}, null, getSetContextValueNameMethodCode());
- }
-
- private JavaMethod createGetContextValueMethod() {
- return new JavaMethod(Modifier.PUBLIC, "<T> T", "getContextValue",
- new JavaArgument[]{new JavaArgument("Class<T>", "clazz")}, null, getGetContextValueMethodCode());
- }
-
- private JavaMethod createGetContextValueNameMethod() {
- return new JavaMethod(Modifier.PUBLIC, "<T> T", "getContextValue",
- new JavaArgument[]{new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name")}, null, getGetContextValueNameMethodCode());
- }
-
- private JavaMethod createGetParentContainer() {
- return new JavaMethod(Modifier.PUBLIC, "<O extends Container> O", "getParentContainer",
- new JavaArgument[]{new JavaArgument("Class<O>", "clazz")}, null, getGetParentContenerMethodCode());
- }
-
- private JavaMethod createGetParentContainerMore() {
- return new JavaMethod(Modifier.PUBLIC, "<O extends Container> O", "getParentContainer",
- new JavaArgument[]{new JavaArgument("Object", "source"), new JavaArgument("Class<O>", "clazz")}, null, getGetParentContenerMethodMoreCode());
- }
-
- private String getSetContextValueMethodCode() {
- return "this.setContextValue(clazz, null);";
- }
-
- private String getSetContextValueNameMethodCode() {
- StringBuffer result = new StringBuffer();
- result.append("$contextMap.put(clazz, name);");
- return result.toString();
- }
-
- private String getGetContextValueMethodCode() {
- return "return this.getContextValue(clazz, null);";
- }
-
- private String getGetContextValueNameMethodCode() {
- StringBuffer result = new StringBuffer();
- result.append("for (Map.Entry<Object,String> entry : $contextMap.entrySet()) {");
- result.append("if (clazz.isAssignableFrom(entry.getKey().getClass()) && (name == null || name == entry.getValue())) {");
- result.append("return (T) entry.getKey();}}");
- result.append("return null;");
- return result.toString();
- }
-
- private String getGetParentContenerMethodCode() {
- StringBuffer result = new StringBuffer();
- result.append("return this.getParentContainer(this, clazz);");
- return result.toString();
- }
-
- private String getGetParentContenerMethodMoreCode() {
- StringBuffer result = new StringBuffer();
- result.append("if (!Container.class.isAssignableFrom(source.getClass())) {return null;}");
- result.append(getLineSeparator());
- result.append("Container parent = ((Container)source).getParent();");
- result.append(getLineSeparator());
- result.append("if (parent != null && !clazz.isAssignableFrom(parent.getClass())){parent = getParentContainer(parent, clazz);}");
- result.append(getLineSeparator());
- result.append("return (O)parent;");
- return result.toString();
- }
-
- private JavaField createObjectMap() {
- return new JavaField(Modifier.PROTECTED, "Map<String,Object>", "$objectMap", "new HashMap<String,Object>()");
- }
-
-
- protected JavaMethod createGetObjectByIdMethod() {
- return new JavaMethod(Modifier.PUBLIC, "java.lang.Object", "getObjectById",
- new JavaArgument[]{new JavaArgument("String", "id")}, null,
- "return $objectMap.get(id);");
- }
-
-
- 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);
- }
-
-
- protected JavaField createJAXXObjectDescriptorField() {
- try {
- JAXXObjectDescriptor descriptor = getJAXXObjectDescriptor();
- 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 new JavaField(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 new JavaField(Modifier.PRIVATE | Modifier.STATIC, "java.lang.String", "$jaxxObjectDescriptor", initializer.toString());
- }
- }
- catch (IOException e) {
- throw new RuntimeException("Internal error: can't-happen error", e);
- }
- }
-
-
- protected JavaMethod createGetJAXXObjectDescriptorMethod() {
- return new JavaMethod(Modifier.PUBLIC | Modifier.STATIC, "jaxx.runtime.JAXXObjectDescriptor", "$getJAXXObjectDescriptor",
- null, null, "return jaxx.runtime.Util.decodeCompressedJAXXObjectDescriptor($jaxxObjectDescriptor);");
- }
-
-
- public String getEventHandlerMethodName(EventHandler handler) {
- String result = eventHandlerMethodNames.get(handler);
- if (result == null) {
- result = "$ev" + eventHandlerMethodNames.size();
- eventHandlerMethodNames.put(handler, result);
- }
- return result;
- }
-
- protected void addEventHandlers(JavaFile javaFile) {
- for (Map.Entry<String, Map<ClassDescriptor, List<EventHandler>>> e1 : eventHandlers.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 = 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(new JavaMethod(Modifier.PUBLIC, "void", methodName,
- new JavaArgument[]{new JavaArgument(getCanonicalName(listenerMethod.getParameterTypes()[0]), "event")}, null,
- handler.getJavaCode()));
-
- }
- }
- }
- }
-
- protected String getCreationCode(CompiledObject object) throws CompilerException {
- if (object instanceof ScriptInitializer) {
- return object.getInitializationCode(this);
- }
- StringBuffer result = new StringBuffer();
- result.append(object.getId());
- result.append(" = ");
- String constructorParams = object.getConstructorParams();
- if (constructorParams != null) {
- //TC - 20081017 compiledObject can have generics
- result.append(" new ").append(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(getCanonicalName(object)).append("();");
- }
- result.append(getLineSeparator());
- String initCode = object.getInitializationCode(this);
- 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();
- }
-
-
- protected void addPropertyChangeSupport(JavaFile javaFile) throws CompilerException {
- javaFile.addField(new JavaField(0, "java.beans.PropertyChangeSupport", "$propertyChangeSupport"));
-
- javaFile.addMethod(new JavaMethod(0, "java.beans.PropertyChangeSupport", "$getPropertyChangeSupport", null, null,
- "if ($propertyChangeSupport == null)\n" +
- " $propertyChangeSupport = new PropertyChangeSupport(this);\n" +
- "return $propertyChangeSupport;"));
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "addPropertyChangeListener", new JavaArgument[]{
- new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
- "$getPropertyChangeSupport().addPropertyChangeListener(listener);"));
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "addPropertyChangeListener", new JavaArgument[]{
- new JavaArgument("java.lang.String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
- "$getPropertyChangeSupport().addPropertyChangeListener(property, listener);"));
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "removePropertyChangeListener", new JavaArgument[]{
- new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
- "$getPropertyChangeSupport().removePropertyChangeListener(listener);"));
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "removePropertyChangeListener", new JavaArgument[]{
- new JavaArgument("java.lang.String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
- "$getPropertyChangeSupport().removePropertyChangeListener(property, listener);"));
-
- javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "firePropertyChange", new JavaArgument[]{
- new JavaArgument("java.lang.String", "propertyName"), new JavaArgument("java.lang.Object", "oldValue"), new JavaArgument("java.lang.Object", "newValue")},
- null, "$getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue);"));
- }
-
-
public void compileFirstPass(final Element tag) throws IOException {
tagsBeingCompiled.push(tag);
@@ -1194,144 +302,36 @@
}
-
- // 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;
+ protected void compileFirstPass() throws IOException {
+ try {
+ InputStream in = new FileInputStream(src);
+ document = parseDocument(in);
+ in.close();
+ compileFirstPass(document.getDocumentElement());
}
- 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;
+ catch (SAXParseException e) {
+ reportError(e.getLineNumber(), "Invalid XML: " + e.getMessage());
}
- 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;
+ catch (SAXException e) {
+ reportError(null, "Error parsing XML document: " + e);
}
-
- 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;
}
-
- public static String capitalize(String s) {
- if (s.length() == 0) {
- return s;
+ protected void compileSecondPass() throws IOException {
+ if (!tagsBeingCompiled.isEmpty()) {
+ throw new RuntimeException("Internal error: starting pass two, but tagsBeingCompiled is not empty: " + tagsBeingCompiled);
}
- return Character.toUpperCase(s.charAt(0)) + s.substring(1);
+ compileSecondPass(document.getDocumentElement());
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- CompiledObject methods -------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
- 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 void openComponent(CompiledObject component) throws CompilerException {
openComponent(component, null);
}
-
public void openComponent(CompiledObject component, String constraints) throws CompilerException {
CompiledObject parent = getOpenComponent();
openInvisibleComponent(component);
@@ -1340,7 +340,6 @@
}
}
-
public void openInvisibleComponent(CompiledObject component) {
if (!ids.containsKey(component)) {
registerCompiledObject(component);
@@ -1348,7 +347,6 @@
openComponents.push(component);
}
-
public CompiledObject getOpenComponent() {
if (openComponents.isEmpty()) {
return null;
@@ -1356,19 +354,12 @@
return openComponents.peek();
}
-
public void closeComponent(CompiledObject component) {
if (openComponents.pop() != component) {
throw new IllegalArgumentException("can only close the topmost open object");
}
}
-
- public CompiledObject getRootObject() {
- return root;
- }
-
-
public void registerCompiledObject(CompiledObject object) {
assert symbolTables.values().contains(symbolTable) : "attempting to register CompiledObject before pass 1 is complete";
if (root == null) {
@@ -1386,33 +377,6 @@
ids.put(object, id);
}
-
- 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 SymbolTable getSymbolTable() {
- return symbolTable;
- }
-
-
public CompiledObject getCompiledObject(String id) {
runInitializers();
assert symbolTables.values().contains(symbolTable) : "attempting to retrieve CompiledObject before pass 1 is complete";
@@ -1420,40 +384,36 @@
}
- private Matcher leftBraceMatcher = Pattern.compile("^(\\{)|[^\\\\](\\{)").matcher("");
-
- private int getNextLeftBrace(String string, int pos) {
- leftBraceMatcher.reset(string);
- return leftBraceMatcher.find(pos) ? Math.max(leftBraceMatcher.start(1), leftBraceMatcher.start(2)) : -1;
+ protected boolean inlineCreation(CompiledObject object) {
+ return object.getId().startsWith("$") && object.getInitializationCode(this).length() < INLINE_THRESHOLD;
}
-
- private Matcher rightBraceMatcher = Pattern.compile("^(\\})|[^\\\\](\\})").matcher("");
-
- private 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;
+ 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);
+ break;
}
+ catch (NoSuchFieldException e) {
+ ancestor = ancestor.getSuperclass();
+ }
}
- return pos;
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- DataBinding methods ----------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
/**
* Examine an attribute value for data binding expressions. Returns a 'cooked' expression which
@@ -1525,27 +485,6 @@
}
}
-
- public ScriptManager getScriptManager() {
- return scriptManager;
- }
-
-
- /**
- * 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 CompilerException if the code cannot be parsed
- */
- public String checkJavaCode(String javaCode) {
- javaCode = scriptManager.trimScript(javaCode);
- scriptManager.checkParse(javaCode);
- return javaCode;
- }
-
-
public void registerEventHandler(EventHandler handler) {
String objectCode = handler.getObjectCode();
Map<ClassDescriptor, List<EventHandler>> listeners = eventHandlers.get(objectCode);
@@ -1562,37 +501,34 @@
handlerList.add(handler);
}
-
- public FieldDescriptor[] getScriptFields() {
- List<FieldDescriptor> scriptFields = symbolTable.getScriptFields();
- return scriptFields.toArray(new FieldDescriptor[scriptFields.size()]);
+ public String getEventHandlerMethodName(EventHandler handler) {
+ String result = eventHandlerMethodNames.get(handler);
+ if (result == null) {
+ result = "$ev" + eventHandlerMethodNames.size();
+ eventHandlerMethodNames.put(handler, result);
+ }
+ return result;
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- Script methods ---------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
public void addScriptField(FieldDescriptor field) {
symbolTable.getScriptFields().add(field);
}
-
- public MethodDescriptor[] getScriptMethods() {
- List<MethodDescriptor> scriptMethods = symbolTable.getScriptMethods();
- return scriptMethods.toArray(new MethodDescriptor[scriptMethods.size()]);
- }
-
-
public void addScriptMethod(MethodDescriptor method) {
if (method.getName().equals("main") && method.getParameterTypes().length == 1 && method.getParameterTypes()[0].getName().equals("[Ljava.lang.String;")) {
- mainDeclared = true;
+ generator.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);
@@ -1611,12 +547,21 @@
}
}
-
public String preprocessScript(String script) throws CompilerException {
return scriptManager.preprocessScript(script);
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- StyleSheet methods -----------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+ protected 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;
@@ -1625,26 +570,13 @@
}
}
-
- 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 Stack<File> getSourceFiles() {
- return sourceFiles;
- }
-
-
public void addInlineStyle(CompiledObject object, String propertyName, boolean dataBinding) {
inlineStyles.add(Rule.inlineAttribute(object, propertyName, dataBinding));
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- Report methods ---------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
public void reportWarning(String warning) {
Element currentTag = null;
@@ -1688,12 +620,10 @@
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) {
@@ -1712,12 +642,10 @@
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) {
@@ -1730,7 +658,6 @@
reportError(lineNumber, error);
}
-
public void reportError(int lineNumber, String error) {
File src = sourceFiles.isEmpty() ? null : sourceFiles.peek();
try {
@@ -1751,50 +678,129 @@
failed = true;
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- Validator methods ------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
/**
- * Escapes a string using standard Java escape sequences, generally in preparation to including it in a string literal
- * in a compiled Java file.
+ * Register in this compiler a new compiled validator.
*
- * @param raw the raw string to be escape
- * @return a string in which all 'dangerous' characters have been replaced by equivalent Java escape sequences
+ * @param validator the compiled validator to register
*/
- 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 void registerValidator(CompiledBeanValidator validator) {
+ validators.add(validator);
+ validatedComponents.addAll(validator.getFields().values());
}
+ /** @return <code>true</code> if some validators were detected, <code>false</code> otherwise */
+ public boolean hasValidator() {
+ return !validators.isEmpty();
+ }
/**
- * Returns the system line separator string.
+ * Test if a given CompiledObject is attached to a validator.
*
- * @return the string used to separate lines
+ * @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 String getLineSeparator() {
- return System.getProperty("line.separator", "\n");
+ public boolean isComponentUsedByValidator(String componentId) {
+ return validatedComponents.contains(componentId);
}
+ /**
+ * Test if a given bean is attached to a validator.
+ *
+ * @param beanId the bean to test
+ * @return <code>true</code> if the given bean is attached to a validator, <code>false</code> otherwise
+ */
+ public boolean isBeanUsedByValidator(String beanId) {
+ for (CompiledBeanValidator validator : validators) {
+ if (beanId.equals(validator.getBean())) {
+ return true;
+ }
+ }
+ return false;
+ }
+ /*---------------------------------------------------------------------------------*/
+ /*-- 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;
+ }
+
+ protected 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()]);
+ }
+
/**
* Returns a <code>ClassLoader</code> which searches the user-specified class path in addition
* to the normal system class path.
@@ -1823,48 +829,132 @@
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);
+ }
- /**
- * @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 static JAXXCompiler getJAXXCompiler(String className) {
- return compilers != null ? compilers.get(className) : null;
+ Stylesheet stylesheet = getStylesheet();
+ if (stylesheet == null) {
+ stylesheet = new Stylesheet();
+ }
+
+ return new JAXXObjectDescriptor(descriptors, stylesheet);
}
+ /*---------------------------------------------------------------------------------*/
+ /*-- Setter methods ---------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
- /**
- * @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 static SymbolTable getSymbolTable(String className) {
- JAXXCompiler compiler = getJAXXCompiler(className);
- if (compiler == null) {
- return null;
- }
- return compiler.getSymbolTable();
+ public void setFailed(boolean failed) {
+ this.failed = failed;
}
- public static File URLtoFile(URL url) {
- return URLtoFile(url.toString());
+ /*---------------------------------------------------------------------------------*/
+ /*-- Delegate methods from JAXXObjectGenerator ------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ public void appendInitializerCode(String code) {
+ generator.getInitializer().append(code);
}
- public static File URLtoFile(String urlString) {
- if (!urlString.startsWith("file:")) {
- throw new IllegalArgumentException("url must start with 'file:'");
+ public void appendBodyCode(String code) {
+ generator.getBodyCode().append(code);
+ }
+
+ public void appendInitDataBindings(String code) {
+ generator.getInitDataBindings().append(code);
+ }
+
+ public void appendProcessDataBinding(String code) {
+ generator.getProcessDataBinding().append(code);
+ }
+
+ public void appendApplyDataBinding(String code) {
+ generator.getApplyDataBinding().append(code);
+ }
+
+ public void appendRemoveDataBinding(String code) {
+ generator.getRemoveDataBinding().append(code);
+ }
+
+ public void appendLateInitializer(String code) {
+ generator.getLateInitializer().append(code);
+ }
+
+ public boolean haveProcessDataBinding() {
+ return generator.getProcessDataBinding().length() > 0;
+ }
+
+ public boolean haveApplyDataBinding() {
+ return generator.getApplyDataBinding().length() > 0;
+ }
+
+ public boolean haveRemoveDataBinding() {
+ return generator.getRemoveDataBinding().length() > 0;
+ }
+
+ public void addMethodToJavaFile(JavaMethod method) {
+ generator.getJavaFile().addMethod(method);
+ }
+
+ public boolean hasMethod(String methodName) {
+ JavaMethod[] methods = generator.getJavaFile().getMethods();
+ for (JavaMethod method : methods) {
+ if (methodName.equals(method.getName())) {
+ return true;
+ }
}
- urlString = urlString.substring("file:".length());
- if (urlString.startsWith("/") && System.getProperty("os.name").startsWith("Windows")) {
- urlString = urlString.substring(1);
+ return false;
+ }
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Other methods ----------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ public void addImport(String text) {
+ if (text.endsWith("*")) {
+ importedPackages.add(text.substring(0, text.length() - 1));
+ } else {
+ importedClasses.add(text);
}
- try {
- return new File(URLDecoder.decode(urlString.replace('/', File.separatorChar), "utf-8"));
+
+ if (!text.equals("*")) {
+ generator.getJavaFile().addImport(text);
}
- catch (UnsupportedEncodingException e) {
- throw new RuntimeException(e);
- }
}
public void addDependencyClass(String className) {
@@ -1905,335 +995,21 @@
}
}
-
/**
- * 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>.
+ * Verifies that a snippet of Java code parses correctly. A warning is generated if the string has enclosing
+ * curly braces.
*
- * @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
+ * @param javaCode the Java code snippet to test
+ * @return a "cooked" version of the string which has enclosing curly braces removed.
+ * @throws CompilerException if the code cannot be parsed
*/
- public static synchronized boolean compile(File base, String[] relativePaths, CompilerOptions options) {
- File[] files = new File[relativePaths.length];
- String[] 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(':', '.');
- }
- return compile(files, classNames, options);
+ public String checkJavaCode(String javaCode) {
+ javaCode = scriptManager.trimScript(javaCode);
+ scriptManager.checkParse(javaCode);
+ return javaCode;
}
-
- /** Resets all state in preparation for a new compilation session. */
- private static void reset() {
- errorCount = 0;
- warningCount = 0;
- jaxxFiles.clear();
- jaxxFileClassNames.clear();
- symbolTables.clear();
- compilers.clear();
- }
-
-
/**
- * 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));
- }
- destDir.mkdirs();
- } else {
- //destDir = file.getParentFile();
- }
- JAXXCompiler 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.failed) {
- 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.failed) {
- compiler.runInitializers();
- }
- if (options.isVerbose()) {
-
- log.info("compile second pass for " + className);
- }
- compiler.compileSecondPass();
- if (options.isVerbose()) {
-
- log.info("done with result [" + !compiler.failed + "] for " + className);
- }
- if (!compiler.failed) {
-
- } 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.failed) {
- success = false;
- }
- }
- }
-
- // code generation
- 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 code generation");
- }
- compiler.generateCode();
- if (compiler.failed) {
- 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 (errorCount==0) {
- reset();
- }
- }
- }
-
-
- private 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 String getVersion() {
- return "1.0.4";
- }
-
-
- public static void main(String[] arg) throws Exception {
- 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);
- }
-
- public File getDest() {
- return dest;
- }
-
- public void setFailed(boolean failed) {
- this.failed = failed;
- }
-
- /**
- * Register in this compiler a new compiled validator.
- *
- * @param validator the compiled validator to register
- */
- public void registerValidator(CompiledBeanValidator validator) {
- validators.add(validator);
- validatedComponents.addAll(validator.getFields().values());
- }
-
- /** @return <code>true</code> if some validators were detected, <code>false</code> otherwise */
- public boolean hasValidator() {
- return !validators.isEmpty();
- }
-
- /**
- * Test if a given CompiledObject is attached to a validator.
- *
- * @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 boolean isComponentUsedByValidator(String componentId) {
- return validatedComponents.contains(componentId);
- }
-
- /**
- * Test if a given bean is attached to a validator.
- *
- * @param beanId the bean to test
- * @return <code>true</code> if the given bean is attached to a validator, <code>false</code> otherwise
- */
- public boolean isBeanUsedByValidator(String beanId) {
- for (CompiledBeanValidator validator : validators) {
- if(beanId.equals(validator.getBean())) {
- return true;
- }
- }
- return false;
- }
-
- /**
* Check that a reference exists in symbol table on second compil pass
*
* @param tag the current tag
@@ -2258,4 +1034,112 @@
}
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;
+ }
+
}
Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompilerHelper.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -0,0 +1,657 @@
+package jaxx.compiler;
+
+import jaxx.CompilerException;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.spi.Initializer;
+import jaxx.tags.DefaultObjectHandler;
+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.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.IOException;
+import java.io.InputStream;
+import java.io.UnsupportedEncodingException;
+import java.net.URL;
+import java.net.URLDecoder;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.ServiceLoader;
+import java.util.Stack;
+
+/** @author chemit */
+public class JAXXCompilerHelper {
+
+ /** 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. */
+ protected static final int INLINE_THRESHOLD = 300;
+
+ protected static final int PASS_1 = 0;
+
+ protected static final int PASS_2 = 1;
+
+ /** Contains import declarations (of the form "javax.swing.") which are always imported in all compiler instances. */
+ protected static List<String> staticImports = new ArrayList<String>();
+
+ static {
+ //TODO humm, we should be able to import only what is needed
+ staticImports.add("java.awt.*");
+ staticImports.add("java.awt.event.*");
+ staticImports.add("java.beans.*");
+ staticImports.add("java.io.*");
+ staticImports.add("java.lang.*");
+ staticImports.add("java.util.*");
+ staticImports.add("javax.swing.*");
+ staticImports.add("javax.swing.border.*");
+ staticImports.add("javax.swing.event.*");
+ staticImports.add("jaxx.runtime.swing.JAXXButtonGroup");
+ staticImports.add("jaxx.runtime.swing.HBox");
+ staticImports.add("jaxx.runtime.swing.VBox");
+ staticImports.add("jaxx.runtime.swing.Table");
+ staticImports.add("static org.codelutin.i18n.I18n._");
+ staticImports.add("static org.codelutin.jaxx.util.UIHelper.createImageIcon");
+ }
+
+ protected static DefaultObjectHandler firstPassClassTagHandler = new DefaultObjectHandler(ClassDescriptorLoader.getClassDescriptor(Object.class));
+
+ /** Files being compiled during the compilation session, may be modified as compilation progresses and additional dependencies are found. */
+ protected static List<File> jaxxFiles = new ArrayList<File>();
+
+ /** Class names corresponding to the files in the jaxxFiles list. */
+ protected static List<String> jaxxFileClassNames = new ArrayList<String>();
+
+ /** Maps the names of classes being compiled to the compiler instance handling the compilation. */
+ protected static 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 static Map<File, SymbolTable> symbolTables = new HashMap<File, SymbolTable>();
+
+ protected static int currentPass;
+
+ 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>();
+
+ protected static int errorCount;
+ protected static int warningCount;
+
+ public static void loadLibraries(boolean verbose) throws IOException, ClassNotFoundException, InstantiationException, IllegalAccessException {
+ 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 static void init() {
+ // forces static initializer to run if it hasn't yet
+ }
+
+ /** Resets all state in preparation for a new compilation session. */
+ protected static void reset() {
+ errorCount = warningCount = 0;
+ jaxxFiles.clear();
+ jaxxFileClassNames.clear();
+ symbolTables.clear();
+ compilers.clear();
+ }
+
+ public static String getVersion() {
+ return "1.0.4";
+ }
+
+ /**
+ * Creates a dummy JAXXCompiler for use in unit testing.
+ *
+ * @return the compiler
+ */
+ public static JAXXCompiler createDummyCompiler() {
+ return createDummyCompiler(JAXXCompiler.class.getClassLoader());
+ }
+
+ /**
+ * Creates a dummy JAXXCompiler for use in unit testing.
+ *
+ * @param classLoader class loader to use
+ * @return the compiler
+ */
+ public static JAXXCompiler createDummyCompiler(ClassLoader classLoader) {
+ return new JAXXCompiler(classLoader);
+ }
+
+ /**
+ * @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 static 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 static 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 static String getLineSeparator() {
+ return System.getProperty("line.separator", "\n");
+ }
+
+ /**
+ * 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 synchronized boolean compile(File base, String[] relativePaths, CompilerOptions options) {
+ File[] files = new File[relativePaths.length];
+ String[] 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(':', '.');
+ }
+ return compile(files, classNames, options);
+ }
+
+ /**
+ * 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));
+ }
+ destDir.mkdirs();
+ } else {
+ //destDir = file.getParentFile();
+ }
+ JAXXCompiler 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.failed) {
+ 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.failed) {
+ compiler.runInitializers();
+ }
+ if (options.isVerbose()) {
+
+ log.info("compile second pass for " + className);
+ }
+ compiler.compileSecondPass();
+ if (options.isVerbose()) {
+
+ log.info("done with result [" + !compiler.failed + "] for " + className);
+ }
+ if (!compiler.failed) {
+
+ } 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.failed) {
+ success = false;
+ }
+ }
+ }
+
+ // code generation
+ 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 code generation");
+ }
+ compiler.generator.generateCode();
+ //compiler.generateCode();
+ if (compiler.failed) {
+ 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 (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;
+ }
+
+ public static String capitalize(String s) {
+ if (s.length() == 0) {
+ return s;
+ }
+ return Character.toUpperCase(s.charAt(0)) + s.substring(1);
+ }
+
+ /**
+ * 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);
+ }
+ }
+
+ 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 {
+ 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);
+ JAXXCompiler.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 &= (JAXXCompiler.errorCount == 0 && files.size() > 0);
+
+ if (success) {
+ success = JAXXCompiler.compile(new File("."), files.toArray(new String[files.size()]), options);
+ } else {
+ showUsage();
+ System.exit(1);
+ }
+
+ System.exit(success ? 0 : 1);
+ }
+
+}
Added: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java (rev 0)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXObjectGenerator.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -0,0 +1,657 @@
+package jaxx.compiler;
+
+import jaxx.CompilerException;
+import jaxx.reflect.ClassDescriptor;
+import jaxx.reflect.ClassDescriptorLoader;
+import jaxx.reflect.MethodDescriptor;
+import jaxx.runtime.JAXXObject;
+import jaxx.runtime.JAXXObjectDescriptor;
+import jaxx.runtime.swing.Application;
+import jaxx.tags.validator.BeanValidatorHandler.CompiledBeanValidator;
+import jaxx.types.TypeManager;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.ObjectOutputStream;
+import java.io.PrintWriter;
+import java.lang.reflect.Modifier;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.GZIPOutputStream;
+
+/**
+ * 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 {
+
+ /** log */
+ protected static final Log log = LogFactory.getLog(JAXXObjectGenerator.class);
+
+ /** the compile used to parse the file to be generated here. */
+ protected JAXXCompiler compiler;
+
+ /** the file to be generated */
+ protected JavaFile javaFile = new JavaFile();
+
+ /** Generated .java file. */
+ protected File dest;
+
+ /** 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;
+
+ public JAXXObjectGenerator(JAXXCompiler compiler) {
+ this.compiler = compiler;
+ }
+
+ protected void generateCode() throws IOException {
+ 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);
+ }
+ PrintWriter out = new PrintWriter(new FileWriter(dest));
+ createJavaSource(out);
+ out.close();
+ }
+
+ protected void createJavaSource(PrintWriter out) throws IOException {
+ int dotPos = getOutputClassName().lastIndexOf(".");
+ String packageName = dotPos != -1 ? getOutputClassName().substring(0, dotPos) : null;
+ String simpleClassName = getOutputClassName().substring(dotPos + 1);
+ outputClass(packageName, simpleClassName, out);
+ }
+
+ protected void outputClass(String packageName, String className, PrintWriter out) throws CompilerException {
+ createJavaFile(packageName, className);
+ out.println(javaFile.toString());
+ }
+
+ protected void createJavaFile(String packageName, String className) throws CompilerException {
+ String fullClassName = packageName != null ? packageName + "." + className : className;
+ CompiledObject root = compiler.getRootObject();
+ 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.setInterfaces(new String[]{JAXXCompiler.getCanonicalName(JAXXObject.class)});
+
+ for (CompiledObject object : compiler.getObjects().values()) {
+ if (!object.isOverride() && !(object instanceof ScriptInitializer)) {
+ int access = object.getId().startsWith("$") ? Modifier.PRIVATE : Modifier.PROTECTED;
+ if (object == root) {
+ javaFile.addField(new JavaField(access, fullClassName, object.getId(), "this"));
+ } else {
+ //TC -20081017 can have generic on compiled Object
+ javaFile.addField(new JavaField(access, JAXXCompiler.getCanonicalName(object), object.getId()));
+ //javaFile.addField(new JavaField(access, getCanonicalName(object.getObjectClass()), object.getId()));
+ }
+ }
+ }
+
+ if (!superclassIsJAXXObject) {
+ // add logger
+ if (getOptions().isAddLogger()) {
+ javaFile.addImport("org.apache.commons.logging.Log");
+ javaFile.addImport("org.apache.commons.logging.LogFactory");
+ javaFile.addField(createLoggerField(fullClassName));
+ }
+
+ javaFile.addField(new JavaField(Modifier.PROTECTED, "java.util.List<Object>", "$activeBindings", "new ArrayList<Object>()"));
+ javaFile.addField(new JavaField(Modifier.PROTECTED, "java.util.Map<String,Object>", "$bindingSources", "new HashMap<String,Object>()"));
+ javaFile.addField(new JavaField(Modifier.PROTECTED, "java.util.List<String>", "validatorIds", "new ArrayList<String>()"));
+ }
+
+ javaFile.addImport("jaxx.runtime.validator.BeanValidator");
+
+ if (compiler.getStylesheet() != null) {
+ javaFile.addField(new JavaField(0, "java.util.Map", "$previousValues", "new java.util.HashMap()"));
+ }
+
+ javaFile.addMethod(createConstructor(className));
+ javaFile.addMethod(createInitializer(className));
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "BeanValidator<?>", "getValidator", new JavaArgument[]{new JavaArgument("String", "validatorId")},
+ null, "return (BeanValidator)(validatorIds.contains(validatorId)?getObjectById(validatorId):null);"));
+
+ for (DataBinding dataBinding : compiler.getDataBindings()) {
+ if (dataBinding.compile(true)) {
+ initDataBindings.append("applyDataBinding(").append(TypeManager.getJavaCode(dataBinding.getId())).append(");").append(JAXXCompiler.getLineSeparator());
+ }
+ }
+
+ javaFile.addBodyCode(bodyCode.toString());
+
+ for (CompiledObject object : objects.values()) {
+ if (!compiler.inlineCreation(object) && object != root) {
+ javaFile.addMethod(new JavaMethod(Modifier.PROTECTED, "void", object.getCreationMethodName(), null, null, getCreationCode(object)));
+ }
+ }
+
+ javaFile.addField(new JavaField(Modifier.PRIVATE, "boolean", "allComponentsCreated"));
+
+ javaFile.addMethod(createCompleteSetupMethod());
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "applyDataBinding", new JavaArgument[]{new JavaArgument("String", "$binding")},
+ null, applyDataBinding.toString() + JAXXCompiler.getLineSeparator() + " processDataBinding($binding);"));
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "removeDataBinding", new JavaArgument[]{new JavaArgument("String", "$binding")},
+ null, removeDataBinding.toString()));
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "processDataBinding", new JavaArgument[]{new JavaArgument("String", "dest")},
+ null, "processDataBinding(dest, false);"));
+
+ javaFile.addMethod(createProcessDataBindingMethod());
+
+ if (!superclassIsJAXXObject) {
+ javaFile.addField(createObjectMap());
+ javaFile.addMethod(createGetObjectByIdMethod());
+ }
+
+ javaFile.addField(createJAXXObjectDescriptorField());
+ javaFile.addMethod(createGetJAXXObjectDescriptorMethod());
+
+ /*
+ * Gestion du context
+ */
+ javaFile.addField(createContextField());
+ javaFile.addMethod(createSetContextValueMethod());
+ javaFile.addMethod(createSetContextValueNameMethod());
+ javaFile.addMethod(createGetContextValueMethod());
+ javaFile.addMethod(createGetContextValueNameMethod());
+ javaFile.addMethod(createGetParentContainer());
+ javaFile.addMethod(createGetParentContainerMore());
+ ClassDescriptor currentClass = root.getObjectClass();
+ MethodDescriptor firePropertyChange = null;
+ while (firePropertyChange == null && currentClass != null) {
+ try {
+ firePropertyChange = currentClass.getDeclaredMethodDescriptor("firePropertyChange", new ClassDescriptor[]{
+ 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(new JavaMethod(Modifier.PUBLIC, "void", "firePropertyChange", new JavaArgument[]{
+ new JavaArgument("java.lang.String", "propertyName"), new JavaArgument("java.lang.Object", "oldValue"), new JavaArgument("java.lang.Object", "newValue")},
+ null, "super.firePropertyChange(propertyName, oldValue, newValue);"));
+ } else {
+ // either no support at all or firePropertyChange isn't accessible
+ addPropertyChangeSupport(javaFile);
+ }
+
+ addEventHandlers(javaFile);
+
+ if (ClassDescriptorLoader.getClassDescriptor(Application.class).isAssignableFrom(root.getObjectClass()) && !isMainDeclared()) {
+ // TODO: check for existing main method first
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC | Modifier.STATIC, "void", "main",
+ new JavaArgument[]{new JavaArgument("String[]", "arg")}, null,
+ "SwingUtilities.invokeLater(new Runnable() { public void run() { new " + className + "().setVisible(true); } });"));
+ }
+ }
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Create fields ----------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ private JavaField createObjectMap() {
+ return new JavaField(Modifier.PROTECTED, "Map<String,Object>", "$objectMap", "new HashMap<String,Object>()");
+ }
+
+ private JavaField createContextField() {
+ return new JavaField(Modifier.PROTECTED, "Map<Object,String>", "$contextMap", "new HashMap<Object,String>()");
+ }
+
+ private JavaField createLoggerField(String className) {
+ return new JavaField(Modifier.PUBLIC + Modifier.STATIC + Modifier.FINAL, "Log", "log", "LogFactory.getLog(" + className + ".class)");
+ }
+
+ protected JavaField createJAXXObjectDescriptorField() {
+ try {
+ JAXXObjectDescriptor descriptor = compiler.getJAXXObjectDescriptor();
+ 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 new JavaField(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 new JavaField(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 JavaMethod createGetJAXXObjectDescriptorMethod() {
+ return new JavaMethod(Modifier.PUBLIC | Modifier.STATIC, "jaxx.runtime.JAXXObjectDescriptor", "$getJAXXObjectDescriptor",
+ null, null, "return jaxx.runtime.Util.decodeCompressedJAXXObjectDescriptor($jaxxObjectDescriptor);");
+ }
+
+ protected JavaMethod createGetObjectByIdMethod() {
+ return new JavaMethod(Modifier.PUBLIC, "java.lang.Object", "getObjectById",
+ new JavaArgument[]{new JavaArgument("String", "id")}, null,
+ "return $objectMap.get(id);");
+ }
+
+ private JavaMethod createSetContextValueMethod() {
+
+ return new JavaMethod(Modifier.PUBLIC, "void", "setContextValue",
+ new JavaArgument[]{new JavaArgument("Object", "clazz")}, null, getSetContextValueMethodCode());
+ }
+
+ private JavaMethod createSetContextValueNameMethod() {
+ return new JavaMethod(Modifier.PUBLIC, "void", "setContextValue",
+ new JavaArgument[]{new JavaArgument("Object", "clazz"), new JavaArgument("String", "name")}, null, getSetContextValueNameMethodCode());
+ }
+
+ private JavaMethod createGetContextValueMethod() {
+ return new JavaMethod(Modifier.PUBLIC, "<T> T", "getContextValue",
+ new JavaArgument[]{new JavaArgument("Class<T>", "clazz")}, null, getGetContextValueMethodCode());
+ }
+
+ private JavaMethod createGetContextValueNameMethod() {
+ return new JavaMethod(Modifier.PUBLIC, "<T> T", "getContextValue",
+ new JavaArgument[]{new JavaArgument("Class<T>", "clazz"), new JavaArgument("String", "name")}, null, getGetContextValueNameMethodCode());
+ }
+
+ private JavaMethod createGetParentContainer() {
+ return new JavaMethod(Modifier.PUBLIC, "<O extends Container> O", "getParentContainer",
+ new JavaArgument[]{new JavaArgument("Class<O>", "clazz")}, null, getGetParentContenerMethodCode());
+ }
+
+ private JavaMethod createGetParentContainerMore() {
+ return new JavaMethod(Modifier.PUBLIC, "<O extends Container> O", "getParentContainer",
+ new JavaArgument[]{new JavaArgument("Object", "source"), new JavaArgument("Class<O>", "clazz")}, null, getGetParentContenerMethodMoreCode());
+ }
+
+
+ protected void addPropertyChangeSupport(JavaFile javaFile) throws CompilerException {
+ javaFile.addField(new JavaField(0, "java.beans.PropertyChangeSupport", "$propertyChangeSupport"));
+
+ javaFile.addMethod(new JavaMethod(0, "java.beans.PropertyChangeSupport", "$getPropertyChangeSupport", null, null,
+ "if ($propertyChangeSupport == null)\n" +
+ " $propertyChangeSupport = new PropertyChangeSupport(this);\n" +
+ "return $propertyChangeSupport;"));
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "addPropertyChangeListener", new JavaArgument[]{
+ new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
+ "$getPropertyChangeSupport().addPropertyChangeListener(listener);"));
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "addPropertyChangeListener", new JavaArgument[]{
+ new JavaArgument("java.lang.String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
+ "$getPropertyChangeSupport().addPropertyChangeListener(property, listener);"));
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "removePropertyChangeListener", new JavaArgument[]{
+ new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
+ "$getPropertyChangeSupport().removePropertyChangeListener(listener);"));
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "removePropertyChangeListener", new JavaArgument[]{
+ new JavaArgument("java.lang.String", "property"), new JavaArgument("java.beans.PropertyChangeListener", "listener")}, null,
+ "$getPropertyChangeSupport().removePropertyChangeListener(property, listener);"));
+
+ javaFile.addMethod(new JavaMethod(Modifier.PUBLIC, "void", "firePropertyChange", new JavaArgument[]{
+ new JavaArgument("java.lang.String", "propertyName"), new JavaArgument("java.lang.Object", "oldValue"), new JavaArgument("java.lang.Object", "newValue")},
+ null, "$getPropertyChangeSupport().firePropertyChange(propertyName, oldValue, newValue);"));
+ }
+
+
+ protected void addEventHandlers(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(new JavaMethod(Modifier.PUBLIC, "void", methodName,
+ new JavaArgument[]{new JavaArgument(JAXXCompiler.getCanonicalName(listenerMethod.getParameterTypes()[0]), "event")}, null,
+ handler.getJavaCode()));
+ }
+ }
+ }
+ }
+
+ protected JavaMethod createConstructor(String className) throws CompilerException {
+ StringBuffer code = new StringBuffer();
+ String constructorParams = compiler.getRootObject().getConstructorParams();
+ if (constructorParams != null) {
+ code.append(" super(").append(constructorParams).append(");");
+ code.append(JAXXCompiler.getLineSeparator());
+ }
+ code.append("$initialize();");
+ code.append(JAXXCompiler.getLineSeparator());
+ return new JavaMethod(Modifier.PUBLIC, null, className, null, null, code.toString());
+ }
+
+
+ protected JavaMethod createInitializer(String className) throws CompilerException {
+ StringBuffer code = new StringBuffer();
+ CompiledObject root = compiler.getRootObject();
+ 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(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 (initializer.length() > 0) {
+ code.append(initializer);
+ code.append(JAXXCompiler.getLineSeparator());
+ }
+ code.append("$completeSetup();");
+ code.append(JAXXCompiler.getLineSeparator());
+ return new JavaMethod(Modifier.PRIVATE, "void", "$initialize", null, null, code.toString());
+ }
+
+
+ protected JavaMethod createCompleteSetupMethod() {
+ 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() + additionCode + "}";
+ javaFile.addMethod(new JavaMethod(Modifier.PROTECTED, "void", object.getAdditionMethodName(), null, null, additionCode));
+ }
+ }
+ //code.append(getLineSeparator());
+ }
+
+ code.append(initDataBindings);
+
+ if (lateInitializer.length() > 0) {
+ code.append(lateInitializer);
+ code.append(JAXXCompiler.getLineSeparator());
+ }
+
+ if (compiler.hasValidator()) {
+ // register validator
+ for (CompiledBeanValidator validator : compiler.getValidators()) {
+ String id = TypeManager.getJavaCode(validator.getId());
+ code.append("validatorIds.add(").append(id).append(");");
+ code.append(JAXXCompiler.getLineSeparator());
+ code.append("getValidator(").append(id).append(").installUIs();");
+ code.append("getValidator(").append(id).append(").validate();");
+ code.append(JAXXCompiler.getLineSeparator());
+ }
+ }
+ return new JavaMethod(Modifier.PRIVATE, "void", "$completeSetup", null, null, code.toString());
+ }
+
+ protected JavaMethod createProcessDataBindingMethod() {
+ 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 (processDataBinding.length() > 0) {
+ code.append(" if (!$force && $activeBindings.contains($dest)) return;");
+ code.append(JAXXCompiler.getLineSeparator());
+ code.append(" $activeBindings.add($dest);");
+ code.append(JAXXCompiler.getLineSeparator());
+ code.append(" try {");
+ code.append(JAXXCompiler.getLineSeparator());
+ if (processDataBinding.length() > 0) {
+ code.append(processDataBinding);
+ 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 new JavaMethod(Modifier.PUBLIC, "void", "processDataBinding",
+ new JavaArgument[]{new JavaArgument("String", "$dest"), new JavaArgument("boolean", "$force")},
+ null, code.toString());
+ }
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Create methods code ----------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+ private String getSetContextValueMethodCode() {
+ return "this.setContextValue(clazz, null);";
+ }
+
+ private String getSetContextValueNameMethodCode() {
+ StringBuffer result = new StringBuffer();
+ result.append("$contextMap.put(clazz, name);");
+ return result.toString();
+ }
+
+ private String getGetContextValueMethodCode() {
+ return "return this.getContextValue(clazz, null);";
+ }
+
+ private String getGetContextValueNameMethodCode() {
+ StringBuffer result = new StringBuffer();
+ result.append("for (Map.Entry<Object,String> entry : $contextMap.entrySet()) {");
+ result.append("if (clazz.isAssignableFrom(entry.getKey().getClass()) && (name == null || name == entry.getValue())) {");
+ result.append("return (T) entry.getKey();}}");
+ result.append("return null;");
+ return result.toString();
+ }
+
+ private String getGetParentContenerMethodCode() {
+ StringBuffer result = new StringBuffer();
+ result.append("return this.getParentContainer(this, clazz);");
+ return result.toString();
+ }
+
+ private String getGetParentContenerMethodMoreCode() {
+ StringBuffer result = new StringBuffer();
+ result.append("if (!Container.class.isAssignableFrom(source.getClass())) {return null;}");
+ result.append(JAXXCompiler.getLineSeparator());
+ result.append("Container parent = ((Container)source).getParent();");
+ result.append(JAXXCompiler.getLineSeparator());
+ result.append("if (parent != null && !clazz.isAssignableFrom(parent.getClass())){parent = getParentContainer(parent, clazz);}");
+ result.append(JAXXCompiler.getLineSeparator());
+ result.append("return (O)parent;");
+ return result.toString();
+ }
+
+ protected String getCreationCode(CompiledObject object) throws CompilerException {
+ if (object instanceof ScriptInitializer) {
+ return object.getInitializationCode(compiler);
+ }
+ StringBuffer result = new StringBuffer();
+ result.append(object.getId());
+ result.append(" = ");
+ 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();
+ }
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Delegate methods from JAXXCompiler -------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ public String getOutputClassName() {
+ return compiler.getOutputClassName();
+ }
+
+ public File getBaseDir() {
+ return compiler.getBaseDir();
+ }
+
+ public CompilerOptions getOptions() {
+ return compiler.getOptions();
+ }
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Getter methods ---------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ public JavaFile getJavaFile() {
+ return javaFile;
+ }
+
+ 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;
+ }
+
+ /*---------------------------------------------------------------------------------*/
+ /*-- Setter methods ---------------------------------------------------------------*/
+ /*---------------------------------------------------------------------------------*/
+
+ public void setMainDeclared(boolean mainDeclared) {
+ this.mainDeclared = mainDeclared;
+ }
+}
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/ScriptManager.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/ScriptManager.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/ScriptManager.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -1,181 +1,181 @@
-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;
- }
-
-
+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";
@@ -196,141 +196,141 @@
}
}
- compiler.bodyCode.append(modifiers).append(" ").append(node.getText().substring(0,node.getText().length()-1) + 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.bodyCode.append(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.bodyCode.append(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.bodyCode.append(text.substring(0, equals).trim()).append(";");
- 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.bodyCode.append(text);
- }
- compiler.bodyCode.append("\n");
- //compiler.bodyCode.append(";\n");
- } else {
- String text = node.getText().trim();
- if (text.length() > 0) {
- if (!text.endsWith(";")) {
- text += ";";
- }
- compiler.initializer.append(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);
- }
- }
- }
+ }
+
+
+ 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);
+ }
+ }
+ }
}
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/css/Stylesheet.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -168,7 +168,7 @@
ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseExited",
new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}),
propertyCode, compiler);
- compiler.initDataBindings.append("{").append(propertyCode).append("}");
+ compiler.appendInitDataBindings("{" + propertyCode + "}");
}
catch (NoSuchMethodException e) {
compiler.reportError("mouseout pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)");
@@ -193,7 +193,7 @@
ClassDescriptorLoader.getClassDescriptor(MouseListener.class).getMethodDescriptor("mouseReleased",
new ClassDescriptor[]{ClassDescriptorLoader.getClassDescriptor(MouseEvent.class)}),
propertyCode, compiler);
- compiler.initDataBindings.append("{").append(propertyCode).append("}");
+ compiler.appendInitDataBindings("{" + propertyCode + "}");
}
catch (NoSuchMethodException e) {
compiler.reportError("mouseup pseudoclass cannot be applied to object " + object.getObjectClass().getName() + " (no addMouseListener method)");
@@ -203,11 +203,12 @@
pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode());
String dest = object.getId() + ".style." + pseudoClass + ".add";
String destCode = TypeManager.getJavaCode(dest);
- if (compiler.processDataBinding.length() > 0)
- compiler.processDataBinding.append("else ");
- compiler.processDataBinding.append("if ($dest.equals(").append(destCode).append(")) { if (").append(pseudoClass).append(") { ").append(propertyCode).append("} }");
+ 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.initDataBindings.append("applyDataBinding(").append(destCode).append(");");
+ compiler.appendInitDataBindings("applyDataBinding("+ destCode + ");");
} else
throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass);
}
@@ -267,11 +268,12 @@
pseudoClass = replaceObjectReferences(pseudoClass, object.getJavaCode());
String dest = object.getId() + ".style." + pseudoClass + ".remove";
String destCode = TypeManager.getJavaCode(dest);
- if (compiler.processDataBinding.length() > 0)
- compiler.processDataBinding.append("else ");
- compiler.processDataBinding.append("if ($dest.equals(").append(destCode).append(")) { if (").append(invert(pseudoClass)).append(") { ").append(propertyCode).append("} }");
+ 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.initDataBindings.append("applyDataBinding(").append(destCode).append(");");
+ compiler.appendInitDataBindings("applyDataBinding(" + destCode + ");");
} else
throw new IllegalArgumentException("unrecognized pseudoclass: " + pseudoClass);
}
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -295,17 +295,10 @@
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 = false;
- JavaMethod[] methods = compiler.getJavaFile().getMethods();
- for (JavaMethod method : methods) {
- if (method.getName().equals(methodName)) {
- methodExists = true;
- break;
- }
- }
+ boolean methodExists = compiler.hasMethod(methodName);
ClassDescriptor eventClass = getEventClass(eventInfo.listenerClass);
if (!methodExists) {
- compiler.getJavaFile().addMethod(new JavaMethod(Modifier.PUBLIC, "void", methodName,
+ compiler.addMethodToJavaFile(new JavaMethod(Modifier.PUBLIC, "void", methodName,
new JavaArgument[]{new JavaArgument(JAXXCompiler.getCanonicalName(eventClass), "event")}, null,
propertyChangeListenerCode + ".propertyChange(null);"));
}
@@ -358,19 +351,12 @@
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 = false;
- JavaMethod[] methods = compiler.getJavaFile().getMethods();
- for (JavaMethod method : methods) {
- if (method.getName().equals(methodName)) {
- methodExists = true;
- break;
- }
- }
- ClassDescriptor eventClass = getEventClass(eventInfo.listenerClass);
+ boolean methodExists = compiler.hasMethod(methodName);
if (!methodExists) {
- compiler.getJavaFile().addMethod(new JavaMethod(Modifier.PUBLIC, "void", methodName,
+ 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);"));
+ propertyChangeListenerCode + ".propertyChange(null);"));
}
try {
String modelMemberName = eventInfo.modelName != null ? "get" + JAXXCompiler.capitalize(eventInfo.modelName) : null;
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/ApplicationHandler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/ApplicationHandler.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/ApplicationHandler.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -26,7 +26,7 @@
@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.bodyCode.append("{ ").append(object.getJavaCode()).append(".setLookAndFeel(").append(TypeManager.getJavaCode(stringValue)).append("); }").append(JAXXCompiler.getLineSeparator());
+ compiler.appendBodyCode("{ " + object.getJavaCode() + ".setLookAndFeel(" + TypeManager.getJavaCode(stringValue) + "); }" + JAXXCompiler.getLineSeparator());
} else {
super.setAttribute(object, propertyName, stringValue, inline, compiler);
}
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JInternalFrameHandler.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -48,6 +48,6 @@
@Override
public void setAttributes(CompiledObject object, Element tag, JAXXCompiler compiler) throws CompilerException {
super.setAttributes(object, tag, compiler);
- compiler.initializer.append(object.getId()).append(".pack();\n");
+ compiler.appendInitializerCode(object.getId() + ".pack();\n");
}
}
\ No newline at end of file
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JWindowHandler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JWindowHandler.java 2008-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/swing/JWindowHandler.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -50,9 +50,10 @@
@Override
public void compileSecondPass(Element tag, JAXXCompiler compiler) throws CompilerException, IOException {
super.compileSecondPass(tag, compiler);
- CompiledObject object = (CompiledObject) objectMap.get(tag);
+ CompiledObject object = objectMap.get(tag);
Map properties = object.getProperties();
- if (!properties.containsKey("width") && !properties.containsKey("height"))
- compiler.lateInitializer.append(object.getId()).append(".pack();\n");
+ if (!properties.containsKey("width") && !properties.containsKey("height")) {
+ compiler.appendLateInitializer(object.getId() + ".pack();\n");
+ }
}
}
\ No newline at end of file
Modified: lutinjaxx/trunk/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-10-19 18:05:04 UTC (rev 976)
+++ lutinjaxx/trunk/maven-jaxx-plugin/src/test/java/org/codelutin/jaxx/CompilerTest.java 2008-10-19 19:44:06 UTC (rev 977)
@@ -1,6 +1,7 @@
package org.codelutin.jaxx;
import jaxx.compiler.JAXXCompiler;
+import jaxx.compiler.JAXXCompilerHelper;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.logging.SystemStreamLog;
@@ -89,8 +90,8 @@
//do nothing
}
});
- Field fieldCompilers = JAXXCompiler.class.getDeclaredField("compilers");
- Field fieldErrorCount = JAXXCompiler.class.getDeclaredField("errorCount");
+ Field fieldCompilers = JAXXCompilerHelper.class.getDeclaredField("compilers");
+ Field fieldErrorCount = JAXXCompilerHelper.class.getDeclaredField("errorCount");
fieldCompilers.setAccessible(true);
fieldErrorCount.setAccessible(true);
@@ -207,8 +208,8 @@
//do nothing
}
});
- Field fieldCompilers = JAXXCompiler.class.getDeclaredField("compilers");
- Field fieldErrorCount = JAXXCompiler.class.getDeclaredField("errorCount");
+ Field fieldCompilers = JAXXCompilerHelper.class.getDeclaredField("compilers");
+ Field fieldErrorCount = JAXXCompilerHelper.class.getDeclaredField("errorCount");
fieldCompilers.setAccessible(true);
fieldErrorCount.setAccessible(true);
1
0
19 Oct '08
Author: tchemit
Date: 2008-10-19 18:05:04 +0000 (Sun, 19 Oct 2008)
New Revision: 976
Added:
lutinjaxx/tags/20081019_0.5-SNAPSHOT-before-JAXXCompiler-refactor/
Log:
make a tag before commit of JAXXCompiler refactor in two class : JAXXCompiler and JAXXObjectGenerator wich is now responsible of the java file generator
Copied: lutinjaxx/tags/20081019_0.5-SNAPSHOT-before-JAXXCompiler-refactor (from rev 975, lutinjaxx/trunk)
1
0
[Buix-commits] r975 - lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
18 Oct '08
Author: tchemit
Date: 2008-10-18 11:29:08 +0000 (Sat, 18 Oct 2008)
New Revision: 975
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java
Log:
improve coherence
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2008-10-18 11:28:25 UTC (rev 974)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/BeanValidatorHandler.java 2008-10-18 11:29:08 UTC (rev 975)
@@ -98,6 +98,7 @@
}
String bean = info.getBean();
+ boolean error = false;
if (bean != null) {
if (compiler.checkReference(tag, bean, true, BEAN_ATTRIBUTE)) {
String code = getSetPropertyCode(info.getJavaCode(), BEAN_ATTRIBUTE, bean, compiler);
@@ -105,23 +106,37 @@
// add generic type to validator
JAXXBeanInfo beanInfo = info.getBeanDescriptor(compiler);
info.setGenericTypes(new String[]{beanInfo.getJAXXBeanDescriptor().getClassDescriptor().getName()});
+ } else {
+ error=true;
}
- }
- if (info.getAutoField()) {
- if (bean == null) {
- compiler.reportError("tag '" + tag.getLocalName() + "' need a " + BEAN_ATTRIBUTE + " attribute to use autofield mode");
- } else {
+ //TODO: checkthe bean is not already used in another validator
+ if (!error && compiler.isBeanUsedByValidator(bean)) {
+ compiler.reportError("the bean '" + bean + "' is already used in another the validator, can not used it in '" + tag + "'");
+ error = true;
+ }
+
+ if (!error && info.getAutoField()) {
+ //if (bean == null) {
+ // compiler.reportError("tag '" + tag.getLocalName() + "' need a " + BEAN_ATTRIBUTE + " attribute to use autofield mode");
+ //} else {
registerAutoFieldBean(tag, compiler, info);
+ // }
}
- }
- // add fieldrepresentation invocations
- addFieldRepresentations(tag, compiler, info);
+ if (!error && info.getBeanDescriptor(compiler) != null) {
- // register the validator in compiler
- compiler.registerValidator(info);
+ // add fieldrepresentation invocations
+ addFieldRepresentations(tag, compiler, info);
+ // register the validator in compiler
+ compiler.registerValidator(info);
+ }
+
+ } else {
+ compiler.reportError("tag '" + tag + "' requires a bean attribute");
+ }
+
// close the compiled object
compiler.closeComponent(info);
}
@@ -178,7 +193,7 @@
}
if (compiler.isComponentUsedByValidator(component)) {
// component is already used by another validator
- compiler.reportError("component '"+component+"' is already used by another validator.");
+ compiler.reportError("component '" + component + "' is already used by another validator.");
continue;
}
String keyCode = TypeManager.getJavaCode(propertyName);
@@ -300,7 +315,12 @@
public JAXXBeanInfo getBeanDescriptor(JAXXCompiler compiler) {
if (beanDescriptor == null && bean != null) {
try {
- ClassDescriptor beanClassDescriptor = ClassDescriptorLoader.getClassDescriptor(compiler.getSymbolTable().getClassTagIds().get(bean));
+ String 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 = getJAXXBeanInfo(beanClassDescriptor);
} catch (ClassNotFoundException e) {
compiler.reportError("could not load class " + bean);
1
0
[Buix-commits] r974 - lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
18 Oct '08
Author: tchemit
Date: 2008-10-18 11:28:25 +0000 (Sat, 18 Oct 2008)
New Revision: 974
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java
Log:
test if component is not already attached to another validator
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2008-10-18 11:27:58 UTC (rev 973)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/validator/FieldValidatorHandler.java 2008-10-18 11:28:25 UTC (rev 974)
@@ -61,8 +61,13 @@
}
component = component.trim();
+ // check component is not already used by this validator
+ if (validator.getFields().containsValue(component)) {
+ compiler.reportError(FIELD_VALIDATOR_TAG + " tag found a attribute " + COMPONENT_ATTRIBUTE + " ["+component+"] already used in this validator");
+ return;
+ }
// check component exist (again perharps, but if error will known exactly which tag failed...)
- if (compiler.checkReference(tag, component, true, component)) {
+ if (compiler.checkReference(tag, component, true, COMPONENT_ATTRIBUTE)) {
// add a field
validator.addField(name, component, compiler);
}
1
0
[Buix-commits] r973 - lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
18 Oct '08
Author: tchemit
Date: 2008-10-18 11:27:58 +0000 (Sat, 18 Oct 2008)
New Revision: 973
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java
Log:
catch runtime execption to add error to report
add method to test if a bean was not previously attached to a validator
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java 2008-10-18 11:26:34 UTC (rev 972)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/compiler/JAXXCompiler.java 2008-10-18 11:27:58 UTC (rev 973)
@@ -347,7 +347,13 @@
if (log.isDebugEnabled()) {
log.debug(runnable);
}
- runnable.run();
+ try {
+ runnable.run();
+ } catch (Exception e) {
+ //TC - 20081018 report error and quit
+ reportError(e.getMessage());
+ return;
+ }
}
initializers.clear();
}
@@ -2085,7 +2091,10 @@
return false;
}
finally {
- reset();
+ //TC - 20081018 only reset when no error was detected
+ if (errorCount==0) {
+ reset();
+ }
}
}
@@ -2210,6 +2219,21 @@
}
/**
+ * Test if a given bean is attached to a validator.
+ *
+ * @param beanId the bean to test
+ * @return <code>true</code> if the given bean is attached to a validator, <code>false</code> otherwise
+ */
+ public boolean isBeanUsedByValidator(String beanId) {
+ for (CompiledBeanValidator validator : validators) {
+ if(beanId.equals(validator.getBean())) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
* Check that a reference exists in symbol table on second compil pass
*
* @param tag the current tag
1
0
[Buix-commits] r972 - lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
18 Oct '08
Author: tchemit
Date: 2008-10-18 11:26:34 +0000 (Sat, 18 Oct 2008)
New Revision: 972
Modified:
lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java
Log:
catch runtime execption to add error to report
Modified: lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java
===================================================================
--- lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-10-18 11:25:58 UTC (rev 971)
+++ lutinjaxx/trunk/jaxx-core/src/main/java/jaxx/tags/DefaultObjectHandler.java 2008-10-18 11:26:34 UTC (rev 972)
@@ -859,6 +859,8 @@
}
catch (ClassNotFoundException e) {
throw new CompilerException(e);
+ } catch (IllegalArgumentException e) {
+ compiler.reportError(e.getMessage());
}
}
1
0
[Buix-commits] r971 - lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
by tchemit@users.labs.libre-entreprise.org 18 Oct '08
18 Oct '08
Author: tchemit
Date: 2008-10-18 11:25:58 +0000 (Sat, 18 Oct 2008)
New Revision: 971
Modified:
lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java
Log:
add excludes property on goal
Modified: lutinjaxx/trunk/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-10-18 11:25:38 UTC (rev 970)
+++ lutinjaxx/trunk/maven-jaxx-plugin/src/main/java/org/codelutin/jaxx/JaxxGeneratorMojo.java 2008-10-18 11:25:58 UTC (rev 971)
@@ -116,6 +116,13 @@
protected String[] includes;
/**
+ * pour filter les fichiers a ne pas traiter
+ *
+ * @parameter expression="${jaxx.excludes}"
+ */
+ protected String[] excludes;
+
+ /**
* to force generation of java source for any jaxx files with no timestamp checking.
* <p/>
* By default, never force generation.
@@ -179,6 +186,11 @@
ds.setBasedir(src);
boolean noIncludes = includes == null || includes.length == 0;
ds.setIncludes(noIncludes ? INCLUDES : includes);
+
+ if (excludes!=null && excludes.length>0) {
+ ds.setExcludes(excludes);
+ }
+
ds.scan();
String[] files = ds.getIncludedFiles();
if (verbose) {
1
0