View Javadoc

1   /*
2    * Copyright 1999-2006 Faculty of Mathematics, Physics and Informatics, Comenius
3    * University, Bratislava. This file is protected by the Mozilla Public License
4    * version 1.1 (the License); you may not use this file except in compliance
5    * with the License. You may obtain a copy of the License at
6    * http://euromath2.sourceforge.net/license.html Unless required by applicable
7    * law or agreed to in writing, software distributed under the License is
8    * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
9    * KIND, either express or implied. See the License for the specific language
10   * governing permissions and limitations under the License.
11   */
12  package sk.uniba.euromath.document;
13  import java.io.IOException;
14  import java.util.Collection;
15  import java.util.EnumSet;
16  import java.util.HashMap;
17  import java.util.HashSet;
18  import java.util.Map;
19  import java.util.Set;
20  import org.apache.commons.io.FileUtils;
21  import sk.baka.ikslibs.SourceEnum;
22  import sk.baka.xml.gene.CoordinatorInfo;
23  import sk.baka.xml.gene.ExportException;
24  import sk.baka.xml.gene.ICoordinator;
25  import sk.baka.xml.gene.controller.ExportController;
26  import sk.baka.xml.gene.exportgraph.ExportGraph;
27  import sk.baka.xml.gene.exportgraph.ExportGraphBuilder;
28  import sk.baka.xml.gene.exportgraph.GraphNode;
29  import sk.baka.xml.gene.exportgraph.INamespaceAcceptor;
30  import sk.baka.xml.gene.exportgraph.NamespaceMapAcceptor;
31  import sk.baka.xml.gene.exportgraph.TransformGraph;
32  import sk.uniba.euromath.editor.EditorSite;
33  import sk.uniba.euromath.editor.RendererSelector;
34  import sk.uniba.euromath.gene.GeneDataProvider;
35  /***
36   * Represents one presentation of document.
37   * @author Martin Vysny
38   */
39  public final class DocumentView {
40  	/***
41  	 * Graph containing graph nodes for all namespaces present in the document.
42  	 */
43  	private final ExportGraph editGraph;
44  	/***
45  	 * The graph builder.
46  	 */
47  	private final ExportGraphBuilder builder = new ExportGraphBuilder();
48  	/***
49  	 * The data provider instance.
50  	 */
51  	private final GeneDataProvider provider;
52  	/***
53  	 * The document instance.
54  	 */
55  	private final XMLAccess doc;
56  	/***
57  	 * Constructs the instance of object.
58  	 * @param doc document to view
59  	 * @param selector selects preferred renderers. May be <code>null</code> -
60  	 * in such case no renderers are preferred.
61  	 * @param site the transformed data receiver.
62  	 */
63  	public DocumentView(final XMLAccess doc, final RendererSelector selector,
64  			final EditorSite site) {
65  		super();
66  		this.doc = doc;
67  		provider = new GeneDataProvider(
68  				selector == null ? new RendererSelector() : selector, doc, site);
69  		final INamespaceAcceptor sourceNamespaces = ExportGraphBuilder
70  				.getDocumentNamespaces(doc.getSplittedDoc());
71  		editGraph = builder.newGraph(sourceNamespaces, provider
72  				.getCoordinatorInfo(), true);
73  	}
74  	/***
75  	 * The transformation graph, set in {@link #initialize(TransformGraph)}.
76  	 */
77  	private TransformGraph transformGraph = null;
78  	/***
79  	 * Initializes the view, performing the transformation. If an exception is
80  	 * thrown during export, view is automatically closed and it must not be
81  	 * further used.
82  	 * @param graph transform graph.
83  	 * @throws ExportException if error occurs during the transformation.
84  	 * @throws IOException if i/o error occurs during the transformation.
85  	 */
86  	public void initialize(final TransformGraph graph) throws ExportException,
87  			IOException {
88  		checkNotClosed();
89  		if (isInitialized())
90  			throw new IllegalStateException("View is already initialized."); //$NON-NLS-1$
91  		// check if all namespaces are present.
92  		final Set<String> namespaces = new HashSet<String>(editGraph
93  				.getAllNodesAsMap().keySet());
94  		namespaces.removeAll(graph.allNamespaces());
95  		if (!namespaces.isEmpty())
96  			throw new ExportException(
97  					"Missing transformers for namespaces: " + namespaces); //$NON-NLS-1$
98  		transformGraph = new TransformGraph(graph);
99  		boolean initializedProperly = false;
100 		try {
101 			export();
102 			initializedProperly = true;
103 		} finally {
104 			if (!initializedProperly)
105 				close();
106 		}
107 	}
108 	/***
109 	 * Constructs graph for given set of namespaces.
110 	 * @param namespaces namespaces
111 	 * @return graph containing export nodes for all namespaces.
112 	 */
113 	public ExportGraph getGraphFor(
114 			final Collection< ? extends String> namespaces) {
115 		checkNotClosed();
116 		// create new graph nodes only for new namespaces
117 		final Map<String, GraphNode> allNodes = editGraph.getAllNodesAsMap();
118 		final Map<String, EnumSet<SourceEnum>> newNamespaces = new HashMap<String, EnumSet<SourceEnum>>();
119 		for (final String ns : namespaces) {
120 			if (!allNodes.containsKey(ns))
121 				newNamespaces.put(ns, EnumSet.of(SourceEnum.DOM));
122 		}
123 		// construct graph for these new namespaces.
124 		final CoordinatorInfo info = provider.getCoordinatorInfo();
125 		final ExportGraph result = builder.newGraph(new NamespaceMapAcceptor(
126 				newNamespaces), info, true);
127 		// add known graph nodes from the editGraph
128 		for (final String ns : namespaces) {
129 			final GraphNode node = allNodes.get(ns);
130 			final boolean isRegular = editGraph.isRegular(node);
131 			if (node != null)
132 				result.addNode(node, isRegular, false);
133 		}
134 		return result;
135 	}
136 	/***
137 	 * Returns the current exporter graph. The graph must not be modified!
138 	 * @return the exporter graph.
139 	 */
140 	public ExportGraph getEditGraph() {
141 		checkNotClosed();
142 		return editGraph;
143 	}
144 	/***
145 	 * Registers new transformers, ignoring transformers already registered.
146 	 * @param graph graph to register.
147 	 */
148 	public void addTransformers(final TransformGraph graph) {
149 		checkNotClosed();
150 		transformGraph.addAll(graph, false);
151 	}
152 	/***
153 	 * Exports the document.
154 	 * @throws ExportException if shit happens.
155 	 * @throws IOException if i/o error occurs.
156 	 */
157 	void export() throws ExportException, IOException {
158 		checkInitialized();
159 		checkNotClosed();
160 		final ICoordinator editorDataReceiver = provider.getCoordinator();
161 		final ExportController controller = new ExportController(FileUtils
162 				.toFile(doc.getDocumentURL()), doc.getSplittedDoc(),
163 				transformGraph, editorDataReceiver);
164 		controller.export(null);
165 	}
166 	/***
167 	 * Checks if this view is initialized. Unintialized views are not subjects
168 	 * for GENE transformation.
169 	 * @return <code>true</code> if this view is initialized,
170 	 * <code>false</code> otherwise.
171 	 */
172 	public boolean isInitialized() {
173 		return transformGraph != null;
174 	}
175 	/***
176 	 * Checks if this view is initialized. If not, exception is thrown.
177 	 */
178 	private void checkInitialized() {
179 		if (!isInitialized())
180 			throw new IllegalStateException("Not initialized."); //$NON-NLS-1$
181 	}
182 	/***
183 	 * The editor data provider coordinator info.
184 	 * @return info.
185 	 */
186 	public CoordinatorInfo getCoordinatorInfo() {
187 		checkNotClosed();
188 		return provider.getCoordinatorInfo();
189 	}
190 	/***
191 	 * Closes and invalidates this view. Closing an already closed view has no
192 	 * effect.
193 	 */
194 	void close() {
195 		if (isClosed())
196 			return;
197 		provider.getCoordinator().dispose();
198 		closed = true;
199 	}
200 	/***
201 	 * <code>true</code> if this view is closed.
202 	 */
203 	private boolean closed = false;
204 	/***
205 	 * Returns <code>true</code> if this view is closed. If the view is
206 	 * closed, it becomes invalid and must not be used.
207 	 * @return <code>true</code> if this view is closed
208 	 */
209 	public boolean isClosed() {
210 		return closed;
211 	}
212 	/***
213 	 * Checks if this view is closed. If yes then exception is thrown.
214 	 */
215 	private void checkNotClosed() {
216 		if (isClosed())
217 			throw new IllegalStateException("The view is closed."); //$NON-NLS-1$
218 	}
219 	/*
220 	 * (non-Javadoc)
221 	 * @see java.lang.Object#finalize()
222 	 */
223 	@Override
224 	protected void finalize() throws Throwable {
225 		close();
226 		super.finalize();
227 	}
228 }