Author: akazakov
Date: 2008-01-15 15:25:42 -0500 (Tue, 15 Jan 2008)
New Revision: 5730
Added:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/ELStringToken.java
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELStringTokenizer.java
trunk/seam/tests/org.jboss.tools.seam.core.test/projects/SeamWebWarTestProject/WebContent/JBIDE-1631.xhtml
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELTokenizer.java
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamELValidator.java
trunk/seam/tests/org.jboss.tools.seam.core.test/src/org/jboss/tools/seam/core/test/SeamValidatorsTest.java
Log:
http://jira.jboss.com/jira/browse/JBIDE-1631
Added:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/ELStringToken.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/ELStringToken.java
(rev 0)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/ELStringToken.java 2008-01-15
20:25:42 UTC (rev 5730)
@@ -0,0 +1,123 @@
+ /*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at
http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.seam.internal.core.el;
+
+import org.eclipse.jface.text.rules.IToken;
+
+/**
+ * Token of the string with EL expression.
+ * @author Alexey Kazakov
+ */
+public class ELStringToken implements IToken {
+ public static final ELStringToken EOF = new ELStringToken(-1, -1, null);
+
+ private int start;
+ private int length;
+ private CharSequence chars;
+ private String body;
+
+ /**
+ * Constructs the ELStringToken object
+ *
+ * @param start
+ * @param length
+ * @param chars
+ */
+ public ELStringToken(int start, int length, CharSequence chars) {
+ this.start = start;
+ this.length = length;
+ this.chars = chars;
+ }
+
+ /**
+ * Returns string representation for the token
+ */
+ public String toString() {
+ return "ELStringToken(" + start + ", " + length + ") [" +
(chars == null ? "<Empty>" : chars.toString()) + "]";
//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#getData()
+ */
+ public Object getData() {
+// return (chars == null ? null : chars.subSequence(start, start+length).toString());
+ return getText();
+ }
+
+ /**
+ * @return offset of token
+ */
+ public int getStart() {
+ return start;
+ }
+
+ /**
+ * @param start
+ */
+ public void setStart(int start) {
+ this.start = start;
+ }
+
+ /**
+ * @return length of token
+ */
+ public int getLength() {
+ return length;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isEOF()
+ */
+ public boolean isEOF() {
+ return (start == -1 && length == -1 && chars == null);
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isOther()
+ */
+ public boolean isOther() {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isUndefined()
+ */
+ public boolean isUndefined() {
+ return false;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.IToken#isWhitespace()
+ */
+ public boolean isWhitespace() {
+ return false;
+ }
+
+ /*
+ * Returns the token text
+ */
+ public String getText() {
+ return chars.toString();
+ }
+
+ /*
+ * Returns text of EL without brackets
+ */
+ public String getBody() {
+ if(chars.length()<4) {
+ return "";
+ }
+ if(body==null) {
+ body = chars.subSequence(2, chars.length()-1).toString();
+ }
+ return body;
+ }
+}
\ No newline at end of file
Added:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELStringTokenizer.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELStringTokenizer.java
(rev 0)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELStringTokenizer.java 2008-01-15
20:25:42 UTC (rev 5730)
@@ -0,0 +1,152 @@
+ /*******************************************************************************
+ * Copyright (c) 2007 Red Hat, Inc.
+ * Distributed under license by Red Hat, Inc. All rights reserved.
+ * This program is made available under the terms of the
+ * Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at
http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Red Hat, Inc. - initial API and implementation
+ ******************************************************************************/
+package org.jboss.tools.seam.internal.core.el;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.jboss.tools.seam.core.SeamCorePlugin;
+
+/**
+ * Parses string and creates list of tokens for each EL of this string.
+ * @author Alexey Kazakov
+ */
+public class SeamELStringTokenizer {
+
+ private String sourceString;
+ private List<ELStringToken> fTokens;
+ private int index;
+ private int offset = 0;
+
+ private static final int START_EL_FIRST_SYMBOL = '#';
+ private static final int START_EL_LAST_SYMBOL = '{';
+ private static final int END_EL_SYMBOL = '}';
+
+ /**
+ * Constructs SeamELStringTokenizer object.
+ * Parse string and get all EL from it.
+ * For example: string is '#{var1.pr != var2.pr} #{f1.pr1}'
+ * then tokens are ["#{var1.pr !=
var2.pr}","#{f1.pr1}"]
+ * @param sourceString
+ */
+ public SeamELStringTokenizer(String sourceString) {
+ this(sourceString, 0);
+ }
+
+ private SeamELStringTokenizer(String sourceString, int offset) {
+ this.offset = offset;
+ this.sourceString = sourceString;
+ index = 0;
+ fTokens = new ArrayList<ELStringToken>();
+ parse();
+ }
+
+ /**
+ * Returns list of tokens for the parsed string
+ *
+ * @return
+ */
+ public List<ELStringToken> getTokens() {
+ return fTokens;
+ }
+
+ /*
+ * Performs parsing of string
+ */
+ private void parse() {
+ ELStringToken token;
+ while ((token = getNextToken()) != ELStringToken.EOF) {
+ fTokens.add(token);
+ }
+ }
+
+ /*
+ * Calculates and returns next token of string
+ *
+ * @return
+ */
+ private ELStringToken getNextToken() {
+ int ch = readNextChar();
+ while(ch!=-1) {
+ int secondCh = readNextChar();
+ if (secondCh == -1) {
+ return ELStringToken.EOF;
+ }
+ releaseChar();
+
+ if(ch == START_EL_FIRST_SYMBOL && secondCh == START_EL_LAST_SYMBOL) {
+ releaseChar();
+ return readELToken();
+ }
+ ch = readNextChar();
+ }
+ return ELStringToken.EOF;
+ }
+
+ /*
+ * Returns the CharSequence object
+ *
+ * @param start
+ * @param length
+ * @return
+ */
+ private CharSequence getCharSequence(int start, int length) {
+ String text = ""; //$NON-NLS-1$
+ try {
+ text = sourceString.substring(start, start + length);
+ } catch (StringIndexOutOfBoundsException e) {
+ SeamCorePlugin.getDefault().logError(e);
+ }
+ return text.subSequence(0, text.length());
+ }
+ /*
+ * Reads and returns the string token from the expression
+ * @return
+ */
+ private ELStringToken readELToken() {
+ int startOfToken = index;
+ readNextChar();
+ readNextChar();
+ int ch;
+ while((ch = readNextChar()) != -1) {
+ if (ch==END_EL_SYMBOL) {
+ int length = index - startOfToken;
+ return new ELStringToken(offset + startOfToken, length, getCharSequence(startOfToken,
length));
+ }
+ }
+ return ELStringToken.EOF;
+ }
+
+ /* Reads the next character
+ * @return
+ */
+ private int readNextChar() {
+ int c = -1;
+ try {
+ if (index < sourceString.length()) {
+ c = sourceString.charAt(index);
+ }
+ } catch (StringIndexOutOfBoundsException e) {
+ SeamCorePlugin.getPluginLog().logError(e);
+ }
+ index++;
+ return c;
+ }
+
+ /*
+ * returns the character to the document
+ */
+ private void releaseChar() {
+ if (index > 0) {
+ index--;
+ }
+ }
+}
\ No newline at end of file
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELTokenizer.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELTokenizer.java 2008-01-15
20:13:04 UTC (rev 5729)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/el/SeamELTokenizer.java 2008-01-15
20:25:42 UTC (rev 5730)
@@ -16,8 +16,7 @@
import org.jboss.tools.seam.core.SeamCorePlugin;
/**
- * EL string parser.
- * Creates list of tokens for the operands and operators
+ * Parses EL and creates list of tokens for the operands and operators within one EL.
* @author Alexey Kazakov
*/
public class SeamELTokenizer {
@@ -44,10 +43,9 @@
/**
* Constructs SeamELTokenizer object.
- * Constructs SeamELTokenizer object
* Parse an expression.
* For example: expression is '#{var1.pr != var2.pr}'
- * then tokens are {"var1.pr"," ", "!=",
" ", "var2",}
+ * then tokens are ["var1.pr"," ", "!=",
" ", "var2.pr"]
* @param expression
*/
public SeamELTokenizer(String expression) {
@@ -63,7 +61,7 @@
}
/**
- * Returns list of tokens for the expression parsed
+ * Returns list of tokens for the parsed expression
*
* @return
*/
Modified:
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamELValidator.java
===================================================================
---
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamELValidator.java 2008-01-15
20:13:04 UTC (rev 5729)
+++
trunk/seam/plugins/org.jboss.tools.seam.core/src/org/jboss/tools/seam/internal/core/validation/SeamELValidator.java 2008-01-15
20:25:42 UTC (rev 5730)
@@ -11,7 +11,6 @@
package org.jboss.tools.seam.internal.core.validation;
import java.io.IOException;
-import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -46,8 +45,10 @@
import org.jboss.tools.seam.core.SeamCorePlugin;
import org.jboss.tools.seam.core.SeamPreferences;
import org.jboss.tools.seam.internal.core.el.ELOperandToken;
+import org.jboss.tools.seam.internal.core.el.ELStringToken;
import org.jboss.tools.seam.internal.core.el.ELToken;
import org.jboss.tools.seam.internal.core.el.SeamELCompletionEngine;
+import org.jboss.tools.seam.internal.core.el.SeamELStringTokenizer;
import org.jboss.tools.seam.internal.core.el.SeamELTokenizer;
import org.jboss.tools.seam.internal.core.el.TypeInfoCollector;
@@ -217,41 +218,27 @@
* @param length - length of string in file
*/
private void validateString(IFile file, String string, int offset) {
- Set<EL> els = new HashSet<EL>();
- String localString = string;
- while(!reporter.isCancelled()) {
- int startEl = localString.indexOf("#{"); //$NON-NLS-1$
- int endEl = -1;
-// if(startEl==-1) {
-// startEl = localString.indexOf("${");
-// }
- if(startEl>-1) {
- endEl = localString.lastIndexOf('}');
- if(endEl>-1) {
- String value = localString.substring(startEl+2, endEl);
- int os = offset + startEl + 2;
- int ln = value.length();
- els.add(new EL(value, ln, os));
- localString = localString.substring(endEl);
- offset = offset + endEl;
- continue;
+ int startEl = string.indexOf("#{"); //$NON-NLS-1$
+ if(startEl>-1) {
+ SeamELStringTokenizer st = new SeamELStringTokenizer(string);
+ List<ELStringToken> tokens = st.getTokens();
+ for (ELStringToken stringToken : tokens) {
+ if(reporter.isCancelled()) {
+ return;
}
+ stringToken.setStart(offset + stringToken.getStart() + 2);
+ validateEl(file, stringToken);
}
- break;
}
-
- for(EL el: els) {
- validateEl(file, el);
- }
}
- private void validateEl(IFile file, EL el) {
- String exp = el.value;
+ private void validateEl(IFile file, ELStringToken el) {
+ String exp = el.getBody();
SeamELTokenizer elTokenizer = new SeamELTokenizer(exp);
List<ELToken> tokens = elTokenizer.getTokens();
for (ELToken token : tokens) {
if(token.getType()==ELToken.EL_VARIABLE_TOKEN) {
- validateElOperand(file, token, el.getOffset());
+ validateElOperand(file, token, el.getStart());
}
}
}
@@ -329,40 +316,4 @@
addError(UNKNOWN_EL_VARIABLE_PROPERTY_NAME_MESSAGE_ID,
SeamPreferences.UNKNOWN_EL_VARIABLE_PROPERTY_NAME, new String[]{varName}, lengthOfVarName,
offsetOfVarName, file);
}
}
-
- public static class EL {
- private String value;
- private int length;
- private int offset;
-
- public EL(String value, int length, int offset) {
- this.value = value;
- this.length = length;
- this.offset = offset;
- }
-
- public String getValue() {
- return value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- public int getLength() {
- return length;
- }
-
- public void setLength(int length) {
- this.length = length;
- }
-
- public int getOffset() {
- return offset;
- }
-
- public void setOffset(int offset) {
- this.offset = offset;
- }
- }
}
\ No newline at end of file
Added:
trunk/seam/tests/org.jboss.tools.seam.core.test/projects/SeamWebWarTestProject/WebContent/JBIDE-1631.xhtml
===================================================================
---
trunk/seam/tests/org.jboss.tools.seam.core.test/projects/SeamWebWarTestProject/WebContent/JBIDE-1631.xhtml
(rev 0)
+++
trunk/seam/tests/org.jboss.tools.seam.core.test/projects/SeamWebWarTestProject/WebContent/JBIDE-1631.xhtml 2008-01-15
20:25:42 UTC (rev 5730)
@@ -0,0 +1,32 @@
+<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
+
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<ui:composition
xmlns="http://www.w3.org/1999/xhtml"
+
xmlns:s="http://jboss.com/products/seam/taglib"
+
xmlns:ui="http://java.sun.com/jsf/facelets"
+
xmlns:f="http://java.sun.com/jsf/core"
+
xmlns:h="http://java.sun.com/jsf/html"
+
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
+ template="layout/template.xhtml">
+
+<ui:define name="body">
+
+ <h:messages globalOnly="true" styleClass="message"/>
+
+ <rich:panel>
+ #{authenticator.foo1} #{authenticator.foo2}
+ <f:facet name="header">Welcome!</f:facet>
+ <p>This empty shell application includes:</p>
+ <ul>
+ <li>Ant build script</li>
+ <li>Deployment to JBoss AS</li>
+ <li>Integration testing using TestNG and JBoss Embeddable EJB3</li>
+ <li>EJB 3.0 Seam components</li>
+ <li>Templated Facelets views</li>
+ <li>HSQL (or MySQL) Datasource</li>
+ <li>Default CSS stylesheet</li>
+ <li>Internationalization support</li>
+ </ul>
+ </rich:panel>
+
+</ui:define>
+</ui:composition>
\ No newline at end of file
Modified:
trunk/seam/tests/org.jboss.tools.seam.core.test/src/org/jboss/tools/seam/core/test/SeamValidatorsTest.java
===================================================================
---
trunk/seam/tests/org.jboss.tools.seam.core.test/src/org/jboss/tools/seam/core/test/SeamValidatorsTest.java 2008-01-15
20:13:04 UTC (rev 5729)
+++
trunk/seam/tests/org.jboss.tools.seam.core.test/src/org/jboss/tools/seam/core/test/SeamValidatorsTest.java 2008-01-15
20:25:42 UTC (rev 5730)
@@ -824,22 +824,29 @@
JUnitUtils.fail("Error in changing 'abcComponent.java' content to "
+
"'abcComponent.3'", ex);
}
-
+
refreshProject(project);
-
+
number = getMarkersNumber(abcComponentXHTMLFile);
assertFalse("Problem marker 'Unpaired Getter/Setter' not found' not
found' not found' not found", number == 0);
messages = getMarkersMessage(abcComponentXHTMLFile);
assertTrue("Problem marker 'Unpaired Getter/Setter' not found",
"Property \"actionType\" has only Getter. Setter is
missing.".equals(messages[0]));
-
+
lineNumbers = getMarkersNumbersOfLine(abcComponentXHTMLFile);
-
+
assertTrue("Problem marker has wrong line number", lineNumbers[0] == 22);
+ // Test for
http://jira.jboss.com/jira/browse/JBIDE-1631
+ IFile jbide1631XHTMLFile = project.getFile("WebContent/JBIDE-1631.xhtml");
+ lineNumbers = getMarkersNumbersOfLine(jbide1631XHTMLFile);
+ String errorMessage = "Seam tools doesn't validate string with a few EL
properly. There should be two markers in string '#{authenticator.foo1}
#{authenticator.foo2}'.";
+ assertTrue(errorMessage, lineNumbers.length>1);
+ assertTrue(errorMessage, lineNumbers[0] == 16);
+ assertTrue(errorMessage, lineNumbers[1] == 16);
}
-
+
private void modifyPreferences(){
IPreferenceStore store = SeamCorePlugin.getDefault().getPreferenceStore();
store.putValue(SeamPreferences.UNKNOWN_EL_VARIABLE_NAME, SeamPreferences.ERROR);