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, Plutext Pty Ltd.
*
* This file is part of docx4j.
docx4j is 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.docx4j.openpackaging.parts;
import java.io.InputStream;
import java.util.List;
import javax.xml.bind.Binder;
import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.Unmarshaller;
import javax.xml.namespace.QName;
import javax.xml.transform.Templates;
import javax.xml.transform.dom.DOMResult;
import org.apache.commons.io.IOUtils;
import org.docx4j.XmlUtils;
import org.docx4j.jaxb.JAXBAssociation;
import org.docx4j.jaxb.JaxbValidationEventHandler;
import org.docx4j.jaxb.XPathBinderAssociationIsPartialException;
import org.docx4j.openpackaging.exceptions.Docx4JException;
import org.docx4j.openpackaging.exceptions.InvalidFormatException;
import org.docx4j.openpackaging.io3.stores.PartStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Node;
/**
* @author jharrop
* @since 2.8
*/
public abstract class JaxbXmlPartXPathAware extends JaxbXmlPart
implements XPathEnabled {
protected static Logger log = LoggerFactory.getLogger(JaxbXmlPartXPathAware.class);
public JaxbXmlPartXPathAware(PartName partName)
throws InvalidFormatException {
super(partName);
// TODO Auto-generated constructor stub
}
protected Binder binder;
/**
* Enables synchronization between XML infoset nodes and JAXB objects
* representing same XML document.
*
* An instance of this class maintains the association between XML nodes
* of an infoset preserving view and a JAXB representation of an XML document.
* Navigation between the two views is provided by the methods
* getXMLNode(Object) and getJAXBNode(Object) .
*
* In theory, modifications can be made to either the infoset preserving view or
* the JAXB representation of the document while the other view remains
* unmodified. The binder ought to be able to synchronize the changes made in
* the modified view back into the other view using the appropriate
* Binder update methods, #updateXML(Object, Object) or #updateJAXB(Object).
*
* But JAXB doesn't currently work as advertised .. access to this
* object is offered for advanced users on an experimental basis only.
*/
public Binder getBinder() {
if (jaxbElement == null) {
// Test jaxbElement, since we don't want to do the
// below if jaxbElement has already been set
// using setJaxbElement (which doesn't create
// binder)
PartStore partStore = this.getPackage().getSourcePartStore();
InputStream is = null;
try {
String name = this.getPartName().getName();
try {
this.setContentLengthAsLoaded(
partStore.getPartSize( name.substring(1)));
} catch (UnsupportedOperationException uoe) {}
is = partStore.loadPart(
name.substring(1));
if (is==null) {
log.warn(name + " missing from part store");
} else {
log.info("Lazily unmarshalling " + name);
unmarshal( is );
}
} catch (JAXBException e) {
log.error(e.getMessage(), e);
} catch (Docx4JException e) {
log.error(e.getMessage(), e);
} finally {
IOUtils.closeQuietly(is);
}
} else if (binder==null) {
// User might have set jaxb element, without creating a binder
try {
log.debug("creating binder for " + this.getJaxbElement().getClass().getName());
org.w3c.dom.Document doc = XmlUtils.neww3cDomDocument();
this.marshal(doc);
unmarshal( doc.getDocumentElement() );
} catch (JAXBException e) {
log.error(e.getMessage(), e);
}
}
return binder;
}
/** You can't use this override to create/update a binder, since this would set the
* jaxbElement field to something different to the object being passed in
* (as a consequence of the process to create a binder).
*
* We don't want that, because calling code may then continue to manipulate
* the field, without effect..
*
* See instead createBinderAndJaxbElement
*/
@Override
public void setJaxbElement(E jaxbElement) {
super.setJaxbElement(jaxbElement);
binder=null; // any existing binder is invalid
}
/**
* Set the JAXBElement for this part, and a corresponding
* binder, based on the object provided. Returns the new
* JAXBElement, so calling code can manipulate it. Beware
* that this object is different to the one passed in!
* @param source
* @return
* @throws JAXBException
* @since 3.0.0
*/
public E createBinderAndJaxbElement(E source) throws JAXBException {
// In order to create binder:-
log.info("creating binder");
org.w3c.dom.Document doc = XmlUtils.marshaltoW3CDomDocument(source);
unmarshal(doc.getDocumentElement());
// return the newly created object, so calling code can use it in place
// of their source object
return jaxbElement;
}
/**
* Fetch JAXB Nodes matching an XPath (for example "//w:p").
*
* If you have modified your JAXB objects (eg added or changed a
* w:p paragraph), you need to update the association. The problem
* is that this can only be done ONCE, owing to a bug in JAXB:
* see https://jaxb.dev.java.net/issues/show_bug.cgi?id=459
*
* So this is left for you to choose to do via the refreshXmlFirst parameter.
*
* @param xpathExpr
* @param refreshXmlFirst
* @return
* @throws JAXBException
* @throws XPathBinderAssociationIsPartialException
*/
public List