001: /*
002: * The contents of this file are subject to the terms of the Common Development
003: * and Distribution License (the License). You may not use this file except in
004: * compliance with the License.
005: *
006: * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
007: * or http://www.netbeans.org/cddl.txt.
008: *
009: * When distributing Covered Code, include this CDDL Header Notice in each file
010: * and include the License file at http://www.netbeans.org/cddl.txt.
011: * If applicable, add the following below the CDDL Header, with the fields
012: * enclosed by brackets [] replaced by your own identifying information:
013: * "Portions Copyrighted [year] [name of copyright owner]"
014: *
015: * The Original Software is NetBeans. The Initial Developer of the Original
016: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
017: * Microsystems, Inc. All Rights Reserved.
018: */
019:
020: package org.netbeans.modules.xslt.mapper.methoid;
021:
022: import java.awt.Component;
023: import java.awt.Window;
024: import javax.swing.JOptionPane;
025:
026: import org.netbeans.modules.xml.xpath.XPathStringLiteral;
027: import org.openide.util.NbBundle;
028: import org.openide.windows.WindowManager;
029:
030: import java.util.ArrayList;
031: import java.util.List;
032: import org.netbeans.modules.soa.mapper.common.basicmapper.IBasicMapper;
033: import org.netbeans.modules.soa.mapper.common.basicmapper.literal.BasicLiteralEditorFactory;
034: import org.netbeans.modules.soa.mapper.common.basicmapper.literal.ILiteralEditor;
035: import org.netbeans.modules.soa.mapper.common.basicmapper.methoid.IFieldNode;
036: import org.netbeans.modules.xslt.mapper.model.nodes.CanvasNode;
037:
038: import org.netbeans.modules.xslt.mapper.model.nodes.LiteralCanvasNode;
039:
040: /**
041: * Updates the xpath expression for string literals.
042: *
043: * @author jsandusky
044: */
045: public class StringLiteralUpdater extends AbstractLiteralUpdater {
046:
047: public ILiteralEditor getEditor(IBasicMapper basicMapper,
048: IFieldNode field) {
049: // Check if the field represents a duration.
050: String literalName = field.getLiteralName();
051: String name = field.getName();
052: List<String> names = new ArrayList<String>();
053: if (literalName != null) {
054: if (!names.contains(literalName)) {
055: names.add(literalName);
056: }
057: }
058: if (name != null) {
059: if (!names.contains(name)) {
060: names.add(name);
061: }
062: }
063: // TODO reimplement
064: // for (String value: names) {
065: // try {
066: // Duration duration = Duration.parse(value);
067: // return new DurationLiteralEditor(getWindowOwner(basicMapper),
068: // basicMapper, field, this);
069: // } catch (Throwable t) {
070: // // value does not represent a XML Schema duration, continue.
071: // }
072: // }
073: return BasicLiteralEditorFactory.createBasicStringEditor(
074: basicMapper, field, this );
075: }
076:
077: private static Window getWindowOwner(IBasicMapper basicMapper) {
078: Window window = null;
079: Component parent = basicMapper.getMapperViewManager()
080: .getCanvasView().getCanvas().getUIComponent();
081: while (parent != null && !(parent instanceof Window)) {
082: parent = parent.getParent();
083: }
084: if (parent == null) {
085: parent = WindowManager.getDefault().getMainWindow();
086: }
087: return (Window) parent;
088: }
089:
090: public String getLiteralDisplayText(String literalText) {
091: return getQuotedString(literalText).string;
092: }
093:
094: public String literalSet(IFieldNode fieldNode, String newValue) {
095: if (!isValidStringLiteral(newValue)) {
096: String title = NbBundle.getMessage(
097: StringLiteralUpdater.class,
098: "STR_INVALID_STRING_LITERAL_TITLE"); // NOI18N
099: String msg = NbBundle.getMessage(
100: StringLiteralUpdater.class,
101: "STR_INVALID_STRING_LITERAL_MSG", newValue); // NOI18N
102: JOptionPane.showMessageDialog(WindowManager.getDefault()
103: .getMainWindow(), msg, title,
104: JOptionPane.ERROR_MESSAGE);
105: return null;
106: }
107: // TODO reimplement
108: // XPathLiteralNodeImpl literalNode = (XPathLiteralNodeImpl) fieldNode.getNodeObject();
109: // if (literalNode == null) {
110: // XPathStringLiteral stringLiteral = AbstractXPathModelHelper.getInstance().newXPathStringLiteral(newValue);
111: // literalNode = new XPathLiteralNodeImpl(stringLiteral);
112: // } else {
113: // XPathStringLiteral stringLiteral = (XPathStringLiteral) literalNode.getLiteral();
114: // stringLiteral.setValue(newValue);
115: // }
116: // super.applyLiteral(fieldNode, newValue, literalNode);
117:
118: CanvasNode canvasNode = (CanvasNode) fieldNode.getGroupNode()
119: .getNodeObject();
120: if (canvasNode != null
121: && canvasNode instanceof LiteralCanvasNode) {
122: XPathStringLiteral literal = (XPathStringLiteral) canvasNode
123: .getDataObject();
124: literal.setValue(newValue);
125: }
126: mProcessor.updateNodeExpression(fieldNode);
127:
128: return newValue;
129: }
130:
131: private boolean isValidStringLiteral(String literal) {
132: // by this point, string is quoted
133: // now we validate that the string follows xpath 1.0 spec
134: // - josh
135: QuotedString quotedString = getQuotedString(literal);
136: return quotedString.quote.isQuotingValid(quotedString.string);
137:
138: }
139:
140: private QuotedString getQuotedString(String literal) {
141: QuoteType quoteType = QuoteType.getQuoteType(literal);
142: if (quoteType == QuoteType.UNQUOTED) {
143: if (literal.indexOf(QuoteType.SINGLE.quote) >= 0) {
144: // string contains a single-quote,
145: // it must be quoted with double-quotes
146: literal = QuoteType.DOUBLE.quote + literal
147: + QuoteType.DOUBLE.quote;
148: quoteType = QuoteType.DOUBLE;
149: } else {
150: // by default, single-quote the string
151: literal = QuoteType.SINGLE.quote + literal
152: + QuoteType.SINGLE.quote;
153: quoteType = QuoteType.SINGLE;
154: }
155: }
156: return new QuotedString(literal, quoteType);
157: }
158:
159: private static final class QuotedString {
160: public final String string;
161: public final QuoteType quote;
162:
163: public QuotedString(String quotedString, QuoteType quoteType) {
164: string = quotedString;
165: quote = quoteType;
166: }
167: }
168:
169: private static final class QuoteType {
170: private static final QuoteType SINGLE = new QuoteType("'"); // NOI18N
171: private static final QuoteType DOUBLE = new QuoteType("\""); // NOI18N
172: private static final QuoteType UNQUOTED = new QuoteType();
173: public final String quote;
174:
175: private QuoteType(String quoteString) {
176: quote = quoteString;
177: }
178:
179: private QuoteType() {
180: quote = null;
181: }
182:
183: public boolean isStringQuoted(String literal) {
184: if (quote == null) {
185: return false;
186: }
187: if (literal.length() >= 2) {
188: if (literal.startsWith(quote)
189: && literal.endsWith(quote)) {
190: return true;
191: }
192: }
193: return false;
194: }
195:
196: public boolean isQuotingValid(String literal) {
197: if (quote == null) {
198: return false;
199: }
200: // ensure that we have only our beginning quote and end quote
201: // any more than that and our number of sections will be greater than 3
202: // any less than that and our number of sections will be less than 3
203: String[] quoteSections = literal.split(quote, 4);
204: return quoteSections.length == 3;
205: }
206:
207: public static QuoteType getQuoteType(String literal) {
208: QuoteType quoteType = UNQUOTED;
209: // if string is already quoted, mark as such
210: if (SINGLE.isStringQuoted(literal)) {
211: quoteType = SINGLE;
212: } else if (DOUBLE.isStringQuoted(literal)) {
213: quoteType = DOUBLE;
214: }
215: return quoteType;
216: }
217: }
218: }
|