1 /*******************************************************************************
2 * Copyright (c) 2012-2013 University of Stuttgart.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * and the Apache License 2.0 which both accompany this distribution,
6 * and are available at http://www.eclipse.org/legal/epl-v10.html
7 * and http://www.apache.org/licenses/LICENSE-2.0
10 * Oliver Kopp - initial API and implementation
11 *******************************************************************************/
12 package org.eclipse.winery.repository;
14 import javax.xml.bind.JAXBContext;
15 import javax.xml.bind.JAXBException;
16 import javax.xml.bind.Marshaller;
17 import javax.xml.bind.Unmarshaller;
19 import org.eclipse.winery.common.propertydefinitionkv.WinerysPropertiesDefinition;
20 import org.eclipse.winery.model.tosca.TDefinitions;
21 import org.eclipse.winery.repository.backend.MockXMLElement;
22 import org.eclipse.winery.repository.resources.admin.NamespacesResource;
23 import org.eclipse.winery.model.selfservice.Application;
24 import org.slf4j.Logger;
25 import org.slf4j.LoggerFactory;
27 import com.sun.xml.bind.marshaller.NamespacePrefixMapper;
29 // if com.sun.xml.bind.marshaller.NamespacePrefixMapper cannot be resolved,
31 // http://mvnrepository.com/artifact/com.googlecode.jaxb-namespaceprefixmapper-interfaces/JAXBNamespacePrefixMapper/2.2.4
33 // also com.sun.xml.internal.bind.marshaller.NamespacePrefixMapper could be the
37 * Bundles all general JAXB functionality
39 public class JAXBSupport {
41 private static final Logger logger = LoggerFactory.getLogger(JAXBSupport.class);
43 // thread-safe JAXB as inspired by https://jaxb.java.net/guide/Performance_and_thread_safety.html
44 // The other possibility: Each subclass sets JAXBContext.newInstance(theSubClass.class); in its static {} part.
45 // This seems to be more complicated than listing all subclasses in initContext
46 public final static JAXBContext context = JAXBSupport.initContext();
48 private final static PrefixMapper prefixMapper = new PrefixMapper();
53 * https://jaxb.java.net/2.2.5/docs/release-documentation.html#marshalling
56 * See http://www.jarvana.com/jarvana/view/com/sun/xml/bind/jaxb-impl/2.2.2/
57 * jaxb-impl-2.2.2-javadoc.jar!/com/sun/xml/bind/marshaller/
58 * NamespacePrefixMapper.html for a JavaDoc of the NamespacePrefixMapper
60 private static class PrefixMapper extends NamespacePrefixMapper {
63 public String getPreferredPrefix(String namespaceUri, String suggestion, boolean requirePrefix) {
64 if (namespaceUri.equals("")) {
68 // this does not work to get TOSCA elements without prefix
69 // possibly because the attribute "name" is present without prefix
70 // if (namespaceUri.equals(Namespaces.TOSCA_NAMESPACE)) {
74 String prefix = NamespacesResource.getPrefix(namespaceUri);
80 private static JAXBContext initContext() {
83 // For winery classes, eventually the package+jaxb.index method could be better. See http://stackoverflow.com/a/3628525/873282
85 context = JAXBContext.newInstance(
86 TDefinitions.class, // all other elements are referred by "@XmlSeeAlso"
87 WinerysPropertiesDefinition.class,
88 // for the self-service portal
90 // MockXMLElement is added for testing purposes only.
91 MockXMLElement.class);
93 } catch (JAXBException e) {
94 JAXBSupport.logger.error("Could not initialize JAXBContext", e);
95 throw new IllegalStateException(e);
101 * Creates a marshaller
103 * @throws IllegalStateException if marshaller could not be instantiated
105 public static Marshaller createMarshaller(boolean includeProcessingInstruction) {
108 m = JAXBSupport.context.createMarshaller();
109 // pretty printed output is required as the XML is sent 1:1 to the browser for editing
110 m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
111 m.setProperty("com.sun.xml.bind.namespacePrefixMapper", JAXBSupport.prefixMapper);
112 if (!includeProcessingInstruction) {
113 // side effect of JAXB_FRAGMENT property (when true): processing instruction is not included
114 m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
116 } catch (JAXBException e) {
117 JAXBSupport.logger.error("Could not instantiate marshaller", e);
118 throw new IllegalStateException(e);
125 * Creates an unmarshaller
127 * @throws IllegalStateException if unmarshaller could not be instantiated
129 public static Unmarshaller createUnmarshaller() {
131 return JAXBSupport.context.createUnmarshaller();
132 } catch (JAXBException e) {
133 JAXBSupport.logger.error("Could not instantiate unmarshaller", e);
134 throw new IllegalStateException(e);