001: //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/trunk/src/org/deegree/tools/datastore/ModifyFTProperties.java $
002: /*---------------- FILE HEADER ------------------------------------------
003:
004: This file is part of deegree.
005: Copyright (C) 2001-2008 by:
006: EXSE, Department of Geography, University of Bonn
007: http://www.giub.uni-bonn.de/deegree/
008: lat/lon GmbH
009: http://www.lat-lon.de
010:
011: This library is free software; you can redistribute it and/or
012: modify it under the terms of the GNU Lesser General Public
013: License as published by the Free Software Foundation; either
014: version 2.1 of the License, or (at your option) any later version.
015:
016: This library is distributed in the hope that it will be useful,
017: but WITHOUT ANY WARRANTY; without even the implied warranty of
018: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
019: Lesser General Public License for more details.
020:
021: You should have received a copy of the GNU Lesser General Public
022: License along with this library; if not, write to the Free Software
023: Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
024:
025: Contact:
026:
027: Andreas Poth
028: lat/lon GmbH
029: Aennchenstr. 19
030: 53177 Bonn
031: Germany
032: E-Mail: poth@lat-lon.de
033:
034: Prof. Dr. Klaus Greve
035: Department of Geography
036: University of Bonn
037: Meckenheimer Allee 166
038: 53115 Bonn
039: Germany
040: E-Mail: greve@giub.uni-bonn.de
041:
042: ---------------------------------------------------------------------------*/
043: package org.deegree.tools.datastore;
044:
045: import java.io.File;
046: import java.io.FileOutputStream;
047: import java.net.URI;
048: import java.net.URL;
049: import java.util.Properties;
050:
051: import org.deegree.datatypes.Types;
052: import org.deegree.datatypes.parameter.InvalidParameterNameException;
053: import org.deegree.framework.util.StringTools;
054: import org.deegree.framework.xml.NamespaceContext;
055: import org.deegree.framework.xml.XMLFragment;
056: import org.deegree.framework.xml.XMLParsingException;
057: import org.deegree.framework.xml.XMLTools;
058: import org.deegree.ogcbase.CommonNamespaces;
059: import org.w3c.dom.Element;
060: import org.w3c.dom.Node;
061:
062: /**
063: * This class enables a user to add a new property to a deegree WFS feature type definition. It is
064: * possible to add a simple property from the feature types major table, a simple property from
065: * another table and a complex property from another already available feature type.
066: *
067: *
068: * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
069: * @author last edited by: $Author: apoth $
070: *
071: * @version $Revision: 9346 $, $Date: 2007-12-27 08:39:07 -0800 (Thu, 27 Dec 2007) $
072: */
073: public class ModifyFTProperties {
074:
075: private static NamespaceContext nsCntxt = CommonNamespaces
076: .getNamespaceContext();
077:
078: private static URI xsd = CommonNamespaces.XSNS;
079:
080: private static URI dgwfs = CommonNamespaces.DEEGREEWFS;
081:
082: private URL ftDefFile;
083:
084: private String featureType;
085:
086: private String propertyName;
087:
088: private String source;
089:
090: private String from;
091:
092: private String to;
093:
094: private int relType = 0;
095:
096: private String databaseFieldName;
097:
098: private int type = 0;
099:
100: /**
101: *
102: * @param ftDefFile
103: * schema file containing feature type defintion
104: * @param featureType
105: * qualified name of the feature to enhance
106: * @param propertyName
107: * name of the new property
108: * @param databaseFieldName
109: * @param type
110: * type code of the ne2 property (@see org.deegree.datatypes.Types)
111: */
112: public ModifyFTProperties(URL ftDefFile, String featureType,
113: String propertyName, String databaseFieldName, int type) {
114: this .ftDefFile = ftDefFile;
115: this .featureType = featureType;
116: this .propertyName = propertyName;
117: this .type = type;
118: this .databaseFieldName = databaseFieldName;
119: }
120:
121: /**
122: *
123: * @param ftDefFile
124: * schema file containing feature type defintion
125: * @param featureType
126: * qualified name of the feature to enhance
127: * @param propertyName
128: * name of the new property
129: * @param databaseFieldName
130: * @param table
131: * @param from
132: * @param to
133: * @param type
134: * type code of the new property (@see org.deegree.datatypes.Types)
135: * @param relType
136: */
137: public ModifyFTProperties(URL ftDefFile, String featureType,
138: String propertyName, String databaseFieldName,
139: String table, String from, String to, int type, int relType) {
140: this .ftDefFile = ftDefFile;
141: this .featureType = featureType;
142: this .propertyName = propertyName;
143: this .type = type;
144: this .source = table;
145: this .from = from;
146: this .to = to;
147: this .relType = relType;
148: this .databaseFieldName = databaseFieldName;
149: }
150:
151: /**
152: * adds a property from the feature types major table
153: *
154: * @throws Exception
155: */
156: public void addSimplePropertyFromMainTable() throws Exception {
157:
158: XMLFragment xml = new XMLFragment();
159: xml.load(ftDefFile);
160:
161: if (doesPropertyAlreadyExist(xml, propertyName)) {
162: throw new InvalidParameterNameException(
163: "Property already exits", "propertyName");
164: }
165:
166: Element cType = getPropertyParent(xml);
167:
168: Element elem = XMLTools.appendElement(cType, xsd, "element");
169: elem.setAttribute("name", propertyName);
170: elem.setAttribute("type", "xsd:"
171: + Types.getXSDTypeForSQLType(type, 0));
172: Element el = XMLTools.appendElement(elem, xsd, "annotation");
173: el = XMLTools.appendElement(el, xsd, "appinfo");
174: el = XMLTools.appendElement(el, dgwfs, "deegreewfs:Content");
175: el = XMLTools.appendElement(el, dgwfs,
176: "deegreewfs:MappingField");
177: el.setAttribute("field", databaseFieldName);
178: el.setAttribute("type", Types.getTypeNameForSQLTypeCode(type));
179:
180: File file = new File(ftDefFile.getFile());
181: FileOutputStream fos = new FileOutputStream(file);
182: xml.write(fos);
183: fos.close();
184: }
185:
186: /**
187: * returns the parent node where to add the additional property
188: *
189: * @param xml
190: * @return the parent node where to add the additional property
191: * @throws XMLParsingException
192: */
193: private Element getPropertyParent(XMLFragment xml)
194: throws XMLParsingException {
195: String xpath = StringTools
196: .concat(100, "xs:complexType[./@name = '", featureType,
197: "Type']/xs:complexContent/",
198: "xs:extension/xs:sequence");
199: return (Element) XMLTools.getNode(xml.getRootElement(), xpath,
200: nsCntxt);
201: }
202:
203: /**
204: * returns true if a property with the same name as the one to add already exists for
205: * a feature type
206: *
207: * @param xml
208: * @param propertyName
209: * @return true if property already exists
210: * @throws XMLParsingException
211: */
212: private boolean doesPropertyAlreadyExist(XMLFragment xml,
213: String propertyName) throws XMLParsingException {
214: String xPath = ".//xsd:element[./@name = '" + propertyName
215: + "']";
216: nsCntxt.addNamespace("xsd", xsd);
217: Node node = XMLTools.getNode(xml.getRootElement(), xPath,
218: nsCntxt);
219: return node != null;
220: }
221:
222: /**
223: * @throws Exception
224: */
225: public void addSimplePropertyFromOtherTable() throws Exception {
226: XMLFragment xml = new XMLFragment();
227: xml.load(ftDefFile);
228:
229: if (doesPropertyAlreadyExist(xml, propertyName)) {
230: throw new InvalidParameterNameException(
231: "Property already exits", "propertyName");
232: }
233:
234: Element cType = getPropertyParent(xml);
235:
236: Element elem = XMLTools.appendElement(cType, xsd, "element");
237: elem.setAttribute("name", propertyName);
238: elem.setAttribute("type", "xsd:"
239: + Types.getXSDTypeForSQLType(type, 0));
240: Element el = XMLTools.appendElement(elem, xsd, "annotation");
241: el = XMLTools.appendElement(el, xsd, "appinfo");
242: el = XMLTools.appendElement(el, dgwfs, "deegreewfs:Content");
243: Element mfElem = XMLTools.appendElement(el, dgwfs,
244: "deegreewfs:MappingField");
245: mfElem.setAttribute("field", databaseFieldName);
246: mfElem.setAttribute("type", Types
247: .getTypeNameForSQLTypeCode(type));
248:
249: // append relation informations
250: Element relElem = XMLTools.appendElement(el, dgwfs,
251: "deegreewfs:Relation");
252: el = XMLTools.appendElement(relElem, dgwfs, "deegreewfs:From");
253: el = XMLTools.appendElement(el, dgwfs,
254: "deegreewfs:MappingField");
255: el.setAttribute("field", from);
256: el.setAttribute("type", Types
257: .getTypeNameForSQLTypeCode(relType));
258: el = XMLTools.appendElement(relElem, dgwfs, "deegreewfs:To");
259: el = XMLTools.appendElement(el, dgwfs,
260: "deegreewfs:MappingField");
261: el.setAttribute("field", to);
262: el.setAttribute("type", Types
263: .getTypeNameForSQLTypeCode(relType));
264: el.setAttribute("table", source);
265:
266: File file = new File(ftDefFile.getFile());
267: FileOutputStream fos = new FileOutputStream(file);
268: xml.write(fos);
269: fos.close();
270: }
271:
272: /**
273: *
274: */
275: public void addComplexProperty() {
276: // TODO
277: }
278:
279: private static boolean validate(Properties map) {
280: if (map.getProperty("-action") == null) {
281: return false;
282: }
283: if (map.getProperty("-xsd") == null) {
284: return false;
285: }
286: if (map.getProperty("-featureType") == null) {
287: return false;
288: }
289: if (map.getProperty("-propertyName") == null) {
290: return false;
291: }
292: return true;
293: }
294:
295: private static void printHelp() {
296: System.out.println("properties:");
297: System.out.println("-action (addProperty|removeProperty)");
298: System.out.println("-xsd");
299: System.out.println("-featureType");
300: System.out.println("-propertyName");
301: System.out.println("-type (simple|complex)");
302: System.out.println("must be set!");
303: System.out.println("If -source is set ");
304: System.out.println("-fkSource");
305: System.out.println("-fkTarget");
306: System.out.println("-fkType");
307: System.out.println("must be set too!");
308: }
309:
310: /**
311: * @param args
312: * @throws Exception
313: */
314: public static void main(String[] args) throws Exception {
315:
316: Properties map = new Properties();
317: for (int i = 0; i < args.length; i += 2) {
318: System.out.println(args[i + 1]);
319: map.put(args[i], args[i + 1]);
320: }
321: if (!validate(map)) {
322: printHelp();
323: return;
324: }
325:
326: String action = map.getProperty("-action");
327: URL url = new URL(map.getProperty("-xsd"));
328: String ft = map.getProperty("-featureType");
329: String prop = map.getProperty("-propertyName");
330: if ("addProperty".equals(action)) {
331: String field = map.getProperty("-fieldName");
332: int type = Types.getTypeCodeForSQLType(map
333: .getProperty("-propertyType"));
334: if ("simple".equals(map.getProperty("-type"))
335: && map.getProperty("-source") == null) {
336: ModifyFTProperties add = new ModifyFTProperties(url,
337: ft, prop, field, type);
338: add.addSimplePropertyFromMainTable();
339: }
340: if ("simple".equals(map.getProperty("-type"))
341: && map.getProperty("-source") != null) {
342: String table = map.getProperty("-source");
343: String from = map.getProperty("-fkSource");
344: String to = map.getProperty("-fkTarget");
345: int fkType = Types.getTypeCodeForSQLType(map
346: .getProperty("-fkType"));
347: ModifyFTProperties add = new ModifyFTProperties(url,
348: ft, prop, field, table, from, to, fkType, type);
349: add.addSimplePropertyFromOtherTable();
350: } else if ("complex".equals(map.getProperty("-type"))) {
351: // TODO
352: throw new Exception("not supported yet");
353: } else {
354: throw new Exception("not supported operation");
355: }
356:
357: } else if ("removeProperty".equals(action)) {
358: // TODO
359: throw new Exception("not supported yet");
360: } else {
361: throw new Exception("not supported operation");
362: }
363:
364: }
365:
366: }
|