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