1
2
3
4
5
6
7
8
9
10
11
12 package sk.uniba.euromath.editor;
13 import java.io.File;
14 import java.io.IOException;
15 import java.io.OutputStream;
16 import java.net.URL;
17 import javax.xml.transform.dom.DOMSource;
18 import javax.xml.transform.stream.StreamResult;
19
20 import org.eclipse.core.runtime.IPath;
21 import org.eclipse.ui.IEditorInput;
22 import org.xml.sax.SAXException;
23
24 import sk.baka.ikslibs.TransformUtils;
25 import sk.baka.xml.gene.ExportUtils;
26 import sk.uniba.euromath.document.DocumentException;
27 import sk.uniba.euromath.document.DocumentFactory;
28 import sk.uniba.euromath.document.XMLAccess;
29 import sk.uniba.euromath.document.schema.plug.SchemaException;
30 import sk.uniba.euromath.gene.gui.widgets.XMLSerializerPropertiesWidget;
31 import sk.uniba.euromath.tools.EclipseUtils;
32 /***
33 * Responsible for loading and saving XML data.
34 * @author TV, Martin Vysny
35 */
36 public final class XMLResourceManipulator {
37 /***
38 * Input file specification. May be instance of
39 * <code>LocalFilesystemEditorInput</code> or
40 * <code>NewDocumentEditorInput</code>.
41 */
42 private final IEditorInput input;
43 /***
44 * The document deserialized from editor input.
45 */
46 private XMLAccess xmlAccess = null;
47 /***
48 * Constructor.
49 * @param editorInput document is deserialized from this editor input.
50 */
51 public XMLResourceManipulator(IEditorInput editorInput) {
52 super();
53 this.input = editorInput;
54 if (!isInputValid())
55 throw new IllegalArgumentException(
56 "Invalid editor input instance: "
57 + editorInput.getClass().getName());
58 }
59 /***
60 * Returns location path to the XML file.
61 * @return path to the xml file. The file may not exist if it was created.
62 */
63 public IPath getFile() {
64 if (this.input instanceof NewDocumentEditorInput){
65 URL documentURL=((NewDocumentEditorInput) this.input).xmlAccess
66 .getDocumentURL();
67 return EclipseUtils.urlToPath(documentURL);
68 }
69 return ((LocalFilesystemEditorInput) this.input).getFile();
70 }
71 /***
72 * Returns the document instance.
73 * @return the document instance. Never <code>null</code>.
74 */
75 public XMLAccess getXmlAccess() {
76 if (this.xmlAccess == null)
77 throw new IllegalStateException("Document was not yet loaded");
78 return this.xmlAccess;
79 }
80 /***
81 * Checks if this editor input is valid.
82 * @return <code>true</code> if given editor input is valid,
83 * <code>false</code> otherwise.
84 */
85 protected final boolean isInputValid() {
86 return (this.input != null)
87 && ((this.input instanceof LocalFilesystemEditorInput) || (this.input instanceof NewDocumentEditorInput));
88 }
89 /***
90 * Deserializes the document. The function fails if document is already
91 * loaded.
92 * @throws SAXException
93 * @throws IOException
94 * @throws DocumentException
95 * @throws SchemaException
96 */
97 public void load() throws SAXException, IOException, DocumentException,
98 SchemaException {
99 if (this.xmlAccess != null)
100 throw new IllegalStateException("Document is already loaded.");
101 if (this.input instanceof NewDocumentEditorInput) {
102
103 this.xmlAccess = ((NewDocumentEditorInput) this.input).xmlAccess;
104 assert this.xmlAccess != null;
105 return;
106 }
107
108 load(getFile());
109 }
110 /***
111 * @param data
112 * @throws SAXException
113 * @throws IOException
114 * @throws DocumentException
115 * @throws SchemaException
116 */
117 protected void load(IPath data) throws SAXException, IOException,
118 DocumentException, SchemaException {
119 if (this.xmlAccess != null)
120 throw new IllegalStateException("Document is already loaded.");
121 DocumentFactory loader = new DocumentFactory();
122 this.xmlAccess = loader.loadDocument(data);
123 this.xmlAccess.loadGlobalSchemas();
124 this.xmlAccess.validate();
125 }
126 /***
127 * Saves (serializes) the document.
128 * @param fullPathAndName if not <code>null</code> then document is saved
129 * into given file name. Otherwise, it is saved to a file name specified by
130 * the XMLAccess instance.
131 * @throws IOException when i/o error occurs.
132 */
133 public void save(String fullPathAndName) throws IOException {
134 if (fullPathAndName == null)
135 fullPathAndName = getFile().toOSString();
136 final OutputStream out = ExportUtils.openStream(new File(fullPathAndName));
137 try {
138 this.xmlAccess.saveDocument(out, this.xmlAccess.getEncoding(), true);
139 } finally {
140 out.close();
141 }
142 this.xmlAccess.getUndoManager().mark(true);
143 }
144
145 /***
146 * Serializes the document object model. Uses the DOM Level 3 Load/Save
147 * functionality, for details please see the DOM Level3 LS documentation.
148 * @param fullPathAndName if not <code>null</code> then document is saved
149 * into given file name. Otherwise, it is saved to a file name specified by
150 * the XMLAccess instance.
151 * @param encoding the encoding of the document. If <code>null</code> then
152 * default is used.
153 * @param deq output format parameters. May be <code>null</code> - in such
154 * case it is ignored.
155 * @throws IOException if serialization fails.
156 */
157 public void save(String fullPathAndName, final String encoding,
158 final XMLSerializerPropertiesWidget deq) throws IOException {
159 if (fullPathAndName == null)
160 fullPathAndName = getFile().toOSString();
161 final OutputStream out = ExportUtils.openStream(new File(fullPathAndName));
162 try {
163 TransformUtils.serialize(
164 new DOMSource(this.xmlAccess.getDocument()),
165 new StreamResult(out), encoding);
166 } finally {
167 out.close();
168 }
169 this.xmlAccess.getUndoManager().mark(true);
170 }
171 }