/*
* JBoss, Home of Professional Open Source.
* Copyright 2011, Red Hat Middleware LLC, and individual contributors
* as indicated by the @author tags. See the copyright.txt file in the
* distribution for a full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.jboss.as.core.model.test;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executors;
import javax.xml.namespace.QName;
import javax.xml.stream.XMLStreamException;
import org.jboss.as.controller.RunningMode;
import org.jboss.as.controller.descriptions.ModelDescriptionConstants;
import org.jboss.as.controller.extension.ExtensionRegistry;
import org.jboss.as.controller.parsing.Namespace;
import org.jboss.as.controller.persistence.ModelMarshallingContext;
import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
import org.jboss.as.host.controller.parsing.DomainXml;
import org.jboss.as.host.controller.parsing.HostXml;
import org.jboss.as.model.test.ModelTestParser;
import org.jboss.as.server.parsing.StandaloneXml;
import org.jboss.dmr.ModelNode;
import org.jboss.staxmapper.XMLElementReader;
import org.jboss.staxmapper.XMLElementWriter;
import org.jboss.staxmapper.XMLExtendedStreamReader;
import org.jboss.staxmapper.XMLExtendedStreamWriter;
import org.jboss.staxmapper.XMLMapper;
/**
*
* @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
*/
public class TestParser implements ModelTestParser {
private final TestModelType type;
private final XMLElementReader<List<ModelNode>> reader;
private final XMLElementWriter<ModelMarshallingContext> writer;
private volatile List<ModelWriteSanitizer> writeSanitizers;
public TestParser(TestModelType type, XMLElementReader<List<ModelNode>> reader, XMLElementWriter<ModelMarshallingContext> writer) {
this.type = type;
this.reader = reader;
this.writer = writer;
}
public static TestParser create(ExtensionRegistry registry, XMLMapper xmlMapper, TestModelType type) {
TestParser testParser;
String root;
if (type == TestModelType.STANDALONE) {
StandaloneXml standaloneXml = new StandaloneXml(null, Executors.newCachedThreadPool(), registry);
testParser = new TestParser(type, standaloneXml, standaloneXml);
root = "server";
} else if (type == TestModelType.DOMAIN) {
DomainXml domainXml = new DomainXml(null, Executors.newCachedThreadPool(), registry);
testParser = new TestParser(type, domainXml, domainXml);
root = "domain";
} else if (type == TestModelType.HOST) {
HostXml hostXml = new HostXml("master", RunningMode.NORMAL, false, null, Executors.newCachedThreadPool(), registry);
testParser = new TestParser(type, hostXml, hostXml);
root = "host";
} else {
throw new IllegalArgumentException("Unknown type " + type);
}
try {
for (Namespace ns : Namespace.ALL_NAMESPACES) {
xmlMapper.registerRootElement(new QName(ns.getUriString(), root), testParser);
}
} catch (NoSuchFieldError e) {
//7.1.2 does not have the ALL_NAMESPACES field
xmlMapper.registerRootElement(new QName(Namespace.DOMAIN_1_0.getUriString(), root), testParser);
xmlMapper.registerRootElement(new QName(Namespace.DOMAIN_1_1.getUriString(), root), testParser);
xmlMapper.registerRootElement(new QName(Namespace.DOMAIN_1_2.getUriString(), root), testParser);
}
return testParser;
}
void addModelWriteSanitizer(ModelWriteSanitizer writeSanitizer) {
if (writeSanitizer == null) {
return;
}
if (writeSanitizers == null) {
writeSanitizers = new ArrayList<ModelWriteSanitizer>();
}
writeSanitizers.add(writeSanitizer);
}
@Override
public void readElement(XMLExtendedStreamReader reader, List<ModelNode> value) throws XMLStreamException {
this.reader.readElement(reader, value);
}
@Override
public void writeContent(XMLExtendedStreamWriter streamWriter, ModelMarshallingContext context) throws XMLStreamException {
this.writer.writeContent(streamWriter, sanitizeContext(wrapPossibleHost(context)));
}
private ModelMarshallingContext wrapPossibleHost(final ModelMarshallingContext context) {
if (type == TestModelType.HOST) {
return new ModelMarshallingContext() {
@Override
public XMLElementWriter<SubsystemMarshallingContext> getSubsystemWriter(String subsystemName) {
return context.getSubsystemWriter(subsystemName);
}
@Override
public ModelNode getModelNode() {
return context.getModelNode().get(ModelDescriptionConstants.HOST, "master");
}
};
}
return context;
}
private ModelMarshallingContext sanitizeContext(final ModelMarshallingContext context) {
if (writeSanitizers == null) {
return context;
}
ModelNode model = context.getModelNode();
for (ModelWriteSanitizer sanitizer : writeSanitizers) {
model = sanitizer.sanitize(model);
}
final ModelNode theModel = model;
return new ModelMarshallingContext() {
@Override
public XMLElementWriter<SubsystemMarshallingContext> getSubsystemWriter(String subsystemName) {
return context.getSubsystemWriter(subsystemName);
}
@Override
public ModelNode getModelNode() {
return theModel;
}
};
}
}