001: /**********************************************************************************
002: * $URL: https://source.sakaiproject.org/svn/metaobj/tags/sakai_2-4-1/metaobj-impl/api-impl/src/java/org/sakaiproject/metaobj/utils/xml/impl/BaseElementType.java $
003: * $Id: BaseElementType.java 14225 2006-09-05 17:39:44Z chmaurer@iupui.edu $
004: ***********************************************************************************
005: *
006: * Copyright (c) 2004, 2005, 2006 The Sakai Foundation.
007: *
008: * Licensed under the Educational Community License, Version 1.0 (the "License");
009: * you may not use this file except in compliance with the License.
010: * You may obtain a copy of the License at
011: *
012: * http://www.opensource.org/licenses/ecl1.php
013: *
014: * Unless required by applicable law or agreed to in writing, software
015: * distributed under the License is distributed on an "AS IS" BASIS,
016: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
017: * See the License for the specific language governing permissions and
018: * limitations under the License.
019: *
020: **********************************************************************************/package org.sakaiproject.metaobj.utils.xml.impl;
021:
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025: import java.util.regex.Pattern;
026:
027: import org.jdom.Attribute;
028: import org.jdom.Element;
029: import org.jdom.Namespace;
030: import org.sakaiproject.metaobj.utils.xml.ElementType;
031: import org.sakaiproject.metaobj.utils.xml.NormalizationException;
032: import org.sakaiproject.metaobj.utils.xml.SchemaNode;
033: import org.sakaiproject.metaobj.utils.xml.ValidatedNode;
034: import org.sakaiproject.metaobj.utils.xml.ValidationError;
035: import org.sakaiproject.metaobj.utils.xml.ValueRange;
036:
037: /**
038: * Created by IntelliJ IDEA.
039: * User: John Ellis
040: * Date: Apr 15, 2004
041: * Time: 5:07:44 PM
042: * To change this template use File | Settings | File Templates.
043: */
044: public class BaseElementType implements ElementType {
045:
046: protected static final int WHITE_SPACE_TYPE_NONE = 0;
047: protected static final int WHITE_SPACE_TYPE_PRESERVE = 1;
048: // replace with spaces
049: protected static final int WHITE_SPACE_TYPE_REPLACE = 2;
050: // remove all whitespace and replace with spaces
051: protected static final int WHITE_SPACE_TYPE_COLLAPSE = 3;
052:
053: protected int length = -1;
054: protected int maxLength = -1;
055: protected int minLength = -1;
056: protected Pattern pattern = null;
057: protected int whiteSpaceType = WHITE_SPACE_TYPE_NONE;
058: protected String defaultValue = "";
059: protected String fixedValue = "";
060: protected Element schemaElement;
061: protected SchemaNode parentNode = null;
062: private List enumeration = null;
063: private String baseType;
064:
065: public BaseElementType(String typeName, Element schemaElement,
066: SchemaNode parentNode, Namespace xsdNamespace) {
067: setBaseType(typeName);
068: this .schemaElement = schemaElement;
069: this .parentNode = parentNode;
070: init(xsdNamespace);
071: }
072:
073: protected void init(Namespace xsdNamespace) {
074: Element simpleType = schemaElement.getChild("simpleType",
075: xsdNamespace);
076: if (simpleType != null) {
077: Element restrictions = simpleType.getChild("restriction",
078: xsdNamespace);
079: if (restrictions != null) {
080: // process restrictions
081: length = processIntRestriction(restrictions, "length",
082: xsdNamespace, length);
083: maxLength = processIntRestriction(restrictions,
084: "maxLength", xsdNamespace, maxLength);
085: minLength = processIntRestriction(restrictions,
086: "minLength", xsdNamespace, minLength);
087:
088: String patternValue = processStringRestriction(
089: restrictions, "pattern", xsdNamespace);
090:
091: if (patternValue != null) {
092: pattern = Pattern.compile(patternValue);
093: }
094:
095: String whiteSpaceValue = processStringRestriction(
096: restrictions, "whiteSpace", xsdNamespace);
097: if (whiteSpaceValue != null) {
098: if (whiteSpaceValue.equals("preserve")) {
099: whiteSpaceType = WHITE_SPACE_TYPE_PRESERVE;
100: }
101: if (whiteSpaceValue.equals("replace")) {
102: whiteSpaceType = WHITE_SPACE_TYPE_REPLACE;
103: }
104: if (whiteSpaceValue.equals("collapse")) {
105: whiteSpaceType = WHITE_SPACE_TYPE_COLLAPSE;
106: }
107: }
108: }
109: }
110:
111: if (schemaElement.getAttribute("default") != null) {
112: defaultValue = schemaElement.getAttributeValue("default");
113: }
114: if (schemaElement.getAttribute("fixed") != null) {
115: fixedValue = schemaElement.getAttributeValue("fixed");
116: defaultValue = fixedValue;
117: }
118: }
119:
120: protected void processEnumerations(Element restrictions,
121: Namespace xsdNamespace) {
122: List enums = restrictions.getChildren("enumeration",
123: xsdNamespace);
124: List temp = null;
125: enumeration = null;
126:
127: if (enums.size() > 0) {
128: temp = new ArrayList();
129: }
130:
131: for (Iterator i = enums.iterator(); i.hasNext();) {
132: Element enumer = (Element) i.next();
133: String value = enumer.getAttributeValue("value");
134: temp.add(getActualNormalizedValue(value));
135: }
136:
137: enumeration = temp;
138: }
139:
140: protected String processStringRestriction(Element restrictions,
141: String s, Namespace xsdNamespace) {
142: Element currentRestriction = restrictions.getChild(s,
143: xsdNamespace);
144:
145: if (currentRestriction == null) {
146: return null;
147: }
148:
149: return currentRestriction.getAttributeValue("value");
150: }
151:
152: protected int processIntRestriction(Element restrictions, String s,
153: Namespace xsdNamespace, int defaultValue) {
154: String value = processStringRestriction(restrictions, s,
155: xsdNamespace);
156:
157: if (value == null) {
158: return defaultValue;
159: }
160:
161: return Integer.parseInt(value);
162: }
163:
164: /**
165: * Validates the passed in node and all children.
166: * Will also normalize any values.
167: *
168: * @param node a jdom element to validate
169: * @return the validated Element wrapped
170: * in a ValidatedNode class
171: */
172: public ValidatedNode validateAndNormalize(Element node) {
173: ValidatedNodeImpl validatedNode = new ValidatedNodeImpl(
174: parentNode, node);
175:
176: String value = node.getText();
177:
178: try {
179: value = getSchemaNormalizedValue(value);
180: node.setText(value);
181: validatedNode
182: .setNormalizedValue(getActualNormalizedValue(value));
183:
184: if (value == null || value.length() == 0) {
185: return null;
186: }
187: } catch (NormalizationException exp) {
188: validatedNode.getErrors().add(
189: new ValidationError(validatedNode, exp
190: .getErrorCode(), exp.getErrorInfo()));
191: }
192:
193: return validatedNode;
194: }
195:
196: public String getSchemaNormalizedValue(Object value)
197: throws NormalizationException {
198:
199: if (value == null) {
200: return null;
201: }
202:
203: return getSchemaNormalizedValue(value.toString());
204: }
205:
206: public String getSchemaNormalizedValue(String value)
207: throws NormalizationException {
208: if (value == null) {
209: return defaultValue;
210: }
211:
212: if (fixedValue != null && fixedValue.length() > 0) {
213: return fixedValue;
214: }
215:
216: String startingValue = handleWhiteSpace(value.toString());
217:
218: int valueLength = startingValue.length();
219:
220: if (length != -1 && valueLength != length) {
221: throw new NormalizationException("Invalid string length",
222: NormalizationException.INVALID_LENGTH_ERROR_CODE,
223: new Object[] { startingValue, new Integer(length) });
224: }
225:
226: if (maxLength != -1 && valueLength > maxLength) {
227: throw new NormalizationException(
228: "Invalid string length",
229: NormalizationException.INVALID_LENGTH_TOO_LONG_ERROR_CODE,
230: new Object[] { startingValue,
231: new Integer(maxLength) });
232: }
233:
234: if (minLength != -1 && valueLength < minLength
235: && minLength == 1) {
236: throw new NormalizationException("Required field",
237: NormalizationException.REQIRED_FIELD_ERROR_CODE,
238: new Object[0]);
239: }
240:
241: if (minLength != -1 && valueLength < minLength) {
242: throw new NormalizationException(
243: "Invalid string length",
244: NormalizationException.INVALID_LENGTH_TOO_SHORT_ERROR_CODE,
245: new Object[] { startingValue,
246: new Integer(minLength) });
247: }
248:
249: if (pattern != null
250: && !pattern.matcher(startingValue).matches()) {
251: throw new NormalizationException(
252: "Invalid string pattern",
253: NormalizationException.INVALID_PATTERN_MATCH_ERROR_CODE,
254: new Object[] { startingValue, pattern.pattern() });
255: }
256:
257: return startingValue;
258: }
259:
260: private String handleWhiteSpace(String s) {
261: if (whiteSpaceType == WHITE_SPACE_TYPE_NONE
262: || whiteSpaceType == WHITE_SPACE_TYPE_PRESERVE) {
263: return s;
264: }
265:
266: if (whiteSpaceType == WHITE_SPACE_TYPE_REPLACE) {
267: s = s.replaceAll("\\s", " ");
268: } else if (whiteSpaceType == WHITE_SPACE_TYPE_COLLAPSE) {
269: s = s.replaceAll("\\s+", " ");
270: }
271:
272: return s;
273: }
274:
275: public Class getObjectType() {
276: return String.class;
277: }
278:
279: public Object getActualNormalizedValue(String value) {
280: Object returned = getSchemaNormalizedValue(value);
281:
282: if (enumeration != null) {
283: if (!enumeration.contains(returned)) {
284: throw new NormalizationException(
285: "Not enumerated",
286: NormalizationException.NOT_IN_ENUMERATION_ERROR_CODE,
287: new Object[] { returned });
288: }
289: }
290:
291: return returned;
292: }
293:
294: public int getLength() {
295: return length;
296: }
297:
298: public int getMaxLength() {
299: return maxLength;
300: }
301:
302: public int getMinLength() {
303: return minLength;
304: }
305:
306: public Pattern getPattern() {
307: return pattern;
308: }
309:
310: public ValueRange getRange() {
311: return null;
312: }
313:
314: public int getWhiteSpaceType() {
315: return whiteSpaceType;
316: }
317:
318: public String getDefaultValue() {
319: return defaultValue;
320: }
321:
322: public String getFixedValue() {
323: return fixedValue;
324: }
325:
326: public List getEnumeration() {
327: return enumeration;
328: }
329:
330: public BaseElementType postInit(Namespace xsdNamespace) {
331: Element simpleType = schemaElement.getChild("simpleType",
332: xsdNamespace);
333: if (simpleType != null) {
334: Element restrictions = simpleType.getChild("restriction",
335: xsdNamespace);
336:
337: if (restrictions != null) {
338: processEnumerations(restrictions, xsdNamespace);
339: }
340: }
341:
342: return this ;
343: }
344:
345: public ValidatedNode validateAndNormalize(Attribute node) {
346: ValidatedNodeImpl validatedNode = new ValidatedNodeImpl(
347: parentNode, null);
348:
349: String value = node.getValue();
350:
351: try {
352: value = getSchemaNormalizedValue(value);
353: node.setValue(value);
354: validatedNode
355: .setNormalizedValue(getActualNormalizedValue(value));
356:
357: if (value == null || value.length() == 0) {
358: return null;
359: }
360: } catch (NormalizationException exp) {
361: validatedNode.getErrors().add(
362: new ValidationError(validatedNode, exp
363: .getErrorCode(), exp.getErrorInfo()));
364: }
365:
366: return validatedNode;
367: }
368:
369: public String getBaseType() {
370: return baseType;
371: }
372:
373: public void setBaseType(String baseType) {
374: this.baseType = baseType;
375: }
376:
377: }
|