// Path: common/src/main/java/com/nortal/jroad/enums/XRoadProtocolVersion.java
// public enum XRoadProtocolVersion {
// 
//   V2_0("2.0", "xtee", "http://x-tee.riik.ee/xsd/xtee.xsd"),
//   V3_0("3.0", "xrd", "http://x-rd.net/xsd/xroad.xsd"),
//   V3_1("3.1", "xrd", "http://x-road.ee/xsd/x-road.xsd"),
//   V4_0("4.0", "xrd", "http://x-road.eu/xsd/xroad.xsd");
// 
//   private final String code;
//   private final String namespacePrefix;
//   private final String namespaceUri;
// 
//   private XRoadProtocolVersion(String code, String namespacePrefix, String namespaceUri) {
//     this.code = code;
//     this.namespaceUri = namespaceUri;
//     this.namespacePrefix = namespacePrefix;
//   }
// 
//   public String getCode() {
//     return code;
//   }
// 
//   public String getNamespacePrefix() {
//     return namespacePrefix;
//   }
// 
//   public String getNamespaceUri() {
//     return namespaceUri;
//   }
// 
//   public static XRoadProtocolVersion getValueByVersionCode(String code) {
//     for (XRoadProtocolVersion version : XRoadProtocolVersion.values()) {
//       if (version.getCode().equals(code)) {
//         return version;
//       }
//     }
//     return null;
//   }
// 
//   public static XRoadProtocolVersion getValueByNamespaceURI(String uri) {
//     for (XRoadProtocolVersion version : XRoadProtocolVersion.values()) {
//       if (version.getNamespaceUri().startsWith(uri)) {
//         return version;
//       }
//     }
//     return null;
//   }
// 
// }
// 
// Path: common/src/main/java/com/nortal/jroad/model/BeanXTeeMessage.java
// @Deprecated
// public class BeanXTeeMessage<T> implements XTeeMessage<T> {
//   private List<XTeeAttachment> attachments;
//   private XTeeHeader header;
//   private T content;
// 
//   public BeanXTeeMessage(XTeeHeader header, T content, List<XTeeAttachment> attachments) {
//     this.attachments = attachments;
//     this.header = header;
//     this.content = content;
//   }
// 
//   public List<XTeeAttachment> getAttachments() {
//     return attachments;
//   }
// 
//   public XTeeHeader getHeader() {
//     return header;
//   }
// 
//   public T getContent() {
//     return content;
//   }
// 
//   public void setContent(T content) {
//     this.content = content;
//   }
// 
//   public void setAttachments(List<XTeeAttachment> attachments) {
//     this.attachments = attachments;
//   }
// 
//   public void setHeader(XTeeHeader header) {
//     this.header = header;
//   }
// }
// 
// Path: common/src/main/java/com/nortal/jroad/util/AttachmentUtil.java
// public class AttachmentUtil {
//   private static long salt = 0;
// 
//   public static String getUniqueCid() {
//     salt++;
//     return UUID.randomUUID().toString() + String.valueOf(salt);
//   }
// 
// }


import com.nortal.jroad.enums.XRoadProtocolVersion;
import com.nortal.jroad.model.BeanXTeeMessage;
import com.nortal.jroad.model.XTeeAttachment;
import com.nortal.jroad.model.XTeeMessage;
import com.nortal.jroad.util.AttachmentUtil;
import com.nortal.jroad.util.SOAPUtil;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.activation.DataHandler;
import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.bind.attachment.AttachmentUnmarshaller;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
 * Copyright 2015 Nortal Licensed 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 com.nortal.jroad.endpoint;


/**
 * X-Tee endpoint that provides request/response manipulation using Java objects via JAXB API. All extension classes
 * must implement the method method {@link AbstractXTeeJAXBEndpoint#invokeBean(Object)}.
 *
 * @author Dmitri Danilkin
 * @author Lauri Lättemäe (lauri.lattemae@nortal.com) - protocol 4.0
 */
public abstract class AbstractXTeeJAXBEndpoint<T> extends AbstractXTeeBaseEndpoint {
  private static final class JaxbContextKey {
    private final String contextPath;
    private final ClassLoader classLoader;

    public JaxbContextKey(final String contextPath, final ClassLoader classLoader) {
      this.contextPath = contextPath;
      this.classLoader = classLoader;
    }

    @Override
    public boolean equals(final Object other) {
      if (this == other) {
        return true;
      }
      if (other == null || !getClass().equals(other.getClass())) {
        return false;
      }
      JaxbContextKey otherKey = (JaxbContextKey) other;
      return ((contextPath == null) ? (otherKey.contextPath == null) : (contextPath.equals(otherKey.contextPath)))
          && ((classLoader == null) ? (otherKey.classLoader == null) : (classLoader.equals(otherKey.classLoader)));
    }

// Path: common/src/main/java/com/nortal/jroad/enums/XRoadProtocolVersion.java
// public enum XRoadProtocolVersion {
// 
//   V2_0("2.0", "xtee", "http://x-tee.riik.ee/xsd/xtee.xsd"),
//   V3_0("3.0", "xrd", "http://x-rd.net/xsd/xroad.xsd"),
//   V3_1("3.1", "xrd", "http://x-road.ee/xsd/x-road.xsd"),
//   V4_0("4.0", "xrd", "http://x-road.eu/xsd/xroad.xsd");
// 
//   private final String code;
//   private final String namespacePrefix;
//   private final String namespaceUri;
// 
//   private XRoadProtocolVersion(String code, String namespacePrefix, String namespaceUri) {
//     this.code = code;
//     this.namespaceUri = namespaceUri;
//     this.namespacePrefix = namespacePrefix;
//   }
// 
//   public String getCode() {
//     return code;
//   }
// 
//   public String getNamespacePrefix() {
//     return namespacePrefix;
//   }
// 
//   public String getNamespaceUri() {
//     return namespaceUri;
//   }
// 
//   public static XRoadProtocolVersion getValueByVersionCode(String code) {
//     for (XRoadProtocolVersion version : XRoadProtocolVersion.values()) {
//       if (version.getCode().equals(code)) {
//         return version;
//       }
//     }
//     return null;
//   }
// 
//   public static XRoadProtocolVersion getValueByNamespaceURI(String uri) {
//     for (XRoadProtocolVersion version : XRoadProtocolVersion.values()) {
//       if (version.getNamespaceUri().startsWith(uri)) {
//         return version;
//       }
//     }
//     return null;
//   }
// 
// }
// 
// Path: common/src/main/java/com/nortal/jroad/model/BeanXTeeMessage.java
// @Deprecated
// public class BeanXTeeMessage<T> implements XTeeMessage<T> {
//   private List<XTeeAttachment> attachments;
//   private XTeeHeader header;
//   private T content;
// 
//   public BeanXTeeMessage(XTeeHeader header, T content, List<XTeeAttachment> attachments) {
//     this.attachments = attachments;
//     this.header = header;
//     this.content = content;
//   }
// 
//   public List<XTeeAttachment> getAttachments() {
//     return attachments;
//   }
// 
//   public XTeeHeader getHeader() {
//     return header;
//   }
// 
//   public T getContent() {
//     return content;
//   }
// 
//   public void setContent(T content) {
//     this.content = content;
//   }
// 
//   public void setAttachments(List<XTeeAttachment> attachments) {
//     this.attachments = attachments;
//   }
// 
//   public void setHeader(XTeeHeader header) {
//     this.header = header;
//   }
// }
// 
// Path: common/src/main/java/com/nortal/jroad/util/AttachmentUtil.java
// public class AttachmentUtil {
//   private static long salt = 0;
// 
//   public static String getUniqueCid() {
//     salt++;
//     return UUID.randomUUID().toString() + String.valueOf(salt);
//   }
// 
// }


// Path: server/src/main/java/com/nortal/jroad/endpoint/AbstractXTeeJAXBEndpoint.java
import com.nortal.jroad.enums.XRoadProtocolVersion;
import com.nortal.jroad.model.BeanXTeeMessage;
import com.nortal.jroad.model.XTeeAttachment;
import com.nortal.jroad.model.XTeeMessage;
import com.nortal.jroad.util.AttachmentUtil;
import com.nortal.jroad.util.SOAPUtil;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.activation.DataHandler;
import javax.annotation.Resource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.attachment.AttachmentMarshaller;
import javax.xml.bind.attachment.AttachmentUnmarshaller;
import javax.xml.namespace.QName;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

/**
 * Copyright 2015 Nortal Licensed 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 com.nortal.jroad.endpoint;


/**
 * X-Tee endpoint that provides request/response manipulation using Java objects via JAXB API. All extension classes
 * must implement the method method {@link AbstractXTeeJAXBEndpoint#invokeBean(Object)}.
 *
 * @author Dmitri Danilkin
 * @author Lauri Lättemäe (lauri.lattemae@nortal.com) - protocol 4.0
 */
public abstract class AbstractXTeeJAXBEndpoint<T> extends AbstractXTeeBaseEndpoint {
  private static final class JaxbContextKey {
    private final String contextPath;
    private final ClassLoader classLoader;

    public JaxbContextKey(final String contextPath, final ClassLoader classLoader) {
      this.contextPath = contextPath;
      this.classLoader = classLoader;
    }

    @Override
    public boolean equals(final Object other) {
      if (this == other) {
        return true;
      }
      if (other == null || !getClass().equals(other.getClass())) {
        return false;
      }
      JaxbContextKey otherKey = (JaxbContextKey) other;
      return ((contextPath == null) ? (otherKey.contextPath == null) : (contextPath.equals(otherKey.contextPath)))
          && ((classLoader == null) ? (otherKey.classLoader == null) : (classLoader.equals(otherKey.classLoader)));
    }

    @Override