Author: elman
Date: Tue Sep 8 13:09:56 2009
New Revision: 812495
URL: http://svn.apache.org/viewvc?rev=812495&view=rev
Log:
Making SyndContent/AtomContent support Object values instead of String. See [WINK-161]
Added:
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AnyContentHandler.java (with props)
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomXhtml.java (with props)
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/XmlWrapper.java
Modified:
incubator/wink/trunk/pom.xml
incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java
incubator/wink/trunk/wink-common/pom.xml
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/runtime/AbstractRuntimeContext.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomContent.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomEntry.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomFeed.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomJAXBUtils.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomText.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/ObjectFactory.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndContent.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndSimpleContent.java
incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndText.java
incubator/wink/trunk/wink-common/src/main/resources/org/apache/wink/common/internal/i18n/resource.properties
incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/internal/application/ApplicationFileLoaderTest.java
incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/model/app/AppTest.java
incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/model/atom/AtomTest.java
incubator/wink/trunk/wink-common/src/test/java/org/apache/wink/common/model/opensearch/OpenSearchTest.java
incubator/wink/trunk/wink-component-test-support/src/main/java/org/apache/wink/test/mock/TestUtils.java
incubator/wink/trunk/wink-examples/ext/History/src/main/java/org/apache/wink/example/history/resources/DefectAsset.java
incubator/wink/trunk/wink-examples/ext/History/src/test/java/org/apache/wink/example/history/HistoryTest.java
incubator/wink/trunk/wink-examples/ext/History/src/test/resources/org/apache/wink/example/history/defect1_1_afterdelete_atom.xml
incubator/wink/trunk/wink-examples/ext/History/src/test/resources/org/apache/wink/example/history/defect1_1_atom.xml
incubator/wink/trunk/wink-examples/ext/History/src/test/resources/org/apache/wink/example/history/defect1_4_atom.xml
incubator/wink/trunk/wink-examples/ext/History/src/test/resources/org/apache/wink/example/history/defect1_5_atom.xml
incubator/wink/trunk/wink-examples/ext/History/src/test/resources/org/apache/wink/example/history/initial_defect1_atom.xml
incubator/wink/trunk/wink-providers/wink-jettison-provider/src/test/java/org/apache/wink/server/internal/providers/entity/jettison/JettisonJAXBBadgerFishTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/AbstractResourceBeanTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/AbstractResourceWithDuplicateWorkspaceTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/AtomEntryProviderTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/AtomFeedProviderTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/EntityLocatorProviderTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/SyndEntryLocatorProviderTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/providers/entity/SyndFeedLocatorProviderTest.java
incubator/wink/trunk/wink-server/src/test/java/org/apache/wink/server/internal/registry/ResponseDispatchTest.java
Modified: incubator/wink/trunk/pom.xml
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/pom.xml?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/pom.xml (original)
+++ incubator/wink/trunk/pom.xml Tue Sep 8 13:09:56 2009
@@ -451,11 +451,6 @@
<version>1.1</version>
</dependency>
<dependency>
- <groupId>xerces</groupId>
- <artifactId>xercesImpl</artifactId>
- <version>2.6.2</version>
- </dependency>
- <dependency>
<groupId>org.json</groupId>
<artifactId>json</artifactId>
<version>20080701</version>
Modified: incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java (original)
+++ incubator/wink/trunk/wink-client/src/test/java/org/apache/wink/client/ProvidersTest.java Tue Sep 8 13:09:56 2009
@@ -32,6 +32,7 @@
import org.apache.wink.client.RestClient;
import org.apache.wink.common.internal.providers.entity.atom.AtomFeedProvider;
import org.apache.wink.common.model.atom.AtomFeed;
+import org.apache.wink.test.mock.TestUtils;
import junit.framework.TestCase;
@@ -81,7 +82,7 @@
+ " </entry>\n"
+ "</feed>\n";
- public void testAtomFeedReadWrite() throws WebApplicationException, IOException {
+ public void testAtomFeedReadWrite() throws Exception {
MockHttpServer server = new MockHttpServer(SERVER_PORT);
server.setMockResponseCode(200);
server.setMockResponseContentEchoRequest(true);
@@ -116,7 +117,8 @@
os);
String actual = os.toString();
- assertEquals(FEED, actual);
+ String msg = TestUtils.diffIgnoreUpdateWithAttributeQualifier(FEED, actual);
+ assertNull(msg, msg);
} finally {
server.stopServer();
}
Modified: incubator/wink/trunk/wink-common/pom.xml
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/pom.xml?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/pom.xml (original)
+++ incubator/wink/trunk/wink-common/pom.xml Tue Sep 8 13:09:56 2009
@@ -70,10 +70,6 @@
<artifactId>activation</artifactId>
</dependency>
<dependency>
- <groupId>xerces</groupId>
- <artifactId>xercesImpl</artifactId>
- </dependency>
- <dependency>
<groupId>javax.ws.rs</groupId>
<artifactId>jsr311-api</artifactId>
</dependency>
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/runtime/AbstractRuntimeContext.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/runtime/AbstractRuntimeContext.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/runtime/AbstractRuntimeContext.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/internal/runtime/AbstractRuntimeContext.java Tue Sep 8 13:09:56 2009
@@ -39,16 +39,16 @@
this.attributes = new HashMap<String, Object>();
}
- public Map<String, Object> getAttributes() {
+ public final Map<String, Object> getAttributes() {
return attributes;
}
- public <T> void setAttribute(Class<T> type, T object) {
+ public final <T> void setAttribute(Class<T> type, T object) {
getAttributes().put(type.getName(), object);
}
@SuppressWarnings("unchecked")
- public <T> T getAttribute(Class<T> type) {
+ public final <T> T getAttribute(Class<T> type) {
return (T)getAttributes().get(type.getName());
}
Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AnyContentHandler.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AnyContentHandler.java?rev=812495&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AnyContentHandler.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AnyContentHandler.java Tue Sep 8 13:09:56 2009
@@ -0,0 +1,117 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.wink.common.model.atom;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.ext.MessageBodyWriter;
+import javax.ws.rs.ext.Providers;
+import javax.xml.bind.ValidationEventHandler;
+import javax.xml.bind.annotation.DomHandler;
+import javax.xml.transform.Source;
+import javax.xml.transform.stream.StreamResult;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.wink.common.RestConstants;
+import org.apache.wink.common.RuntimeContext;
+import org.apache.wink.common.internal.i18n.Messages;
+import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
+import org.apache.wink.common.utils.ProviderUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Handles objects wrapped with XmlWrapper
+ */
+/* package */class AnyContentHandler implements DomHandler<XmlWrapper, StreamResult> {
+
+ private static final Logger logger = LoggerFactory.getLogger(AnyContentHandler.class);
+
+ public StreamResult createUnmarshaller(ValidationEventHandler errorHandler) {
+ return new StreamResult(new ByteArrayOutputStream());
+ }
+
+ public XmlWrapper getElement(StreamResult rt) {
+ return new XmlWrapper(((ByteArrayOutputStream)rt.getOutputStream()).toByteArray(), null);
+ }
+
+ @SuppressWarnings("unchecked")
+ public Source marshal(XmlWrapper xmlWrapper, ValidationEventHandler errorHandler) {
+ MediaType type = null;
+
+ String contentType = xmlWrapper.getType();
+ if (contentType == null) {
+ // should never happen
+ type = MediaType.APPLICATION_OCTET_STREAM_TYPE;
+ } else if (contentType.equals("xhtml")) {
+ type = MediaType.APPLICATION_XML_TYPE;
+ } else {
+ type = MediaType.valueOf(contentType);
+ }
+
+ RuntimeContext runtimeContext = RuntimeContextTLS.getRuntimeContext();
+ Providers providers = runtimeContext.getProviders();
+ Class<? extends Object> cls = xmlWrapper.getValue().getClass();
+
+ // this code ignores possible generic types
+ // if in the future we would like to support the generic types
+ // should check here if cls is GenericEntity and handle it
+
+ MessageBodyWriter<Object> writer =
+ (MessageBodyWriter<Object>)providers.getMessageBodyWriter(cls, cls, null, type);
+
+ if (writer == null) {
+ logger.error(Messages.getMessage("noWriterFound"), cls.getName(), type.toString());
+ throw new WebApplicationException(500);
+ }
+
+ ByteArrayOutputStream os = new ByteArrayOutputStream();
+ try {
+ writer.writeTo(xmlWrapper.getValue(),
+ cls,
+ cls,
+ AtomJAXBUtils.EMPTY_ARRAY,
+ type,
+ AtomJAXBUtils.EMPTY_OBJECT_MAP,
+ os);
+ } catch (IOException e) {
+ throw new WebApplicationException(e);
+ }
+ byte[] result;
+ if (contentType.equals("xhtml")) {
+ try {
+ result =
+ new StringBuilder().append("<div xmlns=\"")
+ .append(RestConstants.NAMESPACE_XHTML).append("\">").append(os
+ .toString(ProviderUtils.getCharset(type))).append("</div>").toString()
+ .getBytes();
+ } catch (UnsupportedEncodingException e) {
+ throw new WebApplicationException(e);
+ }
+ } else {
+ result = os.toByteArray();
+ }
+ return new StreamSource(new ByteArrayInputStream(result));
+ }
+}
Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AnyContentHandler.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomContent.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomContent.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomContent.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomContent.java Tue Sep 8 13:09:56 2009
@@ -17,18 +17,18 @@
* under the License.
*
*******************************************************************************/
-//
-// This file was generated by the JavaTM Architecture for XML Binding(JAXB) Reference Implementation, v2.1.1-b02-fcs
-// See <a href="http://java.sun.com/xml/jaxb">http://java.sun.com/xml/jaxb</a>
-// Any modifications to this file will be lost upon recompilation of the source schema.
-// Generated on: 2008.05.27 at 11:24:25 AM IDT
-//
-
package org.apache.wink.common.model.atom;
-import java.util.ArrayList;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
import java.util.List;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Providers;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
@@ -182,20 +182,20 @@
*
* </pre>
*/
-@XmlAccessorType(XmlAccessType.FIELD)
+@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "atomContent", propOrder = {"any"})
public class AtomContent extends AtomCommonAttributes {
- @XmlMixed
- @XmlAnyElement
- protected List<Object> any;
+ @XmlTransient
+ private List<Object> any;
+
@XmlAttribute
- protected String type;
+ protected String type;
@XmlAttribute
- protected String src;
+ protected String src;
@XmlTransient
- private String savedValue = null;
+ private Object savedValue = null;
public AtomContent() {
}
@@ -207,7 +207,8 @@
}
setSrc(value.getSrc());
setType(value.getType());
- setValue(value.getValue());
+ // copies the value AS IS without invoking providers
+ setValue(value.getValue(Object.class));
}
public SyndContent toSynd(SyndContent value) {
@@ -217,17 +218,11 @@
super.toSynd(value);
value.setSrc(getSrc());
value.setType(getType());
- value.setValue(getValue());
+ // copies the value AS IS without invoking providers
+ value.setValue(getValue(Object.class));
return value;
}
- private List<Object> getAny() {
- if (any == null) {
- any = new ArrayList<Object>();
- }
- return this.any;
- }
-
/**
* Gets the value of type.
*/
@@ -260,7 +255,7 @@
/**
* Sets the content of the "atom:content" element as a String. The "type"
- * attrbiute should be set prior to setting the contents.
+ * attribute should be set prior to setting the contents.
* <p>
* Atom Documents MUST conform to the following rules. Atom Processors MUST
* interpret atom:content according to the first applicable rule.
@@ -306,37 +301,90 @@
* <li>
* </ol>
*/
- public void setValue(String value) {
- if (value == null) {
- getAny().clear();
- return;
- }
-
- if (getAny().size() == 0) {
- getAny().add(0, value);
+ public void setValue(Object value) {
+ if (value != null) {
+ any = Arrays.asList(value);
} else {
- getAny().set(0, value);
+ any = null;
}
-
checkValidity();
}
/**
+ * <p>
* Gets the content of the "atom:content" element as a String. The "type"
* attribute should be used to determine how to treat the content.
+ * <p>
+ * Pay attention that de-serialization occurs each time the method is
+ * called, so multiple calls to this method may effect the application
+ * performance.
*/
public String getValue() {
- if (getAny().size() == 0) {
- return null;
+ return getValue(String.class);
+ }
+
+ /**
+ * <p>
+ * Gets the content of the "atom:content" element serialized to provided
+ * class. The "type" attribute should be used to determine how to treat the
+ * content.
+ * <p>
+ * Pay attention that de-serialization occurs each time the method is
+ * called, so multiple calls to this method may effect the application
+ * performance.
+ */
+ public <T> T getValue(Class<T> cls) {
+ try {
+ return getValue(cls,
+ cls,
+ null,
+ AtomJAXBUtils.EMPTY_ARRAY,
+ AtomJAXBUtils.EMPTY_STRING_MAP,
+ AtomJAXBUtils.determineMediaType(type));
+ } catch (IOException e) {
+ // should never happen
+ throw new WebApplicationException(e);
}
- Object s = getAny().get(0);
- return s != null ? s.toString() : null;
+ }
+ /**
+ * <p>
+ * Gets the content of the "atom:content" element serialized to provided
+ * class according to provided parameters.
+ * <p>
+ * Pay attention that de-serialization occurs each time the method is
+ * called, so multiple calls to this method may effect the application
+ * performance.
+ */
+ public <T> T getValue(Class<T> cls,
+ Type genericType,
+ Providers providers,
+ Annotation[] annotations,
+ MultivaluedMap<String, String> httpHeaders,
+ MediaType mediaType) throws IOException {
+ return AtomJAXBUtils.readValue(getAny(),
+ cls,
+ providers,
+ genericType,
+ annotations,
+ httpHeaders,
+ mediaType);
+ }
+
+ @XmlMixed
+ @XmlAnyElement(lax = true, value = AnyContentHandler.class)
+ List<Object> getAny() {
+ AtomJAXBUtils.fixAnyContent(any, type);
+ return any;
+ }
+
+ void setAny(List<Object> any) {
+ this.any = any;
}
public void checkValidity() {
- if (getSrc() != null && getValue() != null) {
+ if (src != null && any != null) {
throw new RestException("Content element may have either inline or out-of-line content");
- } else if (getSrc() != null && getType() != null) {
+ } else if (src != null && type != null) {
if (type.equals("text") || type.equals("html") || type.equals("xhtml")) {
throw new RestException(
"Type attribute of content element must be a valid mime type when content is out-of-line");
@@ -349,7 +397,7 @@
savedValue = null;
}
- /* package */String saveValue() {
+ /* package */Object saveValue() {
this.savedValue = getValue();
setValue(null);
return this.savedValue;
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomEntry.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomEntry.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomEntry.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomEntry.java Tue Sep 8 13:09:56 2009
@@ -170,7 +170,8 @@
}
public static Marshaller getMarshaller() {
- return JAXBUtils.createMarshaller(atomContext);
+ Marshaller marshaller = JAXBUtils.createMarshaller(atomContext);
+ return marshaller;
}
public static Unmarshaller getUnmarshaller() {
@@ -190,7 +191,7 @@
public static void marshal(AtomEntry entry, OutputStream os) throws IOException {
JAXBElement<AtomEntry> entryElement = new ObjectFactory().createEntry(entry);
Marshaller marshaller = AtomEntry.getMarshaller();
- AtomJAXBUtils.marshal(marshaller, entryElement, null, os);
+ AtomJAXBUtils.marshal(marshaller, entryElement, os);
}
public JAXBNamespacePrefixMapper getNamespacePrefixMapper() {
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomFeed.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomFeed.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomFeed.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomFeed.java Tue Sep 8 13:09:56 2009
@@ -259,7 +259,7 @@
public static void marshal(AtomFeed feed, OutputStream os) throws IOException {
JAXBElement<AtomFeed> feedElement = new ObjectFactory().createFeed(feed);
Marshaller marshaller = AtomFeed.getMarshaller();
- AtomJAXBUtils.marshal(marshaller, feedElement, null, os);
+ AtomJAXBUtils.marshal(marshaller, feedElement, os);
}
public JAXBNamespacePrefixMapper getNamespacePrefixMapper() {
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomJAXBUtils.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomJAXBUtils.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomJAXBUtils.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomJAXBUtils.java Tue Sep 8 13:09:56 2009
@@ -20,56 +20,65 @@
package org.apache.wink.common.model.atom;
-import java.io.CharArrayWriter;
+import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
-import java.io.StringReader;
-import java.io.UnsupportedEncodingException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
import java.util.Calendar;
import java.util.GregorianCalendar;
-import java.util.Map;
-import java.util.Set;
+import java.util.List;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.ext.MessageBodyReader;
+import javax.ws.rs.ext.Providers;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
-import javax.xml.bind.UnmarshallerHandler;
import javax.xml.datatype.DatatypeFactory;
import javax.xml.datatype.XMLGregorianCalendar;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParserFactory;
-import org.apache.wink.common.RestConstants;
import org.apache.wink.common.RestException;
-import org.apache.wink.common.internal.model.NamespacePrefixMapperProvider;
-import org.apache.wink.common.internal.utils.SAXHandlerWrapper;
-import org.apache.wink.common.model.JAXBNamespacePrefixMapper;
-import org.apache.xml.serialize.EncodingInfo;
-import org.apache.xml.serialize.Method;
-import org.apache.xml.serialize.OutputFormat;
-import org.apache.xml.serialize.XMLSerializer;
-import org.xml.sax.Attributes;
+import org.apache.wink.common.RuntimeContext;
+import org.apache.wink.common.internal.MultivaluedMapImpl;
+import org.apache.wink.common.internal.runtime.RuntimeContextTLS;
+import org.apache.wink.common.internal.utils.UnmodifiableMultivaluedMap;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
-import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.ext.LexicalHandler;
public class AtomJAXBUtils {
- private final static SAXParserFactory spf;
- private final static EncodingInfo encodingInfo;
- private static final DatatypeFactory datatypeFactory;
+ public static final MultivaluedMap<String, Object> EMPTY_OBJECT_MAP =
+ new UnmodifiableMultivaluedMap<String, Object>(
+ new MultivaluedMapImpl<String, Object>());
+ public static final MultivaluedMap<String, String> EMPTY_STRING_MAP =
+ new UnmodifiableMultivaluedMap<String, String>(
+ new MultivaluedMapImpl<String, String>());
+ public static final Annotation[] EMPTY_ARRAY = new Annotation[0];
+ private final static SAXParserFactory spf;
+ private final static DatatypeFactory datatypeFactory;
+ private static final Logger logger =
+ LoggerFactory
+ .getLogger(AtomJAXBUtils.class);
static {
try {
spf = SAXParserFactory.newInstance();
spf.setNamespaceAware(true);
spf.setValidating(false);
- encodingInfo = (new OutputFormat(Method.XML, "UTF-8", true)).getEncodingInfo();
datatypeFactory = DatatypeFactory.newInstance();
} catch (Exception e) {
throw new RestException("Error setting up Atom JAXB utils", e);
@@ -126,716 +135,41 @@
}
xmlReader.parse(new InputSource(reader));
} catch (SAXException e) {
- throw new RestException(errorMessage, e);
+ logger.error(errorMessage);
+ throw new WebApplicationException(e);
} catch (ParserConfigurationException e) {
- // shoudln't happen
- throw new RestException(errorMessage, e);
+ logger.error(errorMessage);
+ throw new WebApplicationException(e);
} catch (IOException e) {
- throw new RestException(errorMessage, e);
+ logger.error(errorMessage);
+ throw new WebApplicationException(e);
}
}
public static Object unmarshal(Unmarshaller unmarshaller, Reader reader) throws IOException {
Object result = null;
try {
- UnmarshallerHandler unmarshallerHandler = unmarshaller.getUnmarshallerHandler();
- AtomUnmarshallingListener.AtomUnmarshallerHandler handler =
- new AtomUnmarshallingListener.AtomUnmarshallerHandler(unmarshallerHandler);
- AtomUnmarshallingListener listener = new AtomUnmarshallingListener(handler);
- unmarshaller.setListener(listener);
- // here is where the magic begins.
- // SAX will parse the XML document, and our handler will get all the
- // SAX events
- saxParse(reader, handler, "failed to unmarshal object");
- // parsing is done and the JAXB object is ready
- result = handler.getResult();
+ result = unmarshaller.unmarshal(reader);
if (result instanceof JAXBElement<?>) {
result = ((JAXBElement<?>)result).getValue();
}
} catch (IllegalStateException e) {
- throw new RestException("failed to unmarshal object", e);
+ throw new WebApplicationException(e);
} catch (JAXBException e) {
- throw new RestException("failed to unmarshal object", e);
+ throw new WebApplicationException(e);
}
return result;
}
public static void marshal(Marshaller marshaller, Object jaxbObject, OutputStream os)
throws IOException {
- marshal(marshaller, jaxbObject, null, null, os);
- }
-
- public static void marshal(Marshaller marshaller,
- Object jaxbObject,
- Map<String, String> processingInstructions,
- OutputStream os) throws IOException {
- marshal(marshaller, jaxbObject, processingInstructions, null, os);
- }
-
- public static void marshal(Marshaller marshaller,
- Object jaxbObject,
- Map<String, String> processingInstructions,
- JAXBNamespacePrefixMapper namespacePrefixMapper,
- OutputStream os) throws IOException {
try {
- // create a new SAX serializer for creating the XML output.
- // we will invoke the marshal of JAXB to send all its marshaling
- // events to this handler
- AtomMarshallingListener.AtomMarshallerHandler handler =
- new AtomMarshallingListener.AtomMarshallerHandler(processingInstructions,
- marshaller);
- if (namespacePrefixMapper == null) {
- Object jaxb = jaxbObject;
- if (jaxbObject instanceof JAXBElement<?>) {
- jaxb = ((JAXBElement<?>)jaxbObject).getValue();
- }
- if (jaxb instanceof NamespacePrefixMapperProvider) {
- namespacePrefixMapper =
- ((NamespacePrefixMapperProvider)jaxb).getNamespacePrefixMapper();
- }
- }
- handler.setNamespacePrefixMapper(namespacePrefixMapper);
- handler.setOutputByteStream(os);
- // add our listener to the marshaler so we will receive events from
- // JAXB
- marshaller.setListener(new AtomMarshallingListener(handler));
- // perform the marshaling so that our marshaler (xml serializer)
- // will receive all the
- // SAX events
- ContentHandler xmlSerializer = handler.asContentHandler();
- marshaller.marshal(jaxbObject, xmlSerializer);
+ marshaller.marshal(jaxbObject, os);
} catch (JAXBException e) {
- throw new RestException("failed to marshal object (" + jaxbObject.getClass().getName()
- + ")", e);
- }
- }
-
- // ========================== AtomMarshallingListener
- // =================================
-
- //
- // JAXB marshaling listener which is used to get events from JAXB during the
- // marshaling of an
- // XML
- //
- public static class AtomMarshallingListener extends Marshaller.Listener {
-
- // this is the AtomMarshallerHandler that will receive all the SAX
- // events from JAXB for
- // creating the
- // XML output.
- private AtomMarshallerHandler handler;
-
- public AtomMarshallingListener(AtomMarshallerHandler handler) {
- this.handler = handler;
- }
-
- @Override
- public void beforeMarshal(Object source) {
- if (isValueActuallyXml(source)) {
- // handler.setIsContentXml(true);
- String xmlContent = null;
- if (source instanceof AtomContent) {
- AtomContent content = (AtomContent)source;
- xmlContent = content.saveValue();
- if (content.getType().equals("xhtml")) {
- xmlContent = surroundWithXhtmlDiv(xmlContent);
- }
- } else if (source instanceof AtomText) {
- AtomText text = (AtomText)source;
- // we know that the type is xhtml, or we wouldn't have
- // gotten here
- xmlContent = text.saveValue();
- xmlContent = surroundWithXhtmlDiv(xmlContent);
- }
- handler.pushXmlContent(xmlContent);
- }
- }
-
- private String surroundWithXhtmlDiv(String xhtml) {
- if (xhtml == null) {
- return null;
- }
- return "<div xmlns=\"" + RestConstants.NAMESPACE_XHTML + "\">" + xhtml + "</div>";
- }
-
- @Override
- public void afterMarshal(Object source) {
- if (isValueActuallyXml(source)) {
- // restore original value
- if (source instanceof AtomContent) {
- AtomContent content = (AtomContent)source;
- content.revertValue();
- } else if (source instanceof AtomText) {
- AtomText text = (AtomText)source;
- text.revertValue();
- }
- }
- }
-
- /**
- * AtomMarshallerHandler is a SAX ContentHandler which extends
- * XMLSerliazer to create an XML output from SAX events.
- */
- public static class AtomMarshallerHandler extends XMLSerializer {
- // this is used to control the output of the xml that the
- // XMLSerializer will produce
- private OutputFormat of;
- private int indentation = 4;
-
- private Map<String, String> processingInstructions;
- private JAXBNamespacePrefixMapper namespacePrefixMapper;
-
- private String xmlContent;
-
- public AtomMarshallerHandler(Map<String, String> processingInstructions,
- Marshaller marshaller) throws JAXBException,
- UnsupportedEncodingException {
- this.processingInstructions = processingInstructions;
- namespacePrefixMapper = null;
- xmlContent = null;
-
- // prepare the OutputFormat to output the XML as desired
- of = new OutputFormat();
- of.setMethod(Method.XML);
- String encoding = (String)marshaller.getProperty(Marshaller.JAXB_ENCODING);
- of.setEncoding(encoding == null ? encodingInfo : new OutputFormat(Method.XML,
- encoding, true)
- .getEncodingInfo());
- Boolean property =
- (Boolean)marshaller.getProperty(Marshaller.JAXB_FORMATTED_OUTPUT);
- boolean formattedOutput = false;
- if (property != null) {
- formattedOutput = property.booleanValue();
- }
- of.setIndenting(formattedOutput);
- if (formattedOutput) {
- of.setIndent(indentation);
- of.setLineWidth(256);
- }
-
- property = (Boolean)marshaller.getProperty(Marshaller.JAXB_FRAGMENT);
- boolean xmlDeclaration = false;
- if (property != null) {
- xmlDeclaration = property.booleanValue();
- }
- of.setOmitXMLDeclaration(xmlDeclaration);
- super.setOutputFormat(of);
- }
-
- public void setNamespacePrefixMapper(JAXBNamespacePrefixMapper namespacePrefixMapper) {
- this.namespacePrefixMapper = namespacePrefixMapper;
- }
-
- public String popXmlContent() {
- String ret = xmlContent;
- xmlContent = null;
- return ret;
- }
-
- public void pushXmlContent(String xmlContent) {
- this.xmlContent = xmlContent;
- }
-
- public boolean isXmlContent() {
- return xmlContent != null;
- }
-
- // ======= ContentHandler methods ============
-
- @Override
- public void startDocument(String rootTagName) throws IOException {
- // if the user supplied additional processing instructions, add
- // them now
- if (processingInstructions != null) {
- Set<String> keys = processingInstructions.keySet();
- String attributes = null;
- for (String key : keys) {
- try {
- attributes = processingInstructions.get(key);
- super.processingInstruction(key, attributes);
- } catch (SAXException e) {
- throw new RestException("failed to add processing instruction '" + key
- + "' with attributes '"
- + attributes
- + "'", e);
- }
- }
- }
- super.startDocument(rootTagName);
- }
-
- @Override
- public void startPrefixMapping(String prefix, String uri) throws SAXException {
- if (namespacePrefixMapper != null) {
- if (namespacePrefixMapper.isNamespaceOmitted(uri)) {
- return;
- }
- prefix = namespacePrefixMapper.getPreferredPrefix(uri, prefix, true);
- }
- super.startPrefixMapping(prefix, uri);
- }
-
- @Override
- public void startElement(String namespaceURI,
- String localName,
- String rawName,
- Attributes attrs) throws SAXException {
-
- if (namespacePrefixMapper != null) {
- String prefix =
- namespacePrefixMapper.getPreferredPrefix(namespaceURI, null, false);
- if (prefix != null) {
- if (prefix.length() == 0) {
- rawName = localName;
- } else {
- rawName = prefix + ":" + localName;
- }
- }
- }
- super.startElement(namespaceURI, localName, rawName, attrs);
-
- if (isXmlContent()) {
- parseXmlContent();
- }
- }
-
- private void parseXmlContent() {
- String xmlContent = popXmlContent();
- JAXBNamespacePrefixMapper mapper = namespacePrefixMapper;
- // disable the prefix mapper
- namespacePrefixMapper = null;
- // parse the xml content and send all events to this handler,
- // except for the startDocument and endDocument events
- saxParse(new StringReader(xmlContent),
- new XmlContentHandler(this),
- "Bad XML content in Atom");
- // restore the prefix mapper
- namespacePrefixMapper = mapper;
- }
-
- /**
- * Delegates all SAX events to the contained handler except for the
- * start and end document events
- */
- private static class XmlContentHandler extends SAXHandlerWrapper {
- public XmlContentHandler(ContentHandler handler) {
- super(handler);
- }
-
- @Override
- public void startDocument() throws SAXException {
- // no op
- }
-
- @Override
- public void endDocument() throws SAXException {
- // no op
- }
- }
- }
-
- }
-
- // ========================== AtomUnmarshallingListener
- // =================================
-
- public static class AtomUnmarshallingListener extends Unmarshaller.Listener {
-
- private AtomUnmarshallerHandler unmarshallerHandler;
-
- public AtomUnmarshallingListener(AtomUnmarshallerHandler handler) {
- this.unmarshallerHandler = handler;
- }
-
- @Override
- public void beforeUnmarshal(Object target, Object parent) {
- // if JAXB is just about to unmarshal an AtomContent element
- if (target instanceof AtomContent) {
- unmarshallerHandler.startSpecialContent(target);
-
- // if JAXB is just about to unmarshal an AtomText construct
- // element
- } else if (target instanceof AtomText) {
- unmarshallerHandler.startSpecialContent(target);
- }
- }
-
- @Override
- public void afterUnmarshal(Object target, Object parent) {
- if (target instanceof AtomContent) {
- ((AtomContent)target).setValue(unmarshallerHandler.endSpecialContent());
- } else if (target instanceof AtomText) {
- ((AtomText)target).setValue(unmarshallerHandler.endSpecialContent());
- }
- }
-
- /**
- * This handler is used to receive all SAX events during the parsing of
- * an incoming Atom feed or entry. During the parsing of the XML we will
- * delegate almost all of the events to JAXB so it can do its magic.
- * Events that are related to the contents of a <content> element or
- * to a text construct element will be redirected to an instance of a
- * SpecialContentHandler for converting the contents into a string even
- * if it is xml
- */
- public static class AtomUnmarshallerHandler implements UnmarshallerHandler, LexicalHandler {
-
- // the JAXB ContentHandler that will receive all the delegated SAX
- // parser events other
- // than the events related to elements whose xml contents need to be
- // treated as text
- private UnmarshallerHandler jaxbHandler;
-
- // this is an xml serializer to handle SAX events during the parsing
- // of an element whose xml contents needs to be treated as text,
- // even
- // if it is xml
- private SpecialContentHandler specialContentHandler;
-
- // flag for indicating that we are currently handing an element
- // whose
- // contents needs to be treated as text, even if it is xml
- private boolean isSpecialContent;
-
- public AtomUnmarshallerHandler(UnmarshallerHandler handler) {
- jaxbHandler = handler;
- isSpecialContent = false;
- }
-
- public void startSpecialContent(Object target) {
- // this method is called from the UnmarshallerListener, who
- // received a notification
- // that a JAXB element is going to be unmarshalled.
- isSpecialContent = true;
- specialContentHandler = new SpecialContentHandler(target);
- try {
- specialContentHandler.startDocument();
- } catch (SAXException e) {
- // shouldn't happen
- throw new RestException("xmlSerializer failed", e);
- }
- }
-
- public String endSpecialContent() {
- try {
- specialContentHandler.endDocument();
- } catch (SAXException e) {
- // shouldn't happen
- throw new RestException("xmlSerializer failed", e);
- }
- String contentStr = specialContentHandler.getResult();
- return contentStr;
- }
-
- public Object getResult() throws JAXBException, IllegalStateException {
- return jaxbHandler.getResult();
- }
-
- // ======= ContentHandler methods ============
-
- public void endElement(String uri, String localName, String name) throws SAXException {
- if (isSpecialContent) {
- if (specialContentHandler.isDone()) {
- isSpecialContent = false;
- } else {
- // delegate the event to the special content serializer
- specialContentHandler.endElement(uri, localName, name);
- return;
- }
- }
-
- // delegate the event to JAXB
- jaxbHandler.endElement(uri, localName, name);
- }
-
- public void startElement(String uri, String localName, String name, Attributes atts)
- throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.startElement(uri, localName, name, atts);
- return;
- }
- jaxbHandler.startElement(uri, localName, name, atts);
- }
-
- public void characters(char[] ch, int start, int length) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.characters(ch, start, length);
- return;
- }
- jaxbHandler.characters(ch, start, length);
- }
-
- public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.ignorableWhitespace(ch, start, length);
- return;
- }
- jaxbHandler.ignorableWhitespace(ch, start, length);
- }
-
- public void processingInstruction(String target, String data) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.processingInstruction(target, data);
- return;
- }
- jaxbHandler.processingInstruction(target, data);
- }
-
- public void setDocumentLocator(Locator locator) {
- if (isSpecialContent) {
- specialContentHandler.setDocumentLocator(locator);
- return;
- }
- jaxbHandler.setDocumentLocator(locator);
- }
-
- public void skippedEntity(String name) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.skippedEntity(name);
- return;
- }
- jaxbHandler.skippedEntity(name);
- }
-
- public void startDocument() throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.startDocument();
- return;
- }
- jaxbHandler.startDocument();
- }
-
- public void endDocument() throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.endDocument();
- return;
- }
- jaxbHandler.endDocument();
- }
-
- public void startPrefixMapping(String prefix, String uri) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.startPrefixMapping(prefix, uri);
- return;
- }
- jaxbHandler.startPrefixMapping(prefix, uri);
- }
-
- public void endPrefixMapping(String prefix) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.endPrefixMapping(prefix);
- return;
- }
- jaxbHandler.endPrefixMapping(prefix);
- }
-
- // ======= LexicalHandler methods ============
-
- public void startCDATA() throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.startCDATA();
- }
- }
-
- public void endCDATA() throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.endCDATA();
- }
- }
-
- public void comment(char[] ch, int start, int length) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.comment(ch, start, length);
- }
- }
-
- public void startDTD(String name, String publicId, String systemId) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.startDTD(name, publicId, systemId);
- }
- }
-
- public void endDTD() throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.endDTD();
- }
- }
-
- public void startEntity(String name) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.startEntity(name);
- }
- }
-
- public void endEntity(String name) throws SAXException {
- if (isSpecialContent) {
- specialContentHandler.endEntity(name);
- }
- }
- }
-
- private static class SpecialContentHandler extends SAXHandlerWrapper {
- // the JAXB object whose value may be text or xml
- private Object target;
-
- private CharArrayWriter writer;
- private int elementCounter;
- private boolean isXhtml;
- private boolean isXmlOpen;
-
- public SpecialContentHandler(Object target) {
- super(initXmlSerializer());
- this.target = target;
- writer = new CharArrayWriter();
- ((XMLSerializer)getHandler()).setOutputCharStream(writer);
- elementCounter = 0;
- isXhtml = false;
- isXmlOpen = false;
- }
-
- private static ContentHandler initXmlSerializer() {
- OutputFormat outputFormat = new OutputFormat();
- outputFormat.setMethod(Method.XML);
- outputFormat.setEncoding(encodingInfo);
- outputFormat.setOmitXMLDeclaration(true);
- XMLSerializer xmlSerializer = new XMLSerializer(outputFormat);
- return xmlSerializer;
- }
-
- public String getResult() {
- String result = writer.toString();
- if (result.length() == 0) {
- return null;
- }
- if (isXmlOpen) {
- result = result.trim();
- if (!result.startsWith("<") && !isXhtml) {
- throw new RuntimeException(
- "Illegal atom content: must contain a single child element");
- }
- }
- return result;
- }
-
- public boolean isDone() {
- return elementCounter == 0;
- }
-
- private boolean isFirstElement() {
- return elementCounter == 1;
- }
-
- private boolean isLastElement() {
- return elementCounter == 0;
- }
-
- private boolean isRootElement() {
- return elementCounter == 0;
- }
-
- @Override
- public void startElement(String uri, String localName, String name, Attributes atts)
- throws SAXException {
- if (isRootElement()) {
- openXml();
- }
-
- ++elementCounter;
- // if we need to skip processing of the first <div> element
- if (isFirstElement() && isXhtml) {
- // if we are unmarshalling xhtml, we need to skip processing
- // of the first <div>
- // element
- if (uri.equals(RestConstants.NAMESPACE_XHTML) && localName
- .equalsIgnoreCase("div")) {
- // if this is the first div element, then we must ignore
- // it
- return;
- } else {
- throw new RuntimeException(
- "Illegal content: xhtml content must have a div root element");
- }
- }
-
- // delegate the event to the xml serializer
- super.startElement(uri, localName, name, atts);
- }
-
- private void openXml() {
- if (isXmlOpen) {
- throw new RuntimeException(
- "Illegal atom content: must have only one root element");
- }
-
- // get the type of contents of the JAXB object
- String type = null;
- if (target instanceof AtomContent) {
- type = ((AtomContent)target).getType();
- } else if (target instanceof AtomText) {
- type = ((AtomText)target).getType().name();
- }
-
- if (AtomTextType.xhtml.name().equals(type)) {
- isXhtml = true;
- }
-
- if (!isXhtml && !isTypeXml(type)) {
- throw new RuntimeException(
- "Illegal atom content: must not contain child elements");
- }
- isXmlOpen = true;
- }
-
- @Override
- public void endElement(String uri, String localName, String name) throws SAXException {
- --elementCounter;
- // if we need to skip processing of the first <div> element
- if (isLastElement() && isXhtml) {
- if (uri.equals(RestConstants.NAMESPACE_XHTML) && localName
- .equalsIgnoreCase("div")) {
- return;
- }
- }
- // delegate the event to the xml serializer
- super.endElement(uri, localName, name);
- }
-
- @Override
- public void characters(char[] ch, int start, int length) throws SAXException {
- if (isXmlOpen) {
- super.characters(ch, start, length);
- } else {
- writer.write(ch, start, length);
- }
- }
+ throw new WebApplicationException(e);
}
}
- // /**
- // * Remove xml declaration from XML.
- // *
- // * @param xmlStr
- // * The XML
- // * @return String The XML without xml declaration
- // */
- // public static String stripXmlDecl(String xmlStr) {
- //
- // if (xmlStr == null) {
- // return null;
- // }
- //
- // int startInd;
- // int endInd;
- // StringBuilder xmlStrBuilder = new StringBuilder(xmlStr);
- //
- // while ((startInd = xmlStrBuilder.indexOf("<?")) >= 0) {
- // endInd = xmlStrBuilder.indexOf("?>") + 2;
- // xmlStrBuilder.replace(startInd, endInd, "");
- // }
- // return xmlStrBuilder.toString();
- // }
- //
public static XMLGregorianCalendar timeToXmlGregorianCalendar(long time) {
if (time == -1) {
return null;
@@ -854,4 +188,139 @@
long time = calendar.getTimeInMillis();
return time;
}
+
+ @SuppressWarnings("unchecked")
+ public static <T> T readValue(List<Object> list,
+ Class<T> type,
+ Providers providers,
+ Type genericType,
+ Annotation[] annotations,
+ MultivaluedMap<String, String> httpHeaders,
+ MediaType mediaType) throws IOException {
+ if (list == null || list.isEmpty()) {
+ return null;
+ }
+
+ Object value = list.get(0);
+
+ if (value == null) {
+ return null;
+ }
+
+ Class<? extends Object> cls = value.getClass();
+ if (type.isAssignableFrom(cls)) {
+ return (T)value;
+ }
+
+ if (value instanceof JAXBElement<?>) {
+ value = ((JAXBElement<?>)value).getValue();
+ return readValue(Arrays.asList(value),
+ type,
+ providers,
+ genericType,
+ annotations,
+ httpHeaders,
+ mediaType);
+ }
+
+ if (cls == AtomXhtml.class) {
+ return readValue(((AtomXhtml)value).getAny(),
+ type,
+ providers,
+ genericType,
+ annotations,
+ httpHeaders,
+ mediaType);
+ }
+
+ if (cls == XmlWrapper.class) {
+ value = ((XmlWrapper)value).getValue();
+ return readValue(Arrays.asList(value),
+ type,
+ providers,
+ genericType,
+ annotations,
+ httpHeaders,
+ mediaType);
+ }
+
+ if (value instanceof byte[]) {
+ if (providers == null) {
+ // try to get Providers from the TLS
+ RuntimeContext runtimeContext = RuntimeContextTLS.getRuntimeContext();
+ if (runtimeContext != null) {
+ providers = runtimeContext.getProviders();
+ }
+ }
+ MessageBodyReader<T> reader =
+ providers.getMessageBodyReader(type, type, EMPTY_ARRAY, mediaType);
+ if (reader == null)
+ throw new WebApplicationException(Response.Status.UNSUPPORTED_MEDIA_TYPE);
+ T read =
+ reader.readFrom(type,
+ type,
+ annotations,
+ mediaType,
+ httpHeaders,
+ new ByteArrayInputStream((byte[])value));
+ return read;
+ }
+ throw new ClassCastException("Cannot cast " + value.getClass().getName()
+ + " to "
+ + type.getName());
+
+ }
+
+ public static MediaType determineMediaType(String type) {
+ MediaType mediaType;
+ if (type == null || type.equals("text") || type.equals("html")) {
+ mediaType = MediaType.TEXT_PLAIN_TYPE;
+ } else if (type.equals("xhtml")) {
+ mediaType = MediaType.APPLICATION_XML_TYPE;
+ } else {
+ mediaType = MediaType.valueOf(type);
+ }
+ return mediaType;
+ }
+
+ /**
+ * Fixes content of any list.
+ * <p>
+ * This method provides the solution of wrapping the necessary elements with
+ * XmlWrapper in order to invoke AnyContentHandler later.
+ *
+ * @param any
+ * @param type
+ */
+ public static void fixAnyContent(List<Object> any, String type) {
+ if (any == null || any.isEmpty()) {
+ // nothing to handle for null or empty objects
+ return;
+ }
+
+ // retrieve the value to handle
+ Object value = any.get(0);
+
+ if (type == null) {
+ // if type not set, use AtomTextType.text
+ type = AtomTextType.text.name();
+ }
+
+ if (value instanceof XmlWrapper) {
+ XmlWrapper xmlWrapper = (XmlWrapper)value;
+ if (xmlWrapper.getType() == null) {
+ // fixes type on the XmlWrapper in the case it was not set, it
+ // happens if the same object was unmarsheled, and now is going
+ // to be marsheled back to xml
+ xmlWrapper.setType(type);
+ }
+ } else if (value.getClass() == String.class && !isTypeXml(type)) {
+ // Non xml strings should be escaped
+ // nothing to do
+ } else {
+ // wrapping with XmlWrapper will cause the Providers code to run
+ // xml content won't be escaped
+ any.set(0, new XmlWrapper(value, type));
+ }
+ }
}
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomText.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomText.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomText.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomText.java Tue Sep 8 13:09:56 2009
@@ -26,9 +26,16 @@
package org.apache.wink.common.model.atom;
-import java.util.ArrayList;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
import java.util.List;
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Providers;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAnyElement;
@@ -123,15 +130,26 @@
@XmlType(name = "atomText", propOrder = {"any"})
public class AtomText extends AtomCommonAttributes {
- @XmlMixed
- @XmlAnyElement(lax = true)
- protected List<Object> any;
+ @XmlTransient
+ private List<Object> any;
+
@XmlAttribute
protected AtomTextType type;
@XmlTransient
private String savedValue = null;
+ @XmlMixed
+ @XmlAnyElement(lax = true, value = AnyContentHandler.class)
+ List<Object> getAny() {
+ AtomJAXBUtils.fixAnyContent(any, type == null ? null : type.name());
+ return any;
+ }
+
+ void setAny(List<Object> any) {
+ this.any = any;
+ }
+
/**
* Create an empty AtomText with no type and no value
*/
@@ -166,7 +184,7 @@
if (value.getType() != null) {
setType(AtomTextType.valueOf(value.getType().toString()));
}
- setValue(value.getValue());
+ setValue(value.getValue(Object.class));
}
public SyndText toSynd(SyndText value) {
@@ -177,40 +195,77 @@
if (getType() != null) {
value.setType(SyndTextType.valueOf(getType().toString()));
}
- value.setValue(getValue());
+ value.setValue(getValue(Object.class));
return value;
}
- private List<Object> getAny() {
- if (any == null) {
- any = new ArrayList<Object>();
- }
- return this.any;
- }
-
- public void setValue(String value) {
- if (value == null) {
- getAny().clear();
- return;
- }
-
- if (getAny().size() == 0) {
- getAny().add(value);
+ public void setValue(Object value) {
+ if (value != null) {
+ any = Arrays.asList(value);
} else {
- getAny().set(0, value);
+ any = null;
}
}
+ /**
+ * <p>
+ * Gets the content of the "atom:text" element as a String. The "type"
+ * attribute should be used to determine how to treat the content.
+ * <p>
+ * Pay attention that de-serialization occurs each time the method is
+ * called, so multiple calls to this method may effect the application
+ * performance.
+ */
public String getValue() {
- if (getAny().size() == 0) {
- return null;
- }
+ return getValue(String.class);
+ }
- Object o = getAny().get(0);
- if (o instanceof String) {
- return (String)o;
+ /**
+ * <p>
+ * Gets the content of the "atom:text" element serialized to provided class.
+ * The "type" attribute should be used to determine how to treat the
+ * content.
+ * <p>
+ * Pay attention that de-serialization occurs each time the method is
+ * called, so multiple calls to this method may effect the application
+ * performance.
+ */
+ public <T> T getValue(Class<T> cls) {
+ try {
+ return getValue(cls,
+ cls,
+ null,
+ AtomJAXBUtils.EMPTY_ARRAY,
+ AtomJAXBUtils.EMPTY_STRING_MAP,
+ AtomJAXBUtils.determineMediaType(type == null ? null : type.name()));
+ } catch (IOException e) {
+ // should never happen
+ throw new WebApplicationException(e);
}
- return null;
+ }
+
+ /**
+ * <p>
+ * Gets the content of the "atom:text" element serialized to provided class
+ * according to provided parameters.
+ * <p>
+ * Pay attention that de-serialization occurs each time the method is
+ * called, so multiple calls to this method may effect the application
+ * performance.
+ */
+ public <T> T getValue(Class<T> cls,
+ Type genericType,
+ Providers providers,
+ Annotation[] annotations,
+ MultivaluedMap<String, String> httpHeaders,
+ MediaType mediaType) throws IOException {
+ return AtomJAXBUtils.readValue(getAny(),
+ cls,
+ providers,
+ genericType,
+ annotations,
+ httpHeaders,
+ mediaType);
}
/**
Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomXhtml.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomXhtml.java?rev=812495&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomXhtml.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomXhtml.java Tue Sep 8 13:09:56 2009
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.wink.common.model.atom;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.ws.rs.core.MediaType;
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAnyElement;
+import javax.xml.bind.annotation.XmlMixed;
+import javax.xml.bind.annotation.XmlType;
+
+/**
+ * Used to de-serialize XHTML content.
+ */
+@XmlType(name = "div", propOrder = {"any"})
+@XmlAccessorType(XmlAccessType.FIELD)
+/* package */class AtomXhtml {
+
+ @XmlMixed
+ @XmlAnyElement(value = AnyContentHandler.class)
+ private List<Object> any;
+
+ public AtomXhtml() {
+ }
+
+ public void setAny(Object obj) {
+ this.any = Arrays.asList((Object)new XmlWrapper(obj, MediaType.APPLICATION_XML));
+ }
+
+ public List<Object> getAny() {
+ return any;
+ }
+
+}
Propchange: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/AtomXhtml.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/ObjectFactory.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/ObjectFactory.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/ObjectFactory.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/ObjectFactory.java Tue Sep 8 13:09:56 2009
@@ -31,6 +31,8 @@
import javax.xml.bind.annotation.XmlRegistry;
import javax.xml.namespace.QName;
+import org.apache.wink.common.RestConstants;
+
/**
* This object contains factory methods for each Java content interface and Java
* element interface generated in the org.apache.wink.common.model.atom package.
@@ -96,6 +98,10 @@
return new AtomEntry();
}
+ public AtomXhtml createAtomXhtml() {
+ return new AtomXhtml();
+ }
+
/**
* Create an instance of {@link AtomCommonAttributes }
*/
@@ -140,6 +146,12 @@
return new JAXBElement<AtomContent>(_Content_QNAME, AtomContent.class, null, value);
}
+ @XmlElementDecl(namespace = RestConstants.NAMESPACE_XHTML, name = "div")
+ public JAXBElement<AtomXhtml> createAtomXhtml(AtomXhtml value) {
+ return new JAXBElement<AtomXhtml>(new QName(RestConstants.NAMESPACE_XHTML, "div"),
+ AtomXhtml.class, null, value);
+ }
+
/**
* Create an instance of {@link JAXBElement }{@code <}{@link AtomText }{@code
* >}
Added: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/XmlWrapper.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/XmlWrapper.java?rev=812495&view=auto
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/XmlWrapper.java (added)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/atom/XmlWrapper.java Tue Sep 8 13:09:56 2009
@@ -0,0 +1,288 @@
+/*******************************************************************************
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *******************************************************************************/
+package org.apache.wink.common.model.atom;
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.DOMException;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.TypeInfo;
+import org.w3c.dom.UserDataHandler;
+
+/* package */class XmlWrapper implements Element {
+
+ private Object value;
+ private String type;
+
+ public XmlWrapper(Object value, String type) {
+ this.value = value;
+ this.type = type;
+ }
+
+ public void setValue(Object value) {
+ this.value = value;
+ }
+
+ public Object getValue() {
+ return value;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public String getAttribute(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getAttributeNS(String namespaceURI, String localName) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Attr getAttributeNode(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Attr getAttributeNodeNS(String namespaceURI, String localName) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public NodeList getElementsByTagName(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ public NodeList getElementsByTagNameNS(String namespaceURI, String localName)
+ throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public TypeInfo getSchemaTypeInfo() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getTagName() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasAttribute(String name) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasAttributeNS(String namespaceURI, String localName) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeAttribute(String name) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void removeAttributeNS(String namespaceURI, String localName) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Attr removeAttributeNode(Attr oldAttr) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setAttribute(String name, String value) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setAttributeNS(String namespaceURI, String qualifiedName, String value)
+ throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Attr setAttributeNode(Attr newAttr) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Attr setAttributeNodeNS(Attr newAttr) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setIdAttribute(String name, boolean isId) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setIdAttributeNS(String namespaceURI, String localName, boolean isId)
+ throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setIdAttributeNode(Attr idAttr, boolean isId) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node appendChild(Node newChild) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node cloneNode(boolean deep) {
+ throw new UnsupportedOperationException();
+ }
+
+ public short compareDocumentPosition(Node other) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public NamedNodeMap getAttributes() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getBaseURI() {
+ throw new UnsupportedOperationException();
+ }
+
+ public NodeList getChildNodes() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getFeature(String feature, String version) {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node getFirstChild() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node getLastChild() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getLocalName() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getNamespaceURI() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node getNextSibling() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getNodeName() {
+ throw new UnsupportedOperationException();
+ }
+
+ public short getNodeType() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getNodeValue() throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Document getOwnerDocument() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node getParentNode() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getPrefix() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node getPreviousSibling() {
+ throw new UnsupportedOperationException();
+ }
+
+ public String getTextContent() throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object getUserData(String key) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasAttributes() {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean hasChildNodes() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node insertBefore(Node newChild, Node refChild) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isDefaultNamespace(String namespaceURI) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isEqualNode(Node arg) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isSameNode(Node other) {
+ throw new UnsupportedOperationException();
+ }
+
+ public boolean isSupported(String feature, String version) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String lookupNamespaceURI(String prefix) {
+ throw new UnsupportedOperationException();
+ }
+
+ public String lookupPrefix(String namespaceURI) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void normalize() {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node removeChild(Node oldChild) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Node replaceChild(Node newChild, Node oldChild) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setNodeValue(String nodeValue) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setPrefix(String prefix) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void setTextContent(String textContent) throws DOMException {
+ throw new UnsupportedOperationException();
+ }
+
+ public Object setUserData(String key, Object data, UserDataHandler handler) {
+ throw new UnsupportedOperationException();
+ }
+
+}
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndContent.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndContent.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndContent.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndContent.java Tue Sep 8 13:09:56 2009
@@ -22,7 +22,6 @@
public class SyndContent extends SyndSimpleContent {
- private String type;
private String src;
public SyndContent() {
@@ -34,22 +33,11 @@
*
* @param value the value of the text construct
*/
- public SyndContent(String value) {
- this(value, SyndTextType.text.name(), false);
+ public SyndContent(Object value) {
+ this(value, SyndTextType.text.name());
}
/**
- * Creates a new SyndContent with the specified value and type attribute.
- *
- * @param value the value of the text construct
- * @param type the type attribute
- */
- // TODO: Michael: uncomment this constructor
- // public SyndContent(String value, String type) {
- // this(value, type, false);
- // }
-
- /**
* Creates a new SyndContent with the specified value or src, and type
* attribute.
*
@@ -57,17 +45,19 @@
* attribute.
* @param type the type attribute
* @param isSrc true indicates that the value parameter is the value of the
- * src attribute
+ * src attribute.
*/
- public SyndContent(String value, String type, boolean isSrc) {
- super(isSrc ? null : value);
- this.type = type;
- this.src = isSrc ? value : null;
+ public SyndContent(Object value, String type, boolean isSrc) {
+ super(isSrc ? null : value, type);
+ this.src = isSrc ? String.valueOf(value) : null;
+ }
+
+ public SyndContent(Object value, String type) {
+ super(value, type);
}
public SyndContent(SyndContent other) {
super(other);
- this.type = other.type;
this.src = other.src;
}
Modified: incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndSimpleContent.java
URL: http://svn.apache.org/viewvc/incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndSimpleContent.java?rev=812495&r1=812494&r2=812495&view=diff
==============================================================================
--- incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndSimpleContent.java (original)
+++ incubator/wink/trunk/wink-common/src/main/java/org/apache/wink/common/model/synd/SyndSimpleContent.java Tue Sep 8 13:09:56 2009
@@ -20,27 +20,76 @@
package org.apache.wink.common.model.synd;
+import java.io.IOException;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.Arrays;
+
+import javax.ws.rs.WebApplicationException;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.MultivaluedMap;
+import javax.ws.rs.ext.Providers;
+
+import org.apache.wink.common.model.atom.AtomJAXBUtils;
+
public abstract class SyndSimpleContent extends SyndCommonAttributes {
- private String value;
+ private Object value;
+ protected String type;
public SyndSimpleContent() {
}
- public SyndSimpleContent(String value) {
+ public SyndSimpleContent(Object value) {
+ this(value, SyndTextType.text.name());
+ }
+
+ public SyndSimpleContent(Object value, String type) {
this.value = value;
+ this.type = type;
}
public SyndSimpleContent(SyndSimpleContent other) {
super(other);
this.value = other.value;
+ this.type = other.type;
}
public String getValue() {
- return value;
+ return getValue(String.class);
+ }
+
+ public <T> T getValue(Class<T> cls) {
+ try {
+ return getValue(cls,
+ cls,
+ null,
+ AtomJAXBUtils.EMPTY_ARRAY,
+ AtomJAXBUtils.EMPTY_STRING_MAP,
+ AtomJAXBUtils.determineMediaType(type));
+ } catch (IOException e) {
+ // should never happen
+ throw new WebApplicationException(e);
+ }
+ }
+
+ public <T> T getValue(Class<T> cls,
+ Type genericType,
+ Providers providers,
+ Annotation[] annotations,
+ MultivaluedMap<String, String> httpHeaders,
+ MediaType mediaType) throws IOException {
+
+ return AtomJAXBUtils.readValue(Arrays.asList(value),
+ cls,
+ providers,
+ genericType,
+ annotations,
+ httpHeaders,
+ mediaType);
}
- public void setValue(String value) {
+ public void setValue(Object value) {
this.value = value;
}
|