r393 - in trunk: . jredmine-client jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3 jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api jredmine-client/src/main/resources/META-INF/services jredmine-client/src/test/java/org/nuiton/jredmine/model/io/xpp3 jredmine-maven-plugin
Author: tchemit Date: 2012-11-11 10:10:44 +0100 (Sun, 11 Nov 2012) New Revision: 393 Url: http://nuiton.org/repositories/revision/jredmine/393 Log: fixes #2410: Do not used anylonger xpp3 api from helper-plugin refs #2411: Updates to helper-maven-plugin 2.0 Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AbstractXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AttributeValueToProperty.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DataConverter.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DefaultDataConverter.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/PropertyMapper.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagContentToProperty.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagTextContentToProperty.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Helper.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Reader.java trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.jredmine.model.io.xpp3.api.Xpp3Reader Removed: trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.io.xpp3.Xpp3Reader Modified: trunk/jredmine-client/pom.xml trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/AttachmentXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueCategoryXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssuePriorityXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueStatusXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/NewsXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/ProjectXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineDataConverter.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3Helper.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TimeEntryXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TrackerXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/UserXpp3Reader.java trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/VersionXpp3Reader.java trunk/jredmine-client/src/test/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3HelperTest.java trunk/jredmine-maven-plugin/pom.xml trunk/pom.xml Modified: trunk/jredmine-client/pom.xml =================================================================== --- trunk/jredmine-client/pom.xml 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/pom.xml 2012-11-11 09:10:44 UTC (rev 393) @@ -48,22 +48,6 @@ <dependencies> <dependency> - <groupId>org.nuiton</groupId> - <artifactId>helper-maven-plugin</artifactId> - <scope>compile</scope> - <exclusions> - <exclusion> - <groupId>velocity</groupId> - <artifactId>velocity</artifactId> - </exclusion> - <exclusion> - <groupId>commons-httpclient</groupId> - <artifactId>commons-httpclient</artifactId> - </exclusion> - </exclusions> - </dependency> - - <dependency> <groupId>commons-codec</groupId> <artifactId>commons-codec</artifactId> <scope>runtime</scope> @@ -215,9 +199,11 @@ <descriptorRef>full</descriptorRef> </descriptorRefs> <descriptors> - <descriptor>src/main/assembly/jredmine_rails-1.x.xml + <descriptor> + src/main/assembly/jredmine_rails-1.x.xml </descriptor> - <descriptor>src/main/assembly/jredmine_rails-2.x.xml + <descriptor> + src/main/assembly/jredmine_rails-2.x.xml </descriptor> </descriptors> </configuration> Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/AttachmentXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/AttachmentXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/AttachmentXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Attachment; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueCategoryXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueCategoryXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueCategoryXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,9 +24,9 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Issue; import org.nuiton.jredmine.model.IssueCategory; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssuePriorityXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssuePriorityXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssuePriorityXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,9 +24,9 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Issue; import org.nuiton.jredmine.model.IssuePriority; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueStatusXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueStatusXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueStatusXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,9 +24,9 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Issue; import org.nuiton.jredmine.model.IssueStatus; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/IssueXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Issue; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/NewsXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/NewsXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/NewsXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.News; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/ProjectXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/ProjectXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/ProjectXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Project; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineDataConverter.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineDataConverter.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineDataConverter.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,7 +24,7 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.DataConverter; +import org.nuiton.jredmine.model.io.xpp3.api.DataConverter; import java.text.DateFormat; import java.text.SimpleDateFormat; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3Helper.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3Helper.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3Helper.java 2012-11-11 09:10:44 UTC (rev 393) @@ -29,8 +29,8 @@ import org.codehaus.plexus.util.IOUtil; import org.codehaus.plexus.util.ReaderFactory; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; -import org.nuiton.io.xpp3.Xpp3Helper; -import org.nuiton.io.xpp3.Xpp3Reader; +import org.nuiton.jredmine.model.io.xpp3.api.Xpp3Helper; +import org.nuiton.jredmine.model.io.xpp3.api.Xpp3Reader; import java.io.ByteArrayInputStream; import java.io.File; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TimeEntryXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TimeEntryXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TimeEntryXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.TimeEntry; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TrackerXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TrackerXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/TrackerXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Tracker; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/UserXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/UserXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/UserXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.User; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Modified: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/VersionXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/VersionXpp3Reader.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/VersionXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -24,8 +24,8 @@ */ package org.nuiton.jredmine.model.io.xpp3; -import org.nuiton.io.xpp3.AbstractXpp3Reader; import org.nuiton.jredmine.model.Version; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; import java.beans.IntrospectionException; Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AbstractXpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AbstractXpp3Reader.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AbstractXpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,593 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +import com.google.common.collect.Sets; +import org.codehaus.plexus.util.xml.pull.MXParser; +import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +import java.beans.IntrospectionException; +import java.io.IOException; +import java.io.Reader; +import java.lang.reflect.Array; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.TreeMap; + +/** + * An abstract xpp3Reader based on {@link PropertyMapper} to set properties of + * the objects to build. + * <p/> + * To implements a new parser, just implements method {@link #initMappers()} to + * see authorized mapping from tag to pojo properties. + * <p/> + * The logic of setting properties from xml (tag and attributes) is done in + * <p/> + * <ul> + * <li>{@link #read(String, Class, XmlPullParser, boolean)} </li> + * <li>{@link #readArray(String, String, Class, XmlPullParser, boolean)}</li> + * </ul> + * <p/> + * The default implementation is to map tag text to a pojo's property. + * <p/> + * If you want to do something more complex, override these methods. + * + * @param <O> the type of object to be build by the reader + * @author tchemit <chemit@codelutin.com> + * @see PropertyMapper + * @see Xpp3Reader + * @since 1.0.0 + */ +public abstract class AbstractXpp3Reader<O> implements Xpp3Reader<O> { + + /** + * If set the parser will be loaded with all single characters + * from the XHTML specification. + * The entities used: + * <ul> + * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li> + * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li> + * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li> + * </ul> + */ + protected boolean addDefaultEntities = true; + + /** the type of the object to produce from the xml streams. */ + protected final Class<O> type; + + /** the root tag of an object to retreave from xml streams. */ + protected String rootTagName; + + /** the root tag of an array of objets to retreave from xml streams. */ + protected String arrayRootTagName; + + /** + * the univers of mappers availables, initialized in {@link #initMappers()}. + * <p/> + * Each mapper of the dictionary is associated to the fully qualified name + * of the target class # the tag name or attribute name. + * <p/> + * Example : + * <pre> + * org.nuiton.util.MyPojo#my-tag + * org.nuiton.util.MyPojo#my-attribute + * </pre> + */ + protected Map<String, PropertyMapper> allMappers; + + protected abstract void initMappers() throws IntrospectionException; + + protected AbstractXpp3Reader(Class<O> type, String rootTagName) { + this(type, null, rootTagName); + } + + protected AbstractXpp3Reader(Class<O> type, + String arrayRootTagName, + String rootTagName) { + this.type = type; + this.rootTagName = rootTagName; + this.arrayRootTagName = arrayRootTagName; + allMappers = new TreeMap<String, PropertyMapper>(); + try { + initMappers(); + } catch (IntrospectionException e) { + throw new IllegalStateException( + "could not init " + this + " for reason " + + e.getMessage(), e); + } + } + + @Override + public Class<O> getType() { + return type; + } + + @Override + public String getRootTagName() { + return rootTagName; + } + + @Override + public void setRootTagName(String rootTagName) { + this.rootTagName = rootTagName; + } + + @Override + public String getArrayRootTagName() { + return arrayRootTagName; + } + + @Override + public void setParentRootTagName(String parentRootTagName) { + arrayRootTagName = parentRootTagName; + } + + @Override + public boolean isAddDefaultEntities() { + return addDefaultEntities; + } + + @Override + public void setAddDefaultEntities(boolean addDefaultEntities) { + this.addDefaultEntities = addDefaultEntities; + } + + @Override + public O read(Reader reader) throws IOException, XmlPullParserException { + return read(reader, true); + } + + @Override + public O read(Reader reader, + boolean strict) throws IOException, XmlPullParserException { + XmlPullParser parser = new MXParser(); + + parser.setInput(reader); + + if (addDefaultEntities) { + + Xpp3Helper.addDefaultEntities(parser); + } + + parser.next(); + + // read the first open tag getRootTagName() and consume the matching + // ending tag + O result = read(getRootTagName(), getType(), parser, strict); + + // go after the ending tag getRootTagName() + parser.next(); + + // must be at the end of the document + checkEndOfXml(parser); + + return result; + } + + @Override + public O[] readArray(Reader reader) + throws IOException, XmlPullParserException { + return readArray(reader, true); + } + + @Override + public O[] readArray(Reader reader, boolean strict) + throws IOException, XmlPullParserException { + XmlPullParser parser = new MXParser(); + + parser.setInput(reader); + + if (addDefaultEntities) { + + Xpp3Helper.addDefaultEntities(parser); + } + + parser.next(); + + parser.getEventType(); + + O[] result = readArray(getArrayRootTagName(), + getRootTagName(), + getType(), + parser, + strict + ); + + parser.next(); + + checkEndOfXml(parser); + + return result; + } + + /** + * Obtain all mappers for a given type. + * <p/> + * In the result, the keys are now the tag-name of attribute-name. + * <p/> + * Example : + * <pre> + * my-tag + * my-attribute + * </pre> + * + * @param srcType the target type of the searched mappers + * @return the dictionnary of mappers for the given type. + */ + public Map<String, PropertyMapper> getMappers(Class<?> srcType) { + Map<String, PropertyMapper> result = + new TreeMap<String, PropertyMapper>(); + String prefix = srcType.getName() + "#"; + for (Entry<String, PropertyMapper> e : allMappers.entrySet()) { + if (e.getKey().startsWith(prefix)) { + result.put(e.getValue().getTagName(), e.getValue()); + } + } + return result; + } + + /** + * Obtain all mappers for a given type. + * <p/> + * In the result, the keys are now the tag-name of attribute-name. + * <p/> + * Example : + * <pre> + * my-tag + * my-attribute + * </pre> + * + * @param srcType the target type of the searched mappers + * @param tagName the tag target of the searched mappers + * @return the dictionnary of mappers for the given type. + */ + public Map<String, PropertyMapper> getMappers(Class<?> srcType, String tagName) { + Map<String, PropertyMapper> result = + new TreeMap<String, PropertyMapper>(); + String prefix = srcType.getName() + "#" + tagName + "#"; + for (Entry<String, PropertyMapper> e : allMappers.entrySet()) { + if (e.getKey().startsWith(prefix)) { + + result.put(((AttributeValueToProperty) e.getValue()).getAttributeName(), e.getValue()); + } + } + return result; + } + + /** + * Parse the xml stream from the given parser and a build the associated + * object. + * <p/> + * This default implementation just match a tag text content to a pojo + * property. + * <p/> + * No work is done on attribute values here. + * <p/> + * Note: The parser must accept as a next open tag the required one . + * <p/> + * the next node name is given by <code>getRootTagName()</code> + * <p/> + * Example : + * <pre> + * ... + * <my-pojo> + * <my-property>myValue</my-property> + * </my-pojo> + * </pre> + * + * @param <T> the type of object to build + * @param rootTagName the name of the root tag matching the object to build + * @param type the type of object to build + * @param parser the xpp3 parser + * @param strict flag to indicate if should fail if a unknown tag + * (or attribute ?) is scanned + * @return the single object build from the xml stream. + * @throws IOException if any io pb + * @throws XmlPullParserException if any parsing pb + */ + public <T> T read(String rootTagName, + Class<T> type, + XmlPullParser parser, + boolean strict) + throws XmlPullParserException, IOException { + + // search open tag rootTagName + gotoNextOpenTag(rootTagName, parser); + + // can init result + T result; + try { + result = type.newInstance(); + } catch (Exception ex) { + // should never happens! + throw new RuntimeException( + "could not instanciate a new " + getType().getName() + + " for reason : " + ex.getMessage(), ex); + } + + // prepare alvailable mappers for the given type + Map<String, PropertyMapper> mappers = getMappers(type); + + Set<String> parsed = new HashSet<String>(); + + // deal with all attributes + { + Set<String> attributeParsed = Sets.newHashSet(); + Map<String, PropertyMapper> attributeMappers = getMappers(type, rootTagName); + int attributeCount = parser.getAttributeCount(); + for (int i = 0; i < attributeCount; i++) { + String attributeName = parser.getAttributeName(i); + PropertyMapper mapper = attributeMappers.get(attributeName); + if (mapper != null) { + mapper.setProperty(result, parser, attributeParsed, strict); + } + } + } + try { + // go to next tag + int eventType = parser.next(); + + while (true) { + + checkNotEndOfXml(parser, rootTagName); + + if (eventType == XmlPullParser.START_TAG) { + PropertyMapper mapper = mappers.get(parser.getName()); + if (mapper != null) { + mapper.setProperty(result, parser, parsed, strict); + } else if (strict) { + throw new XmlPullParserException( + "Unrecognised tag: '" + parser.getName() + + "'", parser, null); + } + + // deal with all attributes + { + Set<String> attributeParsed = Sets.newHashSet(); + Map<String, PropertyMapper> attributeMappers = getMappers(type, rootTagName); + int attributeCount = parser.getAttributeCount(); + for (int i = 0; i < attributeCount; i++) { + String attributeName = parser.getAttributeName(i); + PropertyMapper attributeMapper = attributeMappers.get(attributeName); + if (attributeMapper != null) { + attributeMapper.setProperty(result, parser, attributeParsed, strict); + } + } + } + } else if (eventType == XmlPullParser.END_TAG) { + if (parser.getName().equals(rootTagName)) { + // have reach the end of the object + break; + } + } + + // try next event + eventType = parser.next(); + } + return result; + } finally { + parsed.clear(); + if (mappers != null) { + mappers.clear(); + } + } + } + + /** + * Parse the xml stream from the given parser and a build an array of + * associated object. + * <p/> + * This default implementation just match a tag text content to a pojo + * property. + * <p/> + * No work is done on attribute values here. + * <p/> + * Note: The next node of the parser must be the one given by + * {@code parentRootTagName} and sub nodes with names {@code rootTagName}. + * <p/> + * Example : + * <pre> + * ... + * <my-pojos> + * <my-pojo> + * <my-property>myValue</my-property> + * </my-pojo> + * <my-pojo> + * <my-property>myValue2</my-property> + * </my-pojo> + * </my-pojos> + * </pre> + * + * @param <T> the type of objects to build + * @param parentRootTagName the tag's name of the array container + * @param rootTagName the tag's name of each object to build + * @param type the type of objects to build + * @param parser the xpp3 parser + * @param strict flag to indicate if should fail if a unknown + * tag (or attribute ?) is scanned + * @return the single object build from the xml stream. + * @throws IOException if any io pb + * @throws XmlPullParserException if any parsing pb + */ + public <T> T[] readArray(String parentRootTagName, + String rootTagName, + Class<T> type, + XmlPullParser parser, + boolean strict) + throws XmlPullParserException, IOException { + + // search open tag parentRootTagName + // if not found, will raise an parsing exception + gotoNextOpenTag(parentRootTagName, parser); + + // can init result + List<T> results = new ArrayList<T>(); + + boolean addChild = false; + boolean quit = false; + + while (!quit) { + + addChild = false; + quit = false; + + // search next opening tag (rootTagName) or ending tag + // (parentRootTagName) + + while (true) { + + checkNotEndOfXml(parser, parentRootTagName); + +// int eventType = parser.getEventType(); + + int eventType = parser.next(); + + if (eventType == XmlPullParser.START_TAG && + rootTagName.equals(parser.getName())) { + // there is a child to read + addChild = true; + break; + } + + if (eventType == XmlPullParser.END_TAG && + parentRootTagName.equals(parser.getName())) { + // can quit main loop, end of work + quit = true; + break; + } + + } + + if (addChild) { + + // find an object to add + T result = read(rootTagName, type, parser, strict); + + results.add(result); + + // go for another round + continue; + } + + // no more child + // must be at the end of tag + if (!quit) { + throw new XmlPullParserException( + "should be on " + parentRootTagName + + " but was not : " + parser.getName()); + } + } + + // can not directly instanciate a generic array (or don't known how ?) + return results.toArray((T[]) Array.newInstance(type, results.size())); + } + + protected int gotoNextOpenTag(String tagName, XmlPullParser parser) + throws XmlPullParserException, IOException { + // search next open tag tagName + + int eventType = parser.getEventType(); + + while (eventType != XmlPullParser.START_TAG || + !parser.getName().equals(tagName)) { + + checkNotEndOfXml(parser, tagName); + + eventType = parser.next(); + } + + return eventType; + } + + /** + * Checks that a given parser is not at the end of the xml document. + * + * @param parser the parser to check + * @param tagName the endign tag's name + * @throws XmlPullParserException if the parser is at the end of the xml + * stream, instead of the {@code tagName} + * ending tag + */ + protected void checkNotEndOfXml(XmlPullParser parser, String tagName) + throws XmlPullParserException { + if (parser.getEventType() == XmlPullParser.END_DOCUMENT) { + // can not be here ? + throw new XmlPullParserException( + "end of document found... but required at least the " + + "ending tag " + tagName); + } + } + + /** + * Checks that a given parser is at the end of the xml document. + * + * @param parser the parser to check + * @throws XmlPullParserException if the parser is not at the end of the + * xml stream. + */ + protected void checkEndOfXml(XmlPullParser parser) + throws XmlPullParserException { + // must be at the end of the document + if (parser.getEventType() != XmlPullParser.END_DOCUMENT) { + throw new XmlPullParserException( + "should be at the end of document but was not... : " + + parser.getName()); + } + } + + protected void addTagTextContentMappers(DataConverter type, + boolean onlyOne, + String... tagNames) throws IntrospectionException { + TagTextContentToProperty.addMapper( + getType(), + type, + onlyOne, + allMappers, + tagNames + ); + } + + protected void addAttributeValueMappers(DataConverter type, + boolean onlyOne, + String... attributeNames) throws IntrospectionException { + AttributeValueToProperty.addMapper( + getType(), + type, + onlyOne, + allMappers, + getRootTagName(), + attributeNames + ); + } + + protected <O> void addTagContentMapper(Class<O> type, + boolean onlyOne, + Xpp3Reader<O> reader) throws IntrospectionException { + TagContentToProperty.addMapper( + getType(), + type, + onlyOne, + allMappers, + reader.getRootTagName(), + reader, + false + ); + } + + protected <O> void addTagContentsMapper(Class<O> type, + boolean onlyOne, + Xpp3Reader<O> reader) throws IntrospectionException { + TagContentToProperty.addMapper( + getType(), + type, + onlyOne, + allMappers, + reader.getArrayRootTagName(), + reader, + true + ); + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AbstractXpp3Reader.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AttributeValueToProperty.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AttributeValueToProperty.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AttributeValueToProperty.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,85 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +import org.codehaus.plexus.util.xml.pull.XmlPullParser; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.util.Map; + +/** + * Property mapper from a attribute content. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.5 + */ +public class AttributeValueToProperty extends PropertyMapper { + + protected final String attributeName; + + public AttributeValueToProperty(String tagName, + String attributeName, + String propertyName, + Class<?> containerType, + DataConverter type, + boolean onlyOne, + PropertyDescriptor descriptor) { + super(tagName, + propertyName, + containerType, + type, + onlyOne, + descriptor + ); + this.attributeName = attributeName; + } + + public String getAttributeName() { + return attributeName; + } + + protected String getXmlName() { + return attributeName; + } + + @Override + protected Object getDataFromXml(XmlPullParser parser) + throws Exception { + String t = parser.getAttributeValue("", attributeName); + Object result = null; + if (t != null && !(t = t.trim()).isEmpty()) { + result = type.convert(t); + } + return result; + } + + public static void addMapper(Class<?> containerType, + DataConverter type, + boolean onlyOne, + Map<String, PropertyMapper> allMappers, + String tagName, + String... attributeNames) throws IntrospectionException, + IllegalArgumentException { + + for (String attributeName : attributeNames) { + + // the tag-name is transformed to tagName + String propertyName = TAG_NAME_TRANSFORMER.apply(attributeName); + + PropertyDescriptor descriptor = getDescriptor(containerType, + propertyName); + + PropertyMapper mapper = new AttributeValueToProperty( + tagName, + attributeName, + propertyName, + containerType, + type, + onlyOne, + descriptor + ); + mapper.registerMapper(allMappers, containerType, tagName, attributeName); + } + + } + +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/AttributeValueToProperty.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DataConverter.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DataConverter.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DataConverter.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,15 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +/** + * A contract to a data converter from a text value to a typed value. + * <p/> + * We does not here use the commons-beans classes, since we could have different + * types of converter for a same type.... + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0.3 + */ +public interface DataConverter { + + Object convert(String t) throws Exception; +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DataConverter.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DefaultDataConverter.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DefaultDataConverter.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DefaultDataConverter.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,60 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +/** + * A enumaration to convert some data from a string representation. + * <p/> + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0.0 + */ +public enum DefaultDataConverter implements DataConverter { + + Boolean { + @Override + public Object convert(String t) throws Exception { + Object r = java.lang.Boolean.valueOf(t); + return r; + } + }, + Short { + @Override + public Object convert(String t) throws Exception { + Object r = java.lang.Short.valueOf(t); + return r; + } + }, + Integer { + @Override + public Object convert(String t) throws Exception { + Object r = java.lang.Integer.valueOf(t); + return r; + } + }, + Long { + @Override + public Object convert(String t) throws Exception { + Object r = java.lang.Long.valueOf(t); + return r; + } + }, + Float { + @Override + public Object convert(String t) throws Exception { + Object r = java.lang.Float.valueOf(t); + return r; + } + }, + Double { + @Override + public Object convert(String t) throws Exception { + Object r = java.lang.Double.valueOf(t); + return r; + } + }, + Text { + @Override + public Object convert(String t) throws Exception { + return t; + } + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/DefaultDataConverter.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/PropertyMapper.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/PropertyMapper.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/PropertyMapper.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,223 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +import com.google.common.base.Function; +import org.apache.commons.lang3.StringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +import java.beans.BeanInfo; +import java.beans.IntrospectionException; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.io.IOException; +import java.text.ParseException; +import java.util.Map; +import java.util.Set; + +/** + * A abstract object to map an xml value (tag or attribute, or esle?) to a pojo property. + * <p/> + * Two implementations are given : + * <p/> + * <ul> + * <li>{@link TagTextContentToProperty} to map the text content of a tag + * to a pojo's property</li> + * <li>{@link AttributeValueToProperty} to map the text content of a tag + * to a pojo's property</li> + * </ul> + * + * @author tchemit <chemit@codelutin.com> + * @since 1.0.3 + */ +public abstract class PropertyMapper { + + /** Logger. */ + private static final Log log = LogFactory.getLog(PropertyMapper.class); + + /** name of tag. */ + protected final String name; + + /** the pojo's property to set */ + protected final String propertyName; + + /** the converter from xml to pojo's property type */ + protected final DataConverter type; + + /** the type of the pojo container of the property */ + protected final Class<?> containerType; + + /** the pojo's property descriptor */ + protected final PropertyDescriptor descriptor; + + /** + * a flag to check to use only once the mapper. (should not be used for + * attributes implementations). + */ + protected final boolean onlyOne; + + protected PropertyMapper(String tagName, + String propertyName, + Class<?> containerType, + DataConverter type, + boolean onlyOne, + PropertyDescriptor descriptor) { + name = tagName; + this.propertyName = propertyName; + this.type = type; + this.onlyOne = onlyOne; + this.containerType = containerType; + this.descriptor = descriptor; + } + + protected String getXmlName() { + return name; + } + + protected abstract Object getDataFromXml(XmlPullParser parser) + throws Exception; + + public void setProperty(Object src, + XmlPullParser parser, + Set<String> parsed, boolean strict) + throws XmlPullParserException, IOException { + if (onlyOne && parsed.contains(getXmlName())) { + throw new XmlPullParserException( + "Duplicated tag: \'" + parser.getName() + "\'", + parser, + null + ); + } + parsed.add(getXmlName()); + try { + if (log.isDebugEnabled()) { + log.debug(getXmlName()); + } + Object r = getDataFromXml(parser); + if (r != null) { + descriptor.getWriteMethod().invoke(src, r); + } + } catch (XmlPullParserException e) { + throw e; + } catch (NumberFormatException e) { + if (strict) { + throw new XmlPullParserException(e.getMessage()); + } + } catch (ParseException e) { + if (strict) { + throw new XmlPullParserException(e.getMessage()); + } + } catch (Exception e) { + throw new XmlPullParserException(e.getMessage(), parser, e); + } + } + + public PropertyDescriptor getDescriptor() { + return descriptor; + } + + public boolean isOnlyOne() { + return onlyOne; + } + + public String getPropertyName() { + return propertyName; + } + + public String getTagName() { + return name; + } + + public DataConverter getType() { + return type; + } + + public Class<?> getContainerType() { + return containerType; + } + + public String getName() { + return name; + } + + @Override + public String toString() { + ToStringBuilder toStringBuilder = new ToStringBuilder(this); + toStringBuilder.append("name", name); + toStringBuilder.append("propertyName", propertyName); + toStringBuilder.append("onlyOne", onlyOne); + toStringBuilder.append("type", type); + toStringBuilder.append("containerType", containerType); + return toStringBuilder.toString(); + } + + public static final Function<String, String> TAG_NAME_TRANSFORMER = new Function<String, String>() { + @Override + public String apply(String input) { + String[] parts = input.split("-"); + StringBuilder buffer = new StringBuilder(); + for (int i = 0, j = parts.length; i < j; i++) { + if (i == 0) { + buffer.append(parts[i]); + } else { + buffer.append(StringUtils.capitalize(parts[i])); + } + } + parts = buffer.toString().split("_"); + buffer = new StringBuilder(); + for (int i = 0, j = parts.length; i < j; i++) { + if (i == 0) { + buffer.append(parts[i]); + } else { + buffer.append(StringUtils.capitalize(parts[i])); + } + } + String result = buffer.toString(); + return result; + } + }; + + public static String getMapperForTag(Class<?> type) { + return type.getName() + "#"; + } + + public static String getMapperForAttribute(Class<?> type, String attributeName) { + return type.getName() + "#" + attributeName + "#"; + } + + protected static PropertyDescriptor getDescriptor(Class<?> containerType, + String propertyName) throws IntrospectionException { + BeanInfo beanInfo = Introspector.getBeanInfo(containerType); + PropertyDescriptor descriptor = null; + for (PropertyDescriptor propertyDescriptor : + beanInfo.getPropertyDescriptors()) { + if (propertyDescriptor.getName().equals(propertyName)) { + descriptor = propertyDescriptor; + break; + } + } + if (descriptor == null) { + throw new IllegalArgumentException( + "could not find a property descriptor for property " + + propertyName + " of " + containerType); + } + return descriptor; + } + + protected void registerMapper(Map<String, PropertyMapper> allMappers, + Class<?> containerType, + String tagName, + String attributeName) { + String key; + if (attributeName == null) { + // tag scope + key = getMapperForTag(containerType) + tagName; + } else { + // attribute scope + key = getMapperForAttribute(containerType, tagName) + attributeName; + } + allMappers.put(key, this); + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/PropertyMapper.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagContentToProperty.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagContentToProperty.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagContentToProperty.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,94 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +import org.codehaus.plexus.util.xml.pull.XmlPullParser; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.util.Map; + +/** + * Property mapper from a tag content to an object. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.5 + */ +public class TagContentToProperty<O> extends PropertyMapper { + + private final Xpp3Reader<O> reader; + + private final Class<O> datatype; + + private final boolean multiple; + + public TagContentToProperty(String tagName, + String propertyName, + Class<?> containerType, + Class<O> type, + boolean onlyOne, + PropertyDescriptor descriptor, + Xpp3Reader<O> reader, + boolean multiple) { + super(tagName, + propertyName, + containerType, + null, + onlyOne, + descriptor + ); + datatype = type; + this.reader = reader; + this.multiple = multiple; + } + + @Override + protected Object getDataFromXml(XmlPullParser parser) + throws Exception { + Object result; + if (multiple) { + result = reader.readArray( + reader.getArrayRootTagName(), + reader.getRootTagName(), + datatype, + parser, + true + ); + } else { + result = reader.read( + reader.getRootTagName(), + datatype, + parser, + true + ); + } + return result; + } + + public static <O> void addMapper(Class<?> containerType, + Class<O> type, + boolean onlyOne, + Map<String, PropertyMapper> allMappers, + String tagName, + Xpp3Reader<O> reader, + boolean multiple + ) throws IntrospectionException, + IllegalArgumentException { + + // the tag-name is transformed to tagName + String propertyName = TAG_NAME_TRANSFORMER.apply(tagName); + + PropertyDescriptor descriptor = getDescriptor(containerType, + propertyName); + + PropertyMapper mapper = new TagContentToProperty<O>( + tagName, + propertyName, + containerType, + type, + onlyOne, + descriptor, + reader, + multiple + ); + mapper.registerMapper(allMappers, containerType, tagName, null); + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagContentToProperty.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagTextContentToProperty.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagTextContentToProperty.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagTextContentToProperty.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,68 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +import org.codehaus.plexus.util.xml.pull.XmlPullParser; + +import java.beans.IntrospectionException; +import java.beans.PropertyDescriptor; +import java.util.Map; + +/** + * Property mapp from a tag text content. + * + * @author tchemit <chemit@codelutin.com> + * @since 1.5 + */ +public class TagTextContentToProperty extends PropertyMapper { + + public TagTextContentToProperty(String tagName, + String propertyName, + Class<?> containerType, + DataConverter type, + boolean onlyOne, + PropertyDescriptor descriptor) { + super(tagName, + propertyName, + containerType, + type, + onlyOne, + descriptor + ); + } + + @Override + protected Object getDataFromXml(XmlPullParser parser) + throws Exception { + String t = parser.nextText(); + Object result = null; + if (t != null && !(t = t.trim()).isEmpty()) { + result = type.convert(t); + } + return result; + } + + public static void addMapper(Class<?> containerType, + DataConverter type, + boolean onlyOne, + Map<String, PropertyMapper> allMappers, + String... tagNames) throws IntrospectionException { + for (String tagName : tagNames) { + + // the tag-name is transformed to tagName + String propertyName = TAG_NAME_TRANSFORMER.apply(tagName); + + PropertyDescriptor descriptor = getDescriptor(containerType, + propertyName); + + + PropertyMapper mapper = new TagTextContentToProperty( + tagName, + propertyName, + containerType, + type, + onlyOne, + descriptor + ); + mapper.registerMapper(allMappers, containerType, tagName, null); + } + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/TagTextContentToProperty.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Helper.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Helper.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Helper.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,469 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.codehaus.plexus.util.IOUtil; +import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +import java.io.IOException; +import java.io.Reader; +import java.io.StringReader; +import java.io.StringWriter; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; +import java.util.ServiceLoader; + +/** + * A Helper to read some data stored in xml with a {@link Xpp3Reader}. + * <p/> + * In this class, there is some methods to obtain a discovered {@link Xpp3Reader} + * registred by a {@link ServiceLoader} mecanism. + * + * @author tchemit <chemit@codelutin.com> + * @see Xpp3Reader + * @since 1.0.3 + */ +public class Xpp3Helper { + + /** Logger */ + private static final Log log = LogFactory.getLog(Xpp3Helper.class); + + /** + * les readers enregistres via un {@link ServiceLoader} + * sur le contrat {@link Xpp3Reader}. + */ + protected static Map<Class<?>, Xpp3Reader<?>> readers; + + /** + * Read a single object from a xml stream. + * + * @param <O> the type of object to read + * @param klass the type of object to read + * @param reader the reader where to parse the xml + * @return the loaded object + * @throws IOException if any io pb + * @throws XmlPullParserException if any parsing pb + */ + public static <O> O readObject(Class<O> klass, Reader reader) + throws IOException, XmlPullParserException { + + if (klass == null) { + throw new NullPointerException("klass parameter can not be null"); + } + + if (reader == null) { + throw new NullPointerException("reader parameter can not be null"); + } + + Xpp3Reader<O> modelReader = getReader(klass); + + if (modelReader == null) { + throw new IllegalArgumentException( + "could not find xpp3Reader for type " + klass); + } + + O result = null; + + try { + + StringWriter sWriter = new StringWriter(); + + IOUtil.copy(reader, sWriter); + + String rawInput = sWriter.toString(); + if (log.isDebugEnabled()) { + log.debug("content to read : \n" + rawInput); + } + StringReader sReader = new StringReader(rawInput); + + result = modelReader.read(sReader); + + } finally { + IOUtil.close(reader); + } + + return result; + } + + /** + * Read an array of objects from a xml stream. + * + * @param <O> the type of objects to return + * @param klass the type of object to read + * @param reader the reader where to parse the xml + * @return the loaded objects + * @throws IOException if any io pb + * @throws XmlPullParserException if any parsing pb + */ + public static <O> O[] readObjects(Class<O> klass, Reader reader) + throws IOException, XmlPullParserException { + + if (klass == null) { + throw new NullPointerException("klass parameter can not be null"); + } + + if (reader == null) { + throw new NullPointerException("reader parameter can not be null"); + } + + Xpp3Reader<O> modelReader = getReader(klass); + + if (modelReader == null) { + throw new IllegalArgumentException( + "could not find xpp3Reader for type " + klass); + } + + O[] result = null; + + try { + + StringWriter sWriter = new StringWriter(); + + IOUtil.copy(reader, sWriter); + + String rawInput = sWriter.toString(); + if (log.isDebugEnabled()) { + log.debug("content to read : \n" + rawInput); + } + StringReader sReader = new StringReader(rawInput); + + result = modelReader.readArray(sReader); + + } finally { + IOUtil.close(reader); + } + + return result; + } + + /** @return an iterator on all registred {@link Xpp3Reader}. */ + public static Iterator<Xpp3Reader<?>> getReaderItetator() { + return getReaders().values().iterator(); + } + + /** + * Obtain the loaded reader which match his {@link Xpp3Reader#getType()} + * with the given type. + * + * @param <T> the type of the data which should be parsed by the + * researched parser + * @param klass the type of the data which should be parsed by the + * researched parser + * @return the parser for the given type + */ + public static <T> Xpp3Reader<T> getReader(Class<T> klass) { + Xpp3Reader<T> reader = (Xpp3Reader<T>) getReaders().get(klass); + return reader; + } + + /** + * Clean all the registred readers. + * <p/> + * To reload them, just call a {@link #getReader(Class)}. + */ + public static void clearReaders() { + if (readers != null) { + readers.clear(); + readers = null; + } + } + + /** + * Add to the parser, the default replacers for all single characters + * from the XHTML specification. + * The entities used: + * <ul> + * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent</li> + * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent</li> + * <li>http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent</li> + * </ul> + * + * @param parser the parser to configure + * @throws XmlPullParserException if any pb + */ + public static void addDefaultEntities(XmlPullParser parser) + throws XmlPullParserException { + // ---------------------------------------------------------------------- + // Latin 1 entities + // ---------------------------------------------------------------------- + parser.defineEntityReplacementText("nbsp", "\u00a0"); + parser.defineEntityReplacementText("iexcl", "\u00a1"); + parser.defineEntityReplacementText("cent", "\u00a2"); + parser.defineEntityReplacementText("pound", "\u00a3"); + parser.defineEntityReplacementText("curren", "\u00a4"); + parser.defineEntityReplacementText("yen", "\u00a5"); + parser.defineEntityReplacementText("brvbar", "\u00a6"); + parser.defineEntityReplacementText("sect", "\u00a7"); + parser.defineEntityReplacementText("uml", "\u00a8"); + parser.defineEntityReplacementText("copy", "\u00a9"); + parser.defineEntityReplacementText("ordf", "\u00aa"); + parser.defineEntityReplacementText("laquo", "\u00ab"); + parser.defineEntityReplacementText("not", "\u00ac"); + parser.defineEntityReplacementText("shy", "\u00ad"); + parser.defineEntityReplacementText("reg", "\u00ae"); + parser.defineEntityReplacementText("macr", "\u00af"); + parser.defineEntityReplacementText("deg", "\u00b0"); + parser.defineEntityReplacementText("plusmn", "\u00b1"); + parser.defineEntityReplacementText("sup2", "\u00b2"); + parser.defineEntityReplacementText("sup3", "\u00b3"); + parser.defineEntityReplacementText("acute", "\u00b4"); + parser.defineEntityReplacementText("micro", "\u00b5"); + parser.defineEntityReplacementText("para", "\u00b6"); + parser.defineEntityReplacementText("middot", "\u00b7"); + parser.defineEntityReplacementText("cedil", "\u00b8"); + parser.defineEntityReplacementText("sup1", "\u00b9"); + parser.defineEntityReplacementText("ordm", "\u00ba"); + parser.defineEntityReplacementText("raquo", "\u00bb"); + parser.defineEntityReplacementText("frac14", "\u00bc"); + parser.defineEntityReplacementText("frac12", "\u00bd"); + parser.defineEntityReplacementText("frac34", "\u00be"); + parser.defineEntityReplacementText("iquest", "\u00bf"); + parser.defineEntityReplacementText("Agrave", "\u00c0"); + parser.defineEntityReplacementText("Aacute", "\u00c1"); + parser.defineEntityReplacementText("Acirc", "\u00c2"); + parser.defineEntityReplacementText("Atilde", "\u00c3"); + parser.defineEntityReplacementText("Auml", "\u00c4"); + parser.defineEntityReplacementText("Aring", "\u00c5"); + parser.defineEntityReplacementText("AElig", "\u00c6"); + parser.defineEntityReplacementText("Ccedil", "\u00c7"); + parser.defineEntityReplacementText("Egrave", "\u00c8"); + parser.defineEntityReplacementText("Eacute", "\u00c9"); + parser.defineEntityReplacementText("Ecirc", "\u00ca"); + parser.defineEntityReplacementText("Euml", "\u00cb"); + parser.defineEntityReplacementText("Igrave", "\u00cc"); + parser.defineEntityReplacementText("Iacute", "\u00cd"); + parser.defineEntityReplacementText("Icirc", "\u00ce"); + parser.defineEntityReplacementText("Iuml", "\u00cf"); + parser.defineEntityReplacementText("ETH", "\u00d0"); + parser.defineEntityReplacementText("Ntilde", "\u00d1"); + parser.defineEntityReplacementText("Ograve", "\u00d2"); + parser.defineEntityReplacementText("Oacute", "\u00d3"); + parser.defineEntityReplacementText("Ocirc", "\u00d4"); + parser.defineEntityReplacementText("Otilde", "\u00d5"); + parser.defineEntityReplacementText("Ouml", "\u00d6"); + parser.defineEntityReplacementText("times", "\u00d7"); + parser.defineEntityReplacementText("Oslash", "\u00d8"); + parser.defineEntityReplacementText("Ugrave", "\u00d9"); + parser.defineEntityReplacementText("Uacute", "\u00da"); + parser.defineEntityReplacementText("Ucirc", "\u00db"); + parser.defineEntityReplacementText("Uuml", "\u00dc"); + parser.defineEntityReplacementText("Yacute", "\u00dd"); + parser.defineEntityReplacementText("THORN", "\u00de"); + parser.defineEntityReplacementText("szlig", "\u00df"); + parser.defineEntityReplacementText("agrave", "\u00e0"); + parser.defineEntityReplacementText("aacute", "\u00e1"); + parser.defineEntityReplacementText("acirc", "\u00e2"); + parser.defineEntityReplacementText("atilde", "\u00e3"); + parser.defineEntityReplacementText("auml", "\u00e4"); + parser.defineEntityReplacementText("aring", "\u00e5"); + parser.defineEntityReplacementText("aelig", "\u00e6"); + parser.defineEntityReplacementText("ccedil", "\u00e7"); + parser.defineEntityReplacementText("egrave", "\u00e8"); + parser.defineEntityReplacementText("eacute", "\u00e9"); + parser.defineEntityReplacementText("ecirc", "\u00ea"); + parser.defineEntityReplacementText("euml", "\u00eb"); + parser.defineEntityReplacementText("igrave", "\u00ec"); + parser.defineEntityReplacementText("iacute", "\u00ed"); + parser.defineEntityReplacementText("icirc", "\u00ee"); + parser.defineEntityReplacementText("iuml", "\u00ef"); + parser.defineEntityReplacementText("eth", "\u00f0"); + parser.defineEntityReplacementText("ntilde", "\u00f1"); + parser.defineEntityReplacementText("ograve", "\u00f2"); + parser.defineEntityReplacementText("oacute", "\u00f3"); + parser.defineEntityReplacementText("ocirc", "\u00f4"); + parser.defineEntityReplacementText("otilde", "\u00f5"); + parser.defineEntityReplacementText("ouml", "\u00f6"); + parser.defineEntityReplacementText("divide", "\u00f7"); + parser.defineEntityReplacementText("oslash", "\u00f8"); + parser.defineEntityReplacementText("ugrave", "\u00f9"); + parser.defineEntityReplacementText("uacute", "\u00fa"); + parser.defineEntityReplacementText("ucirc", "\u00fb"); + parser.defineEntityReplacementText("uuml", "\u00fc"); + parser.defineEntityReplacementText("yacute", "\u00fd"); + parser.defineEntityReplacementText("thorn", "\u00fe"); + parser.defineEntityReplacementText("yuml", "\u00ff"); + // ---------------------------------------------------------------------- + // Special entities + // ---------------------------------------------------------------------- + parser.defineEntityReplacementText("OElig", "\u0152"); + parser.defineEntityReplacementText("oelig", "\u0153"); + parser.defineEntityReplacementText("Scaron", "\u0160"); + parser.defineEntityReplacementText("scaron", "\u0161"); + parser.defineEntityReplacementText("Yuml", "\u0178"); + parser.defineEntityReplacementText("circ", "\u02c6"); + parser.defineEntityReplacementText("tilde", "\u02dc"); + parser.defineEntityReplacementText("ensp", "\u2002"); + parser.defineEntityReplacementText("emsp", "\u2003"); + parser.defineEntityReplacementText("thinsp", "\u2009"); + parser.defineEntityReplacementText("zwnj", "\u200c"); + parser.defineEntityReplacementText("zwj", "\u200d"); + parser.defineEntityReplacementText("lrm", "\u200e"); + parser.defineEntityReplacementText("rlm", "\u200f"); + parser.defineEntityReplacementText("ndash", "\u2013"); + parser.defineEntityReplacementText("mdash", "\u2014"); + parser.defineEntityReplacementText("lsquo", "\u2018"); + parser.defineEntityReplacementText("rsquo", "\u2019"); + parser.defineEntityReplacementText("sbquo", "\u201a"); + parser.defineEntityReplacementText("ldquo", "\u201c"); + parser.defineEntityReplacementText("rdquo", "\u201d"); + parser.defineEntityReplacementText("bdquo", "\u201e"); + parser.defineEntityReplacementText("dagger", "\u2020"); + parser.defineEntityReplacementText("Dagger", "\u2021"); + parser.defineEntityReplacementText("permil", "\u2030"); + parser.defineEntityReplacementText("lsaquo", "\u2039"); + parser.defineEntityReplacementText("rsaquo", "\u203a"); + parser.defineEntityReplacementText("euro", "\u20ac"); + // ---------------------------------------------------------------------- + // Symbol entities + // ---------------------------------------------------------------------- + parser.defineEntityReplacementText("fnof", "\u0192"); + parser.defineEntityReplacementText("Alpha", "\u0391"); + parser.defineEntityReplacementText("Beta", "\u0392"); + parser.defineEntityReplacementText("Gamma", "\u0393"); + parser.defineEntityReplacementText("Delta", "\u0394"); + parser.defineEntityReplacementText("Epsilon", "\u0395"); + parser.defineEntityReplacementText("Zeta", "\u0396"); + parser.defineEntityReplacementText("Eta", "\u0397"); + parser.defineEntityReplacementText("Theta", "\u0398"); + parser.defineEntityReplacementText("Iota", "\u0399"); + parser.defineEntityReplacementText("Kappa", "\u039a"); + parser.defineEntityReplacementText("Lambda", "\u039b"); + parser.defineEntityReplacementText("Mu", "\u039c"); + parser.defineEntityReplacementText("Nu", "\u039d"); + parser.defineEntityReplacementText("Xi", "\u039e"); + parser.defineEntityReplacementText("Omicron", "\u039f"); + parser.defineEntityReplacementText("Pi", "\u03a0"); + parser.defineEntityReplacementText("Rho", "\u03a1"); + parser.defineEntityReplacementText("Sigma", "\u03a3"); + parser.defineEntityReplacementText("Tau", "\u03a4"); + parser.defineEntityReplacementText("Upsilon", "\u03a5"); + parser.defineEntityReplacementText("Phi", "\u03a6"); + parser.defineEntityReplacementText("Chi", "\u03a7"); + parser.defineEntityReplacementText("Psi", "\u03a8"); + parser.defineEntityReplacementText("Omega", "\u03a9"); + parser.defineEntityReplacementText("alpha", "\u03b1"); + parser.defineEntityReplacementText("beta", "\u03b2"); + parser.defineEntityReplacementText("gamma", "\u03b3"); + parser.defineEntityReplacementText("delta", "\u03b4"); + parser.defineEntityReplacementText("epsilon", "\u03b5"); + parser.defineEntityReplacementText("zeta", "\u03b6"); + parser.defineEntityReplacementText("eta", "\u03b7"); + parser.defineEntityReplacementText("theta", "\u03b8"); + parser.defineEntityReplacementText("iota", "\u03b9"); + parser.defineEntityReplacementText("kappa", "\u03ba"); + parser.defineEntityReplacementText("lambda", "\u03bb"); + parser.defineEntityReplacementText("mu", "\u03bc"); + parser.defineEntityReplacementText("nu", "\u03bd"); + parser.defineEntityReplacementText("xi", "\u03be"); + parser.defineEntityReplacementText("omicron", "\u03bf"); + parser.defineEntityReplacementText("pi", "\u03c0"); + parser.defineEntityReplacementText("rho", "\u03c1"); + parser.defineEntityReplacementText("sigmaf", "\u03c2"); + parser.defineEntityReplacementText("sigma", "\u03c3"); + parser.defineEntityReplacementText("tau", "\u03c4"); + parser.defineEntityReplacementText("upsilon", "\u03c5"); + parser.defineEntityReplacementText("phi", "\u03c6"); + parser.defineEntityReplacementText("chi", "\u03c7"); + parser.defineEntityReplacementText("psi", "\u03c8"); + parser.defineEntityReplacementText("omega", "\u03c9"); + parser.defineEntityReplacementText("thetasym", "\u03d1"); + parser.defineEntityReplacementText("upsih", "\u03d2"); + parser.defineEntityReplacementText("piv", "\u03d6"); + parser.defineEntityReplacementText("bull", "\u2022"); + parser.defineEntityReplacementText("hellip", "\u2026"); + parser.defineEntityReplacementText("prime", "\u2032"); + parser.defineEntityReplacementText("Prime", "\u2033"); + parser.defineEntityReplacementText("oline", "\u203e"); + parser.defineEntityReplacementText("frasl", "\u2044"); + parser.defineEntityReplacementText("weierp", "\u2118"); + parser.defineEntityReplacementText("image", "\u2111"); + parser.defineEntityReplacementText("real", "\u211c"); + parser.defineEntityReplacementText("trade", "\u2122"); + parser.defineEntityReplacementText("alefsym", "\u2135"); + parser.defineEntityReplacementText("larr", "\u2190"); + parser.defineEntityReplacementText("uarr", "\u2191"); + parser.defineEntityReplacementText("rarr", "\u2192"); + parser.defineEntityReplacementText("darr", "\u2193"); + parser.defineEntityReplacementText("harr", "\u2194"); + parser.defineEntityReplacementText("crarr", "\u21b5"); + parser.defineEntityReplacementText("lArr", "\u21d0"); + parser.defineEntityReplacementText("uArr", "\u21d1"); + parser.defineEntityReplacementText("rArr", "\u21d2"); + parser.defineEntityReplacementText("dArr", "\u21d3"); + parser.defineEntityReplacementText("hArr", "\u21d4"); + parser.defineEntityReplacementText("forall", "\u2200"); + parser.defineEntityReplacementText("part", "\u2202"); + parser.defineEntityReplacementText("exist", "\u2203"); + parser.defineEntityReplacementText("empty", "\u2205"); + parser.defineEntityReplacementText("nabla", "\u2207"); + parser.defineEntityReplacementText("isin", "\u2208"); + parser.defineEntityReplacementText("notin", "\u2209"); + parser.defineEntityReplacementText("ni", "\u220b"); + parser.defineEntityReplacementText("prod", "\u220f"); + parser.defineEntityReplacementText("sum", "\u2211"); + parser.defineEntityReplacementText("minus", "\u2212"); + parser.defineEntityReplacementText("lowast", "\u2217"); + parser.defineEntityReplacementText("radic", "\u221a"); + parser.defineEntityReplacementText("prop", "\u221d"); + parser.defineEntityReplacementText("infin", "\u221e"); + parser.defineEntityReplacementText("ang", "\u2220"); + parser.defineEntityReplacementText("and", "\u2227"); + parser.defineEntityReplacementText("or", "\u2228"); + parser.defineEntityReplacementText("cap", "\u2229"); + parser.defineEntityReplacementText("cup", "\u222a"); + parser.defineEntityReplacementText("int", "\u222b"); + parser.defineEntityReplacementText("there4", "\u2234"); + parser.defineEntityReplacementText("sim", "\u223c"); + parser.defineEntityReplacementText("cong", "\u2245"); + parser.defineEntityReplacementText("asymp", "\u2248"); + parser.defineEntityReplacementText("ne", "\u2260"); + parser.defineEntityReplacementText("equiv", "\u2261"); + parser.defineEntityReplacementText("le", "\u2264"); + parser.defineEntityReplacementText("ge", "\u2265"); + parser.defineEntityReplacementText("sub", "\u2282"); + parser.defineEntityReplacementText("sup", "\u2283"); + parser.defineEntityReplacementText("nsub", "\u2284"); + parser.defineEntityReplacementText("sube", "\u2286"); + parser.defineEntityReplacementText("supe", "\u2287"); + parser.defineEntityReplacementText("oplus", "\u2295"); + parser.defineEntityReplacementText("otimes", "\u2297"); + parser.defineEntityReplacementText("perp", "\u22a5"); + parser.defineEntityReplacementText("sdot", "\u22c5"); + parser.defineEntityReplacementText("lceil", "\u2308"); + parser.defineEntityReplacementText("rceil", "\u2309"); + parser.defineEntityReplacementText("lfloor", "\u230a"); + parser.defineEntityReplacementText("rfloor", "\u230b"); + parser.defineEntityReplacementText("lang", "\u2329"); + parser.defineEntityReplacementText("rang", "\u232a"); + parser.defineEntityReplacementText("loz", "\u25ca"); + parser.defineEntityReplacementText("spades", "\u2660"); + parser.defineEntityReplacementText("clubs", "\u2663"); + parser.defineEntityReplacementText("hearts", "\u2665"); + parser.defineEntityReplacementText("diams", "\u2666"); + } + + /** + * Load (if {@link #readers} is {@code null} the readers via a + * {@link ServiceLoader} of contract {@link Xpp3Reader} and returns + * the dictionnary of discovered associated to their type + * ({@link Xpp3Reader#getType()}). + * + * @return all the {@link Xpp3Reader} registred via a {@link ServiceLoader} + * on the contract {@link Xpp3Reader} associated to their type + * ({@link Xpp3Reader#getType()}). + */ + protected static Map<Class<?>, Xpp3Reader<?>> getReaders() { + if (readers == null) { + readers = new HashMap<Class<?>, Xpp3Reader<?>>(); + for (Xpp3Reader<?> r : ServiceLoader.load( + Xpp3Reader.class, + Xpp3Helper.class.getClassLoader())) { + + readers.put(r.getType(), r); + } + } + return readers; + } +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Helper.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Added: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Reader.java =================================================================== --- trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Reader.java (rev 0) +++ trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Reader.java 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,170 @@ +package org.nuiton.jredmine.model.io.xpp3.api; + +import org.codehaus.plexus.util.xml.pull.XmlPullParser; +import org.codehaus.plexus.util.xml.pull.XmlPullParserException; + +import java.io.IOException; +import java.io.Reader; + +/** + * A simple contract to mark all xpp readers. + * <p/> + * a such reader is associated to a {@link #getType()}. + * <p/> + * The implementations of such readers must be register in a file + * <pre> + * META-INF/services.org.nuiton.io.xpp3.Xpp3Reader + * </pre> + * <p/> + * to make possible auto-discovering of availables reader at runtime. + * <p/> + * See {@link Xpp3Helper#getReader(Class)} and + * {@link Xpp3Helper#getReaders()}. + * + * @author tchemit <chemit@codelutin.com> + * @param <O> the type of object to be build by the reader. + * @since 1.0.3 + */ +public interface Xpp3Reader<O> { + + /** @return the type of main object to read */ + Class<O> getType(); + + /** + * Read a single instance of the typed object and return it. + * <p/> + * Note : this is a convinient method to call + * {@link #read(Reader, boolean)} in strict mode. + * <p/> + * In the xml stream, the root tag must be the {@link #getRootTagName()}. + * <p/> + * Example : + * <pre> + * <issue>: + * ... + * </issue>: + * </pre> + * + * @param reader the xml input reader + * @return Settings + * @throws IOException if any io pb + * @throws XmlPullParserException if parsing error + */ + O read(Reader reader) throws IOException, XmlPullParserException; + + /** + * Read a single instance of the typed object and return it. + * <p/> + * In the xml stream, the root tag must be the {@link #getRootTagName()}. + * <p/> + * Example : + * <pre> + * <issue>: + * ... + * </issue>: + * </pre> + * + * @param reader the xml input reader + * @param strict flag to be strict while parsing + * @return the read object + * @throws IOException if any io pb + * @throws XmlPullParserException if any parsing pb + */ + O read(Reader reader, boolean strict) throws IOException, + XmlPullParserException; + + /** + * Read some instances of the typed object and return it. + * <p/> + * In the xml stream, the root tag must be the + * {@link #getArrayRootTagName()}. + * <p/> + * Note : this is a convinient method to call : + * {@link #readArray(Reader, boolean)} in stritc mode. + * <p/> + * Example : + * <pre> + * <issues>: + * <issue>: + * ... + * </issue>: + * </issues>: + * </pre> + * + * @param reader the xml input reader + * @return the array of read objects. + * @throws IOException if any io pb + * @throws XmlPullParserException if any parsing pb + */ + O[] readArray(Reader reader) throws IOException, XmlPullParserException; + + /** + * Read some instances of the typed object and return it. + * <p/> + * In the xml stream, the root tag must be the + * {@link #getArrayRootTagName()}. + * <p/> + * Example : + * <pre> + * <issues>: + * <issue>: + * ... + * </issue>: + * </issues>: + * </pre> + * + * @param reader the xml input reader + * @param strict flag to be strict while parsing + * @return the array of read objects. + * @throws IOException if any io pb + * @throws XmlPullParserException if any parsing pb + */ + O[] readArray(Reader reader, boolean strict) throws IOException, + XmlPullParserException; + + /** @return the name of the root tag of a object to read */ + String getRootTagName(); + + /** + * Set the name of the root tag of an object to read. + * + * @param rootTagName the name of the tag + */ + void setRootTagName(String rootTagName); + + /** @return the name of the root tag of an array of objets to read */ + String getArrayRootTagName(); + + /** + * Set the name of the root tag for an array of object to read. + * + * @param parentRootTagName the name of the tag + */ + void setParentRootTagName(String parentRootTagName); + + /** + * @return {@code true} if parser will load the default entities, + * {@code false} otherwise. + */ + boolean isAddDefaultEntities(); + + /** + * Set the new value of the {@code defaultEntities} flag. + * + * @param addDefaultEntities the new value. + */ + void setAddDefaultEntities(boolean addDefaultEntities); + + <T> T[] readArray(String parentRootTagName, + String rootTagName, + Class<T> type, + XmlPullParser parser, + boolean strict) + throws XmlPullParserException, IOException; + + <T> T read(String rootTagName, + Class<T> type, + XmlPullParser parser, + boolean strict) + throws XmlPullParserException, IOException; +} Property changes on: trunk/jredmine-client/src/main/java/org/nuiton/jredmine/model/io/xpp3/api/Xpp3Reader.java ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision Added: svn:eol-style + native Deleted: trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.io.xpp3.Xpp3Reader =================================================================== --- trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.io.xpp3.Xpp3Reader 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.io.xpp3.Xpp3Reader 2012-11-11 09:10:44 UTC (rev 393) @@ -1,11 +0,0 @@ -org.nuiton.jredmine.model.io.xpp3.AttachmentXpp3Reader -org.nuiton.jredmine.model.io.xpp3.IssueXpp3Reader -org.nuiton.jredmine.model.io.xpp3.IssueCategoryXpp3Reader -org.nuiton.jredmine.model.io.xpp3.IssuePriorityXpp3Reader -org.nuiton.jredmine.model.io.xpp3.IssueStatusXpp3Reader -org.nuiton.jredmine.model.io.xpp3.NewsXpp3Reader -org.nuiton.jredmine.model.io.xpp3.ProjectXpp3Reader -org.nuiton.jredmine.model.io.xpp3.TrackerXpp3Reader -org.nuiton.jredmine.model.io.xpp3.UserXpp3Reader -org.nuiton.jredmine.model.io.xpp3.VersionXpp3Reader -org.nuiton.jredmine.model.io.xpp3.TimeEntryXpp3Reader Copied: trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.jredmine.model.io.xpp3.api.Xpp3Reader (from rev 392, trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.io.xpp3.Xpp3Reader) =================================================================== --- trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.jredmine.model.io.xpp3.api.Xpp3Reader (rev 0) +++ trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.jredmine.model.io.xpp3.api.Xpp3Reader 2012-11-11 09:10:44 UTC (rev 393) @@ -0,0 +1,11 @@ +org.nuiton.jredmine.model.io.xpp3.AttachmentXpp3Reader +org.nuiton.jredmine.model.io.xpp3.IssueXpp3Reader +org.nuiton.jredmine.model.io.xpp3.IssueCategoryXpp3Reader +org.nuiton.jredmine.model.io.xpp3.IssuePriorityXpp3Reader +org.nuiton.jredmine.model.io.xpp3.IssueStatusXpp3Reader +org.nuiton.jredmine.model.io.xpp3.NewsXpp3Reader +org.nuiton.jredmine.model.io.xpp3.ProjectXpp3Reader +org.nuiton.jredmine.model.io.xpp3.TrackerXpp3Reader +org.nuiton.jredmine.model.io.xpp3.UserXpp3Reader +org.nuiton.jredmine.model.io.xpp3.VersionXpp3Reader +org.nuiton.jredmine.model.io.xpp3.TimeEntryXpp3Reader Property changes on: trunk/jredmine-client/src/main/resources/META-INF/services/org.nuiton.jredmine.model.io.xpp3.api.Xpp3Reader ___________________________________________________________________ Added: svn:keywords + Author Date Id Revision HeadURL Added: svn:eol-style + native Modified: trunk/jredmine-client/src/test/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3HelperTest.java =================================================================== --- trunk/jredmine-client/src/test/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3HelperTest.java 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-client/src/test/java/org/nuiton/jredmine/model/io/xpp3/RedmineXpp3HelperTest.java 2012-11-11 09:10:44 UTC (rev 393) @@ -34,9 +34,6 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import org.nuiton.io.xpp3.AbstractXpp3Reader; -import org.nuiton.io.xpp3.PropertyMapper; -import org.nuiton.io.xpp3.Xpp3Helper; import org.nuiton.jredmine.model.Attachment; import org.nuiton.jredmine.model.Issue; import org.nuiton.jredmine.model.IssueCategory; @@ -48,6 +45,9 @@ import org.nuiton.jredmine.model.Tracker; import org.nuiton.jredmine.model.User; import org.nuiton.jredmine.model.Version; +import org.nuiton.jredmine.model.io.xpp3.api.AbstractXpp3Reader; +import org.nuiton.jredmine.model.io.xpp3.api.PropertyMapper; +import org.nuiton.jredmine.model.io.xpp3.api.Xpp3Helper; import java.beans.Introspector; import java.io.Closeable; Modified: trunk/jredmine-maven-plugin/pom.xml =================================================================== --- trunk/jredmine-maven-plugin/pom.xml 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/jredmine-maven-plugin/pom.xml 2012-11-11 09:10:44 UTC (rev 393) @@ -50,6 +50,11 @@ <dependency> <groupId>org.nuiton</groupId> + <artifactId>helper-maven-plugin-api</artifactId> + </dependency> + + <dependency> + <groupId>org.nuiton</groupId> <artifactId>helper-maven-plugin</artifactId> </dependency> @@ -171,7 +176,7 @@ <dependency> <groupId>org.nuiton</groupId> - <artifactId>helper-maven-plugin</artifactId> + <artifactId>helper-maven-plugin-api</artifactId> <scope>test</scope> <classifier>tests</classifier> </dependency> Modified: trunk/pom.xml =================================================================== --- trunk/pom.xml 2012-10-30 07:43:52 UTC (rev 392) +++ trunk/pom.xml 2012-11-11 09:10:44 UTC (rev 393) @@ -58,6 +58,8 @@ <projectId>jredmine</projectId> + <helperPluginVersion>2.0-SNAPSHOT</helperPluginVersion> + <!-- must be on a fixed version, not on the snapshot to make possible release --> <jredminePluginVersion>1.5</jredminePluginVersion> @@ -119,38 +121,41 @@ <dependency> <groupId>org.nuiton</groupId> - <artifactId>helper-maven-plugin</artifactId> + <artifactId>helper-maven-plugin-api</artifactId> <version>${helperPluginVersion}</version> <scope>compile</scope> <exclusions> - <exclusion> - <groupId>org.apache.maven</groupId> - <artifactId>maven-artifact</artifactId> - </exclusion> <exclusion> - <groupId>org.apache.maven</groupId> - <artifactId>maven-artifact-manager</artifactId> - </exclusion> - - <exclusion> <groupId>org.apache.maven.shared</groupId> <artifactId>maven-dependency-tree</artifactId> </exclusion> <exclusion> - <groupId>org.apache.maven</groupId> - <artifactId>maven-model</artifactId> + <groupId>org.codehaus.plexus</groupId> + <artifactId>plexus-container-default</artifactId> </exclusion> <exclusion> - <groupId>org.apache.maven</groupId> - <artifactId>maven-profile</artifactId> + <groupId>velocity</groupId> + <artifactId>velocity</artifactId> </exclusion> + </exclusions> + + </dependency> + + <dependency> + <groupId>org.nuiton</groupId> + <artifactId>helper-maven-plugin</artifactId> + <version>${helperPluginVersion}</version> + <scope>compile</scope> + <exclusions> + + <exclusion> - <groupId>org.apache.maven</groupId> - <artifactId>maven-settings</artifactId> + <groupId>org.apache.maven.shared</groupId> + <artifactId>maven-dependency-tree</artifactId> </exclusion> <exclusion> @@ -173,36 +178,6 @@ <artifactId>mail</artifactId> </exclusion> - <exclusion> - <groupId>org.codehaus.plexus</groupId> - <artifactId>plexus-container-default</artifactId> - </exclusion> - - <exclusion> - <groupId>org.codehaus.plexus</groupId> - <artifactId>plexus-velocity</artifactId> - </exclusion> - - <exclusion> - <groupId>javax.mail</groupId> - <artifactId>mail</artifactId> - </exclusion> - - <exclusion> - <groupId>org.sonatype.plexus</groupId> - <artifactId>plexus-cipher</artifactId> - </exclusion> - - <exclusion> - <groupId>org.sonatype.plexus</groupId> - <artifactId>plexus-sec-dispatcher</artifactId> - </exclusion> - - <exclusion> - <groupId>velocity</groupId> - <artifactId>velocity</artifactId> - </exclusion> - </exclusions> </dependency> @@ -474,7 +449,7 @@ <dependency> <groupId>org.nuiton</groupId> - <artifactId>helper-maven-plugin</artifactId> + <artifactId>helper-maven-plugin-api</artifactId> <version>${helperPluginVersion}</version> <scope>test</scope> <classifier>tests</classifier>
participants (1)
-
tchemit@users.nuiton.org