Squash commit of ws-transfer implementation from Erich Duda (dudaerich)
This closes #33


Project: http://git-wip-us.apache.org/repos/asf/cxf/repo
Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/517ef67f
Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/517ef67f
Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/517ef67f

Branch: refs/heads/master-jaxrs-2.1
Commit: 517ef67f1a69d386de44153e5e09d51cb47bf4d7
Parents: e158c96
Author: Daniel Kulp <dk...@apache.org>
Authored: Tue May 24 09:26:41 2016 -0400
Committer: Daniel Kulp <dk...@apache.org>
Committed: Tue May 24 09:26:41 2016 -0400

----------------------------------------------------------------------
 rt/ws/pom.xml                                   |   1 +
 rt/ws/transfer/pom.xml                          |  91 +++
 .../apache/cxf/ws/transfer/dialect/Dialect.java |  64 ++
 .../dialect/fragment/FragmentDialect.java       | 622 +++++++++++++++++++
 .../fragment/FragmentDialectConstants.java      |  51 ++
 .../dialect/fragment/faults/FragmentFault.java  |  44 ++
 .../fragment/faults/InvalidExpression.java      |  42 ++
 .../fragment/faults/UnsupportedLanguage.java    |  41 ++
 .../fragment/faults/UnsupportedMode.java        |  42 ++
 .../language/FragmentDialectLanguage.java       |  37 ++
 .../language/FragmentDialectLanguageQName.java  | 134 ++++
 .../FragmentDialectLanguageXPath10.java         | 160 +++++
 .../transfer/manager/MemoryResourceManager.java | 160 +++++
 .../ws/transfer/manager/ResourceManager.java    |  59 ++
 .../cxf/ws/transfer/resource/Resource.java      | 101 +++
 .../cxf/ws/transfer/resource/ResourceLocal.java | 191 ++++++
 .../ws/transfer/resource/ResourceRemote.java    |  49 ++
 .../resourcefactory/ResourceFactory.java        |  61 ++
 .../resourcefactory/ResourceFactoryImpl.java    | 153 +++++
 .../resolver/ResourceReference.java             |  61 ++
 .../resolver/ResourceResolver.java              |  39 ++
 .../resolver/SimpleResourceResolver.java        |  69 ++
 .../ws/transfer/shared/TransferConstants.java   |  60 ++
 .../shared/faults/InvalidRepresentation.java    |  41 ++
 .../ws/transfer/shared/faults/PutDenied.java    |  44 ++
 .../transfer/shared/faults/UnknownDialect.java  |  43 ++
 .../transfer/shared/faults/UnknownResource.java |  42 ++
 .../transfer/shared/faults/WSTransferFault.java |  45 ++
 .../ResourceTransformer.java                    |  30 +
 .../ResourceTypeIdentifier.java                 |  36 ++
 .../ResourceTypeIdentifierResult.java           |  56 ++
 .../ResourceValidator.java                      |  31 +
 .../ValidAndTransformHelper.java                |  63 ++
 .../XSDResourceTypeIdentifier.java              |  87 +++
 .../XSDResourceValidator.java                   |  88 +++
 .../XSLTResourceTransformer.java                |  87 +++
 .../reference-parameter-parsing.xml             |  27 +
 .../main/resources/schemas/catalog-fragment.cat |  21 +
 .../src/main/resources/schemas/catalog.cat      |  23 +
 .../src/main/resources/schemas/fragment.xsd     |  87 +++
 .../src/main/resources/schemas/transfer.xjb     |  37 ++
 .../src/main/resources/schemas/transfer.xsd     | 192 ++++++
 .../src/main/resources/schemas/ws-addr.xsd      | 141 +++++
 .../integration/FragmentGetQNameTest.java       | 171 +++++
 .../integration/FragmentGetXPath10Test.java     | 333 ++++++++++
 .../integration/FragmentPutAddTest.java         | 238 +++++++
 .../integration/FragmentPutInsertAfterTest.java | 194 ++++++
 .../FragmentPutInsertBeforeTest.java            | 194 ++++++
 .../integration/FragmentPutRemoveTest.java      | 113 ++++
 .../integration/FragmentPutReplaceTest.java     | 419 +++++++++++++
 .../integration/IntegrationBaseTest.java        | 196 ++++++
 .../integration/ResourceFactoryTest.java        | 135 ++++
 .../ws/transfer/integration/ResourceTest.java   | 168 +++++
 .../unit/MemoryResourceManagerTest.java         | 204 ++++++
 .../transfer/unit/XSDResourceValidatorTest.java |  60 ++
 .../unit/XSLTResourceTransformerTest.java       |  60 ++
 .../invalidRepresentation.xml                   |  26 +
 .../xml/xsdresourcevalidator/schema.xsd         |  35 ++
 .../validRepresentation.xml                     |  27 +
 .../xsltresourcetransformer/representation.xml  |  26 +
 .../xml/xsltresourcetransformer/stylesheet.xsl  |  43 ++
 systests/pom.xml                                |   3 +-
 systests/ws-transfer/pom.xml                    |  61 ++
 .../systest/ws/transfer/CreateStudentTest.java  | 103 +++
 .../systest/ws/transfer/CreateTeacherTest.java  |  91 +++
 .../cxf/systest/ws/transfer/DeleteTest.java     | 118 ++++
 .../apache/cxf/systest/ws/transfer/GetTest.java | 111 ++++
 .../apache/cxf/systest/ws/transfer/PutTest.java | 129 ++++
 .../cxf/systest/ws/transfer/TestUtils.java      | 174 ++++++
 .../cxf/systest/ws/transfer/UIDManager.java     |  40 ++
 .../transfer/resolver/MyResourceResolver.java   |  55 ++
 .../validator/StudentPutResourceValidator.java  |  47 ++
 .../validator/TeacherResourceValidator.java     |  51 ++
 .../src/test/resources/schema/studentCreate.xsd |  46 ++
 .../src/test/resources/schema/studentPut.xsd    |  47 ++
 .../src/test/resources/schema/teacher.xsd       |  47 ++
 .../resources/schema/teacherCreateBasic.xsd     |  35 ++
 .../src/test/resources/xml/createStudent.xml    |  31 +
 .../test/resources/xml/createStudentPartial.xml |  29 +
 .../test/resources/xml/createStudentWrong.xml   |  32 +
 .../src/test/resources/xml/createTeacher.xml    |  31 +
 .../test/resources/xml/createTeacherPartial.xml |  25 +
 .../test/resources/xml/createTeacherWrong.xml   |  32 +
 .../src/test/resources/xml/putStudent.xml       |  32 +
 .../src/test/resources/xml/putTeacher.xml       |  32 +
 .../src/test/resources/xml/random.xml           |  24 +
 .../src/test/resources/xslt/studentCreate.xsl   | 110 ++++
 .../src/test/resources/xslt/studentPut.xsl      | 108 ++++
 .../test/resources/xslt/teacherCreateBasic.xsl  |  45 ++
 .../resources/xslt/teacherDefaultValues.xsl     | 108 ++++
 90 files changed, 7991 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/pom.xml
----------------------------------------------------------------------
diff --git a/rt/ws/pom.xml b/rt/ws/pom.xml
index 0bea25c..70e1c97 100644
--- a/rt/ws/pom.xml
+++ b/rt/ws/pom.xml
@@ -36,5 +36,6 @@
         <module>rm</module>
         <module>mex</module>
         <module>eventing</module>
+        <module>transfer</module>
     </modules>
 </project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/pom.xml
----------------------------------------------------------------------
diff --git a/rt/ws/transfer/pom.xml b/rt/ws/transfer/pom.xml
new file mode 100644
index 0000000..d2c1a09
--- /dev/null
+++ b/rt/ws/transfer/pom.xml
@@ -0,0 +1,91 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd";>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>cxf-rt-ws-transfer</artifactId>
+  <packaging>jar</packaging>
+  <name>Apache CXF Runtime WS Transfer</name>
+  <url>http://cxf.apache.org</url>
+  
+  <parent>
+      <groupId>org.apache.cxf</groupId>
+      <artifactId>cxf-parent</artifactId>
+      <version>3.2.0-SNAPSHOT</version>
+      <relativePath>../../../parent/pom.xml</relativePath>
+  </parent>
+
+  <properties>
+    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+  </properties>
+
+  <dependencies>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>cxf-rt-frontend-jaxws</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>${project.groupId}</groupId>
+      <artifactId>cxf-rt-transports-local</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.easymock</groupId>
+      <artifactId>easymock</artifactId>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  
+  <build>
+      <plugins>
+          <plugin>
+              <groupId>org.apache.cxf</groupId>
+              <artifactId>cxf-xjc-plugin</artifactId>
+              <version>${cxf.xjc-utils.version}</version>
+              <executions>
+                  <execution>
+                      <id>generate-transfer</id>
+                      <phase>generate-sources</phase>
+                      <goals>
+                          <goal>xsdtojava</goal>
+                      </goals>
+                      <configuration>
+                          
<sourceRoot>${basedir}/target/generated-sources/xjc</sourceRoot>
+                          <xsdOptions>
+                              <xsdOption>
+                                  
<xsd>${basedir}/src/main/resources/schemas/transfer.xsd</xsd>
+                                  
<packagename>org.apache.cxf.ws.transfer</packagename>
+                                  
<bindingFile>${basedir}/src/main/resources/schemas/transfer.xjb</bindingFile>
+                                  
<catalog>${basedir}/src/main/resources/schemas/catalog.cat</catalog>
+                              </xsdOption>
+                          </xsdOptions>
+                      </configuration>
+                  </execution>
+                  <execution>
+                      <id>generate-fragment</id>
+                      <phase>generate-sources</phase>
+                      <goals>
+                          <goal>xsdtojava</goal>
+                      </goals>
+                      <configuration>
+                          
<sourceRoot>${basedir}/target/generated-sources/xjc</sourceRoot>
+                          <xsdOptions>
+                              <xsdOption>
+                                  
<xsd>${basedir}/src/main/resources/schemas/fragment.xsd</xsd>
+                                  
<packagename>org.apache.cxf.ws.transfer.dialect.fragment</packagename>
+                                  
<catalog>${basedir}/src/main/resources/schemas/catalog-fragment.cat</catalog>
+                              </xsdOption>
+                          </xsdOptions>
+                      </configuration>
+                  </execution>
+              </executions>
+          </plugin>
+      </plugins>
+  </build>
+</project>

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/Dialect.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/Dialect.java 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/Dialect.java
new file mode 100644
index 0000000..6ea5208
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/Dialect.java
@@ -0,0 +1,64 @@
+/**
+ * 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.cxf.ws.transfer.dialect;
+
+import org.apache.cxf.ws.transfer.Create;
+import org.apache.cxf.ws.transfer.Delete;
+import org.apache.cxf.ws.transfer.Get;
+import org.apache.cxf.ws.transfer.Put;
+import org.apache.cxf.ws.transfer.Representation;
+
+/**
+ * The interface for a Dialect objects.
+ */
+public interface Dialect {
+    
+    /**
+     * Method for processing incoming Get message by Dialect extension.
+     * @param body Get body
+     * @param representation XML representation stored in the ResourceManager
+     * @return Representation, which will be returned in response.
+     */
+    Object processGet(Get body, Representation representation);
+    
+    /**
+     * Method for processing incoming Put message by Dialect extension.
+     * @param body Put body
+     * @param representation XML representation stored in the ResourceManager
+     * @return Representation, which will be stored in ResourceManager.
+     */
+    Representation processPut(Put body, Representation representation);
+    
+    /**
+     * Method for processing incoming Delete message by Dialect extension.
+     * @param body Delete body
+     * @param representation XML representation stored in the ResourceManager
+     * @return Representation, which will be stored in ResourceManager.
+     */
+    boolean processDelete(Delete body, Representation representation);
+    
+    /**
+     * Method for processing incoming Create message by Dialect extension.
+     * @param body Create body
+     * @return Representation, which will be stored in ResourceManager.
+     */
+    Representation processCreate(Create body);
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialect.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialect.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialect.java
new file mode 100644
index 0000000..8498ff8
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialect.java
@@ -0,0 +1,622 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.annotation.Resource;
+import javax.xml.bind.JAXBElement;
+import javax.xml.ws.WebServiceContext;
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.binding.soap.SoapVersion;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.ws.transfer.Create;
+import org.apache.cxf.ws.transfer.Delete;
+import org.apache.cxf.ws.transfer.Get;
+import org.apache.cxf.ws.transfer.Put;
+import org.apache.cxf.ws.transfer.Representation;
+import org.apache.cxf.ws.transfer.dialect.Dialect;
+import org.apache.cxf.ws.transfer.dialect.fragment.faults.InvalidExpression;
+import org.apache.cxf.ws.transfer.dialect.fragment.faults.UnsupportedLanguage;
+import org.apache.cxf.ws.transfer.dialect.fragment.faults.UnsupportedMode;
+import 
org.apache.cxf.ws.transfer.dialect.fragment.language.FragmentDialectLanguage;
+import 
org.apache.cxf.ws.transfer.dialect.fragment.language.FragmentDialectLanguageQName;
+import 
org.apache.cxf.ws.transfer.dialect.fragment.language.FragmentDialectLanguageXPath10;
+import org.apache.cxf.ws.transfer.shared.faults.InvalidRepresentation;
+import org.apache.cxf.ws.transfer.shared.faults.UnknownDialect;
+
+/**
+ * Implementation of the WS-Fragment dialect.
+ */
+public class FragmentDialect implements Dialect {
+
+    @Resource
+    WebServiceContext context;
+
+    private final Map<String, FragmentDialectLanguage> languages;
+
+    private Pattern badXPathPattern;
+
+    private Pattern goodXPathPattern;
+
+    public FragmentDialect() {
+        languages = new HashMap<String, FragmentDialectLanguage>();
+        languages.put(FragmentDialectConstants.QNAME_LANGUAGE_IRI, new 
FragmentDialectLanguageQName());
+        languages.put(FragmentDialectConstants.XPATH10_LANGUAGE_IRI, new 
FragmentDialectLanguageXPath10());
+        if (badXPathPattern == null) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("//@?");
+            sb.append(FragmentDialectLanguageQName.getQNamePatternString());
+            sb.append("$");
+            badXPathPattern = Pattern.compile(sb.toString());
+        }
+        if (goodXPathPattern == null) {
+            StringBuilder sb = new StringBuilder();
+            sb.append("/@?");
+            sb.append(FragmentDialectLanguageQName.getQNamePatternString());
+            sb.append("$");
+            goodXPathPattern = Pattern.compile(sb.toString());
+        }
+    }
+
+    @Override
+    public JAXBElement<ValueType> processGet(Get body, Representation 
representation) {
+        for (Object o : body.getAny()) {
+            if (o instanceof JAXBElement<?> && 
((JAXBElement<?>)o).getDeclaredType() == ExpressionType.class) {
+                ExpressionType expression = (ExpressionType) 
((JAXBElement<?>)o).getValue();
+                String languageIRI = expression.getLanguage();
+                languageIRI = languageIRI == null ? 
FragmentDialectConstants.XPATH10_LANGUAGE_IRI : languageIRI;
+                if (languages.containsKey(languageIRI)) {
+                    FragmentDialectLanguage language = 
languages.get(languageIRI);
+                    return 
generateGetResponse(language.getResourceFragment(representation, expression));
+                } else {
+                    throw new UnsupportedLanguage();
+                }
+            }
+        }
+        throw new SoapFault("wsf:Expression is not present.", 
getSoapVersion().getSender());
+    }
+
+    @Override
+    public Representation processPut(Put body, Representation representation) {
+        for (Object o : body.getAny()) {
+            if (o instanceof Fragment) {
+                Fragment fragment = (Fragment) o;
+                ExpressionType expression = fragment.getExpression();
+                ValueType value = fragment.getValue();
+
+                if (expression == null) {
+                    throw new SoapFault("wsf:Expression is not present.", 
getSoapVersion().getSender());
+                }
+                if (value == null) {
+                    value = new ValueType();
+                }
+                String languageIRI = expression.getLanguage();
+                languageIRI = languageIRI == null ? 
FragmentDialectConstants.XPATH10_LANGUAGE_IRI : languageIRI;
+                if (languages.containsKey(languageIRI)) {
+                    FragmentDialectLanguage language = 
languages.get(languageIRI);
+                    Object resourceFragment = 
language.getResourceFragment(representation, expression);
+                    String mode = expression.getMode();
+                    mode = mode == null ? 
FragmentDialectConstants.FRAGMENT_MODE_REPLACE : mode;
+                    if (resourceFragment == null && 
FragmentDialectConstants.FRAGMENT_MODE_REPLACE.equals(mode)
+                            && 
FragmentDialectConstants.XPATH10_LANGUAGE_IRI.equals(languageIRI)) {
+                        resourceFragment = 
language.getResourceFragment(representation, getParentXPath(expression));
+                        mode = FragmentDialectConstants.FRAGMENT_MODE_ADD;
+                    }
+                    return modifyRepresentation(resourceFragment, mode, value);
+                } else {
+                    throw new UnsupportedLanguage();
+                }
+            }
+        }
+        throw new SoapFault("wsf:Fragment is not present.", 
getSoapVersion().getSender());
+    }
+
+    @Override
+    public boolean processDelete(Delete body, Representation representation) {
+        throw new UnknownDialect();
+    }
+
+    @Override
+    public Representation processCreate(Create body) {
+        throw new UnknownDialect();
+    }
+
+    /**
+     * Register FragmentDialectLanguage object for IRI.
+     * @param iri
+     * @param language
+     */
+    public void registerLanguage(String iri, FragmentDialectLanguage language) 
{
+        if (languages.containsKey(iri)) {
+            throw new IllegalArgumentException(String.format("IRI \"%s\" is 
already registered", iri));
+        }
+        languages.put(iri, language);
+    }
+
+    /**
+     * Unregister FragmentDialectLanguage object for IRI.
+     * @param iri
+     */
+    public void unregisterLanguage(String iri) {
+        if (!languages.containsKey(iri)) {
+            throw new IllegalArgumentException(String.format("IRI \"%s\" is 
not registered", iri));
+        }
+        languages.remove(iri);
+    }
+
+    /**
+     * Generates Value element, which is returned as response to Get request.
+     * @param value Result of the XPath evaluation.
+     * @return
+     */
+    private JAXBElement<ValueType> generateGetResponse(Object value) {
+        if (value instanceof Node) {
+            return generateGetResponseNode((Node) value);
+        } else if (value instanceof NodeList) {
+            return generateGetResponseNodeList((NodeList) value);
+        } else if (value instanceof String) {
+            return generateGetResponseString((String) value);
+        }
+        ObjectFactory objectFactory = new ObjectFactory();
+        return objectFactory.createValue(new ValueType());
+    }
+
+    /**
+     * Generates Value element from NodeList.
+     * @param nodeList
+     * @return
+     */
+    private JAXBElement<ValueType> generateGetResponseNodeList(NodeList 
nodeList) {
+        ValueType resultValue = new ValueType();
+        for (int i = 0; i < nodeList.getLength(); i++) {
+            resultValue.getContent().add(nodeList.item(i));
+        }
+        ObjectFactory objectFactory = new ObjectFactory();
+        return objectFactory.createValue(resultValue);
+    }
+
+    /**
+     * Generates Value element from Node.
+     * @param node
+     * @return
+     */
+    private JAXBElement<ValueType> generateGetResponseNode(Node node) {
+        Document doc = DOMUtils.createDocument();
+        ValueType resultValue = new ValueType();
+        if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+            Element attrNodeEl = doc.createElementNS(
+                    FragmentDialectConstants.FRAGMENT_2011_03_IRI,
+                    FragmentDialectConstants.FRAGMENT_ATTR_NODE_NAME);
+            attrNodeEl.setAttribute(
+                    FragmentDialectConstants.FRAGMENT_ATTR_NODE_NAME_ATTR,
+                    node.getNodeName()
+            );
+            attrNodeEl.setTextContent(node.getNodeValue());
+            resultValue.getContent().add(attrNodeEl);
+        } else if (node.getNodeType() == Node.TEXT_NODE) {
+            Element textNodeEl = doc.createElementNS(
+                    FragmentDialectConstants.FRAGMENT_2011_03_IRI,
+                    FragmentDialectConstants.FRAGMENT_TEXT_NODE_NAME);
+            textNodeEl.setNodeValue(node.getNodeValue());
+            resultValue.getContent().add(textNodeEl);
+        } else if (node.getNodeType() == Node.ELEMENT_NODE) {
+            resultValue.getContent().add(node);
+        }
+        ObjectFactory objectFactory = new ObjectFactory();
+        return objectFactory.createValue(resultValue);
+    }
+
+    /**
+     * Generates Value element from String.
+     * @param value
+     * @return
+     */
+    private JAXBElement<ValueType> generateGetResponseString(String value) {
+        ValueType resultValue = new ValueType();
+        resultValue.getContent().add(value);
+        ObjectFactory objectFactory = new ObjectFactory();
+        return objectFactory.createValue(resultValue);
+    }
+
+    /**
+     * Returns expression containing XPath, which refers to parent element.
+     * @param expression
+     * @return
+     */
+    private ExpressionType getParentXPath(ExpressionType expression) {
+        String expr;
+        if (expression.getContent().size() == 1) {
+            expr = (String) expression.getContent().get(0);
+        } else {
+            throw new InvalidExpression();
+        }
+        if (badXPathPattern.matcher(expr).find()) {
+            throw new InvalidExpression();
+        }
+        if (goodXPathPattern.matcher(expr).find()) {
+            expression.getContent().clear();
+            expr = expr.replaceFirst(goodXPathPattern.pattern(), "");
+            if (expr.isEmpty()) {
+                expr = "/";
+            }
+            expression.getContent().add(expr);
+            return expression;
+        } else {
+            throw new InvalidExpression();
+        }
+    }
+
+    /**
+     * Process Put requests.
+     * @param resourceFragment Result of the XPath evaluation. It can be Node 
or NodeList.
+     * @param mode Mode defined in the Mode attribute.
+     * @param value Value defined in the Value element.
+     * @return Representation element, which is returned as response.
+     */
+    private Representation modifyRepresentation(
+            Object resourceFragment,
+            String mode,
+            ValueType value) {
+        if (resourceFragment instanceof Node) {
+            List<Node> nodeList = new ArrayList<Node>();
+            nodeList.add((Node) resourceFragment);
+            return modifyRepresentationMode(nodeList, mode, value);
+        } else if (resourceFragment instanceof NodeList) {
+            NodeList rfNodeList = (NodeList) resourceFragment;
+            List<Node> nodeList = new ArrayList<Node>();
+            for (int i = 0; i < rfNodeList.getLength(); i++) {
+                nodeList.add(rfNodeList.item(i));
+            }
+            return modifyRepresentationMode(nodeList, mode, value);
+        } else {
+            throw new InvalidExpression();
+        }
+    }
+
+    /**
+     * Process Put requests.
+     * @param mode Mode defined in the Mode attribute.
+     * @param value Value defined in the Value element.
+     * @return Representation element, which is returned as response.
+     */
+    private Representation modifyRepresentationMode(
+            List<Node> nodeList,
+            String mode,
+            ValueType value) {
+        switch (mode) {
+        case FragmentDialectConstants.FRAGMENT_MODE_REPLACE:
+            return modifyRepresentationModeReplace(nodeList, value);
+        case FragmentDialectConstants.FRAGMENT_MODE_ADD:
+            return modifyRepresentationModeAdd(nodeList, value);
+        case FragmentDialectConstants.FRAGMENT_MODE_INSERT_BEFORE:
+            return modifyRepresentationModeInsertBefore(nodeList, value);
+        case FragmentDialectConstants.FRAGMENT_MODE_INSERT_AFTER:
+            return modifyRepresentationModeInsertAfter(nodeList, value);
+        case FragmentDialectConstants.FRAGMENT_MODE_REMOVE:
+            return modifyRepresentationModeRemove(nodeList, value);
+        default:
+            throw new UnsupportedMode();
+        }
+    }
+
+    /**
+     * Process Put requests for Replace mode.
+     * @param value Value defined in the Value element.
+     * @return Representation element, which is returned as response.
+     */
+    private Representation modifyRepresentationModeReplace(
+            List<Node> nodeList,
+            ValueType value) {
+
+        if (nodeList.isEmpty()) {
+            throw new InvalidExpression();
+        }
+        Node firstNode = nodeList.get(0);
+        Document ownerDocument = firstNode.getOwnerDocument();
+        // if firstNode.getOwnerDocument == null the firstNode is ownerDocument
+        ownerDocument = ownerDocument == null ? (Document) firstNode : 
ownerDocument;
+        Node nextSibling = null;
+        Node parent = null;
+
+        for (Node node : nodeList) {
+            nextSibling = node.getNextSibling();
+            parent = removeNode(node);
+        }
+
+        addNode(ownerDocument, parent, nextSibling, value);
+
+        Representation representation = new Representation();
+        representation.setAny(ownerDocument.getDocumentElement());
+        return representation;
+    }
+
+    /**
+     * Process Put requests for Add mode.
+     * @param value Value defined in the Value element.
+     * @return Representation element, which is returned as response.
+     */
+    private Representation modifyRepresentationModeAdd(
+            List<Node> nodeList,
+            ValueType value) {
+        if (nodeList.isEmpty()) {
+            throw new InvalidExpression();
+        }
+        Node firstNode = nodeList.get(0);
+        Document ownerDocument = firstNode.getOwnerDocument();
+        // if firstNode.getOwnerDocument == null the firstNode is ownerDocument
+        ownerDocument = ownerDocument == null ? (Document) firstNode : 
ownerDocument;
+
+        for (Node node : nodeList) {
+            addNode(ownerDocument, node, null, value);
+        }
+        Representation representation = new Representation();
+        representation.setAny(ownerDocument.getDocumentElement());
+        return representation;
+    }
+
+    /**
+     * Process Put requests for InsertBefore mode.
+     * @param value Value defined in the Value element.
+     * @return Representation element, which is returned as response.
+     */
+    private Representation modifyRepresentationModeInsertBefore(
+            List<Node> nodeList,
+            ValueType value) {
+        if (nodeList.isEmpty()) {
+            throw new InvalidExpression();
+        }
+        Node firstNode = nodeList.get(0);
+        Document ownerDocument = firstNode.getOwnerDocument();
+        // if firstNode.getOwnerDocument == null the firstNode is ownerDocument
+        ownerDocument = ownerDocument == null ? (Document) firstNode : 
ownerDocument;
+
+        Node parent = firstNode.getParentNode();
+        if (parent == null && firstNode.getNodeType() != Node.DOCUMENT_NODE) {
+            throw new InvalidExpression();
+        }
+        if (parent == null) {
+            parent = firstNode;
+            if (((Document) parent).getDocumentElement() != null) {
+                throw new InvalidExpression();
+            }
+        }
+
+        for (Node node : nodeList) {
+            if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+                throw new InvalidRepresentation();
+            }
+            insertBefore(ownerDocument, parent, node, value);
+        }
+
+        Representation representation = new Representation();
+        representation.setAny(ownerDocument.getDocumentElement());
+        return representation;
+    }
+
+    /**
+     * Process Put requests for InsertAfter mode.
+     * @param value Value defined in the Value element.
+     * @return Representation element, which is returned as response.
+     */
+    private Representation modifyRepresentationModeInsertAfter(
+            List<Node> nodeList,
+            ValueType value) {
+        if (nodeList.isEmpty()) {
+            throw new InvalidExpression();
+        }
+        Node firstNode = nodeList.get(0);
+        Document ownerDocument = firstNode.getOwnerDocument();
+        // if firstNode.getOwnerDocument == null the firstNode is ownerDocument
+        ownerDocument = ownerDocument == null ? (Document) firstNode : 
ownerDocument;
+
+        Node parent = firstNode.getParentNode();
+        if (parent == null && firstNode.getNodeType() != Node.DOCUMENT_NODE) {
+            throw new InvalidExpression();
+        }
+        if (parent == null) {
+            parent = firstNode;
+            if (((Document) parent).getDocumentElement() != null) {
+                throw new InvalidExpression();
+            }
+        }
+
+        for (Node node : nodeList) {
+            if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
+                throw new InvalidRepresentation();
+            }
+            insertAfter(ownerDocument, parent, node, value);
+        }
+
+        Representation representation = new Representation();
+        representation.setAny(ownerDocument.getDocumentElement());
+        return representation;
+    }
+
+    /**
+     * Process Put requests for Remove mode.
+     * @param value Value defined in the Value element.
+     * @return Representation element, which is returned as response.
+     */
+    private Representation modifyRepresentationModeRemove(
+            List<Node> nodeList,
+            ValueType value) {
+        if (nodeList.isEmpty()) {
+            throw new InvalidExpression();
+        }
+        Node firstNode = nodeList.get(0);
+        Document ownerDocument = firstNode.getOwnerDocument();
+        // if firstNode.getOwnerDocument == null the firstNode is ownerDocument
+        ownerDocument = ownerDocument == null ? (Document) firstNode : 
ownerDocument;
+
+        for (Node node : nodeList) {
+            removeNode(node);
+        }
+
+        Representation representation = new Representation();
+        representation.setAny(ownerDocument.getDocumentElement());
+        return representation;
+    }
+
+    /**
+     * Helper method. It removes Node and returns its parent.
+     * @param resourceFragment Node to remove.
+     * @return Parent of removed Node.
+     */
+    private Node removeNode(Node resourceFragment) {
+        Node parent = null;
+        if (resourceFragment.getNodeType() == Node.ATTRIBUTE_NODE) {
+            parent = ((Attr)resourceFragment).getOwnerElement();
+        } else {
+            parent = resourceFragment.getParentNode();
+        }
+        if (parent == null) {
+            // resourceFragment is Document Node
+            parent = resourceFragment;
+        }
+        if (resourceFragment.getNodeType() == Node.ATTRIBUTE_NODE) {
+            ((Element)parent).removeAttributeNode((Attr)resourceFragment);
+        } else {
+            if (parent != resourceFragment) {
+                parent.removeChild(resourceFragment);
+            } else {
+                // Both parent and resourceFragment are Document
+                Document doc = (Document) parent;
+                if (doc.getDocumentElement() != null) {
+                    doc.removeChild(doc.getDocumentElement());
+                }
+            }
+        }
+
+        return parent;
+    }
+
+    private void insertAfter(Document ownerDocument, Node parent, Node 
refChild, ValueType value) {
+        for (Object o : value.getContent()) {
+            if (o instanceof Node) {
+                Node node = (Node) o;
+
+                if (
+                        
FragmentDialectConstants.FRAGMENT_2011_03_IRI.equals(node.getNamespaceURI())
+                                && 
FragmentDialectConstants.FRAGMENT_ATTR_NODE_NAME.equals(node.getLocalName())) {
+                    throw new InvalidRepresentation();
+                }
+
+                Node importedNode = ownerDocument.importNode(node, true);
+                if (parent.getNodeType() == Node.DOCUMENT_NODE) {
+                    parent.appendChild(importedNode);
+                } else {
+                    Node nextSibling = refChild.getNextSibling();
+                    if (nextSibling == null) {
+                        parent.appendChild(importedNode);
+                    } else {
+                        parent.insertBefore(importedNode, nextSibling);
+                    }
+                }
+            } else {
+                throw new InvalidExpression();
+            }
+        }
+    }
+
+    private void insertBefore(Document ownerDocument, Node parent, Node 
refChild, ValueType value) {
+        for (Object o : value.getContent()) {
+            if (o instanceof Node) {
+                Node node = (Node) o;
+
+                if (
+                        
FragmentDialectConstants.FRAGMENT_2011_03_IRI.equals(node.getNamespaceURI())
+                                && 
FragmentDialectConstants.FRAGMENT_ATTR_NODE_NAME.equals(node.getLocalName())) {
+                    throw new InvalidRepresentation();
+                }
+
+                Node importedNode = ownerDocument.importNode(node, true);
+                if (parent.getNodeType() == Node.DOCUMENT_NODE) {
+                    parent.appendChild(importedNode);
+                } else {
+                    parent.insertBefore(importedNode, refChild);
+                }
+            } else {
+                throw new InvalidExpression();
+            }
+        }
+    }
+
+    /**
+     * Helper method. It adds new Node as the last child of parent.
+     * @param ownerDocument Document, where the Node is added.
+     * @param parent Parent, where the Node is added.
+     * @param value Value defined in the Value element. It represents newly 
added Node.
+     */
+    private void addNode(Document ownerDocument, Node parent, Node 
nextSibling, ValueType value) {
+        if (ownerDocument == parent && ownerDocument.getDocumentElement() != 
null) {
+            throw new InvalidRepresentation();
+        }
+        for (Object o : value.getContent()) {
+            if (o instanceof String) {
+                parent.setTextContent(parent.getTextContent() + ((String) o));
+            } else if (o instanceof Node) {
+                Node node = (Node) o;
+                if (
+                        
FragmentDialectConstants.FRAGMENT_2011_03_IRI.equals(node.getNamespaceURI())
+                                && 
FragmentDialectConstants.FRAGMENT_ATTR_NODE_NAME.equals(node.getLocalName())) {
+                    String attrName = ((Element)node).getAttributeNS(
+                            FragmentDialectConstants.FRAGMENT_2011_03_IRI,
+                            
FragmentDialectConstants.FRAGMENT_ATTR_NODE_NAME_ATTR);
+                    String attrValue = node.getTextContent();
+                    if (attrName == null) {
+                        throw new SoapFault("wsf:AttributeNode@name is not 
present.", getSoapVersion().getSender());
+                    }
+                    if (((Element) parent).hasAttribute(attrName)) {
+                        throw new InvalidRepresentation();
+                    }
+                    ((Element) parent).setAttribute(attrName, attrValue);
+                } else {
+                    // import the node to the ownerDocument
+                    Node importedNode = ownerDocument.importNode((Node) o, 
true);
+                    if (nextSibling == null) {
+                        parent.appendChild(importedNode);
+                    } else {
+                        parent.insertBefore(importedNode, nextSibling);
+                    }
+                }
+            } else {
+                throw new InvalidExpression();
+            }
+        }
+    }
+
+    private SoapVersion getSoapVersion() {
+        WrappedMessageContext wmc = (WrappedMessageContext) 
context.getMessageContext();
+        SoapMessage message = (SoapMessage) wmc.getWrappedMessage();
+        return message.getVersion();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialectConstants.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialectConstants.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialectConstants.java
new file mode 100644
index 0000000..6ffd009
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/FragmentDialectConstants.java
@@ -0,0 +1,51 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment;
+
+/**
+ * Helper class for holding of constants.
+ */
+public final class FragmentDialectConstants {
+    
+    public static final String FRAGMENT_2011_03_IRI = 
"http://www.w3.org/2011/03/ws-fra";;
+    
+    public static final String QNAME_LANGUAGE_IRI = 
"http://www.w3.org/2011/03/ws-fra/QName";;
+    
+    public static final String XPATH10_LANGUAGE_IRI = 
"http://www.w3.org/2011/03/ws-fra/XPath10";;
+    
+    public static final String FRAGMENT_TEXT_NODE_NAME = "TextNode";
+    
+    public static final String FRAGMENT_ATTR_NODE_NAME = "AttributeNode";
+    
+    public static final String FRAGMENT_ATTR_NODE_NAME_ATTR = "name";
+    
+    public static final String FRAGMENT_MODE_REPLACE = 
"http://www.w3.org/2011/03/ws-fra/Modes/Replace";;
+    
+    public static final String FRAGMENT_MODE_ADD = 
"http://www.w3.org/2011/03/ws-fra/Modes/Add";;
+    
+    public static final String FRAGMENT_MODE_INSERT_BEFORE = 
"http://www.w3.org/2011/03/ws-fra/Modes/InsertBefore";;
+    
+    public static final String FRAGMENT_MODE_INSERT_AFTER = 
"http://www.w3.org/2011/03/ws-fra/Modes/InsertAfter";;
+    
+    public static final String FRAGMENT_MODE_REMOVE = 
"http://www.w3.org/2011/03/ws-fra/Modes/Remove";;
+    
+    private FragmentDialectConstants() {
+        
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/FragmentFault.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/FragmentFault.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/FragmentFault.java
new file mode 100644
index 0000000..3777238
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/FragmentFault.java
@@ -0,0 +1,44 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment.faults;
+
+import javax.xml.namespace.QName;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.helpers.DOMUtils;
+
+/**
+ * The parent for all WS-Fragment-specific faults.
+ */
+public abstract class FragmentFault extends SoapFault {
+
+    private static final long serialVersionUID = 2111286624025926462L;
+
+    public FragmentFault(String reason, String detail, QName faultCode) {
+        super(reason, faultCode);
+        if (detail != null) {
+            Document doc = DOMUtils.createDocument();
+            Element detailEl = doc.createElement("detail");
+            detailEl.setTextContent(detail);
+            setDetail(detailEl);
+        }
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/InvalidExpression.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/InvalidExpression.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/InvalidExpression.java
new file mode 100644
index 0000000..23da1bc
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/InvalidExpression.java
@@ -0,0 +1,42 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment.faults;
+
+import javax.xml.namespace.QName;
+import org.apache.cxf.ws.transfer.dialect.fragment.FragmentDialectConstants;
+
+/**
+ * Definition of the InvalidExpression SOAPFault.
+ */
+public class InvalidExpression extends FragmentFault {
+
+    private static final long serialVersionUID = -1920756304737648952L;
+
+    private static final String SUBCODE = "InvalidExpression";
+
+    private static final String REASON = "The specified Language expression is 
invalid.";
+
+    private static final String DETAIL = "The invalid language expression.";
+
+    public InvalidExpression() {
+        super(REASON, DETAIL,
+                new QName(FragmentDialectConstants.FRAGMENT_2011_03_IRI, 
SUBCODE));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedLanguage.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedLanguage.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedLanguage.java
new file mode 100644
index 0000000..bb13b4c
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedLanguage.java
@@ -0,0 +1,41 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment.faults;
+
+import javax.xml.namespace.QName;
+import org.apache.cxf.ws.transfer.dialect.fragment.FragmentDialectConstants;
+
+/**
+ * Definition of the UnsupportedLanguage SOAPFault.
+ */
+public class UnsupportedLanguage extends FragmentFault {
+
+    private static final long serialVersionUID = 7627652802987243575L;
+
+    private static final String SUBCODE = "UnsupportedLanguage";
+
+    private static final String REASON = "The specified Language IRI is not 
supported.";
+
+    private static final String DETAIL = "The unsupported Language IRI.";
+
+    public UnsupportedLanguage() {
+        super(REASON, DETAIL,
+                new QName(FragmentDialectConstants.FRAGMENT_2011_03_IRI, 
SUBCODE));
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedMode.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedMode.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedMode.java
new file mode 100644
index 0000000..f38b912
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/faults/UnsupportedMode.java
@@ -0,0 +1,42 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment.faults;
+
+import javax.xml.namespace.QName;
+import org.apache.cxf.ws.transfer.dialect.fragment.FragmentDialectConstants;
+
+/**
+ * Definition of the UnsupportedMode SOAPFault.
+ */
+public class UnsupportedMode extends FragmentFault {
+
+    private static final long serialVersionUID = -5824904523582078377L;
+
+    private static final String SUBCODE = "UnsupportedMode";
+
+    private static final String REASON = "The specified mode is not 
supported.";
+
+    private static final String DETAIL = "The unsupported Mode.";
+
+    public UnsupportedMode() {
+        super(REASON, DETAIL,
+                new QName(FragmentDialectConstants.FRAGMENT_2011_03_IRI, 
SUBCODE));
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguage.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguage.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguage.java
new file mode 100644
index 0000000..8ff8018
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguage.java
@@ -0,0 +1,37 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment.language;
+
+import org.apache.cxf.ws.transfer.Representation;
+import org.apache.cxf.ws.transfer.dialect.fragment.ExpressionType;
+
+/**
+ * Interface for FragmentDialect languages.
+ */
+public interface FragmentDialectLanguage {
+    
+    /**
+     * Returns fragment of resource, which is described by expression.
+     * @param representation Resource, from which is fragment computed.
+     * @param expression Expression written in the language.
+     * @return It can return org.w3c.dom.Node | org.w3c.dom.NodeList | String
+     */
+    Object getResourceFragment(Representation representation, ExpressionType 
expression);
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageQName.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageQName.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageQName.java
new file mode 100644
index 0000000..a5d78ad
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageQName.java
@@ -0,0 +1,134 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment.language;
+
+import java.util.Iterator;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import javax.xml.namespace.NamespaceContext;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.apache.cxf.helpers.XPathUtils;
+import org.apache.cxf.ws.transfer.Representation;
+import org.apache.cxf.ws.transfer.dialect.fragment.ExpressionType;
+import org.apache.cxf.ws.transfer.dialect.fragment.faults.InvalidExpression;
+
+/**
+ * Implementation of the QName language.
+ */
+public class FragmentDialectLanguageQName implements FragmentDialectLanguage {
+
+    private static Pattern qNamePattern;
+    
+    public FragmentDialectLanguageQName() {
+        if (qNamePattern == null) {
+            String qName = getQNamePatternString();
+            qNamePattern = Pattern.compile("^" + qName);
+        }
+    }
+
+    /**
+     * Returns regex string, which describes QName format.
+     * @return
+     */
+    public static String getQNamePatternString() {
+        // See http://www.w3.org/TR/REC-xml-names/#NT-PrefixedName
+        // NCNameStartChar
+        // see http://www.w3.org/TR/REC-xml-names/#NT-NCName
+        // and http://www.w3.org/TR/REC-xml/#NT-NameStartChar
+        String ncNameStartChar = 
"[A-Z]|_|[a-z]|[\\x{c0}-\\x{d6}]|[\\x{d8}-\\x{f6}]|[\\x{f8}-\\x{2ff}]|"
+                + 
"[\\x{370}-\\x{37d}]|[\\x{37f}-\\x{1fff}]|[\\x{200c}-\\x{200d}]|"
+                + 
"[\\x{2070}-\\x{218f}]|[\\x{2c00}-\\x{2fef}]|[\\x{3001}-\\x{d7ff}]|"
+                + 
"[\\x{f900}-\\x{fdcf}]|[\\x{fdf0}-\\x{fffd}]|[\\x{10000}-\\x{effff}]";
+        // NCNameChar
+        // see http://www.w3.org/TR/REC-xml/#NT-NameChar
+        String ncNameChar = ncNameStartChar
+                + 
"|-|\\.|[0-9]|\\x{b7}|[\\x{0300}-\\x{036f}]|[\\x{203f}-\\x{2040}]";
+        // NCName
+        // see http://www.w3.org/TR/REC-xml/#NT-Name
+        String ncName = String.format("(%s)(%s)*", ncNameStartChar, 
ncNameChar);
+        // QName
+        // see http://www.w3.org/TR/REC-xml-names/#NT-QName
+        return String.format("((%s):)?(%s)", ncName, ncName);
+    }
+    
+    @Override
+    public Object getResourceFragment(final Representation representation, 
ExpressionType expression) {
+        String expressionStr = getXPathFromQNameExpression(expression);
+        // Evaluate XPath
+        XPathUtils xu = new XPathUtils(new NamespaceContext() {
+            @Override
+            public String getNamespaceURI(String prefix) {
+                if (prefix != null && !prefix.isEmpty()) {
+                    Element resource = (Element) representation.getAny();
+                    return resource.getAttribute("xmlns:" + prefix);
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public String getPrefix(String s) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public Iterator<String> getPrefixes(String s) {
+                throw new UnsupportedOperationException();
+            }
+        });
+        Node resource = (Node) representation.getAny();
+        if (resource == null) {
+            // Returns empty NodeList
+            return new NodeList() {
+                @Override
+                public Node item(int i) {
+                    return null;
+                }
+
+                @Override
+                public int getLength() {
+                    return 0;
+                }
+            };
+        }
+        return xu.getValueList(expressionStr, resource);
+    }
+    
+    /**
+     * Converts expression in QName language to XPath expression.
+     * @param expression Expression in QName language.
+     * @return Expression in XPath language.
+     */
+    private String getXPathFromQNameExpression(ExpressionType expression) {
+        if (expression.getContent().size() == 1) {
+            String expressionValue = (String) expression.getContent().get(0);
+            Matcher m = qNamePattern.matcher(expressionValue);
+            if (m.matches()) {
+                return "/node()/" + expressionValue;
+            } else {
+                throw new InvalidExpression();
+            }
+        } else {
+            throw new InvalidExpression();
+        }
+    }
+    
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageXPath10.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageXPath10.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageXPath10.java
new file mode 100644
index 0000000..86bddab
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/dialect/fragment/language/FragmentDialectLanguageXPath10.java
@@ -0,0 +1,160 @@
+/**
+ * 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.cxf.ws.transfer.dialect.fragment.language;
+
+import java.util.Iterator;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathException;
+import javax.xml.xpath.XPathFactory;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.ws.transfer.Representation;
+import org.apache.cxf.ws.transfer.dialect.fragment.ExpressionType;
+import org.apache.cxf.ws.transfer.dialect.fragment.faults.InvalidExpression;
+
+/**
+ * Implementation of the XPath 1.0 language.
+ */
+public class FragmentDialectLanguageXPath10 implements FragmentDialectLanguage 
{
+
+    private static XPathFactory xpathFactory = XPathFactory.newInstance();
+
+    @Override
+    public Object getResourceFragment(final Representation representation, 
ExpressionType expression) {
+        String expressionStr = getXPathFromExpression(expression);
+        // Evaluate XPath
+        XPath xPath = xpathFactory.newXPath();
+        xPath.setNamespaceContext(new NamespaceContext() {
+
+            @Override
+            public String getNamespaceURI(String prefix) {
+                if (prefix != null && !prefix.isEmpty()) {
+                    Element resource = (Element) representation.getAny();
+                    return resource.getAttribute("xmlns:" + prefix);
+                } else {
+                    return null;
+                }
+            }
+
+            @Override
+            public String getPrefix(String string) {
+                throw new UnsupportedOperationException();
+            }
+
+            @Override
+            public Iterator<String> getPrefixes(String string) {
+                throw new UnsupportedOperationException();
+            }
+        });
+        try {
+            Object resource = representation.getAny();
+            if (resource == null) {
+                resource = DOMUtils.createDocument();
+            }
+            NodeList result = (NodeList) xPath.evaluate(
+                expressionStr, resource, XPathConstants.NODESET);
+            if (checkResultConstraints(result)) {
+                if (result.getLength() == 0) {
+                    return  null;
+                } else {
+                    return result;
+                }
+            } else {
+                return result.item(0);
+            }
+        } catch (XPathException ex) {
+            // See https://www.java.net/node/681793
+        }
+
+        try {
+            return (String) xPath.evaluate(
+                expressionStr, representation.getAny(), XPathConstants.STRING);
+        } catch (XPathException ex) {
+            throw new InvalidExpression();
+        }
+    }
+    
+    /**
+     * Get XPath from the Expression element.
+     * @param expression
+     * @return 
+     */
+    private String getXPathFromExpression(ExpressionType expression) {
+        if (expression.getContent().size() == 1) {
+            return (String) expression.getContent().get(0);
+        } else {
+            throw new InvalidExpression();
+        }
+    }
+    
+    /**
+     * Check if result from evaluation of XPath expression fullfils constraints
+     * defined in the specification.
+     * See http://www.w3.org/TR/ws-fragment/#IdResSubset
+     * @param result
+     * @return If the result is true, the server should return all sequence of 
elements,
+     *         otherwise it should return only the first element.
+     */
+    private boolean checkResultConstraints(NodeList result) {
+        if (result.getLength() > 0) {
+            Node firstNode = result.item(0);
+            if (firstNode.getNodeType() == Node.ELEMENT_NODE) {
+                Element firstEl = (Element) firstNode;
+                // QName attributes
+                String localName = firstEl.getLocalName();
+                String namespace = firstEl.getNamespaceURI();
+                Node parent = firstEl.getParentNode();
+                for (int i = 1; i < result.getLength(); i++) {
+                    Node node = result.item(i);
+                    if (node.getNodeType() == Node.ELEMENT_NODE) {
+                        Element element = (Element) node;
+                        if (!stringEquals(element.getLocalName(), localName)) {
+                            return false;
+                        }
+                        if (!stringEquals(element.getNamespaceURI(), 
namespace)) {
+                            return false;
+                        }
+                        if (element.getParentNode() != parent) {
+                            return false;
+                        }
+                    } else {
+                        return false;
+                    }
+                }
+            } else {
+                return false;
+            }
+        }
+        return true;
+    }
+    
+    /**
+     * Helper method for equation two strings, which can be nullable.
+     * @param str1
+     * @param str2
+     * @return 
+     */
+    private boolean stringEquals(String str1, String str2) {
+        return str1 == null ? str2 == null : str1.equals(str2);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/MemoryResourceManager.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/MemoryResourceManager.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/MemoryResourceManager.java
new file mode 100644
index 0000000..9609013e
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/MemoryResourceManager.java
@@ -0,0 +1,160 @@
+/**
+ * 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.cxf.ws.transfer.manager;
+
+import java.io.StringReader;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+import java.util.logging.Logger;
+
+import javax.annotation.Resource;
+import javax.xml.bind.JAXBElement;
+import javax.xml.namespace.QName;
+import javax.xml.stream.XMLStreamException;
+import javax.xml.ws.WebServiceContext;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.apache.cxf.binding.soap.SoapFault;
+import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.binding.soap.SoapVersion;
+import org.apache.cxf.common.logging.LogUtils;
+import org.apache.cxf.helpers.DOMUtils;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.staxutils.StaxUtils;
+import org.apache.cxf.ws.addressing.ReferenceParametersType;
+import org.apache.cxf.ws.transfer.Representation;
+import org.apache.cxf.ws.transfer.shared.faults.UnknownResource;
+
+/**
+ * In memory implementation for ResourceManager interface.
+ */
+public class MemoryResourceManager implements ResourceManager {
+
+    public static final String REF_NAMESPACE = 
"http://cxf.apache.org/rt/ws/transfer/MemoryResourceManager";;
+
+    public static final String REF_LOCAL_NAME = "uuid";
+
+    private static final Logger LOG = 
LogUtils.getL7dLogger(MemoryResourceManager.class);
+
+    protected Map<String, String> storage;
+
+    @Resource
+    private WebServiceContext context;
+
+    public MemoryResourceManager() {
+        storage = new HashMap<String, String>();
+    }
+
+    @Override
+    public Representation get(ReferenceParametersType ref) {
+        String uuid = getUUID(ref);
+        if (!storage.containsKey(uuid)) {
+            throw new UnknownResource();
+        }
+        String resource = storage.get(uuid);
+        if (resource.isEmpty()) {
+            return new Representation();
+        } else {
+            Document doc = null;
+            try {
+                doc = StaxUtils.read(new StringReader(storage.get(uuid)));
+            } catch (XMLStreamException e) {
+                LOG.severe(e.getLocalizedMessage());
+                throw new SoapFault("Internal Error", 
getSoapVersion().getReceiver());
+            }
+            Representation representation = new Representation();
+            representation.setAny(doc.getDocumentElement());
+            return representation;
+        }
+    }
+
+    @Override
+    public void delete(ReferenceParametersType ref) {
+        String uuid = getUUID(ref);
+        if (!storage.containsKey(uuid)) {
+            throw new UnknownResource();
+        }
+        storage.remove(uuid);
+    }
+
+    @Override
+    public void put(ReferenceParametersType ref, Representation 
newRepresentation) {
+        String uuid = getUUID(ref);
+        if (!storage.containsKey(uuid)) {
+            throw new UnknownResource();
+        }
+        Element representationEl = (Element) newRepresentation.getAny();
+        if (representationEl == null) {
+            storage.put(uuid, "");
+        } else {
+            storage.put(uuid, StaxUtils.toString(representationEl));
+        }
+    }
+
+    @Override
+    public ReferenceParametersType create(Representation initRepresentation) {
+        // Store xmlResource
+        String uuid = UUID.randomUUID().toString();
+        Element representationEl = (Element) initRepresentation.getAny();
+        if (representationEl == null) {
+            storage.put(uuid, "");
+        } else {
+            storage.put(uuid, StaxUtils.toString(representationEl));
+        }
+
+        Element uuidEl = 
DOMUtils.createDocument().createElementNS(REF_NAMESPACE, REF_LOCAL_NAME);
+        uuidEl.setTextContent(uuid);
+
+        // Create referenceParameter
+        ReferenceParametersType refParam = new ReferenceParametersType();
+        refParam.getAny().add(uuidEl);
+        return refParam;
+    }
+
+    private String getUUID(ReferenceParametersType ref) {
+        for (Object object : ref.getAny()) {
+            if (object instanceof JAXBElement) {
+                JAXBElement<?> element = (JAXBElement<?>) object;
+                QName qName = element.getName();
+                if (
+                        REF_NAMESPACE.equals(qName.getNamespaceURI())
+                                && 
REF_LOCAL_NAME.equals(qName.getLocalPart())) {
+                    return (String) element.getValue();
+                }
+            } else if (object instanceof Element) {
+                Element element = (Element) object;
+                if (
+                        REF_NAMESPACE.equals(element.getNamespaceURI())
+                                && 
REF_LOCAL_NAME.equals(element.getLocalName())) {
+                    return element.getTextContent();
+                }
+            }
+        }
+        throw new UnknownResource();
+    }
+
+    private SoapVersion getSoapVersion() {
+        WrappedMessageContext wmc = (WrappedMessageContext) 
context.getMessageContext();
+        SoapMessage message = (SoapMessage) wmc.getWrappedMessage();
+        return message.getVersion();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/ResourceManager.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/ResourceManager.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/ResourceManager.java
new file mode 100644
index 0000000..7dbc6ac
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/manager/ResourceManager.java
@@ -0,0 +1,59 @@
+/**
+ * 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.cxf.ws.transfer.manager;
+
+import org.apache.cxf.ws.addressing.ReferenceParametersType;
+import org.apache.cxf.ws.transfer.Representation;
+
+/**
+ * Interface for managing resource representations.
+ */
+public interface ResourceManager {
+    
+    /**
+     * Returns Representation object given by reference parameter.
+     * @param ref Reference parameter returned by create method.
+     * @return Representation object containing the XML resource.
+     * @see ResourceManager#create(org.apache.cxf.ws.transfer.Representation) 
+     */
+    Representation get(ReferenceParametersType ref);
+    
+    /**
+     * Deletes Representation object given by reference parameter.
+     * @param ref Reference parameter returned by create method.
+     * @see ResourceManager#create(org.apache.cxf.ws.transfer.Representation)
+     */
+    void delete(ReferenceParametersType ref);
+    
+    /**
+     * Replaces Representation object given by reference parameter with 
newRepresentation.
+     * @param ref Reference parameter returned by create method.
+     * @param newRepresentation New Representation object, which will replace 
the old one.
+     * @see ResourceManager#create(org.apache.cxf.ws.transfer.Representation)
+     */
+    void put(ReferenceParametersType ref, Representation newRepresentation);
+    
+    /**
+     * Creates new Representation object from initRepresenation.
+     * @param initRepresentation Representation object containing initial XML 
resource.
+     * @return Reference parameter for newly created Representation object.
+     */
+    ReferenceParametersType create(Representation initRepresentation);
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/Resource.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/Resource.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/Resource.java
new file mode 100644
index 0000000..3280e39
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/Resource.java
@@ -0,0 +1,101 @@
+/**
+ * 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.cxf.ws.transfer.resource;
+
+import javax.jws.WebMethod;
+import javax.jws.WebParam;
+import javax.jws.WebResult;
+import javax.jws.WebService;
+import javax.jws.soap.SOAPBinding;
+import javax.xml.ws.Action;
+import javax.xml.ws.soap.Addressing;
+import org.apache.cxf.ws.transfer.Delete;
+import org.apache.cxf.ws.transfer.DeleteResponse;
+import org.apache.cxf.ws.transfer.Get;
+import org.apache.cxf.ws.transfer.GetResponse;
+import org.apache.cxf.ws.transfer.Put;
+import org.apache.cxf.ws.transfer.PutResponse;
+import org.apache.cxf.ws.transfer.shared.TransferConstants;
+
+/**
+ * The interface definition of a Resource web service, according to the 
specification.
+ */
+@WebService(targetNamespace = TransferConstants.TRANSFER_2011_03_NAMESPACE,
+        name = TransferConstants.NAME_RESOURCE)
+@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
+@Addressing(enabled = true, required = true)
+public interface Resource {
+
+    @Action(
+            input = TransferConstants.ACTION_GET,
+            output = TransferConstants.ACTION_GET_RESPONSE)
+    @WebMethod(operationName = TransferConstants.NAME_OPERATION_GET)
+    @WebResult(
+            name = TransferConstants.NAME_MESSAGE_GET_RESPONSE,
+            targetNamespace = TransferConstants.TRANSFER_2011_03_NAMESPACE,
+            partName = "Body"
+    )
+    GetResponse get(
+        @WebParam(
+                name = TransferConstants.NAME_MESSAGE_GET,
+                targetNamespace = TransferConstants.TRANSFER_2011_03_NAMESPACE,
+                partName = "Body"
+        )
+        Get body
+    );
+
+    @Action(
+            input = TransferConstants.ACTION_DELETE,
+            output = TransferConstants.ACTION_DELETE_RESPONSE
+    )
+    @WebMethod(operationName = TransferConstants.NAME_OPERATION_DELETE)
+    @WebResult(
+            name = TransferConstants.NAME_MESSAGE_DELETE_RESPONSE,
+            targetNamespace = TransferConstants.TRANSFER_2011_03_NAMESPACE,
+            partName = "Body"
+    )
+    DeleteResponse delete(
+        @WebParam(
+                name = TransferConstants.NAME_MESSAGE_DELETE,
+                targetNamespace = TransferConstants.TRANSFER_2011_03_NAMESPACE,
+                partName = "Body"
+        )
+        Delete body
+    );
+
+    @Action(
+            input = TransferConstants.ACTION_PUT,
+            output = TransferConstants.ACTION_PUT_RESPONSE
+    )
+    @WebMethod(operationName = TransferConstants.NAME_OPERATION_PUT)
+    @WebResult(
+            name = TransferConstants.NAME_MESSAGE_PUT_RESPONSE,
+            targetNamespace = TransferConstants.TRANSFER_2011_03_NAMESPACE,
+            partName = "Body"
+    )
+    PutResponse put(
+        @WebParam(
+                name = TransferConstants.NAME_MESSAGE_PUT,
+                targetNamespace = TransferConstants.TRANSFER_2011_03_NAMESPACE,
+                partName = "Body"
+        )
+        Put body
+    );
+}

http://git-wip-us.apache.org/repos/asf/cxf/blob/517ef67f/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/ResourceLocal.java
----------------------------------------------------------------------
diff --git 
a/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/ResourceLocal.java
 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/ResourceLocal.java
new file mode 100644
index 0000000..49333d6
--- /dev/null
+++ 
b/rt/ws/transfer/src/main/java/org/apache/cxf/ws/transfer/resource/ResourceLocal.java
@@ -0,0 +1,191 @@
+/**
+ * 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.cxf.ws.transfer.resource;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import javax.xml.ws.WebServiceContext;
+import org.apache.cxf.jaxws.context.WrappedMessageContext;
+import org.apache.cxf.ws.addressing.AddressingProperties;
+import org.apache.cxf.ws.addressing.JAXWSAConstants;
+import org.apache.cxf.ws.addressing.ReferenceParametersType;
+import org.apache.cxf.ws.transfer.Delete;
+import org.apache.cxf.ws.transfer.DeleteResponse;
+import org.apache.cxf.ws.transfer.Get;
+import org.apache.cxf.ws.transfer.GetResponse;
+import org.apache.cxf.ws.transfer.Put;
+import org.apache.cxf.ws.transfer.PutResponse;
+import org.apache.cxf.ws.transfer.Representation;
+import org.apache.cxf.ws.transfer.dialect.Dialect;
+import org.apache.cxf.ws.transfer.dialect.fragment.FragmentDialect;
+import org.apache.cxf.ws.transfer.dialect.fragment.FragmentDialectConstants;
+import org.apache.cxf.ws.transfer.manager.ResourceManager;
+import org.apache.cxf.ws.transfer.shared.faults.UnknownDialect;
+import 
org.apache.cxf.ws.transfer.validationtransformation.ResourceTypeIdentifier;
+import 
org.apache.cxf.ws.transfer.validationtransformation.ValidAndTransformHelper;
+
+/**
+ * Implementation of the Resource interface for resources, which are created 
locally.
+ * @see org.apache.cxf.ws.transfer.resourcefactory.resolver.ResourceResolver
+ */
+public class ResourceLocal implements Resource {
+    
+    @javax.annotation.Resource
+    protected WebServiceContext context;
+    
+    protected ResourceManager manager;
+    
+    protected List<ResourceTypeIdentifier> resourceTypeIdentifiers;
+    
+    protected Map<String, Dialect> dialects;
+
+    public ResourceLocal() {
+        dialects = new HashMap<String, Dialect>();
+        dialects.put(FragmentDialectConstants.FRAGMENT_2011_03_IRI, new 
FragmentDialect());
+    }
+    
+    public ResourceManager getManager() {
+        return manager;
+    }
+
+    public void setManager(ResourceManager manager) {
+        this.manager = manager;
+    }
+
+    public List<ResourceTypeIdentifier> getResourceTypeIdentifiers() {
+        if (resourceTypeIdentifiers == null) {
+            resourceTypeIdentifiers = new ArrayList<>();
+        }
+        return resourceTypeIdentifiers;
+    }
+
+    public void setResourceTypeIdentifiers(List<ResourceTypeIdentifier> 
resourceTypeIdentifiers) {
+        this.resourceTypeIdentifiers = resourceTypeIdentifiers;
+    }
+    
+    /**
+     * Register Dialect object for URI.
+     * @param iri
+     * @param dialect 
+     */
+    public void registerDialect(String iri, Dialect dialect) {
+        if (dialects.containsKey(iri)) {
+            throw new IllegalArgumentException(String.format("IRI \"%s\" is 
already registered", iri));
+        }
+        dialects.put(iri, dialect);
+    }
+    
+    /**
+     * Unregister dialect URI.
+     * @param iri 
+     */
+    public void unregisterDialect(String iri) {
+        if (!dialects.containsKey(iri)) {
+            throw new IllegalArgumentException(String.format("IRI \"%s\" is 
not registered", iri));
+        }
+        dialects.remove(iri);
+    }
+    
+    @Override
+    public GetResponse get(Get body) {
+        // Getting reference paramaters
+        AddressingProperties addrProps = (AddressingProperties) 
((WrappedMessageContext) context
+                .getMessageContext()).getWrappedMessage()
+                
.getContextualProperty(JAXWSAConstants.ADDRESSING_PROPERTIES_INBOUND);
+        ReferenceParametersType refParams = addrProps
+                .getToEndpointReference()
+                .getReferenceParameters();
+        GetResponse response = new GetResponse();
+        // Getting representation from the ResourceManager
+        Representation representation = manager.get(refParams);
+        // Dialect processing
+        if (body.getDialect() != null && !body.getDialect().isEmpty()) {
+            if (dialects.containsKey(body.getDialect())) {
+                Dialect dialect = dialects.get(body.getDialect());
+                // Send fragment of resource instead it's representation.
+                response.getAny().add(dialect.processGet(body, 
representation));
+            } else {
+                throw new UnknownDialect();
+            }
+        } else {
+            // Send representation obtained from ResourceManager.
+            response.setRepresentation(representation);
+        }
+        return response;
+    }
+
+    @Override
+    public DeleteResponse delete(Delete body) {
+        // Getting reference paramaters
+        AddressingProperties addrProps = (AddressingProperties) 
((WrappedMessageContext) context
+                .getMessageContext()).getWrappedMessage()
+                
.getContextualProperty(JAXWSAConstants.ADDRESSING_PROPERTIES_INBOUND);
+        ReferenceParametersType refParams = addrProps
+                .getToEndpointReference()
+                .getReferenceParameters();
+        boolean delete = true;
+        // Dialect processing
+        if (body.getDialect() != null && !body.getDialect().isEmpty()) {
+            if (dialects.containsKey(body.getDialect())) {
+                Dialect dialect = dialects.get(body.getDialect());
+                delete = dialect.processDelete(body, manager.get(refParams));
+            } else {
+                throw new UnknownDialect();
+            }
+        }
+        if (delete) {
+            manager.delete(refParams);
+        }
+        return new DeleteResponse();
+    }
+
+    @Override
+    public PutResponse put(Put body) {
+        // Getting reference paramaters
+        AddressingProperties addrProps = (AddressingProperties) 
((WrappedMessageContext) context
+                .getMessageContext()).getWrappedMessage()
+                
.getContextualProperty(JAXWSAConstants.ADDRESSING_PROPERTIES_INBOUND);
+        ReferenceParametersType refParams = addrProps
+                .getToEndpointReference()
+                .getReferenceParameters();
+        // Getting representation from the ResourceManager
+        Representation storedRepresentation = manager.get(refParams);
+        // Getting representation from the incoming SOAP message. This 
representation will be stored.
+        Representation putRepresentation = body.getRepresentation();
+        // Dialect processing
+        if (body.getDialect() != null && !body.getDialect().isEmpty()) {
+            if (dialects.containsKey(body.getDialect())) {
+                Dialect dialect = dialects.get(body.getDialect());
+                putRepresentation = dialect.processPut(body, 
storedRepresentation);
+            } else {
+                throw new UnknownDialect();
+            }
+        }
+        ValidAndTransformHelper.validationAndTransformation(
+                resourceTypeIdentifiers, putRepresentation, 
storedRepresentation);
+        manager.put(refParams, putRepresentation);
+        PutResponse response = new PutResponse();
+        response.setRepresentation(putRepresentation);
+        return response;
+    }
+    
+}

Reply via email to