Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/**
* Copyright 2012 Sven Ewald
*
* 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 org.xmlbeam;
import java.io.IOException;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.text.MessageFormat;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpression;
import javax.xml.xpath.XPathExpressionException;
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.xml.sax.SAXException;
import org.xmlbeam.XBProjector.InternalProjection;
import org.xmlbeam.annotation.XBDelete;
import org.xmlbeam.annotation.XBDocURL;
import org.xmlbeam.annotation.XBRead;
import org.xmlbeam.annotation.XBValue;
import org.xmlbeam.annotation.XBWrite;
import org.xmlbeam.dom.DOMAccess;
import org.xmlbeam.types.TypeConverter;
import org.xmlbeam.util.intern.ASMHelper;
import org.xmlbeam.util.intern.DOMHelper;
import org.xmlbeam.util.intern.MethodParamVariableResolver;
import org.xmlbeam.util.intern.ReflectionHelper;
/**
* This class implements the "magic" behind projection methods. Each projection is linked with a
* ProjectionInvocatonHandler which handles method invocations on the projections. Notice that this
* class is not part of the public API. You should not get in touch with this class at all. See
* {@link org.xmlbeam.XBProjector} for API usage.
*
* @author Sven Ewald
*/
@SuppressWarnings("serial")
final class ProjectionInvocationHandler implements InvocationHandler, Serializable {
private final static String NONEMPTY = "(?!^$)";
private final static String XML_NAME_START_CHARS=":A-Z_a-z\\u00C0\\u00D6\\u00D8-\\u00F6\\u00F8-\\u02ff\\u0370-\\u037d"
+ "\\u037f-\\u1fff\\u200c\\u200d\\u2070-\\u218f\\u2c00-\\u2fef\\u3001-\\ud7ff"
+ "\\uf900-\\ufdcf\\ufdf0-\\ufffd"+String.valueOf(Character.toChars(0x10000))+"-"+String.valueOf(Character.toChars(0xEFFFF));
private final static String XML_NAME_CHARS=XML_NAME_START_CHARS+"\\-\\.0-9\\u00B7\\u0300-\\u036F\\u203F-\\u2040";
private final static String XML_ELEMENT = "["+XML_NAME_START_CHARS+"]"+"["+XML_NAME_CHARS+"]*";
private final static String ELEMENT_PATH = "(/"+XML_ELEMENT+"(\\[@?"+XML_ELEMENT+"='.+'\\])?)";
private final static String ATTRIBUTE_PATH = "(/?@"+XML_ELEMENT+")";
private final static String PARENT_PATH = "(/\\.\\.)";
private static final Pattern LEGAL_XPATH_SELECTORS_FOR_SETTERS = Pattern.compile(NONEMPTY + "(^\\.?(" + ELEMENT_PATH + "*" + PARENT_PATH + "*)*(" + ATTRIBUTE_PATH + "|(/\\*))?$)");
private final Node node;
private final Class> projectionInterface;
private final XBProjector projector;
// Used to handle invocations on Java6 Mixins and Object methods.
private final Map, Object> defaultInvokers;
// Used to handle invocations on Java8 default methods.
private transient Object defaultMethodInvoker;
ProjectionInvocationHandler(final XBProjector projector, final Node node, final Class> projectionInterface, final Map, Object> defaultInvokers) {
this.projector = projector;
this.node = node;
this.projectionInterface = projectionInterface;
this.defaultInvokers = defaultInvokers;
}
/**
* @param collection
* @param parentElement
* @param elementSelector
*/
private void applyCollectionSetOnElement(final Collection> collection, final Element parentElement, final String elementSelector) {
final Document document = parentElement.getOwnerDocument();
DOMHelper.removeAllChildrenBySelector(parentElement, elementSelector);
assert !elementSelector.contains("/") : "Selector should be the trail of the path.";
final String elementName = elementSelector.replaceAll("\\[.*", "");
if (collection == null) {
return;
}
for (Object o : collection) {
if (o == null) {
continue;
}
if (!(o instanceof InternalProjection)) {
final Element newElement = document.createElement(elementName);
newElement.setTextContent(o.toString());
parentElement.appendChild(newElement);
continue;
}
final InternalProjection p = (InternalProjection) o;
Element pElement = Node.DOCUMENT_NODE == p.getDOMNode().getNodeType() ? p.getDOMOwnerDocument().getDocumentElement() : (Element) p.getDOMNode();
if (pElement == null) {
continue;
}
Element clone = (Element) pElement.cloneNode(true);
if (!elementName.equals(clone.getNodeName())) {
if (!"*".equals(elementName)) {
clone = DOMHelper.renameElement(clone, elementName);
}
}
DOMHelper.ensureOwnership(document, clone);
parentElement.appendChild(clone);
}
}
private void applySingleSetProjectionOnElement(final InternalProjection projection, final Node parentNode, final String elementSelector) {
final Element newElement = (Element) projection.getDOMBaseElement().cloneNode(true);
DOMHelper.removeAllChildrenBySelector(parentNode, elementSelector);
DOMHelper.ensureOwnership(parentNode.getOwnerDocument(), newElement);
parentNode.appendChild(newElement);
}
private List> evaluateAsList(final XPathExpression expression, final Node node, final Method method) throws XPathExpressionException {
final NodeList nodes = (NodeList) expression.evaluate(node, XPathConstants.NODESET);
final List