KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > xsl > scenario > FileXSLScenario


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.xsl.scenario;
20
21 import java.beans.PropertyChangeEvent JavaDoc;
22 import java.beans.PropertyChangeListener JavaDoc;
23 import java.beans.PropertyChangeSupport JavaDoc;
24 import java.io.File JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.io.Serializable JavaDoc;
28 import java.net.MalformedURLException JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.util.Iterator JavaDoc;
31 import java.util.StringTokenizer JavaDoc;
32 import javax.xml.transform.Result JavaDoc;
33 import javax.xml.transform.Source JavaDoc;
34 import javax.xml.transform.TransformerException JavaDoc;
35 import javax.xml.transform.stream.StreamResult JavaDoc;
36 import org.netbeans.modules.xml.core.actions.InputOutputReporter;
37 import org.netbeans.modules.xml.core.lib.FileUtilities;
38 import org.netbeans.modules.xml.core.lib.GuiUtil;
39 import org.netbeans.modules.xsl.settings.TransformHistory;
40 import org.netbeans.modules.xsl.transform.TransformServlet;
41 import org.netbeans.modules.xsl.ui.TransformPanel;
42 import org.netbeans.modules.xsl.utils.TransformUtil;
43 import org.openide.ErrorManager;
44 import org.openide.awt.HtmlBrowser;
45 import org.openide.cookies.SaveCookie;
46 import org.openide.filesystems.FileAlreadyLockedException;
47 import org.openide.filesystems.FileLock;
48 import org.openide.filesystems.FileObject;
49 import org.openide.filesystems.FileStateInvalidException;
50 import org.openide.filesystems.FileUtil;
51 import org.openide.loaders.DataObject;
52 import org.openide.nodes.Node;
53 import org.openide.xml.XMLUtil;
54 import org.w3c.dom.Document JavaDoc;
55 import org.xml.sax.InputSource JavaDoc;
56 import org.xml.sax.SAXException JavaDoc;
57 import org.netbeans.modules.xml.api.scenario.Scenario;
58 import org.netbeans.modules.xsl.api.XSLScenario;
59
60 /**
61  * File implementation of an XSLScenario.
62  * This scenario implementation can be used to execute an XSL transformation
63  * using a filebased XML source. The results can be saved to file, or
64  * transformed using transformation servlet.
65  * After transforming, the results can be opened in a browser or by applying
66  * the default action of the result file.
67  *
68  * @author asgeir@dimonsoftware.com
69  */

70 public class FileXSLScenario implements Serializable JavaDoc, XSLScenario, PropertyChangeListener JavaDoc {
71     
72     /** The data used by this scenario */
73     protected Data data;
74     
75     /** The name of this scenario */
76     protected String JavaDoc name = "";
77     
78     /** Parsed input document */
79     private transient Document JavaDoc sourceDoc;
80     
81     /** Stores the last UI component returned by getUIComponent() */
82     private transient TransformPanel transPanel;
83     
84     /** Stores the last DataObject passed to getUIComponent() */
85     private transient DataObject lastDataObject;
86
87     /** Support for notifying listeners about PropertyChange */
88     private transient PropertyChangeSupport JavaDoc support;
89     
90     /** Creates a new instance of FileXSLScenario */
91     public FileXSLScenario() {
92         data = new Data();
93     }
94     
95     /**
96      * Executes the DataObject using this scenario.
97      * @param dataObject the DataObject to execute.
98      */

99     public void execute(DataObject dataObject) {
100         InputOutputReporter cookieObserver = new InputOutputReporter(Util.THIS.getString("PROP_transformation_io_name"));
101         try {
102             // Save the file
103
SaveCookie saveCookie = (SaveCookie)dataObject.getCookie(SaveCookie.class);
104             if (saveCookie != null) {
105                 try {
106                     saveCookie.save();
107                 } catch(IOException JavaDoc e) {
108                     cookieObserver.message("Could not save file: " + e.getMessage());
109                 }
110             }
111
112           
113             FileObject baseFO = dataObject.getPrimaryFile();
114             URL JavaDoc baseURL = preferFileURL(baseFO);
115             
116             Source JavaDoc xmlSource = TransformUtil.createSource(baseURL, data.getSourceXML()); // throws IOException, MalformedURLException, FileStateInvalidException, ParserConfigurationException, SAXException
117
if ( Util.THIS.isLoggable() ) Util.THIS.debug(" xmlSource = " + xmlSource.getSystemId());
118             
119             String JavaDoc xslName = TransformUtil.getURLName(baseFO);
120             Source JavaDoc xslSource = TransformUtil.createSource(baseURL, xslName); // throws IOException, MalformedURLException, FileStateInvalidException, ParserConfigurationException, SAXException
121
if ( Util.THIS.isLoggable() ) Util.THIS.debug(" xslSource = " + xslSource.getSystemId());
122             
123             if ( data.getOutput() == null ) { // Preview
124
TransformServlet.prepare(null, xmlSource, xslSource);
125                 showURL(TransformServlet.getServletURL());
126             } else {
127                 String JavaDoc fileName = data.getOutput().replace('\\', '/');
128                 FileObject resultFO = FileUtilities.createFileObject(baseFO.getParent(), fileName, data.isOverwrite()); // throws IOException
129

130                 if ( Util.THIS.isLoggable() ) Util.THIS.debug(" resultFO = " + resultFO);
131                 
132                 OutputStream JavaDoc outputStream = null;
133                 FileLock fileLock = null;
134                 try {
135                     fileLock = resultFO.lock();
136                     outputStream = resultFO.getOutputStream(fileLock);
137                     
138                     Result JavaDoc outputResult = new StreamResult JavaDoc(outputStream); // throws IOException, FileStateInvalidException
139

140                     if ( Util.THIS.isLoggable() ) {
141                         Util.THIS.debug(" resultFO = " + resultFO);
142                         Util.THIS.debug(" outputResult = " + outputResult);
143                     }
144                     
145                     String JavaDoc xmlName = data.getSourceXML();
146                     cookieObserver.message(Util.THIS.getString("MSG_transformation_1", xmlName, xslName));
147                     TransformUtil.transform(xmlSource, null, xslSource, outputResult, null); // throws TransformerException
148

149                     if ( data.getProcess() == TransformHistory.APPLY_DEFAULT_ACTION ) {
150                         GuiUtil.performDefaultAction(resultFO);
151                         GuiUtil.performDefaultAction(resultFO);
152                     } else if ( data.getProcess() == TransformHistory.OPEN_IN_BROWSER ) {
153                         showURL(resultFO.getURL());
154                     }
155                     
156                     GuiUtil.setStatusText(Util.THIS.getString("MSG_opening_browser"));
157                     
158                 } catch (FileAlreadyLockedException exc) {
159                     throw (FileAlreadyLockedException) ErrorManager.getDefault().annotate(exc, Util.THIS.getString("ERR_FileAlreadyLockedException_output"));
160                 } finally {
161                     if ( outputStream != null ) {
162                         outputStream.close();
163                     }
164                     if ( fileLock != null ) {
165                         fileLock.releaseLock();
166                     }
167                 }
168             }
169         } catch (TransformerException JavaDoc exc) { // during fileOutput();
170
// ignore it -> it should be displayed by CookieObserver!
171
} catch(Exception JavaDoc e) {
172             ErrorManager.getDefault().notify(ErrorManager.WARNING, e);
173         }
174         
175         cookieObserver.message(Util.THIS.getString("MSG_transformation_2"));
176         cookieObserver.moveToFront(true);
177         
178         sourceDoc = null;
179     }
180     
181     /**
182      * This method returns the a UI component which can be used to
183      * customize this scenario. To update changes done in the UI panel,
184      * the saveChanges() method can be called.
185      * A new or initialized instance of Component should be returned every
186      * time this method is called.
187      * @param dataObject The DataObject which owns this scenario
188      * @param activatePropertyChange a flag that determines if PropertyChangeEvents are fired
189      * @return A Component which can be used to customize this scenario
190      */

191     public java.awt.Component JavaDoc getCustomizer(DataObject dataObject, boolean activatePropertyChange) {
192         try {
193             transPanel = new TransformPanel(null, null, dataObject);
194             lastDataObject = dataObject;
195             
196             String JavaDoc sourceXML = data.getSourceXML();
197             if (sourceXML.length() > 0) {
198                 FileObject baseFO = dataObject.getPrimaryFile();
199                 URL JavaDoc baseURL = preferFileURL(baseFO.getParent());
200                 URL JavaDoc sourceURL = new URL JavaDoc(baseURL, data.getSourceXML());
201                 sourceXML = sourceURL.toExternalForm();
202             }
203             
204             TransformPanel.Data transData = new TransformPanel.Data(sourceXML,
205             transPanel.getData().getXSL(), data.getOutput(), data.isOverwrite(), data.getProcess());
206             transPanel.setData(transData);
207             if(activatePropertyChange) {
208                 transPanel.addPropertyChangeListener(this);
209             }
210         } catch (Exception JavaDoc e) {
211             // TBD: Notify user
212
e.printStackTrace();
213             transPanel = null;
214         }
215         
216         return transPanel;
217     }
218     
219     /**
220      * Get the name of this scenario
221      * @return The name of this scenario
222      */

223     public String JavaDoc getName() {
224         return name;
225     }
226     
227     /**
228      * Set the name of this scenario
229      * @param name The name of this scenario
230      */

231     public void setName(String JavaDoc name) {
232         String JavaDoc oldName = this.name;
233         this.name = name;
234     }
235     
236     /**
237      * Update this scenario with changes done by the last UI
238      * component returned by the getUIComponent() method.
239      */

240     public void saveChanges() {
241         if (transPanel != null) {
242             TransformPanel.Data transData = transPanel.getData();
243             
244             String JavaDoc sourceXML = transData.getInput();
245             FileObject baseFO = lastDataObject.getPrimaryFile();
246             try {
247                 String JavaDoc baseURL = preferFileURL(baseFO.getParent()).toExternalForm();
248                 sourceXML = relativize(baseURL, sourceXML);
249             } catch(Exception JavaDoc e) {}
250             
251             data.setSourceXML(sourceXML);
252             String JavaDoc outputStr=null;
253             if(transData.getOutput()!=null) {
254                 outputStr=transData.getOutput().toString();
255             }
256             data.setOutput(outputStr);
257             data.setOverwrite(transData.isOverwriteOutput());
258             data.setProcess(transData.getProcessOutput());
259             sourceDoc = null;
260         }
261     }
262     
263     public Document JavaDoc getSourceDocument(DataObject dataObject, boolean reload) throws SAXException JavaDoc, IOException JavaDoc {
264         if (sourceDoc == null || reload) {
265             String JavaDoc sourceXML = data.getSourceXML();
266             if (sourceXML == null || sourceXML.length() == 0) {
267                 return null;
268             }
269             
270             FileObject baseFO = dataObject.getPrimaryFile();
271             URL JavaDoc baseURL = preferFileURL(baseFO);
272             URL JavaDoc url = new URL JavaDoc(baseURL, sourceXML);
273             sourceDoc = XMLUtil.parse(new InputSource JavaDoc(url.toExternalForm()), false, true,
274                 null, TransformUtil.getEntityResolver());
275         }
276         
277         return sourceDoc;
278     }
279     
280     /**
281      * Returns the name of this scenario
282      */

283     public String JavaDoc toString() {
284         return getName();
285     }
286     
287     
288     /**
289      * If possible it finds "file:" URL if <code>fileObject</code> is on LocalFileSystem.
290      * @return URL of <code>fileObject</code>.
291      */

292     protected URL JavaDoc preferFileURL(FileObject fileObject) throws MalformedURLException JavaDoc, FileStateInvalidException {
293         URL JavaDoc fileURL = null;
294         File JavaDoc file = FileUtil.toFile(fileObject);
295         
296         if ( file != null ) {
297             fileURL = file.toURL();
298         } else {
299             fileURL = fileObject.getURL();
300         }
301         return fileURL;
302     }
303     
304     private void showURL(URL JavaDoc url) {
305         HtmlBrowser.URLDisplayer.getDefault().showURL(url);
306         GuiUtil.setStatusText(Util.THIS.getString("MSG_opening_browser"));
307     }
308     
309     /**
310      * Registers PropertyChangeListener to receive events.
311      * @param listener The listener to register.
312      */

313     public void addPropertyChangeListener(PropertyChangeListener JavaDoc listener) {
314         if(support==null) {
315             support = new PropertyChangeSupport JavaDoc(this);
316         }
317         support.addPropertyChangeListener(listener);
318     }
319     
320     /**
321      * Removes PropertyChangeListener from the list of listeners.
322      * @param listener The listener to remove.
323      */

324     public void removePropertyChangeListener(PropertyChangeListener JavaDoc listener) {
325         if(support==null) {
326             support = new PropertyChangeSupport JavaDoc(this);
327         }
328         support.removePropertyChangeListener(listener);
329     }
330     
331     /**
332      * This method gets called when a bound property is changed.
333      * @param evt A PropertyChangeEvent object describing the event source
334      * and the property that has changed.
335      */

336     public void propertyChange(PropertyChangeEvent JavaDoc evt) {
337         if(support==null) {
338             support = new PropertyChangeSupport JavaDoc(this);
339         }
340         if(evt.getPropertyName().equals(TransformPanel.DATA_XML_MODIFIED) ||
341         evt.getPropertyName().equals(TransformPanel.DATA_XSL_MODIFIED) ||
342         evt.getPropertyName().equals(TransformPanel.DATA_OUTPUT_MODIFIED) ||
343         evt.getPropertyName().equals(TransformPanel.DATA_OVERWRITE_MODIFIED) ||
344         evt.getPropertyName().equals(TransformPanel.DATA_PROCESS_MODIFIED)) {
345             support.firePropertyChange(Scenario.PROP_SCENARIO_MODIFIED,evt.getOldValue(), evt.getNewValue());
346         }
347     }
348     
349     private String JavaDoc relativize(String JavaDoc baseURI, String JavaDoc url) {
350         StringTokenizer JavaDoc baseTok = new StringTokenizer JavaDoc(baseURI, "/");
351         StringTokenizer JavaDoc urlTok = new StringTokenizer JavaDoc(url, "/");
352         
353         String JavaDoc curUrlTok = null;
354         int parentTokens = baseTok.countTokens();
355         int origParentTokens = parentTokens;
356         while (baseTok.hasMoreTokens()) {
357             if (!urlTok.hasMoreTokens()) {
358                 curUrlTok = null;
359                 break;
360             }
361             curUrlTok = urlTok.nextToken();
362             if (!curUrlTok.equals(baseTok.nextToken())) {
363                 break;
364             }
365             parentTokens--;
366         }
367         
368         if (parentTokens == origParentTokens) {
369             // Difference in protocol
370
return url;
371         }
372         
373         String JavaDoc resUrl = "";
374         for (int ind = 0; ind < parentTokens; ind++) {
375             resUrl += "../";
376         }
377         
378         if (curUrlTok != null) {
379             if (parentTokens != 0) {
380                 resUrl += curUrlTok;
381                 if (urlTok.hasMoreTokens()) {
382                     resUrl += "/";
383                 }
384             }
385          
386             while (urlTok.hasMoreTokens()) {
387                 resUrl += urlTok.nextToken();
388                 if (urlTok.hasMoreTokens()) {
389                     resUrl += "/";
390                 }
391             }
392         }
393         
394         return resUrl;
395     }
396     
397     public class Data implements Serializable JavaDoc {
398         
399         /** Holds value of property sourceXML. */
400         private String JavaDoc sourceXML = "";
401         
402         /** Holds value of property output. */
403         private String JavaDoc output = null;
404         
405         /** Holds value of property overwrite. */
406         private boolean overwrite = true;
407         
408         /** Holds value of property process. */
409         private int process = -1;
410         
411         /** Getter for property sourceXML.
412          * @return Value of property sourceXML.
413          *
414          */

415         public String JavaDoc getSourceXML() {
416             return this.sourceXML;
417         }
418         
419         /** Setter for property sourceXML.
420          * @param sourceXML New value of property sourceXML.
421          *
422          */

423         public void setSourceXML(String JavaDoc sourceXML) {
424             this.sourceXML = sourceXML;
425         }
426         
427         /** Getter for property output.
428          * @return Value of property output.
429          *
430          */

431         public String JavaDoc getOutput() {
432             return this.output;
433         }
434         
435         /** Setter for property output.
436          * @param output New value of property output.
437          *
438          */

439         public void setOutput(String JavaDoc output) {
440             this.output = output;
441         }
442         
443         /** Getter for property overwrite.
444          * @return Value of property overwrite.
445          *
446          */

447         public boolean isOverwrite() {
448             return this.overwrite;
449         }
450         
451         /** Setter for property overwrite.
452          * @param overwrite New value of property overwrite.
453          *
454          */

455         public void setOverwrite(boolean overwrite) {
456             this.overwrite = overwrite;
457         }
458         
459         /** Getter for property process.
460          * @return Value of property process.
461          *
462          */

463         public int getProcess() {
464             return this.process;
465         }
466         
467         /** Setter for property process.
468          * @param process New value of property process.
469          *
470          */

471         public void setProcess(int process) {
472             this.process = process;
473         }
474         
475     }
476     
477 }
478
Popular Tags