001: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
002: * This code is licensed under the GPL 2.0 license, availible at the root
003: * application directory.
004: */
005:
006: /* Copyright (c) 2001 - 2007 TOPP - www.openplans.org. All rights reserved.
007: * This code is licensed under the GPL 2.0 license, availible at the root
008: * application directory.
009: */
010: package org.vfny.geoserver.config;
011:
012: import org.geotools.feature.AttributeType;
013: import org.vfny.geoserver.global.dto.AttributeTypeInfoDTO;
014: import org.vfny.geoserver.global.xml.NameSpaceElement;
015: import org.vfny.geoserver.global.xml.NameSpaceTranslator;
016: import org.vfny.geoserver.global.xml.NameSpaceTranslatorFactory;
017:
018: /**
019: * Allows editing of AttributeTypeInfo.
020: *
021: * <p>
022: * Represents most of a xs:element for an XMLSchema.
023: * </p>
024: *
025: * <p>
026: * we have three types of information to store, Schema defined types,
027: * references and extentions on types. If the type represented is either a
028: * reference or a Schema defined type then isRef should be true.
029: * </p>
030: *
031: * <p>
032: * Non-complex types are of the form:
033: * </p>
034: *
035: * <ul>
036: * <li>
037: * <code>{element name='test' type='xs:string'/}</code>
038: * </li>
039: * <li>
040: * <code>{element name='test' type='gml:PointType'/}</code>
041: * </li>
042: * </ul>
043: *
044: * <p>
045: * These cases have their type name stored in this.type
046: * </p>
047: *
048: * <p>
049: * For complex types such as:<pre><code>
050: * {element name='test'
051: * {xs:complexContent}
052: * {xs:extension base="gml:AbstractFeatureType"}
053: * {xs:sequence}
054: * {xs:element name="id"
055: * type="xs:string"
056: * minOccurs="0"/}
057: * {xs:element ref="gml:pointProperty"
058: * minOccurs="0"/}
059: * {/xs:sequence}
060: * {/xs:extension}
061: * {/xs:complexContent}
062: * {/element}
063: * </code></pre>
064: * The type will be equals to "(xml fragment)" and
065: * fragment contains a similar to above.
066: * </p>
067: *
068: * <p>
069: * minOccurs, maxOccurs and nillable are all attributes for all cases. There is
070: * more stuff in the XMLSchema spec but we don't care to parse it out right now.
071: * </p>
072: *
073: * @author dzwiers, Refractions Research, Inc.
074: * @version $Id: AttributeTypeInfoConfig.java 6326 2007-03-15 18:36:40Z jdeolive $
075: */
076: public class AttributeTypeInfoConfig {
077: /** Value of getType() used to indicate that fragement is in use */
078: public static final String TYPE_FRAGMENT = "(xml fragment)";
079:
080: /**
081: * XML Fragment used to define stuff.
082: *
083: * <p>
084: * This property is only used with getType() is equals to "(xml fragment)".
085: * </p>
086: *
087: * <p>
088: * baseGMLTypes can only be used in your XML fragment.
089: * </p>
090: */
091: private String fragment;
092:
093: /**
094: * Maxmium number of occurances of this attribute in a feature.
095: *
096: * <p>
097: * For Features based on the Simple Feature Specification this should be a
098: * value of 1. If the attribute is optional it should still be 1, although
099: * often optional is represented by allowing the Attribute to be
100: * <code>nillable</code>.
101: * </p>
102: *
103: * <p>
104: * Common Min..Max Occurs values:
105: * </p>
106: *
107: * <ul>
108: * <li>
109: * 0..<b>1</b>: attribute is optional
110: * </li>
111: * <li>
112: * 1..<b>1</b>: attribute is required (usual for Simple Features)
113: * </li>
114: * <li>
115: * 0..<b>N</b>: attribute forms a list that may be empty
116: * </li>
117: * </ul>
118: *
119: *
120: * @see AttributeTypeInfoDTO.isNillable
121: */
122: private int maxOccurs;
123:
124: /** attribute min occurs */
125: private int minOccurs;
126:
127: /** attribute name */
128: private final String name;
129:
130: /**
131: * Indicate if the attribute is allowed to be <code>null</code>.
132: *
133: * <p>
134: * Nillable is often used to indicate that an attribute is optional. The
135: * use of minOccurs and maxOccurs may be a more correct way to indicate
136: * optional attribtues.
137: * </p>
138: *
139: * @see AttributeTypeInfoDTO.minOccurs
140: * @see AttributeTypeInfoDTO.maxOccurs
141: */
142: private boolean nillable;
143:
144: /**
145: * Element type, a well-known gml or xs type or <code>TYPE_FRAGMENT</code>.
146: *
147: * <p>
148: * If getType is equals to TYPE_FRAGMENT please consult getFragment() to
149: * examin the actual user's definition.
150: * </p>
151: *
152: * <p>
153: * Other than that getType should be one of the constants defined by
154: * GMLUtils.
155: * </p>
156: */
157: public String type;
158:
159: /**
160: * Set up AttributeTypeInfo based on attributeType.
161: *
162: * <p>
163: * Set up is determined by the AttributeTypeInfoDTO( AttributeType )
164: * constructor. This allows all Schema generation to be acomplished in the
165: * same palce.
166: * </p>
167: *
168: * @param attributeType GeoTools2 attributeType used for configuration
169: */
170: public AttributeTypeInfoConfig(AttributeType attributeType) {
171: name = attributeType.getName();
172: minOccurs = 1;
173: maxOccurs = 1;
174:
175: NameSpaceTranslatorFactory nsFactory = NameSpaceTranslatorFactory
176: .getInstance();
177: NameSpaceTranslator nst = nsFactory
178: .getNameSpaceTranslator("xs");
179: NameSpaceElement nse = nst.getElement(name);
180:
181: if (nse == null) {
182: nse = nst.getDefaultElement(attributeType.getType());
183: }
184:
185: if (nse == null) {
186: nst = nsFactory.getNameSpaceTranslator("gml");
187: nse = nst.getElement(name);
188:
189: if (nse == null) {
190: nse = nst.getDefaultElement(attributeType.getType());
191: }
192: }
193:
194: //System.out.println("creating new atypininfig for: " + attributeType +
195: // ", nse = " + nse);
196: //if (nse != null) System.out.println(", nse type = " + nse.getTypeDefName());
197: fragment = "<!-- definition for " + attributeType.getType()
198: + " -->";
199:
200: if (nse == null) {
201: type = TYPE_FRAGMENT;
202: } else {
203: type = nse.getTypeDefName();
204: fragment = "";
205: }
206: }
207:
208: /**
209: * Set up AttributeTypeInfo based on Data Transfer Object.
210: *
211: * @param dto AttributeTypeInfoDTO used for configuration
212: */
213: public AttributeTypeInfoConfig(AttributeTypeInfoDTO dto) {
214: name = dto.getName();
215:
216: if (dto.isComplex()) {
217: type = TYPE_FRAGMENT;
218: fragment = dto.getType();
219: } else {
220: type = dto.getType();
221: fragment = "";
222: }
223:
224: minOccurs = dto.getMinOccurs();
225: maxOccurs = dto.getMaxOccurs();
226: nillable = dto.isNillable();
227: }
228:
229: /**
230: * XML Fragment used to define stuff.
231: *
232: * <p>
233: * This property is only used with getType() is equals to "(xml fragment)".
234: * </p>
235: *
236: * <p>
237: * baseGMLTypes can only be used in your XML fragment.
238: * </p>
239: *
240: * @return Returns the fragment.
241: */
242: public String getFragment() {
243: return fragment;
244: }
245:
246: /**
247: * getMaxOccurs purpose.
248: *
249: * <p>
250: * The max number of occurences for this element.
251: * </p>
252: *
253: * @return max number of occurences
254: */
255: public int getMaxOccurs() {
256: return maxOccurs;
257: }
258:
259: /**
260: * getMinOccurs purpose.
261: *
262: * <p>
263: * the min number of occurences for this element
264: * </p>
265: *
266: * @return min number of occurences
267: */
268: public int getMinOccurs() {
269: return minOccurs;
270: }
271:
272: /**
273: * getName purpose.
274: *
275: * <p>
276: * returns the element name
277: * </p>
278: *
279: * @return the element name
280: */
281: public String getName() {
282: return name;
283: }
284:
285: /**
286: * Element type, a well-known gml or xs type or <code>TYPE_FRAGMENT</code>.
287: *
288: * <p>
289: * If getType is equals to <code>TYPE_FRAGMENT</code> please consult
290: * getFragment() to examine the actual user's definition.
291: * </p>
292: *
293: * <p>
294: * Other than that getType should be one of the constants defined by
295: * GMLUtils.
296: * </p>
297: *
298: * @return The element, or <code>TYPE_FRAGMENT</code>
299: */
300: public String getType() {
301: return type;
302: }
303:
304: /**
305: * Indicate if the attribute is allowed to be <code>null</code>.
306: *
307: * <p>
308: * Nillable is often used to indicate that an attribute is optional. The
309: * use of minOccurs and maxOccurs may be a more correct way to indicate
310: * optional attribtues.
311: * </p>
312: *
313: * @return <code>true </code> to indicate attribute is alloed to be
314: * <code>null</code>
315: *
316: * @see AttributeTypeInfoDTO.setMinOccurs
317: * @see AttributeTypeInfoDTO.setMaxOccurs
318: */
319: public boolean isNillable() {
320: return nillable;
321: }
322:
323: /**
324: * XML Fragment used to define stuff.
325: *
326: * <p>
327: * This property is only used with getType() is equals to "(xml fragment)".
328: * </p>
329: *
330: * <p>
331: * baseGMLTypes can only be used in your XML fragment.
332: * </p>
333: *
334: * @param fragment The fragment to set.
335: */
336: public void setFragment(String fragment) {
337: this .fragment = fragment;
338: }
339:
340: /**
341: * Maxmium number of occurances of this attribute in a feature.
342: *
343: * <p>
344: * For Features based on the Simple Feature Specification this should be a
345: * value of 1. If the attribute is optional it should still be 1, although
346: * often optional is represented by allowing the Attribute to be
347: * <code>nillable</code>.
348: * </p>
349: *
350: * <p>
351: * Common Min..Max Occurs values:
352: * </p>
353: *
354: * <ul>
355: * <li>
356: * 0..<b>1</b>: attribute is optional
357: * </li>
358: * <li>
359: * 1..<b>1</b>: attribute is required (usual for Simple Features)
360: * </li>
361: * <li>
362: * 0..<b>N</b>: attribute forms a list that may be empty
363: * </li>
364: * </ul>
365: *
366: *
367: * @param max The maximum number of occurances
368: *
369: * @see AttributeTypeInfoDTO.isNillable
370: */
371: public void setMaxOccurs(int max) {
372: maxOccurs = max;
373: }
374:
375: /**
376: * Minimum number of occrances of this attribute in a feature.
377: *
378: * <p>
379: * For Features based on the Simple Feture Specification this should be a
380: * value of 1. If the attribute is optional is should be 0, although often
381: * optional is represented by allowing the attribute to be nillable.
382: * </p>
383: * Common Min..Max Occurs values:
384: *
385: * <ul>
386: * <li>
387: * <b>0</b>..1: attribute is optional
388: * </li>
389: * <li>
390: * <b>1</b>..1: attribute is required (usual for Simple Features)
391: * </li>
392: * <li>
393: * <b>0</b>..N: attribute forms a list that may be empty
394: * </li>
395: * </ul>
396: *
397: *
398: * @param min The minimum number of occurances
399: *
400: * @see AttributeTypeInfoDTO.isNillable
401: */
402: public void setMinOccurs(int min) {
403: minOccurs = min;
404: }
405:
406: /**
407: * Indicate if the attribute is allowed to be <code>null</code>.
408: *
409: * <p>
410: * Nillable is often used to indicate that an attribute is optional. The
411: * use of minOccurs and maxOccurs may be a more correct way to indicate
412: * optional attribtues.
413: * </p>
414: *
415: * @param nillable <code>true </code> to indicate attribute is alloed to be
416: * <code>null</code>
417: *
418: * @see AttributeTypeInfoDTO.setMinOccurs
419: * @see AttributeTypeInfoDTO.setMaxOccurs
420: */
421: public void setNillable(boolean nillable) {
422: this .nillable = nillable;
423: }
424:
425: /**
426: * Element type, a well-known gml or xs type or <code>TYPE_FRAGMENT</code>.
427: *
428: * <p>
429: * If getType is equals to <code>TYPE_FRAGMENT</code> please consult
430: * getFragment() to examin the actual user's definition. <br>
431: * Other than that getType should be one of the constants defined by
432: * GMLUtils.
433: * </p>
434: *
435: * @param type DOCUMENT ME!
436: */
437: public void setType(String type) {
438: this .type = type;
439: }
440:
441: public AttributeTypeInfoDTO toDTO() {
442: AttributeTypeInfoDTO dto = new AttributeTypeInfoDTO();
443: dto.setNillable(nillable);
444: dto.setName(name);
445: dto.setMaxOccurs(maxOccurs);
446: dto.setMinOccurs(minOccurs);
447:
448: if (type != TYPE_FRAGMENT) {
449: dto.setComplex(false);
450: dto.setType(type);
451: } else {
452: dto.setComplex(true);
453: dto.setType(fragment);
454: }
455:
456: return dto;
457: }
458: }
|