001: /*
002: * Spoon - http://spoon.gforge.inria.fr/
003: * Copyright (C) 2006 INRIA Futurs <renaud.pawlak@inria.fr>
004: *
005: * This software is governed by the CeCILL-C License under French law and
006: * abiding by the rules of distribution of free software. You can use, modify
007: * and/or redistribute the software under the terms of the CeCILL-C license as
008: * circulated by CEA, CNRS and INRIA at http://www.cecill.info.
009: *
010: * This program is distributed in the hope that it will be useful, but WITHOUT
011: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
012: * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details.
013: *
014: * The fact that you are presently reading this means that you have had
015: * knowledge of the CeCILL-C license and that you accept its terms.
016: */
017:
018: package spoon.support.processing;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.Map;
025: import java.util.TreeMap;
026: import java.util.Map.Entry;
027:
028: import org.xml.sax.Attributes;
029: import org.xml.sax.InputSource;
030: import org.xml.sax.SAXException;
031: import org.xml.sax.XMLReader;
032: import org.xml.sax.helpers.DefaultHandler;
033: import org.xml.sax.helpers.XMLReaderFactory;
034:
035: import spoon.processing.ProcessorProperties;
036: import spoon.reflect.Factory;
037:
038: /**
039: * This class defines a processor properties accessor that parses an XML
040: * description of the properties.
041: */
042: public class XmlProcessorProperties implements ProcessorProperties {
043:
044: /**
045: * Defines the tag handler of an XML Spoon property file.
046: */
047: public class Loader extends DefaultHandler {
048: boolean isValue = false;
049:
050: String name;
051:
052: Object value;
053:
054: /**
055: * Handdles a tag content.
056: */
057: @SuppressWarnings("unchecked")
058: @Override
059: public void characters(char[] ch, int start, int length)
060: throws SAXException {
061: if (isValue) {
062: if ((value == null) || !(value instanceof Collection)) {
063: value = new ArrayList<Object>();
064: }
065: ((Collection<Object>) value).add(new String(ch, start,
066: length));
067: }
068: }
069:
070: /**
071: * Handdles a tag end.
072: */
073: @Override
074: public void endElement(String uri, String localName,
075: String qName) throws SAXException {
076: if (localName.equals("property")) {
077: props.put(name, value);
078: value = null;
079: } else if (localName.equals("value")) {
080: isValue = false;
081: }
082: }
083:
084: /**
085: * Handdles a tag start.
086: */
087: @Override
088: public void startElement(String uri, String localName,
089: String qName, Attributes attributes)
090: throws SAXException {
091: if (localName.equals("property")) {
092: name = attributes.getValue("name");
093: if (attributes.getValue("value") != null) {
094: value = attributes.getValue("value");
095: }
096: } else if (localName.equals("value")) {
097: isValue = true;
098: }
099: }
100: }
101:
102: Factory factory;
103:
104: String processorName;
105:
106: private Map<String, Object> props = new TreeMap<String, Object>();
107:
108: public XmlProcessorProperties(Factory factory, String processorName) {
109: this .processorName = processorName;
110: this .factory = factory;
111: }
112:
113: public XmlProcessorProperties(Factory factory,
114: String processorName, InputStream stream)
115: throws IOException, SAXException {
116: this .processorName = processorName;
117: this .factory = factory;
118: load(stream);
119: }
120:
121: public void addProperty(String name, Object value) {
122: props.put(name, value);
123: }
124:
125: @SuppressWarnings("unchecked")
126: public <T> T get(Class<T> type, String name) {
127: if (!props.containsKey(name)) {
128: return null;
129: }
130: if (type.isArray()) {
131: return (T) factory.convertArray(type.getComponentType(),
132: (Collection<Object>) props.get(name));
133: }
134: return factory.convert(type, props.get(name));
135: }
136:
137: public String getProcessorName() {
138: return processorName;
139: }
140:
141: private void load(InputStream stream) throws IOException,
142: SAXException {
143: if (stream == null) {
144: return;
145: }
146: XMLReader xr;
147: xr = XMLReaderFactory.createXMLReader();
148: Loader handler = new Loader();
149: xr.setContentHandler(handler);
150: xr.parse(new InputSource(stream));
151: }
152:
153: @Override
154: public String toString() {
155: StringBuffer buf = new StringBuffer();
156: buf.append("Properties : \n");
157:
158: for (Entry<String, Object> ent : props.entrySet()) {
159: buf.append(ent.getKey());
160: for (int i = ent.getKey().length(); i < 15; i++) {
161: buf.append(" ");
162: }
163: buf.append(": " + ent.getValue() + "\n");
164: }
165: return buf.toString();
166: }
167: }
|