001: /*
002: * This file is part of PFIXCORE.
003: *
004: * PFIXCORE is free software; you can redistribute it and/or modify
005: * it under the terms of the GNU Lesser General Public License as published by
006: * the Free Software Foundation; either version 2 of the License, or
007: * (at your option) any later version.
008: *
009: * PFIXCORE is distributed in the hope that it will be useful,
010: * but WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
012: * GNU Lesser General Public License for more details.
013: *
014: * You should have received a copy of the GNU Lesser General Public License
015: * along with PFIXCORE; if not, write to the Free Software
016: * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
017: *
018: */
019:
020: package de.schlund.pfixcore.webservice.config;
021:
022: import java.io.CharArrayWriter;
023: import java.io.InputStream;
024: import java.io.ObjectInputStream;
025: import java.io.ObjectOutputStream;
026: import java.io.OutputStream;
027: import java.net.MalformedURLException;
028: import java.util.ArrayList;
029: import java.util.Collection;
030: import java.util.List;
031: import java.util.Stack;
032:
033: import javax.xml.parsers.SAXParser;
034: import javax.xml.parsers.SAXParserFactory;
035:
036: import org.xml.sax.Attributes;
037: import org.xml.sax.SAXException;
038: import org.xml.sax.helpers.DefaultHandler;
039:
040: import de.schlund.pfixcore.webservice.Constants;
041: import de.schlund.pfixcore.webservice.fault.FaultHandler;
042: import de.schlund.pfixxml.config.CustomizationHandler;
043: import de.schlund.pfixxml.resources.FileResource;
044: import de.schlund.pfixxml.resources.ResourceUtil;
045:
046: /**
047: * @author mleidig@schlund.de
048: */
049: public class ConfigurationReader extends DefaultHandler {
050:
051: FileResource configFile;
052: FileResource configDir;
053: Configuration config;
054: Stack<Object> contextStack = new Stack<Object>();
055: Object context;
056: CharArrayWriter content = new CharArrayWriter();
057: List<FileResource> importedFiles = new ArrayList<FileResource>();
058: boolean isRootFile;
059:
060: public static Configuration read(FileResource file)
061: throws Exception {
062: return read(file, true);
063: }
064:
065: private static Configuration read(FileResource file,
066: boolean isRootFile) throws Exception {
067: ConfigurationReader reader = new ConfigurationReader(file,
068: isRootFile);
069: reader.read();
070: return reader.getConfiguration();
071: }
072:
073: public Configuration getConfiguration() {
074: return config;
075: }
076:
077: public ConfigurationReader(FileResource configFile,
078: boolean isRootFile) {
079: this .configFile = configFile;
080: this .isRootFile = isRootFile;
081: configDir = configFile.getParentAsFileResource();
082: }
083:
084: public void read() throws Exception {
085: CustomizationHandler cushandler = new CustomizationHandler(
086: this , Constants.WS_CONF_NS, Constants.CUS_NS);
087: SAXParserFactory spf = SAXParserFactory.newInstance();
088: spf.setNamespaceAware(true);
089: SAXParser parser = spf.newSAXParser();
090: parser.parse(configFile.getInputStream(), cushandler);
091: }
092:
093: private void setContext(Object obj) {
094: contextStack.add(obj);
095: context = obj;
096: }
097:
098: private void resetContext() {
099: contextStack.pop();
100: if (contextStack.empty())
101: context = null;
102: else
103: context = contextStack.peek();
104: }
105:
106: public void startElement(String uri, String localName,
107: String qName, Attributes atts) throws SAXException {
108: content.reset();
109: if (context == null) {
110: if (localName.equals("webservice-config")) {
111: config = new Configuration();
112: setContext(config);
113: }
114: } else if (context instanceof Configuration) {
115: if (localName.equals("webservice-global")) {
116: GlobalServiceConfig globSrvConf = new GlobalServiceConfig();
117: config.setGlobalServiceConfig(globSrvConf);
118: setContext(globSrvConf);
119: } else if (localName.equals("webservice")) {
120: ServiceConfig srvConf = new ServiceConfig(config
121: .getGlobalServiceConfig());
122: String name = getStringAttribute(atts, "name", true);
123: srvConf.setName(name);
124: config.addServiceConfig(srvConf);
125: setContext(srvConf);
126: } else if (localName.equals("import")) {
127: String name = getStringAttribute(atts, "href", true);
128: FileResource impFile = ResourceUtil
129: .getFileResourceFromDocroot(name);
130: importedFiles.add(impFile);
131: }
132: } else if (context instanceof GlobalServiceConfig) {
133: GlobalServiceConfig globSrvConf = (GlobalServiceConfig) context;
134: if (localName.equals("wsdlsupport")) {
135: Boolean wsdlSupport = getBooleanAttribute(atts,
136: "enabled");
137: if (wsdlSupport != null)
138: globSrvConf.setWSDLSupportEnabled(wsdlSupport);
139: String wsdlRepo = getStringAttribute(atts, "repository");
140: if (wsdlRepo != null)
141: globSrvConf.setWSDLRepository(wsdlRepo);
142: } else if (localName.equals("stubgeneration")) {
143: Boolean stubGeneration = getBooleanAttribute(atts,
144: "enabled");
145: if (stubGeneration != null)
146: globSrvConf
147: .setStubGenerationEnabled(stubGeneration);
148: String stubRepo = getStringAttribute(atts, "repository");
149: if (stubRepo != null)
150: globSrvConf.setStubRepository(stubRepo);
151: String jsNamespace = getStringAttribute(atts,
152: "jsnamespace");
153: if (jsNamespace != null)
154: globSrvConf.setStubJSNamespace(jsNamespace);
155: } else if (localName.equals("protocol")) {
156: String proto = getStringAttribute(atts, "type",
157: Constants.PROTOCOL_TYPES);
158: if (proto != null)
159: globSrvConf.setProtocolType(proto);
160: } else if (localName.equals("encoding")) {
161: String encStyle = getStringAttribute(atts, "style",
162: Constants.ENCODING_STYLES);
163: if (encStyle != null)
164: globSrvConf.setEncodingStyle(encStyle);
165: String encUse = getStringAttribute(atts, "use",
166: Constants.ENCODING_USES);
167: if (encUse != null)
168: globSrvConf.setEncodingUse(encUse);
169: } else if (localName.equals("json")) {
170: Boolean hinting = getBooleanAttribute(atts,
171: "classhinting");
172: if (hinting != null)
173: globSrvConf.setJSONClassHinting(hinting);
174: } else if (localName.equals("session")) {
175: String sessType = getStringAttribute(atts, "type",
176: Constants.SESSION_TYPES);
177: if (sessType != null)
178: globSrvConf.setSessionType(sessType);
179: } else if (localName.equals("scope")) {
180: String scopeType = getStringAttribute(atts, "type",
181: Constants.SERVICE_SCOPES);
182: if (scopeType != null)
183: globSrvConf.setScopeType(scopeType);
184: } else if (localName.equals("ssl")) {
185: Boolean sslForce = getBooleanAttribute(atts, "force");
186: if (sslForce != null)
187: globSrvConf.setSSLForce(sslForce);
188: } else if (localName.equals("context")) {
189: String ctxName = getStringAttribute(atts, "name", true);
190: globSrvConf.setContextName(ctxName);
191: Boolean ctxSync = getBooleanAttribute(atts,
192: "synchronize");
193: if (ctxSync != null)
194: globSrvConf.setSynchronizeOnContext(ctxSync);
195: } else if (localName.equals("admin")) {
196: Boolean admin = getBooleanAttribute(atts, "enabled");
197: if (admin != null)
198: globSrvConf.setAdminEnabled(admin);
199: } else if (localName.equals("monitoring")) {
200: Boolean monitoring = getBooleanAttribute(atts,
201: "enabled");
202: if (monitoring != null)
203: globSrvConf.setMonitoringEnabled(monitoring);
204: String monitorScope = getStringAttribute(atts, "scope",
205: Constants.MONITOR_SCOPES);
206: if (monitorScope != null)
207: globSrvConf.setMonitoringScope(monitorScope);
208: Integer monitorSize = getIntegerAttribute(atts,
209: "historysize");
210: if (monitorSize != null)
211: globSrvConf.setMonitoringHistorySize(monitorSize);
212: } else if (localName.equals("logging")) {
213: Boolean logging = getBooleanAttribute(atts, "enabled");
214: if (logging != null)
215: globSrvConf.setLoggingEnabled(logging);
216: } else if (localName.equals("faulthandler")) {
217: FaultHandler faultHandler = (FaultHandler) getObjectAttribute(
218: atts, "class", FaultHandler.class, false);
219: globSrvConf.setFaultHandler(faultHandler);
220: setContext(faultHandler);
221: }
222: } else if (context instanceof ServiceConfig) {
223: ServiceConfig srvConf = (ServiceConfig) context;
224: if (localName.equals("interface")) {
225: String name = getStringAttribute(atts, "name", true);
226: srvConf.setInterfaceName(name);
227: } else if (localName.equals("implementation")) {
228: String name = getStringAttribute(atts, "name", true);
229: srvConf.setImplementationName(name);
230: } else if (localName.equals("protocol")) {
231: String proto = getStringAttribute(atts, "type",
232: Constants.PROTOCOL_TYPES);
233: if (proto != null)
234: srvConf.setProtocolType(proto);
235: } else if (localName.equals("stubgeneration")) {
236: String jsNamespace = getStringAttribute(atts,
237: "jsnamespace");
238: if (jsNamespace != null)
239: srvConf.setStubJSNamespace(jsNamespace);
240: } else if (localName.equals("encoding")) {
241: String encStyle = getStringAttribute(atts, "style",
242: Constants.ENCODING_STYLES);
243: if (encStyle != null)
244: srvConf.setEncodingStyle(encStyle);
245: String encUse = getStringAttribute(atts, "use",
246: Constants.ENCODING_USES);
247: if (encUse != null)
248: srvConf.setEncodingUse(encUse);
249: } else if (localName.equals("json")) {
250: Boolean hinting = getBooleanAttribute(atts,
251: "classhinting");
252: if (hinting != null)
253: srvConf.setJSONClassHinting(hinting);
254: } else if (localName.equals("session")) {
255: String sessType = getStringAttribute(atts, "type",
256: Constants.SESSION_TYPES);
257: if (sessType != null)
258: srvConf.setSessionType(sessType);
259: } else if (localName.equals("scope")) {
260: String scopeType = getStringAttribute(atts, "type",
261: Constants.SERVICE_SCOPES);
262: if (scopeType != null)
263: srvConf.setScopeType(scopeType);
264: } else if (localName.equals("ssl")) {
265: Boolean sslForce = getBooleanAttribute(atts, "force");
266: if (sslForce != null)
267: srvConf.setSSLForce(sslForce);
268: } else if (localName.equals("context")) {
269: String ctxName = getStringAttribute(atts, "name", true);
270: srvConf.setContextName(ctxName);
271: Boolean ctxSync = getBooleanAttribute(atts,
272: "synchronize");
273: if (ctxSync != null)
274: srvConf.setSynchronizeOnContext(ctxSync);
275: } else if (localName.equals("faulthandler")) {
276: FaultHandler faultHandler = (FaultHandler) getObjectAttribute(
277: atts, "class", FaultHandler.class, false);
278: srvConf.setFaultHandler(faultHandler);
279: setContext(faultHandler);
280: }
281: } else if (context instanceof FaultHandler) {
282: FaultHandler faultHandler = (FaultHandler) context;
283: if (localName.equals("param")) {
284: String name = getStringAttribute(atts, "name", true);
285: String value = getStringAttribute(atts, "value", true);
286: faultHandler.addParam(name, value);
287: }
288: }
289: }
290:
291: public void endElement(String uri, String localName, String qName)
292: throws SAXException {
293: if (context instanceof Configuration) {
294: if (localName.equals("webservice-config")) {
295: resetContext();
296: }
297: } else if (context instanceof GlobalServiceConfig) {
298: GlobalServiceConfig globSrvConf = (GlobalServiceConfig) context;
299: if (localName.equals("webservice-global")) {
300: resetContext();
301: } else if (localName.equals("requestpath")) {
302: String path = getContent();
303: if (path != null && !path.equals(""))
304: globSrvConf.setRequestPath(path);
305: }
306: } else if (context instanceof ServiceConfig) {
307: if (localName.equals("webservice")) {
308: resetContext();
309: }
310: } else if (context instanceof FaultHandler) {
311: if (localName.equals("faulthandler")) {
312: FaultHandler faultHandler = (FaultHandler) context;
313: faultHandler.init();
314: resetContext();
315: }
316: }
317: }
318:
319: @Override
320: public void endDocument() throws SAXException {
321: processImports();
322: if (isRootFile) {
323: GlobalServiceConfig globSrvConf = config
324: .getGlobalServiceConfig();
325: if (globSrvConf == null) {
326: globSrvConf = new GlobalServiceConfig();
327: config.setGlobalServiceConfig(globSrvConf);
328: }
329: Collection<ServiceConfig> wsList = config
330: .getServiceConfig();
331: for (ServiceConfig ws : wsList) {
332: ws.setGlobalServiceConfig(globSrvConf);
333: }
334: }
335: FileResource metaFile = ResourceUtil.getFileResource(configDir,
336: "beanmetadata.xml");
337: try {
338: if (config.getGlobalServiceConfig() != null)
339: config.getGlobalServiceConfig()
340: .setDefaultBeanMetaDataURL(metaFile.toURL());
341: } catch (MalformedURLException x) {
342: throw new SAXException(
343: "Can't get default bean metadata URL.", x);
344: }
345: }
346:
347: public void characters(char[] ch, int start, int length)
348: throws SAXException {
349: content.write(ch, start, length);
350: }
351:
352: public String getContent() {
353: return content.toString().trim();
354: }
355:
356: private void processImports() throws SAXException {
357: for (int i = importedFiles.size() - 1; i > -1; i--) {
358: try {
359: FileResource impFile = importedFiles.get(i);
360: Configuration impConf = ConfigurationReader.read(
361: impFile, false);
362: if (config.getGlobalServiceConfig() == null
363: && impConf.getGlobalServiceConfig() != null) {
364: config.setGlobalServiceConfig(impConf
365: .getGlobalServiceConfig());
366: }
367: Collection<ServiceConfig> wsList = impConf
368: .getServiceConfig();
369: for (ServiceConfig ws : wsList) {
370: if (config.getServiceConfig(ws.getName()) == null) {
371: config.addServiceConfig(ws);
372: }
373: }
374: } catch (Exception x) {
375: x.printStackTrace();
376: throw new SAXException(
377: "Error processing imported file: "
378: + importedFiles.get(i), x);
379: }
380: }
381: }
382:
383: private String getStringAttribute(Attributes attributes,
384: String attrName) throws ConfigException {
385: String val = attributes.getValue(attrName);
386: if (val != null)
387: val = val.trim();
388: return val;
389: }
390:
391: private String getStringAttribute(Attributes attributes,
392: String attrName, boolean mandatory) throws ConfigException {
393: String val = attributes.getValue(attrName);
394: if (val == null && mandatory)
395: throw new ConfigException(
396: ConfigException.MISSING_ATTRIBUTE, attrName);
397: return val.trim();
398: }
399:
400: private String getStringAttribute(Attributes attributes,
401: String attrName, String[] allowedValues)
402: throws ConfigException {
403: String val = attributes.getValue(attrName);
404: if (val == null)
405: return null;
406: for (int i = 0; i < allowedValues.length; i++) {
407: if (val.equals(allowedValues[i]))
408: return val;
409: }
410: throw new ConfigException(
411: ConfigException.ILLEGAL_ATTRIBUTE_VALUE, attrName, val);
412: }
413:
414: private Boolean getBooleanAttribute(Attributes attributes,
415: String attrName) throws ConfigException {
416: String val = attributes.getValue(attrName);
417: if (val == null)
418: return null;
419: if (val.equalsIgnoreCase("true"))
420: return true;
421: if (val.equalsIgnoreCase("false"))
422: return false;
423: throw new ConfigException(
424: ConfigException.ILLEGAL_ATTRIBUTE_VALUE, attrName, val);
425: }
426:
427: private Integer getIntegerAttribute(Attributes attributes,
428: String attrName) throws ConfigException {
429: String val = attributes.getValue(attrName);
430: if (val == null)
431: return null;
432: try {
433: int intVal = Integer.parseInt(val);
434: return intVal;
435: } catch (NumberFormatException x) {
436: throw new ConfigException(
437: ConfigException.ILLEGAL_ATTRIBUTE_VALUE, attrName,
438: val);
439: }
440: }
441:
442: private Object getObjectAttribute(Attributes attributes,
443: String attrName, Class<?> super Clazz, boolean mandatory)
444: throws ConfigException {
445: String val = attributes.getValue(attrName);
446: if (val == null) {
447: if (mandatory)
448: throw new ConfigException(
449: ConfigException.MISSING_ATTRIBUTE, attrName);
450: else
451: return null;
452: }
453: try {
454: Class<?> clazz = Class.forName(val);
455: Object obj = clazz.newInstance();
456: if (!super Clazz.isInstance(obj))
457: throw new ClassCastException("Class '" + val
458: + "' can't be casted to '"
459: + super Clazz.getName() + "'.");
460: return obj;
461: } catch (Exception x) {
462: throw new ConfigException(
463: ConfigException.ILLEGAL_ATTRIBUTE_VALUE, attrName,
464: val, x);
465: }
466: }
467:
468: public static void serialize(Configuration config, FileResource file)
469: throws Exception {
470: OutputStream out = file.getOutputStream();
471: serialize(config, out);
472: }
473:
474: public static void serialize(Configuration config, OutputStream out)
475: throws Exception {
476: ObjectOutputStream serializer = new ObjectOutputStream(out);
477: serializer.writeObject(config);
478: serializer.flush();
479: }
480:
481: public static Configuration deserialize(FileResource file)
482: throws Exception {
483: InputStream in = file.getInputStream();
484: return deserialize(in);
485: }
486:
487: public static Configuration deserialize(InputStream in)
488: throws Exception {
489: ObjectInputStream deserializer = new ObjectInputStream(in);
490: return (Configuration) deserializer.readObject();
491: }
492:
493: }
|