001: /*
002: * Copyright 2001-2007 Geert Bevin <gbevin[remove] at uwyn dot com>
003: * Distributed under the terms of either:
004: * - the common development and distribution license (CDDL), v1.0; or
005: * - the GNU Lesser General Public License, v2.1 or later
006: * $Id: Xml2BlockingRepository.java 3634 2007-01-08 21:42:24Z gbevin $
007: */
008: package com.uwyn.rife.rep;
009:
010: import com.uwyn.rife.config.Config;
011: import com.uwyn.rife.database.Datasources;
012: import com.uwyn.rife.ioc.PropertyValue;
013: import com.uwyn.rife.ioc.PropertyValueList;
014: import com.uwyn.rife.ioc.PropertyValueObject;
015: import com.uwyn.rife.ioc.PropertyValueParticipant;
016: import com.uwyn.rife.ioc.PropertyValueTemplate;
017: import com.uwyn.rife.ioc.exceptions.PropertyConstructionException;
018: import com.uwyn.rife.ioc.exceptions.PropertyValueException;
019: import com.uwyn.rife.rep.exceptions.ParticipantNotFoundException;
020: import com.uwyn.rife.resources.ResourceFinder;
021: import com.uwyn.rife.tools.StringUtils;
022: import com.uwyn.rife.xml.Xml2Data;
023: import com.uwyn.rife.xml.exceptions.XmlErrorException;
024: import java.util.ArrayList;
025: import java.util.Stack;
026: import org.xml.sax.Attributes;
027:
028: /**
029: * Processes a <code>Rep</code> XML document and add all the declared
030: * participants to a <code>BlockingRepository</code>.
031: *
032: * @author Geert Bevin (gbevin[remove] at uwyn dot com)
033: * @version $Revision: 3634 $
034: * @see BlockingRepository
035: * @since 1.0
036: */
037: public class Xml2BlockingRepository extends Xml2Data {
038: private BlockingRepository mRepository = null;
039: private String mName = null;
040: private boolean mBlocking = false;
041: private String mParameter = null;
042: private StringBuilder mCharacterData = null;
043:
044: private String mCurrentPropertyName = null;
045:
046: private Stack<String> mParticipantNameStack = null;
047: private Stack<PropertyValueList> mPropertyValuesStack = null;
048: private String mCurrentTemplateType = null;
049:
050: Xml2BlockingRepository(BlockingRepository repository) {
051: mRepository = repository;
052: }
053:
054: /**
055: * Adds all the participants of a provided resource to the repository.
056: *
057: * @param resource the name of the resource that contains the declaration
058: * of the participatns.
059: * @param resourcefinder a <code>ResourceFinder</code> that will be used
060: * to retrieve the resource
061: * @exception XmlErrorException if an error occurs during the processing
062: * of the document
063: */
064: public void addRepParticipants(String resource,
065: ResourceFinder resourcefinder) throws XmlErrorException {
066: processXml(resource, resourcefinder);
067: }
068:
069: public void startElement(String namespaceURI, String localName,
070: String qName, Attributes atts) {
071: if (qName.equals("participant") && null == mCurrentPropertyName) {
072: mCharacterData = new StringBuilder();
073:
074: mName = atts.getValue("name");
075:
076: mBlocking = false;
077: String blocking = atts.getValue("blocking");
078: if (blocking != null
079: && (blocking.equals("1") || blocking.equals("t") || blocking
080: .equals("true"))) {
081: mBlocking = true;
082: }
083:
084: mParameter = atts.getValue("param");
085: } else if (qName.equals("property")) {
086: mCurrentPropertyName = atts.getValue("name");
087: mCharacterData = new StringBuilder();
088: mPropertyValuesStack = new Stack<PropertyValueList>();
089: mPropertyValuesStack.push(new PropertyValueList());
090: } else if (qName.equals("participant")
091: || qName.equals("datasource")) {
092: // check if inapproriate attributes aren't used
093: if (qName.equals("participant")) {
094: if (null == atts.getValue("name")) {
095: throw new XmlErrorException(
096: "The repository 'participant' tag requires the 'name' attribute when it's used as a property value.");
097: }
098: if (atts.getValue("param") != null) {
099: throw new XmlErrorException(
100: "The repository 'participant' tag can't have the 'param' attribute when it's used as a property value.");
101: }
102: }
103:
104: // store the character data of the previous property value series
105: mPropertyValuesStack.peek().add(
106: new PropertyValueObject(mCharacterData.toString()));
107:
108: // initialize the new nested participant
109: if (null == mParticipantNameStack) {
110: mParticipantNameStack = new Stack<String>();
111: }
112:
113: mCharacterData = new StringBuilder();
114:
115: String name;
116: if (qName.equals("datasource")) {
117: name = Datasources.DEFAULT_PARTICIPANT_NAME;
118: } else {
119: name = atts.getValue("name");
120: }
121:
122: mParticipantNameStack.push(name);
123: mPropertyValuesStack.push(new PropertyValueList());
124: } else if (qName.equals("template")) {
125: // store the character data of the previous property value series
126: mPropertyValuesStack.peek().add(
127: new PropertyValueObject(mCharacterData.toString()));
128:
129: mCurrentTemplateType = atts.getValue("type");
130:
131: mCharacterData = new StringBuilder();
132: mPropertyValuesStack.push(new PropertyValueList());
133: } else if (qName.equals("config")) {
134: // store the character data of the previous property value series
135: mPropertyValuesStack.peek().add(
136: new PropertyValueObject(mCharacterData.toString()));
137:
138: // add the property value for the configuration
139: mPropertyValuesStack.peek().add(
140: new PropertyValueParticipant(
141: Config.DEFAULT_PARTICIPANT_NAME,
142: new PropertyValueObject(atts
143: .getValue("param"))));
144:
145: mCharacterData = new StringBuilder();
146: } else if (qName.equals("rep")) {
147: // do nothing
148: } else {
149: throw new XmlErrorException("Unsupport element name '"
150: + qName + "'.");
151: }
152: }
153:
154: public void endElement(String namespaceURI, String localName,
155: String qName) {
156: if (qName.equals("participant") && null == mCurrentPropertyName) {
157: if (!mRepository.addParticipant(StringUtils
158: .trim(mCharacterData.toString()), mName, mBlocking,
159: mParameter)) {
160: throw new ParticipantNotFoundException(mCharacterData
161: .toString());
162: }
163: } else if (qName.equals("property")) {
164: PropertyValueList propvals = mPropertyValuesStack.pop();
165:
166: // store the character data to the current property value series
167: propvals.add(new PropertyValueObject(mCharacterData
168: .toString()));
169:
170: try {
171: mRepository.getProperties().put(mCurrentPropertyName,
172: propvals.makePropertyValue());
173: } catch (PropertyValueException e) {
174: throw new PropertyConstructionException("repository",
175: getXmlPath(), mCurrentPropertyName, e);
176: }
177: mCharacterData = null;
178: mCurrentPropertyName = null;
179: mPropertyValuesStack = null;
180: } else if (qName.equals("participant")
181: || qName.equals("datasource")) {
182: PropertyValueList propvals = mPropertyValuesStack.pop();
183:
184: // store the character data to the current property value series
185: propvals.add(new PropertyValueObject(mCharacterData
186: .toString()));
187:
188: try {
189: PropertyValue propval = new PropertyValueParticipant(
190: mParticipantNameStack.pop(), propvals
191: .makePropertyValue());
192: ArrayList<PropertyValue> containing_propval_series = mPropertyValuesStack
193: .peek();
194: containing_propval_series.add(propval);
195: } catch (PropertyValueException e) {
196: throw new PropertyConstructionException("repository",
197: getXmlPath(), mCurrentPropertyName, e);
198: }
199:
200: mCharacterData = new StringBuilder();
201: } else if (qName.equals("template")) {
202: PropertyValueList propvals = mPropertyValuesStack.pop();
203:
204: // store the character data to the current property value series
205: propvals.add(new PropertyValueObject(mCharacterData
206: .toString()));
207:
208: try {
209: PropertyValue propval = new PropertyValueTemplate(
210: mCurrentTemplateType, propvals
211: .makePropertyValue().getValueString());
212: ArrayList<PropertyValue> containing_propval_series = mPropertyValuesStack
213: .peek();
214: containing_propval_series.add(propval);
215: } catch (PropertyValueException e) {
216: throw new PropertyConstructionException("repository",
217: getXmlPath(), mCurrentPropertyName, e);
218: }
219:
220: mCharacterData = new StringBuilder();
221: }
222: }
223:
224: public void characters(char[] ch, int start, int length) {
225: if (length > 0) {
226: mCharacterData
227: .append(String.copyValueOf(ch, start, length));
228: }
229: }
230: }
|