001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package org.netbeans.modules.web.jsf.editor;
043:
044: import java.io.IOException;
045: import java.io.StringWriter;
046: import javax.swing.JEditorPane;
047: import javax.swing.text.BadLocationException;
048: import org.netbeans.editor.BaseDocument;
049: import org.netbeans.editor.TokenItem;
050: import org.netbeans.editor.ext.ExtSyntaxSupport;
051: import org.netbeans.modules.schema2beans.BaseBean;
052: import org.openide.cookies.EditorCookie;
053: import org.openide.loaders.DataObject;
054: import org.openide.nodes.Node;
055: import org.openide.text.CloneableEditorSupport;
056: import org.openide.util.Exceptions;
057: import org.openide.util.Task;
058:
059: /**
060: *
061: * @author Petr Pisl
062: */
063:
064: public class JSFEditorUtilities {
065:
066: /** The constant from XML editor
067: */
068: // The constant are taken from class org.netbeans.modules.xml.text.syntax.XMLTokenIDs
069: protected final static int XML_ELEMENT = 4;
070: protected final static int XML_TEXT = 1;
071: public final static String END_LINE = System
072: .getProperty("line.separator"); //NOI18N
073:
074: /** Returns the value of from-view-id element of navigation rule definition on the offset possition.
075: * If there is not the navigation rule definition on the offset, then returns null.
076: */
077: public static String getNavigationRule(BaseDocument doc, int offset) {
078: try {
079: ExtSyntaxSupport sup = (ExtSyntaxSupport) doc
080: .getSyntaxSupport();
081: TokenItem token = sup.getTokenChain(offset, offset + 1);
082: // find the srart of the navigation rule definition
083: while (token != null
084: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && (token
085: .getImage().equals("<navigation-rule") || token
086: .getImage().equals("<managed-bean"))))
087: token = token.getPrevious();
088: if (token != null
089: && token.getImage().equals("<navigation-rule")) {
090: // find the from-view-ide element
091: while (token != null
092: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && (token
093: .getImage().equals("</navigation-rule") || token
094: .getImage().equals("<from-view-id"))))
095: token = token.getNext();
096: if (token != null
097: && token.getImage().equals("<from-view-id")) {
098: token = token.getNext();
099: while (token != null
100: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
101: .getImage().equals(">")))
102: token = token.getNext();
103: while (token != null
104: && token.getTokenID().getNumericID() != JSFEditorUtilities.XML_TEXT
105: && token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT)
106: token = token.getNext();
107: if (token != null
108: && token.getTokenID().getNumericID() == JSFEditorUtilities.XML_TEXT)
109: return token.getImage().trim();
110: }
111: }
112: } catch (BadLocationException e) {
113: Exceptions.printStackTrace(e);
114: }
115: return null;
116: }
117:
118: public static int[] getNavigationRuleDefinition(BaseDocument doc,
119: String ruleName) {
120: try {
121: String text = doc.getText(0, doc.getLength());
122: //find first possition of text that is the ruleName
123: int offset = text.indexOf(ruleName);
124: int start = 0;
125: int end = 0;
126: ExtSyntaxSupport sup = (ExtSyntaxSupport) doc
127: .getSyntaxSupport();
128: TokenItem token;
129:
130: while (offset != -1) {
131: token = sup.getTokenChain(offset, offset + 1);
132: if (token != null
133: && token.getTokenID().getNumericID() == JSFEditorUtilities.XML_TEXT) {
134: // find first xml element before the ruleName
135: while (token != null
136: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && !token
137: .getImage().equals(">")))
138: token = token.getPrevious();
139: // is it the rule definition?
140: if (token != null
141: && token.getImage().equals("<from-view-id")) {
142: // find start of the rule definition
143: while (token != null
144: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
145: .getImage().equals(
146: "<navigation-rule")))
147: token = token.getPrevious();
148: if (token != null
149: && token.getImage().equals(
150: "<navigation-rule")) {
151: start = token.getOffset();
152: token = sup.getTokenChain(offset,
153: offset + 1);
154: // find the end of the rule definition
155: while (token != null
156: && !(token.getTokenID()
157: .getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
158: .getImage()
159: .equals("</navigation-rule")))
160: token = token.getNext();
161: if (token != null
162: && token.getImage().equals(
163: "</navigation-rule")) {
164: while (token != null
165: && !(token.getTokenID()
166: .getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
167: .getImage().equals(">")))
168: token = token.getNext();
169: if (token != null
170: && token.getImage().equals(">")) {
171: end = token.getOffset() + 1;
172: return new int[] { start, end };
173: }
174: }
175: return new int[] { start, text.length() };
176: }
177: }
178: }
179: offset = text.indexOf(ruleName, offset
180: + ruleName.length());
181: }
182: } catch (BadLocationException e) {
183: Exceptions.printStackTrace(e);
184: }
185: return new int[] { -1, -1 };
186: }
187:
188: public static int[] getConverterDefinition(BaseDocument doc,
189: String byElement, String content) {
190: try {
191: String text = doc.getText(0, doc.getLength());
192: //find first possition of text that is the ruleName
193: int offset = text.indexOf(content);
194: int start = 0;
195: int end = 0;
196: ExtSyntaxSupport sup = (ExtSyntaxSupport) doc
197: .getSyntaxSupport();
198: TokenItem token;
199:
200: while (offset != -1) {
201: token = sup.getTokenChain(offset, offset + 1);
202: if (token != null
203: && token.getTokenID().getNumericID() == JSFEditorUtilities.XML_TEXT) {
204: // find first xml element before the ruleName
205: while (token != null
206: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && !token
207: .getImage().equals(">")))
208: token = token.getPrevious();
209: // is it the rule definition?
210: if (token != null
211: && token.getImage().equals("<" + byElement)) {
212: // find start of the rule definition
213: while (token != null
214: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
215: .getImage()
216: .equals("<converter")))
217: token = token.getPrevious();
218: if (token != null
219: && token.getImage()
220: .equals("<converter")) {
221: start = token.getOffset();
222: token = sup.getTokenChain(offset,
223: offset + 1);
224: // find the end of the rule definition
225: while (token != null
226: && !(token.getTokenID()
227: .getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
228: .getImage().equals(
229: "</converter")))
230: token = token.getNext();
231: if (token != null
232: && token.getImage().equals(
233: "</converter")) {
234: while (token != null
235: && !(token.getTokenID()
236: .getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
237: .getImage().equals(">")))
238: token = token.getNext();
239: if (token != null
240: && token.getImage().equals(">")) {
241: end = token.getOffset() + 1;
242: return new int[] { start, end };
243: }
244: }
245: return new int[] { start, text.length() };
246: }
247: }
248: }
249: offset = text.indexOf(content, offset
250: + content.length());
251: }
252:
253: } catch (BadLocationException e) {
254: Exceptions.printStackTrace(e);
255: }
256: return new int[] { -1, -1 };
257: }
258:
259: /** Writes new bean to the document directly under <faces-config> element
260: */
261: public static int writeBean(BaseDocument doc, BaseBean bean,
262: String element) throws IOException {
263: String sBean = addNewLines(bean);
264: int possition = -1;
265: ExtSyntaxSupport sup = (ExtSyntaxSupport) doc
266: .getSyntaxSupport();
267: TokenItem token;
268: try {
269: String docText = doc.getText(0, doc.getLength());
270: //Check whether there is root element
271: if (docText.indexOf("<faces-config") == -1) { //NOI18N
272: doc.insertString(doc.getLength(), "<faces-config>" //NOI18N
273: + END_LINE + "</faces-config>", null); //NOI18N
274: docText = doc.getText(0, doc.getLength());
275: }
276: String findString = "</" + element;
277:
278: //find index of last definition
279: int offset = docText.lastIndexOf(findString);
280: if (offset == -1)
281: offset = docText.length() - 2;
282: token = sup.getTokenChain(offset, offset + 1);
283: if (offset < (docText.length() - 2) && token != null
284: && token.getTokenID().getNumericID() == XML_ELEMENT) {
285: while (token != null
286: && !(token.getTokenID().getNumericID() == XML_ELEMENT && token
287: .getImage().equals(">")))
288: //NOI18N
289: token = token.getNext();
290: if (token != null)
291: possition = writeString(doc, sBean, token
292: .getOffset());
293: } else {
294: // write to end
295: if (token != null && token.getImage().equals(">")) //NOI18N
296: token = token.getPrevious();
297: while (token != null
298: && !(token.getTokenID().getNumericID() == XML_ELEMENT && token
299: .getImage().equals(">")))
300: //NOI18N
301: token = token.getPrevious();
302: if (token != null)
303: possition = writeString(doc, sBean, token
304: .getOffset());
305: }
306: } catch (BadLocationException ex) {
307: Exceptions.printStackTrace(ex);
308: }
309: return possition;
310: }
311:
312: private static String addNewLines(final BaseBean bean)
313: throws IOException {
314: StringWriter sWriter = new StringWriter();
315: bean.writeNode(sWriter);
316: String sBean = sWriter.toString();
317: sBean = sBean.replaceAll("><", ">" + END_LINE + "<"); //NOI18N
318: return sBean;
319: }
320:
321: private static int writeString(BaseDocument doc, String text,
322: int offset) {
323: int formatLength = 0;
324: try {
325: doc.atomicLock();
326: offset = doc.getFormatter().indentNewLine(doc, offset + 1);
327: doc.insertString(offset, text, null);
328: formatLength = doc.getFormatter().reformat(doc, offset,
329: offset + text.length() - 1);
330: } catch (BadLocationException ex) {
331: Exceptions.printStackTrace(ex);
332: } finally {
333: doc.atomicUnlock();
334: }
335: return offset + formatLength + 1;
336: }
337:
338: /* Returns offset, where starts the definition of the manage bean
339: **/
340: public static int[] getManagedBeanDefinition(BaseDocument doc,
341: String beanName) {
342: try {
343: String text = doc.getText(0, doc.getLength());
344: int offset = text.indexOf(beanName);
345: int start = 0;
346: int end = 0;
347: ExtSyntaxSupport sup = (ExtSyntaxSupport) doc
348: .getSyntaxSupport();
349: TokenItem token;
350:
351: while (offset != -1) {
352: token = sup.getTokenChain(offset, offset + 1);
353: if (token != null
354: && token.getTokenID().getNumericID() == JSFEditorUtilities.XML_TEXT) {
355: while (token != null
356: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && !token
357: .getImage().equals(">")))
358: token = token.getPrevious();
359: if (token != null
360: && token.getImage().equals(
361: "<managed-bean-name")) { //NOI18N
362: while (token != null
363: && !(token.getTokenID().getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
364: .getImage().equals(
365: "<managed-bean")))
366: token = token.getPrevious();
367: if (token != null
368: && token.getImage().equals(
369: "<managed-bean")) {
370: start = token.getOffset();
371: token = sup.getTokenChain(offset,
372: offset + 1);
373: while (token != null
374: && !(token.getTokenID()
375: .getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
376: .getImage().equals(
377: "</managed-bean")))
378: token = token.getNext();
379: if (token != null
380: && token.getImage().equals(
381: "</managed-bean")) {
382: while (token != null
383: && !(token.getTokenID()
384: .getNumericID() == JSFEditorUtilities.XML_ELEMENT && token
385: .getImage().equals(">")))
386: token = token.getNext();
387: if (token != null
388: && token.getImage().equals(">")) {
389: end = token.getOffset() + 1;
390: return new int[] { start, end };
391: }
392: }
393: return new int[] { start, text.length() };
394: }
395: }
396: }
397: offset = text.indexOf(beanName, offset
398: + beanName.length());
399: }
400: } catch (BadLocationException e) {
401: Exceptions.printStackTrace(e);
402: }
403: return new int[] { -1, -1 };
404: }
405:
406: /**
407: * Method that allows to find its
408: * CloneableEditorSupport from given DataObject
409: * @return the support or null if the CloneableEditorSupport
410: * was not found
411: * This method is hot fix for issue #53309
412: * this methd was copy/pasted from OpenSupport.Env class
413: * @param dob an instance of DataObject
414: */
415: public static CloneableEditorSupport findCloneableEditorSupport(
416: DataObject dob) {
417: Node.Cookie obj = dob
418: .getCookie(org.openide.cookies.OpenCookie.class);
419: if (obj instanceof CloneableEditorSupport) {
420: return (CloneableEditorSupport) obj;
421: }
422: obj = dob.getCookie(org.openide.cookies.EditorCookie.class);
423: if (obj instanceof CloneableEditorSupport) {
424: return (CloneableEditorSupport) obj;
425: }
426: return null;
427: }
428:
429: private static class CreateXMLPane implements Runnable {
430: JEditorPane ep;
431:
432: public void run() {
433: ep = new JEditorPane("text/xml", "");
434: }
435:
436: public JEditorPane getPane() {
437: return ep;
438: }
439: }
440:
441: /** This method returns a BaseDocument for the configuration file. If the configuration
442: * file is not opened, then the document is not created yet and this method push to load
443: * the document to the memory.
444: */
445: public static BaseDocument getBaseDocument(DataObject dataObject) {
446: BaseDocument document = null;
447:
448: if (dataObject != null) {
449: synchronized (dataObject) {
450: EditorCookie editor = dataObject.getLookup().lookup(
451: EditorCookie.class);
452: if (editor != null) {
453: document = (BaseDocument) editor.getDocument();
454: if (document == null) {
455: Task preparing = editor.prepareDocument();
456: preparing.waitFinished();
457: document = (BaseDocument) editor.getDocument();
458: }
459: }
460: }
461: }
462: return document;
463: }
464: }
|