001: package com.xoetrope.carousel.visualizer;
002:
003: import java.io.BufferedWriter;
004: import java.io.File;
005: import java.io.FileWriter;
006: import java.io.Reader;
007: import java.io.Writer;
008: import java.util.Enumeration;
009: import java.util.Vector;
010: import net.xoetrope.editor.project.ProjectListener;
011: import net.xoetrope.editor.project.XEditorProject;
012: import net.xoetrope.editor.project.XEditorProjectManager;
013: import net.xoetrope.optional.data.sql.CachedDatabaseTable;
014: import net.xoetrope.optional.data.sql.DatabaseTable;
015: import net.xoetrope.optional.data.sql.DatabaseTableModel;
016: import net.xoetrope.optional.data.sql.NamedConnectionManager;
017: import net.xoetrope.xml.XmlElement;
018: import net.xoetrope.xml.XmlHelper;
019: import net.xoetrope.xml.XmlSource;
020: import net.xoetrope.xml.nanoxml.NanoXmlElement;
021: import net.xoetrope.xml.nanoxml.NanoXmlWriter;
022: import net.xoetrope.xui.XProject;
023: import net.xoetrope.xui.data.XModel;
024:
025: /**
026: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
027: * the GNU Public License (GPL), please see license.txt for more details. If
028: * you make commercial use of this software you must purchase a commercial
029: * license from Xoetrope.</p>
030: */
031: public class VisualiserProjectListener implements ProjectListener {
032: /**
033: * Notification of project initialized.
034: * @param project the editor project just initialized
035: */
036: public void projectInitialized(XEditorProject project) {
037: }
038:
039: public void projectLoaded(XEditorProject project) {
040: }
041:
042: public void projectUpdated(XEditorProject project) {
043: }
044:
045: public void saveProject(XEditorProject project) {
046: saveDataModel();
047: }
048:
049: public void checkProject(XEditorProject proj) {
050: }
051:
052: public void resetProject(String moduleName, XEditorProject proj) {
053: }
054:
055: /**
056: * Gets the static data file's name
057: * @param elem the XmlElement describing data sources
058: * @return the name of the file
059: */
060: private String getStaticDataFileName(XmlElement elem) {
061: String staticDataFile = "staticdata.xml";
062: XmlElement staticDataEntry = null;
063: Enumeration enumChildren = elem.getChildren().elements();
064: while ((enumChildren.hasMoreElements())
065: && (staticDataEntry == null)) {
066: XmlElement child = (XmlElement) enumChildren.nextElement();
067: String type = child.getAttribute("type");
068: if ((type == null) || type.equals(""))
069: staticDataEntry = child;
070: }
071: if (staticDataEntry == null) {
072: staticDataEntry = new NanoXmlElement("DataSource");
073: staticDataEntry.setAttribute("name", "StaticData");
074: staticDataEntry.setAttribute("filename", staticDataFile);
075: } else {
076: staticDataFile = staticDataEntry.getAttribute("filename");
077: }
078:
079: return staticDataFile;
080: }
081:
082: /**
083: * Retrieves static data from the model and appends it
084: * to the <code>elem</code>
085: * @param elem the XmlElement to which the static data are about
086: * to be appended
087: * @param model the XModel node
088: */
089: private void retrieveStaticData(XmlElement elem, XModel model) {
090: if ((model == null) || (elem == null))
091: return;
092: String tagName = model.getTagName();
093: if ((tagName == null) || tagName.equals(""))
094: return;
095:
096: XmlElement newElem = new NanoXmlElement();
097: newElem.setName(tagName);
098: int numAttributes = model.getNumAttributes();
099: for (int i = 0; i < numAttributes; i++) {
100: String attribName = model.getAttribName(i);
101: String attribValue = model.getAttribValueAsString(i);
102: if ((attribValue != null) && (!attribValue.equals("")))
103: newElem.setAttribute(attribName, attribValue);
104: }
105: elem.addChild(newElem);
106: int numChildren = model.getNumChildren();
107: for (int i = 0; i < numChildren; i++) {
108: XModel child = (XModel) model.get(i);
109: retrieveStaticData(newElem, child);
110: }
111: }
112:
113: /**
114: * Saves the file containing static data
115: * @param the staticDataFileName the name of the file
116: */
117: private void saveStaticDataFile(String staticDataFileName)
118: throws Exception {
119: XEditorProject currentProject = (XEditorProject) XEditorProjectManager
120: .getCurrentProject();
121: XModel rootModel = currentProject.getModel();
122: XmlElement rootXml = new NanoXmlElement(rootModel.getTagName());
123: int numChildren = rootModel.getNumChildren();
124: for (int i = 0; i < numChildren; i++) {
125: retrieveStaticData(rootXml, (XModel) rootModel.get(i));
126: }
127:
128: String path = currentProject.getPath() + File.separator
129: + "resources" + File.separator;
130: File staticDataFile = new File(path + staticDataFileName);
131: staticDataFile.createNewFile();
132: FileWriter fileWriter = new FileWriter(staticDataFile);
133: Writer bufferedWriter = new BufferedWriter(fileWriter);
134: NanoXmlWriter xmlWriter = new NanoXmlWriter(bufferedWriter);
135: xmlWriter.write(rootXml, true, 4);
136: bufferedWriter.flush();
137: fileWriter.flush();
138: bufferedWriter.close();
139: fileWriter.close();
140: }
141:
142: /**
143: * Gets the name of the file describing model database tables
144: * @param elem the XmlElement describing data sources.
145: * @return the name of the file
146: */
147: private String getDbTablesFileName(XmlElement elem) {
148: String dbTableFile = "dbtables.xml";
149: XmlElement databaseEntry = null;
150: Enumeration enumChildren = elem.getChildren().elements();
151: while ((enumChildren.hasMoreElements() && (databaseEntry == null))) {
152: XmlElement child = (XmlElement) enumChildren.nextElement();
153: if ("database".equals(child.getAttribute("type")))
154: databaseEntry = child;
155: }
156: if (databaseEntry == null) {
157: databaseEntry = new NanoXmlElement("DataSource");
158: databaseEntry.setAttribute("name", "Tables");
159: databaseEntry.setAttribute("type", "database");
160: databaseEntry.setAttribute("filename", dbTableFile);
161: elem.addChild(databaseEntry);
162: } else {
163: dbTableFile = databaseEntry.getAttribute("filename");
164: }
165:
166: return dbTableFile;
167: }
168:
169: /**
170: * Retrieves database tables from the model
171: * @param dbTable the Vector which will store retrieved database
172: * tables descriptions.
173: * @param model the XModel from which the database tables are
174: * to be retrieved
175: */
176: private void retrieveDbTables(Vector dbTables, XModel model) {
177: if (model == null)
178: return;
179:
180: if (model instanceof DatabaseTableModel) {
181: DatabaseTable databaseTable = ((DatabaseTableModel) model)
182: .getTable();
183: String id = ((DatabaseTableModel) model).getId();
184: String from = databaseTable.getTableName();
185: String fields = databaseTable.getFields();
186: String where = databaseTable.getWhereClause();
187: String conn = databaseTable.getConnName();
188: String origSql = null;
189: if (databaseTable instanceof CachedDatabaseTable)
190: origSql = ((CachedDatabaseTable) databaseTable)
191: .getOriginalSql();
192:
193: XmlElement resultSet = new NanoXmlElement("ResultSet");
194: resultSet.setAttribute("id", id);
195: resultSet.setAttribute("conn", conn);
196: if (origSql == null) {
197: if (from != null)
198: resultSet.setAttribute("from", from);
199: if (fields != null)
200: resultSet.setAttribute("fields", fields);
201: if (where != null)
202: resultSet.setAttribute("where", where);
203: } else {
204: resultSet.setAttribute("sql", origSql);
205: }
206:
207: dbTables.add(resultSet);
208: }
209:
210: }
211:
212: /**
213: * Retrieves details of database connections which are used to obtain database tables
214: * stored in the model
215: * @param dbTables Vector containing database tables details
216: * @param dbConnections Vector which will store retrieved dabase connections details
217: */
218: private void retrieveConnections(Vector dbTables,
219: Vector dbConnections) {
220: NamedConnectionManager connMgr = (NamedConnectionManager) NamedConnectionManager
221: .getInstance();
222:
223: Enumeration enumTables = dbTables.elements();
224: while (enumTables.hasMoreElements()) {
225: String connName = ((XmlElement) enumTables.nextElement())
226: .getAttribute("conn");
227: if (connName == null)
228: continue;
229:
230: String[] connParams = connMgr.getConnectionParams(connName);
231: if (connParams == null)
232: continue;
233:
234: String id = connParams[0];
235: if (id == null)
236: continue;
237: String url = connParams[1];
238: if (url == null)
239: continue;
240: String user = connParams[2];
241: if (user == null)
242: continue;
243: String password = connParams[3];
244: if (password == null)
245: continue;
246: String driverName = connParams[4];
247:
248: boolean found = false;
249: Enumeration enumConnections = dbConnections.elements();
250: while ((enumConnections.hasMoreElements()) && (!found)) {
251: XmlElement cxml = (XmlElement) enumConnections
252: .nextElement();
253: found = cxml.getAttribute("id").equals(id);
254: }
255: if (!found) {
256: XmlElement connectionXml = new NanoXmlElement(
257: "Connection");
258: connectionXml.setAttribute("id", id);
259: connectionXml.setAttribute("driver", driverName);
260: connectionXml.setAttribute("url", url);
261: connectionXml.setAttribute("user", user);
262: connectionXml.setAttribute("pwd", password);
263: dbConnections.add(connectionXml);
264: }
265: }
266: }
267:
268: /**
269: * Saves the file containing model's database tables descriptions
270: * @param dbTableFileName the name of the file which is to be saved
271: */
272: private void saveDbTableFile(String dbTableFileName)
273: throws Exception {
274: Vector dbTables = new Vector();
275: Vector dbConnections = new Vector();
276: XEditorProject currentProject = (XEditorProject) XEditorProjectManager
277: .getCurrentProject();
278: XModel rootModel = currentProject.getModel();
279:
280: int numChildren = rootModel.getNumChildren();
281: for (int i = 0; i < numChildren; i++) {
282: retrieveDbTables(dbTables, rootModel.get(i));
283: }
284: retrieveConnections(dbTables, dbConnections);
285:
286: XmlElement rootXml = new NanoXmlElement("Datasets");
287:
288: Enumeration enumConns = dbConnections.elements();
289: while (enumConns.hasMoreElements()) {
290: XmlElement connectionXml = (XmlElement) enumConns
291: .nextElement();
292: rootXml.addChild(connectionXml);
293: }
294: Enumeration enumTables = dbTables.elements();
295: while (enumTables.hasMoreElements()) {
296: XmlElement dbTableXml = (XmlElement) enumTables
297: .nextElement();
298: rootXml.addChild(dbTableXml);
299: }
300:
301: String path = currentProject.getPath() + File.separator
302: + "resources" + File.separator;
303: File dbTableFile = new File(path + dbTableFileName);
304: dbTableFile.createNewFile();
305: FileWriter fileWriter = new FileWriter(dbTableFile);
306: Writer bufferedWriter = new BufferedWriter(fileWriter);
307: NanoXmlWriter xmlWriter = new NanoXmlWriter(bufferedWriter);
308: xmlWriter.write(rootXml, true, 4);
309: bufferedWriter.flush();
310: fileWriter.flush();
311: bufferedWriter.close();
312: fileWriter.close();
313: }
314:
315: /**
316: * Updates and saves the datasource file
317: * @param modelFileName the name of the datasource file.
318: * @param elemXml the xml content of datasource file
319: */
320: private void updateModelFile(String modelFileName,
321: XmlElement elemXml) throws Exception {
322: String dbTablesFileName = getDbTablesFileName(elemXml);
323: String staticDataFileName = getStaticDataFileName(elemXml);
324:
325: XmlElement modelXml = new NanoXmlElement("Datasources");
326: XmlElement dbTablesXml = new NanoXmlElement("Datasource");
327: dbTablesXml.setAttribute("type", "database");
328: dbTablesXml.setAttribute("filename", dbTablesFileName);
329: modelXml.addChild(dbTablesXml);
330: XmlElement staticDataXml = new NanoXmlElement("Datasource");
331: staticDataXml.setAttribute("filename", staticDataFileName);
332: modelXml.addChild(staticDataXml);
333:
334: XmlElement routesXml = null, servicesXml = null;
335: Enumeration enumChildren = elemXml.getChildren().elements();
336: while (enumChildren.hasMoreElements()) {
337: XmlElement childXml = (XmlElement) enumChildren
338: .nextElement();
339: String type = childXml.getAttribute("type");
340: if ("routing".equals(type)) {
341: routesXml = childXml;
342: } else if ("service".equals(type)) {
343: servicesXml = childXml;
344: } else {
345: String filename = childXml.getAttribute("filename");
346: if (!filename.equals(staticDataFileName)
347: && !filename.equals(dbTablesFileName)) {
348: XmlElement newChildXml = new NanoXmlElement(
349: childXml.getName());
350: XmlHelper.copyAttributes(childXml, newChildXml);
351: modelXml.addChild(newChildXml);
352: }
353: }
354: }
355: if (routesXml != null) {
356: String name = routesXml.getAttribute("name");
357: String fileName = routesXml.getAttribute("filename");
358: XmlElement elem = new NanoXmlElement("DataSource");
359: if (name != null)
360: elem.setAttribute("name", name);
361: elem.setAttribute("type", "routing");
362: elem.setAttribute("filename", fileName);
363: modelXml.addChild(elem);
364: }
365: if (servicesXml != null) {
366: String name = servicesXml.getAttribute("name");
367: String fileName = servicesXml.getAttribute("filename");
368: XmlElement elem = new NanoXmlElement("DataSource");
369: if (name != null)
370: elem.setAttribute("name", name);
371: elem.setAttribute("type", "service");
372: elem.setAttribute("filename", fileName);
373: modelXml.addChild(elem);
374: }
375:
376: XEditorProject currentProject = (XEditorProject) XEditorProjectManager
377: .getCurrentProject();
378: String path = currentProject.getPath() + File.separator
379: + "resources" + File.separator;
380: File modelFile = new File(path + modelFileName);
381: modelFile.createNewFile();
382: FileWriter fileWriter = new FileWriter(modelFile);
383: BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
384: NanoXmlWriter xmlWriter = new NanoXmlWriter(bufferedWriter);
385: xmlWriter.write(modelXml, true, 4);
386: bufferedWriter.flush();
387: fileWriter.flush();
388: bufferedWriter.close();
389: fileWriter.close();
390: }
391:
392: /**
393: * Saves the project's model to datasources files. This method is being called
394: * from the <code>saveProject</method> of <code>ProjectListener</code> interface.
395: */
396: public void saveDataModel() {
397: try {
398: XEditorProject currentProject = (XEditorProject) XEditorProjectManager
399: .getCurrentProject();
400: String modelFile = currentProject.getModelFile();
401: Reader reader = currentProject.getBufferedReader(modelFile);
402: XmlElement rootXml = XmlSource.read(reader);
403:
404: saveDbTableFile(getDbTablesFileName(rootXml));
405: saveStaticDataFile(getStaticDataFileName(rootXml));
406: updateModelFile(modelFile, rootXml);
407: } catch (Exception e) {
408: e.printStackTrace();
409: }
410: }
411:
412: }
|