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: package org.netbeans.modules.xml.tools.doclet;
042:
043: import java.util.*;
044: import java.awt.datatransfer.StringSelection;
045: import java.io.*;
046:
047: import javax.swing.text.*;
048:
049: import org.openide.*;
050: import org.openide.awt.StatusDisplayer;
051: import org.openide.nodes.*;
052: import org.openide.cookies.*;
053: import org.openide.loaders.*;
054: import org.openide.filesystems.*;
055: import org.openide.util.*;
056: import org.openide.util.datatransfer.ExClipboard;
057: import org.openide.util.actions.*;
058:
059: import org.netbeans.tax.*;
060: import org.netbeans.modules.xml.*;
061: import org.netbeans.modules.xml.actions.CollectDTDAction;
062: import org.netbeans.modules.xml.tools.generator.*;
063: import org.netbeans.modules.xml.tax.cookies.TreeEditorCookie;
064:
065: /**
066: * Creates a documentation upon a standalone DTD. Stores it into html.
067: * It does work only with standalone DTD (it is feature).
068: *
069: * @author Petr Kuzel
070: * @version 1.0
071: */
072: public final class DocletAction extends CookieAction implements
073: CollectDTDAction.DTDAction {
074:
075: /** Stream serialVersionUID. */
076: private static final long serialVersionUID = -4037098165368211623L;
077:
078: /** Creates new CSSStyleAction */
079: public DocletAction() {
080: }
081:
082: public Class[] cookieClasses() {
083: return new Class[] { DTDDataObject.class };
084: }
085:
086: public int mode() {
087: return MODE_ONE;
088: }
089:
090: public void performAction(Node[] nodes) {
091:
092: if (nodes == null)
093: return;
094: if (nodes.length != 1)
095: return;
096:
097: final StringBuffer text = new StringBuffer();
098: final Node dtd = nodes[0];
099:
100: final DTDDataObject dtdo = (DTDDataObject) dtd
101: .getCookie(DTDDataObject.class);
102:
103: Thread thread = null;
104: ErrorManager emgr = ErrorManager.getDefault();
105:
106: try {
107:
108: TreeDocumentRoot result;
109:
110: TreeEditorCookie cake = (TreeEditorCookie) dtdo
111: .getCookie(TreeEditorCookie.class);
112: if (cake != null) {
113: result = cake.openDocumentRoot();
114: } else {
115: throw new TreeException("DTDDataObject:INTERNAL ERROR"); // NOI18N
116: }
117: final TreeDTD treeDTD = (TreeDTD) result;
118:
119: final DTDDoclet doclet = new DTDDoclet();
120:
121: Runnable task = new Runnable() {
122: public void run() {
123: text.append(doclet.createDoclet(treeDTD));
124: }
125: };
126:
127: //start task in paralel with user input
128:
129: thread = new Thread(task, "Creating XML doc..."); // NOI18N
130: thread.setPriority(Thread.MIN_PRIORITY);
131: thread.setDaemon(true);
132: thread.start();
133:
134: try {
135:
136: // ask for file object location
137:
138: FileObject primFile = dtdo.getPrimaryFile();
139: String name = primFile.getName()
140: + NbBundle.getMessage(DocletAction.class,
141: "NAME_SUFFIX_Documentation");
142: FileObject folder = primFile.getParent();
143:
144: FileObject generFile = (new SelectFileDialog(folder,
145: name, "html")).getFileObject(); // NOI18N
146: name = generFile.getName();
147:
148: // wait until documentation generated
149: thread.join();
150:
151: // fill result file
152:
153: FileLock lock = null;
154: try {
155: lock = generFile.lock();
156: OutputStream fout = generFile.getOutputStream(lock);
157: try {
158: OutputStream out = new BufferedOutputStream(
159: fout);
160: Writer writer = new OutputStreamWriter(out,
161: "UTF8"); //NOI18N
162: writer.write(text.toString());
163: writer.flush();
164: } finally {
165: if (fout != null)
166: fout.close();
167: }
168:
169: } catch (IOException ex) {
170: emgr.annotate(ex, NbBundle.getMessage(
171: DocletAction.class,
172: "MSG_error_leaving_in_clipboard"));
173: emgr.notify(ex);
174:
175: leaveInClipboard(text.toString());
176: return;
177:
178: } finally {
179: if (lock != null) {
180: lock.releaseLock();
181: }
182: }
183:
184: // open results in a browser if exists
185:
186: try {
187: DataObject html = DataObject.find(generFile);
188:
189: ViewCookie vc = (ViewCookie) html
190: .getCookie(ViewCookie.class);
191: if (vc != null)
192: vc.view();
193: } catch (DataObjectNotFoundException dex) {
194: // just do not show
195: }
196:
197: } catch (UserCancelException ex) {
198: //user cancelled do nothing
199:
200: } catch (InterruptedException ex) {
201:
202: emgr.annotate(ex, NbBundle.getMessage(
203: DocletAction.class,
204: "MSG_generating_interrupted"));
205: emgr.notify(ex);
206: }
207:
208: } catch (IOException ioex) {
209:
210: emgr.annotate(ioex, NbBundle.getMessage(DocletAction.class,
211: "MSG_IO_ex_docwriting"));
212: emgr.notify(ioex);
213:
214: } catch (TreeException tex) {
215:
216: StatusDisplayer.getDefault().setStatusText(
217: NbBundle.getMessage(DocletAction.class,
218: "MSG_doclet_fatal_error"));
219:
220: } finally {
221: if (thread != null)
222: thread.interrupt();
223: }
224:
225: }
226:
227: private void leaveInClipboard(String text) {
228: StringSelection ss = new StringSelection(text);
229: ExClipboard clipboard = (ExClipboard) Lookup.getDefault()
230: .lookup(ExClipboard.class);
231: clipboard.setContents(ss, null);
232: StatusDisplayer.getDefault().setStatusText(
233: NbBundle.getMessage(DocletAction.class,
234: "MSG_documentation_in_clipboard"));
235: }
236:
237: public HelpCtx getHelpCtx() {
238: return new HelpCtx(getClass());
239: }
240:
241: public String getName() {
242: return NbBundle.getMessage(DocletAction.class,
243: "NAME_Generate_Documentation");
244: }
245:
246: protected boolean asynchronous() {
247: return false;
248: }
249:
250: }
|