Jredmine-commits
Threads by month
- ----- 2026 -----
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
November 2012
- 1 participants
- 4 discussions
Author: tchemit
Date: 2012-11-16 17:15:44 +0100 (Fri, 16 Nov 2012)
New Revision: 396
Url: http://nuiton.org/repositories/revision/jredmine/396
Log:
fix scm url
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2012-11-16 15:34:26 UTC (rev 395)
+++ trunk/pom.xml 2012-11-16 16:15:44 UTC (rev 396)
@@ -78,7 +78,7 @@
<developerConnection>
scm:svn:http://svn.nuiton.org/svn/jredmine/trunk
</developerConnection>
- <url>http://www.nuiton.org/repositories/browse/jredmine/trunk</url>
+ <url>http://nuiton.org/projects/jredmine/repository/show/trunk</url>
</scm>
<distributionManagement>
1
0
Author: tchemit
Date: 2012-11-16 16:34:26 +0100 (Fri, 16 Nov 2012)
New Revision: 395
Url: http://nuiton.org/repositories/revision/jredmine/395
Log:
fixes #2424: Updates to mavenpom 3.4.4
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2012-11-11 19:28:35 UTC (rev 394)
+++ trunk/pom.xml 2012-11-16 15:34:26 UTC (rev 395)
@@ -27,7 +27,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>mavenpom4redmineAndCentral</artifactId>
- <version>3.4.4-SNAPSHOT</version>
+ <version>3.4.4</version>
</parent>
<artifactId>jredmine</artifactId>
1
0
Author: tchemit
Date: 2012-11-11 20:28:35 +0100 (Sun, 11 Nov 2012)
New Revision: 394
Url: http://nuiton.org/repositories/revision/jredmine/394
Log:
refs #2424: Updates to mavenpom 3.4.4
fixes #2411: Updates to helper-maven-plugin 2.0
use last jredmine version (for jredmine internal release)
Modified:
trunk/pom.xml
Modified: trunk/pom.xml
===================================================================
--- trunk/pom.xml 2012-11-11 09:10:44 UTC (rev 393)
+++ trunk/pom.xml 2012-11-11 19:28:35 UTC (rev 394)
@@ -27,7 +27,7 @@
<parent>
<groupId>org.nuiton</groupId>
<artifactId>mavenpom4redmineAndCentral</artifactId>
- <version>3.4.3</version>
+ <version>3.4.4-SNAPSHOT</version>
</parent>
<artifactId>jredmine</artifactId>
@@ -58,10 +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>
+ <jredminePluginVersion>1.5.1</jredminePluginVersion>
<doxiaVersion>1.3</doxiaVersion>
@@ -118,7 +116,6 @@
<version>${httpCommonsHttpclientVersion}</version>
</dependency>
-
<dependency>
<groupId>org.nuiton</groupId>
<artifactId>helper-maven-plugin-api</artifactId>
@@ -152,7 +149,6 @@
<scope>compile</scope>
<exclusions>
-
<exclusion>
<groupId>org.apache.maven.shared</groupId>
<artifactId>maven-dependency-tree</artifactId>
1
0
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
by tchemit@users.nuiton.org 11 Nov '12
by tchemit@users.nuiton.org 11 Nov '12
11 Nov '12
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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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(a)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>
1
0