use of org.glassfish.jaxb.core.v2.schemagen.episode.Bindings in project jaxb-ri by eclipse-ee4j.
the class PluginImpl method run.
/**
* Capture all the generated classes from global schema components
* and generate them in an episode file.
*/
@Override
public boolean run(Outline model, Options opt, ErrorHandler errorHandler) throws SAXException {
OutputStream episodeFileOutputStream = null;
try {
// reorganize qualifying components by their namespaces to
// generate the list nicely
Map<XSSchema, PerSchemaOutlineAdaptors> perSchema = new LinkedHashMap<>();
boolean hasComponentInNoNamespace = false;
// Combine classes and enums into a single list
List<OutlineAdaptor> outlines = new ArrayList<>();
for (ClassOutline co : model.getClasses()) {
XSComponent sc = co.target.getSchemaComponent();
String fullName = co.implClass.fullName();
String packageName = co.implClass.getPackage().name();
OutlineAdaptor adaptor = new OutlineAdaptor(sc, OutlineAdaptor.OutlineType.CLASS, fullName, packageName);
outlines.add(adaptor);
}
for (EnumOutline eo : model.getEnums()) {
XSComponent sc = eo.target.getSchemaComponent();
String fullName = eo.clazz.fullName();
String packageName = eo.clazz.getPackage().name();
OutlineAdaptor adaptor = new OutlineAdaptor(sc, OutlineAdaptor.OutlineType.ENUM, fullName, packageName);
outlines.add(adaptor);
}
for (OutlineAdaptor oa : outlines) {
XSComponent sc = oa.schemaComponent;
if (sc == null)
continue;
if (!(sc instanceof XSDeclaration))
continue;
XSDeclaration decl = (XSDeclaration) sc;
if (decl.isLocal())
// local components cannot be referenced from outside, so no need to list.
continue;
PerSchemaOutlineAdaptors list = perSchema.get(decl.getOwnerSchema());
if (list == null) {
list = new PerSchemaOutlineAdaptors();
perSchema.put(decl.getOwnerSchema(), list);
}
list.add(oa);
if (decl.getTargetNamespace().equals(""))
hasComponentInNoNamespace = true;
}
episodeFileOutputStream = new FileOutputStream(episodeFile);
Bindings bindings = TXW.create(Bindings.class, new StreamSerializer(episodeFileOutputStream, "UTF-8"));
if (// otherwise jaxb binding NS should be the default namespace
hasComponentInNoNamespace)
bindings._namespace(Const.JAXB_NSURI, "jaxb");
else
bindings._namespace(Const.JAXB_NSURI, "");
bindings.version("3.0");
bindings._comment("\n\n" + opt.getPrologComment() + "\n ");
// generate listing per schema
for (Map.Entry<XSSchema, PerSchemaOutlineAdaptors> e : perSchema.entrySet()) {
PerSchemaOutlineAdaptors ps = e.getValue();
Bindings group = bindings.bindings();
String tns = e.getKey().getTargetNamespace();
if (!tns.equals(""))
group._namespace(tns, "tns");
group.scd("x-schema::" + (tns.equals("") ? "" : "tns"));
SchemaBindings schemaBindings = group.schemaBindings();
schemaBindings.map(false);
if (ps.packageNames.size() == 1) {
final String packageName = ps.packageNames.iterator().next();
if (packageName != null && packageName.length() > 0) {
schemaBindings._package().name(packageName);
}
}
for (OutlineAdaptor oa : ps.outlineAdaptors) {
Bindings child = group.bindings();
oa.buildBindings(child);
}
group.commit(true);
}
bindings.commit();
return true;
} catch (IOException e) {
errorHandler.error(new SAXParseException("Failed to write to " + episodeFile, null, e));
return false;
} finally {
if (episodeFileOutputStream != null) {
try {
episodeFileOutputStream.close();
} catch (IOException e) {
errorHandler.error(new SAXParseException("Failed to close file handle for " + episodeFile, null, e));
}
}
}
}
use of org.glassfish.jaxb.core.v2.schemagen.episode.Bindings in project jaxb-ri by eclipse-ee4j.
the class Internalizer method buildTargetNodeMap.
/**
* Determines the target node of the "bindings" element
* by using the inherited target node, then put
* the result into the "result" map and the "scd" map.
*
* @param inheritedTarget
* The current target node. This always exists, even if
* the user starts specifying targets via SCD (in that case
* this inherited target is just not going to be used.)
* @param inheritedSCD
* If the ancestor {@code <bindings>} node specifies @scd to
* specify the target via SCD, then this parameter represents that context.
*/
private void buildTargetNodeMap(Element bindings, @NotNull Node inheritedTarget, @Nullable SCDBasedBindingSet.Target inheritedSCD, Map<Element, List<Node>> result, SCDBasedBindingSet scdResult) {
// start by the inherited target
Node target = inheritedTarget;
ArrayList<Node> targetMultiple = null;
// validate this node ?
// validate(bindings);
boolean required = true;
boolean multiple = false;
if (bindings.getAttribute("required") != null) {
String requiredAttr = bindings.getAttribute("required");
if (requiredAttr.equals("no") || requiredAttr.equals("false") || requiredAttr.equals("0"))
required = false;
}
if (bindings.getAttribute("multiple") != null) {
String requiredAttr = bindings.getAttribute("multiple");
if (requiredAttr.equals("yes") || requiredAttr.equals("true") || requiredAttr.equals("1"))
multiple = true;
}
// look for @schemaLocation
if (bindings.getAttributeNode("schemaLocation") != null) {
String schemaLocation = bindings.getAttribute("schemaLocation");
// enhancement - schemaLocation="*" = bind to all schemas..
if (schemaLocation.equals("*")) {
for (String systemId : forest.listSystemIDs()) {
result.computeIfAbsent(bindings, k -> new ArrayList<>());
result.get(bindings).add(forest.get(systemId).getDocumentElement());
Element[] children = DOMUtils.getChildElements(bindings, Const.JAXB_NSURI, "bindings");
for (Element value : children) buildTargetNodeMap(value, forest.get(systemId).getDocumentElement(), inheritedSCD, result, scdResult);
}
return;
} else {
try {
// TODO: use the URI class
// TODO: honor xml:base
URL loc = new URL(new URL(forest.getSystemId(bindings.getOwnerDocument())), schemaLocation);
schemaLocation = loc.toExternalForm();
target = forest.get(schemaLocation);
if ((target == null) && (loc.getProtocol().startsWith("file"))) {
File f = new File(loc.getFile());
schemaLocation = new File(f.getCanonicalPath()).toURI().toString();
}
} catch (MalformedURLException e) {
} catch (IOException e) {
Logger.getLogger(Internalizer.class.getName()).log(Level.FINEST, e.getLocalizedMessage());
}
target = forest.get(schemaLocation);
if (target == null) {
reportError(bindings, Messages.format(Messages.ERR_INCORRECT_SCHEMA_REFERENCE, schemaLocation, EditDistance.findNearest(schemaLocation, forest.listSystemIDs())));
// abort processing this <jaxb:bindings>
return;
}
target = ((Document) target).getDocumentElement();
}
}
// look for @node
if (bindings.getAttributeNode("node") != null) {
String nodeXPath = bindings.getAttribute("node");
// evaluate this XPath
NodeList nlst;
try {
xpath.setNamespaceContext(new NamespaceContextImpl(bindings));
nlst = (NodeList) xpath.evaluate(nodeXPath, target, XPathConstants.NODESET);
} catch (XPathExpressionException e) {
if (required) {
reportError(bindings, Messages.format(Messages.ERR_XPATH_EVAL, e.getMessage()), e);
// abort processing this <jaxb:bindings>
return;
} else {
return;
}
}
if (nlst.getLength() == 0) {
if (required)
reportError(bindings, Messages.format(Messages.NO_XPATH_EVAL_TO_NO_TARGET, nodeXPath));
// abort
return;
}
if (nlst.getLength() != 1) {
if (!multiple) {
reportError(bindings, Messages.format(Messages.NO_XPATH_EVAL_TOO_MANY_TARGETS, nodeXPath, nlst.getLength()));
// abort
return;
} else {
if (targetMultiple == null)
targetMultiple = new ArrayList<>();
for (int i = 0; i < nlst.getLength(); i++) {
targetMultiple.add(nlst.item(i));
}
}
}
// check
if (!multiple || nlst.getLength() == 1) {
Node rnode = nlst.item(0);
if (!(rnode instanceof Element)) {
reportError(bindings, Messages.format(Messages.NO_XPATH_EVAL_TO_NON_ELEMENT, nodeXPath));
// abort
return;
}
if (!forest.logic.checkIfValidTargetNode(forest, bindings, (Element) rnode)) {
reportError(bindings, Messages.format(Messages.XPATH_EVAL_TO_NON_SCHEMA_ELEMENT, nodeXPath, rnode.getNodeName()));
// abort
return;
}
target = rnode;
} else {
for (Node rnode : targetMultiple) {
if (!(rnode instanceof Element)) {
reportError(bindings, Messages.format(Messages.NO_XPATH_EVAL_TO_NON_ELEMENT, nodeXPath));
// abort
return;
}
if (!forest.logic.checkIfValidTargetNode(forest, bindings, (Element) rnode)) {
reportError(bindings, Messages.format(Messages.XPATH_EVAL_TO_NON_SCHEMA_ELEMENT, nodeXPath, rnode.getNodeName()));
// abort
return;
}
}
}
}
// look for @scd
if (bindings.getAttributeNode("scd") != null) {
String scdPath = bindings.getAttribute("scd");
if (!enableSCD) {
// SCD selector was found, but it's not activated. report an error
// but recover by handling it anyway. this also avoids repeated error messages.
reportError(bindings, Messages.format(Messages.SCD_NOT_ENABLED));
enableSCD = true;
}
try {
inheritedSCD = scdResult.createNewTarget(inheritedSCD, bindings, SCD.create(scdPath, new NamespaceContextImpl(bindings)));
} catch (ParseException e) {
reportError(bindings, Messages.format(Messages.ERR_SCD_EVAL, e.getMessage()), e);
// abort processing this bindings
return;
}
}
// update the result map
if (inheritedSCD != null) {
inheritedSCD.addBinidng(bindings);
} else if (!multiple || targetMultiple == null) {
result.computeIfAbsent(bindings, k -> new ArrayList<>());
result.get(bindings).add(target);
} else {
for (Node rnode : targetMultiple) {
result.computeIfAbsent(bindings, k -> new ArrayList<>());
result.get(bindings).add(rnode);
}
}
// look for child <jaxb:bindings> and process them recursively
Element[] children = DOMUtils.getChildElements(bindings, Const.JAXB_NSURI, "bindings");
for (Element value : children) if (!multiple || targetMultiple == null)
buildTargetNodeMap(value, target, inheritedSCD, result, scdResult);
else {
for (Node rnode : targetMultiple) {
buildTargetNodeMap(value, rnode, inheritedSCD, result, scdResult);
}
}
}
use of org.glassfish.jaxb.core.v2.schemagen.episode.Bindings in project jaxb-ri by eclipse-ee4j.
the class XmlSchemaGenerator method writeEpisodeFile.
/**
* Writes out the episode file.
*/
public void writeEpisodeFile(XmlSerializer out) {
Bindings root = TXW.create(Bindings.class, out);
if (// otherwise jaxb binding NS should be the default namespace
namespaces.containsKey(""))
root._namespace(WellKnownNamespace.JAXB, "jaxb");
root.version("2.1");
// generate listing per schema
for (Map.Entry<String, Namespace> e : namespaces.entrySet()) {
Bindings group = root.bindings();
String prefix;
String tns = e.getKey();
if (!tns.equals("")) {
group._namespace(tns, "tns");
prefix = "tns:";
} else {
prefix = "";
}
group.scd("x-schema::" + (tns.equals("") ? "" : "tns"));
group.schemaBindings().map(false);
for (ClassInfo<T, C> ci : e.getValue().classes) {
// local type
if (ci.getTypeName() == null)
continue;
if (ci.getTypeName().getNamespaceURI().equals(tns)) {
Bindings child = group.bindings();
child.scd('~' + prefix + ci.getTypeName().getLocalPart());
child.klass().ref(ci.getName());
}
if (ci.isElement() && ci.getElementName().getNamespaceURI().equals(tns)) {
Bindings child = group.bindings();
child.scd(prefix + ci.getElementName().getLocalPart());
child.klass().ref(ci.getName());
}
}
for (EnumLeafInfo<T, C> en : e.getValue().enums) {
// local type
if (en.getTypeName() == null)
continue;
Bindings child = group.bindings();
child.scd('~' + prefix + en.getTypeName().getLocalPart());
child.klass().ref(navigator.getClassName(en.getClazz()));
}
group.commit(true);
}
root.commit();
}
Aggregations