summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNan Li2012-09-24 16:57:50 (EDT)
committer Brian Vosburgh2012-09-24 17:40:40 (EDT)
commit93ea11f7623b388b2c1149b7ff66b6e10fb57c1a (patch)
tree0a5fe57605bd3b564aed13855a7d5092e973fc9f
parent8741e266f5eb8aea773ae450fec7722772220423 (diff)
downloadwebtools.dali-93ea11f7623b388b2c1149b7ff66b6e10fb57c1a.zip
webtools.dali-93ea11f7623b388b2c1149b7ff66b6e10fb57c1a.tar.gz
webtools.dali-93ea11f7623b388b2c1149b7ff66b6e10fb57c1a.tar.bz2
[382644] XML code assist for database identifiers with special
characters
-rw-r--r--common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StringTools.java70
-rw-r--r--jpa/plugins/org.eclipse.jpt.jpa.ui/property_files/jpt_ui.properties2
-rw-r--r--jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JpaXmlCompletionProposalComputer.java104
-rw-r--r--jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JptUiMessages.java2
4 files changed, 143 insertions, 35 deletions
diff --git a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StringTools.java b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StringTools.java
index 6e27dbe..affdf30 100644
--- a/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StringTools.java
+++ b/common/plugins/org.eclipse.jpt.common.utility/src/org/eclipse/jpt/common/utility/internal/StringTools.java
@@ -36,7 +36,13 @@ public final class StringTools {
/** XML double quote */
public static final String XML_QUOTE = """; //$NON-NLS-1$
-
+
+ /** XML apostrophe */
+ public static final String XML_APOSTROPHE = "'";
+
+ /** XML ampersand */
+ public static final String XML_AMPERSAND = "&";
+
/** parenthesis */
public static final char OPEN_PARENTHESIS = '(';
public static final char CLOSE_PARENTHESIS = ')';
@@ -53,6 +59,10 @@ public final class StringTools {
public static final char OPEN_CHEVRON = '<';
public static final char CLOSE_CHEVRON = '>';
+ /** XML angle brackets */
+ public static final String XML_OPEN_CHEVRON= "&lt;";
+ public static final String XML_CLOSE_CHEVRON = "&gt;";
+
/** empty string */
public static final String EMPTY_STRING = ""; //$NON-NLS-1$
@@ -5140,32 +5150,76 @@ public final class StringTools {
// ********** convert to XML string literal **********
public static String convertToXmlStringLiteral(String string) {
+ return convertToXmlStringLiteralQuote(string);
+ }
+
+ public static String convertToXmlStringLiteralQuote(String string) {
+ return convertToXmlStringLiteral(string, '"');
+ }
+
+ public static String convertToXmlStringLiteralApostrophe(String string) {
+ return convertToXmlStringLiteral(string, '\'');
+ }
+
+ public static String convertToXmlStringLiteral(String string, char delimiter) {
int len = string.length();
if (len == 0) {
return EMPTY_JAVA_STRING_LITERAL;
}
StringBuilder sb = new StringBuilder(len + 5);
- convertToXmlStringLiteralOn_(string.toCharArray(), sb, len);
+ convertToXmlStringLiteralOn_(string.toCharArray(), sb, len, delimiter);
return sb.toString();
}
- //TODO need to add the rest of the predifende entities to this switch (amp, apos, lt, and gt)
- private static void convertToXmlStringLiteralOn_(char[] string, StringBuilder sb, int len) {
+ //TODO need to add the rest of the predifende entities to this switch (amp, lt, and gt)
+ private static void convertToXmlStringLiteralOn_(char[] string, StringBuilder sb, int len, char delimiter) {
sb.ensureCapacity(sb.length() + len + 5);
- sb.append(QUOTE);
+ sb.append(delimiter);
for (char c : string) {
switch (c) {
case '"': // double-quote
- sb.append(XML_QUOTE);
- break;
+ sb.append((delimiter == '"') ? XML_QUOTE : '"');
+ break;
+ case '\'': // apostrophe
+ sb.append((delimiter == '\'') ? XML_APOSTROPHE : '\'');
+ break;
default:
sb.append(c);
break;
}
}
- sb.append(QUOTE);
+ sb.append(delimiter);
}
+ public static String convertToXmlElementStringLiteral(String string) {
+ int len = string.length();
+ if (len == 0) {
+ return EMPTY_JAVA_STRING_LITERAL;
+ }
+ StringBuilder sb = new StringBuilder(len + 5);
+ convertToXmlElementStringLiteralOn_(string.toCharArray(), sb, len);
+ return sb.toString();
+ }
+
+ private static void convertToXmlElementStringLiteralOn_(char[] string, StringBuilder sb, int len) {
+ sb.ensureCapacity(sb.length() + len + 5);
+ for (char c : string) {
+ switch (c) {
+ case '&': // ampersand
+ sb.append(XML_AMPERSAND);
+ break;
+ case '<': // less-than sign
+ sb.append(XML_OPEN_CHEVRON);
+ break;
+ case '>': // greater-than sign
+ sb.append(XML_CLOSE_CHEVRON);
+ break;
+ default:
+ sb.append(c);
+ break;
+ }
+ }
+ }
// ********** convenience **********
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/property_files/jpt_ui.properties b/jpa/plugins/org.eclipse.jpt.jpa.ui/property_files/jpt_ui.properties
index 85e4283..fff5c3a 100644
--- a/jpa/plugins/org.eclipse.jpt.jpa.ui/property_files/jpt_ui.properties
+++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/property_files/jpt_ui.properties
@@ -206,3 +206,5 @@ SelectJpaProjectWizardPage_msg=Select a JPA project.
SynchronizingClasses_TaskName=Synchronizing classes...
SetJpaSelection_jobName=Setting JPA selection...
+
+JpaXmlCompletionProposalComputer_SpecialNameMsg=Special name will be written in the XML differently from what is shown in the proposal list for its legal usage.
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JpaXmlCompletionProposalComputer.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JpaXmlCompletionProposalComputer.java
index 64d9265..b107ac9 100644
--- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JpaXmlCompletionProposalComputer.java
+++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JpaXmlCompletionProposalComputer.java
@@ -29,13 +29,11 @@ import org.eclipse.jpt.jpa.core.JpaStructureNode;
import org.eclipse.jpt.jpa.core.context.XmlFile;
import org.eclipse.jpt.jpa.ui.internal.plugin.JptJpaUiPlugin;
import org.eclipse.wst.sse.ui.contentassist.CompletionProposalInvocationContext;
-import org.eclipse.wst.sse.ui.internal.contentassist.CustomCompletionProposal;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMDocument;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMElement;
import org.eclipse.wst.xml.core.internal.provisional.document.IDOMNode;
import org.eclipse.wst.xml.ui.internal.XMLUIMessages;
import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
-import org.eclipse.wst.xml.ui.internal.contentassist.XMLRelevanceConstants;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -50,21 +48,21 @@ public class JpaXmlCompletionProposalComputer extends DefaultJpaXmlCompletionPro
public JpaXmlCompletionProposalComputer() {
}
- @Override
- public List<ICompletionProposal> computeCompletionProposals(
- CompletionProposalInvocationContext context,
- IProgressMonitor monitor) {
- try {
- return super.computeCompletionProposals(context, monitor);
- } catch (RuntimeException ex) {
- // When we run into any unexpected exception, we will log the exception
- // and then return an empty list to prevent code completion process from
- // crashing. We need to determine if runtime exceptions should be
- // expected. If so, we could remove the log(ex) in the future.
- JptJpaUiPlugin.instance().logError(ex);
- return Collections.emptyList();
- }
+ @Override
+ public List<ICompletionProposal> computeCompletionProposals(
+ CompletionProposalInvocationContext context,
+ IProgressMonitor monitor) {
+ try {
+ return super.computeCompletionProposals(context, monitor);
+ } catch (RuntimeException ex) {
+ // When we run into any unexpected exception, we will log the exception
+ // and then return an empty list to prevent code completion process from
+ // crashing. We need to determine if runtime exceptions should be
+ // expected. If so, we could remove the log(ex) in the future.
+ JptJpaUiPlugin.instance().logError(ex);
+ return Collections.emptyList();
}
+ }
@Override
protected void addAttributeValueProposals(ContentAssistRequest contentAssistRequest,
@@ -77,17 +75,53 @@ public class JpaXmlCompletionProposalComputer extends DefaultJpaXmlCompletionPro
if (matchString == null) {
matchString = ""; //$NON-NLS-1$
}
+
+ // initialize newMatchingString to an empty string to handle the case when user invokes code assist without giving delimiter
+ String newMatchString = "";
if ((matchString.length() > 0) && (matchString.startsWith("\"") || matchString.startsWith("'"))) { //$NON-NLS-1$ //$NON-NLS-2$
- matchString = matchString.substring(1);
+ newMatchString = matchString.substring(1);
}
- //create suggestions for this attribute value declaration
+ //create completion proposals for this attribute value declaration
int rOffset = contentAssistRequest.getReplacementBeginPosition();
int rLength = contentAssistRequest.getReplacementLength();
for (String possibleValue : proposedValues) {
- if ((matchString.length() == 0) || StringTools.stringStartsWithIgnoreCase(possibleValue, matchString)) {
- String rString = "\"" + possibleValue + "\""; //$NON-NLS-1$ //$NON-NLS-2$
- CompletionProposal proposal = new CompletionProposal(
- rString, rOffset, rLength, rString.length());
+ if ((newMatchString.length() == 0) || StringTools.stringStartsWithIgnoreCase(possibleValue, newMatchString)) {
+
+ // handle values that include special characters like double-quote or apostrophe
+ String convertedPossibleValue = null;
+ if (matchString.startsWith("\"")) {
+ convertedPossibleValue = StringTools.convertToXmlStringLiteralQuote(possibleValue);
+ } else if (matchString.startsWith("'")) {
+ convertedPossibleValue = StringTools.convertToXmlStringLiteralApostrophe(possibleValue);
+ } else {
+ // convert to XML string literal with quotes by default
+ convertedPossibleValue = StringTools.convertToXmlStringLiteralQuote(possibleValue);
+ }
+
+ CompletionProposal proposal = null;
+ // give users an additional message if value includes special characters since what is written
+ // to XML is most likely different from what is shown in the proposal list with this case
+ if (possibleValue.startsWith("\"")) {
+ // handle the case when user does ""<invoke code assist here>" trying to get these special values
+ // User cannot do ""F<invoke code assist here>" or ""F<invoke code assist here>"" trying to
+ // get these values that are special and start with F because XML would regard the F as the
+ // start of another attribute since there are two double-quotes exist before F.
+ if (matchString.startsWith("\"") && newMatchString.startsWith("\"")) {
+ proposal = new CompletionProposal(
+ convertedPossibleValue, rOffset, rLength + 1, convertedPossibleValue.length(), null,
+ possibleValue, null, JptUiMessages.JpaXmlCompletionProposalComputer_SpecialNameMsg);
+ } else {
+ proposal = new CompletionProposal(
+ convertedPossibleValue, rOffset, rLength, convertedPossibleValue.length(), null,
+ possibleValue, null, JptUiMessages.JpaXmlCompletionProposalComputer_SpecialNameMsg);
+ }
+ } else {
+ // do not give the addition message with normal values
+ proposal = new CompletionProposal(
+ convertedPossibleValue, rOffset, rLength, convertedPossibleValue.length(), null,
+ possibleValue, null, null );
+ }
+
contentAssistRequest.addProposal(proposal);
}
}
@@ -141,11 +175,27 @@ public class JpaXmlCompletionProposalComputer extends DefaultJpaXmlCompletionPro
}
for (String possibleValue : proposedValues) {
+
+ String convertedPossibleValue = null;
if ((matchString.length() == 0) || StringTools.stringStartsWithIgnoreCase(possibleValue, matchString)) {
- CustomCompletionProposal proposal = new CustomCompletionProposal(
- possibleValue, begin, length, possibleValue.length(),
- JptJpaUiPlugin.instance().getImage(JptUiIcons.JPA_CONTENT),
- possibleValue, null, null, XMLRelevanceConstants.R_TAG_INSERTION);
+ if (possibleValue.startsWith("\"")) {
+ convertedPossibleValue = StringTools.convertToXmlElementStringLiteral(possibleValue);
+ } else {
+ convertedPossibleValue = possibleValue;
+ }
+
+ CompletionProposal proposal = null;
+ if (possibleValue.startsWith("\"")) {
+ proposal = new CompletionProposal(
+ convertedPossibleValue, begin, length, convertedPossibleValue.length(),
+ JptJpaUiPlugin.instance().getImage(JptUiIcons.JPA_CONTENT), possibleValue, null,
+ JptUiMessages.JpaXmlCompletionProposalComputer_SpecialNameMsg);
+ } else {
+ proposal = new CompletionProposal(
+ convertedPossibleValue, begin, length, convertedPossibleValue.length(),
+ JptJpaUiPlugin.instance().getImage(JptUiIcons.JPA_CONTENT), possibleValue, null, null);
+ }
+
contentAssistRequest.addProposal(proposal);
}
}
@@ -154,7 +204,7 @@ public class JpaXmlCompletionProposalComputer extends DefaultJpaXmlCompletionPro
setErrorMessage(XMLUIMessages.Content_Assist_not_availab_UI_);
}
}
-
+
/**
* Retrieves all of the possible valid values for this attribute/element declaration
*/
diff --git a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JptUiMessages.java b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JptUiMessages.java
index eb4c5ef..521c432 100644
--- a/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JptUiMessages.java
+++ b/jpa/plugins/org.eclipse.jpt.jpa.ui/src/org/eclipse/jpt/jpa/ui/internal/JptUiMessages.java
@@ -193,6 +193,8 @@ public class JptUiMessages {
public static String JavaQueryConversionWizardPage_description;
public static String SetJpaSelection_jobName;
+
+ public static String JpaXmlCompletionProposalComputer_SpecialNameMsg;
private JptUiMessages() {
throw new UnsupportedOperationException();