/*
* ModeShape (http://www.modeshape.org)
*
* 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.modeshape.jboss.subsystem;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.stream.XMLStreamConstants;
import javax.xml.stream.XMLStreamException;
import org.jboss.as.controller.ListAttributeDefinition;
import org.jboss.as.controller.persistence.SubsystemMarshallingContext;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;
import org.jboss.staxmapper.XMLElementWriter;
import org.jboss.staxmapper.XMLExtendedStreamWriter;
/**
* XML writer for current ModeShape subsystem schema version.
*/
public class ModeShapeSubsystemXMLWriter implements XMLStreamConstants, XMLElementWriter<SubsystemMarshallingContext> {
@Override
public void writeContent( XMLExtendedStreamWriter writer,
SubsystemMarshallingContext context ) throws XMLStreamException {
context.startSubsystemElement(Namespace.CURRENT.getUri(), false);
ModelNode model = context.getModelNode();
if (model.isDefined()) {
if (model.hasDefined(ModelKeys.REPOSITORY)) {
for (Property entry : model.get(ModelKeys.REPOSITORY).asPropertyList()) {
String repositoryName = entry.getName();
ModelNode repository = entry.getValue();
writeRepositoryConfiguration(writer, repository, repositoryName);
}
}
if (model.hasDefined(ModelKeys.WEBAPP)) {
for (Property entry : model.get(ModelKeys.WEBAPP).asPropertyList()) {
String webappName = entry.getName();
ModelNode webapp = entry.getValue();
writeWebAppConfiguration(writer, webapp, webappName);
}
}
}
writer.writeEndElement(); // End of subsystem element
}
private void writeWebAppConfiguration( XMLExtendedStreamWriter writer,
ModelNode webapp,
String repositoryName ) throws XMLStreamException {
writer.writeStartElement(Element.WEBAPP.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), repositoryName);
ModelAttributes.EXPLODED.marshallAsAttribute(webapp, false, writer);
writer.writeEndElement();
}
private void writeRepositoryConfiguration( XMLExtendedStreamWriter writer,
ModelNode repository,
String repositoryName ) throws XMLStreamException {
writer.writeStartElement(Element.REPOSITORY.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), repositoryName);
// Repository attributes ...
ModelAttributes.JNDI_NAME.marshallAsAttribute(repository, false, writer);
ModelAttributes.ENABLE_MONITORING.marshallAsAttribute(repository, false, writer);
ModelAttributes.SECURITY_DOMAIN.marshallAsAttribute(repository, false, writer);
ModelAttributes.CLUSTER_NAME.marshallAsAttribute(repository, false, writer);
ModelAttributes.CLUSTER_STACK.marshallAsAttribute(repository, false, writer);
ModelAttributes.CLUSTER_CONFIG.marshallAsAttribute(repository, false, writer);
ModelAttributes.CLUSTER_LOCKING.marshallAsAttribute(repository, false, writer);
writeAttributeAsList(writer, repository, ModelAttributes.ANONYMOUS_ROLES);
ModelAttributes.ANONYMOUS_USERNAME.marshallAsAttribute(repository, false, writer);
ModelAttributes.USE_ANONYMOUS_IF_AUTH_FAILED.marshallAsAttribute(repository, false, writer);
ModelAttributes.GARBAGE_COLLECTION_THREAD_POOL.marshallAsAttribute(repository, false, writer);
ModelAttributes.GARBAGE_COLLECTION_INITIAL_TIME.marshallAsAttribute(repository, false, writer);
ModelAttributes.GARBAGE_COLLECTION_INTERVAL.marshallAsAttribute(repository, false, writer);
ModelAttributes.DOCUMENT_OPTIMIZATION_THREAD_POOL.marshallAsAttribute(repository, false, writer);
ModelAttributes.DOCUMENT_OPTIMIZATION_INITIAL_TIME.marshallAsAttribute(repository, false, writer);
ModelAttributes.DOCUMENT_OPTIMIZATION_INTERVAL.marshallAsAttribute(repository, false, writer);
ModelAttributes.DOCUMENT_OPTIMIZATION_CHILD_COUNT_TARGET.marshallAsAttribute(repository, false, writer);
ModelAttributes.DOCUMENT_OPTIMIZATION_CHILD_COUNT_TOLERANCE.marshallAsAttribute(repository, false, writer);
ModelAttributes.EVENT_BUS_SIZE.marshallAsAttribute(repository, false, writer);
ModelAttributes.LOCK_TIMEOUT_MILLIS.marshallAsAttribute(repository, false, writer);
ModelAttributes.REPOSITORY_MODULE_DEPENDENCIES.marshallAsAttribute(repository, false, writer);
// Nested elements ...
writePersistence(writer, repository);
writeNodeTypes(writer, repository);
writeWorkspaces(writer, repository);
writeJournaling(writer, repository);
writeAuthenticators(writer, repository);
writeIndexProviders(writer, repository);
writeIndexes(writer, repository);
writeReindexing(writer, repository);
writeBinaryStorage(writer, repository);
writeSequencing(writer, repository);
writeExternalSources(writer, repository);
writeTextExtraction(writer, repository);
writer.writeEndElement();
}
private void writePersistence(XMLExtendedStreamWriter writer, ModelNode repository) throws XMLStreamException {
String dbPersistence = Attribute.DB_PERSISTENCE.getLocalName();
if (has(repository, dbPersistence)) {
startIfNeeded(writer, Element.DB_PERSISTENCE, false);
ModelNode persistence = repository.get(dbPersistence).get(dbPersistence);
ModelAttributes.TABLE_NAME.marshallAsAttribute(persistence, false, writer);
ModelAttributes.CREATE_ON_START.marshallAsAttribute(persistence, false, writer);
ModelAttributes.DROP_ON_EXIT.marshallAsAttribute(persistence, false, writer);
ModelAttributes.CONNECTION_URL.marshallAsAttribute(persistence, false, writer);
ModelAttributes.DRIVER.marshallAsAttribute(persistence, false, writer);
ModelAttributes.USERNAME.marshallAsAttribute(persistence, false, writer);
ModelAttributes.PASSWORD.marshallAsAttribute(persistence, false, writer);
ModelAttributes.DB_COMPRESS.marshallAsAttribute(persistence, false, writer);
ModelAttributes.FETCH_SIZE.marshallAsAttribute(persistence, false, writer);
ModelAttributes.POOL_SIZE.marshallAsAttribute(persistence, false, writer);
ModelAttributes.PERSISTENCE_DS_JNDI_NAME.marshallAsAttribute(persistence, false, writer);
// Write out any extra properties ...
if (has(persistence, ModelKeys.PROPERTIES)) {
ModelNode properties = persistence.get(ModelKeys.PROPERTIES);
for (Property property : properties.asPropertyList()) {
writer.writeAttribute(property.getName(), property.getValue().asString());
}
}
writer.writeEndElement();
}
String filePersistence = Attribute.FS_PERSISTENCE.getLocalName();
if (has(repository, filePersistence)) {
startIfNeeded(writer, Element.FILE_PERSISTENCE, false);
ModelNode persistence = repository.get(filePersistence).get(filePersistence);
ModelAttributes.FS_PATH.marshallAsAttribute(persistence, false, writer);
ModelAttributes.FS_COMPRESS.marshallAsAttribute(persistence, false, writer);
writer.writeEndElement();
}
}
private void writeNodeTypes( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
boolean started = false;
if (has(repository, ModelKeys.NODE_TYPES)) {
started = startIfNeeded(writer, Element.NODE_TYPES, started);
List<ModelNode> nodeTypes = repository.get(ModelKeys.NODE_TYPES).asList();
for (ModelNode nodeType : nodeTypes) {
writer.writeStartElement(Element.NODE_TYPE.getLocalName());
writer.writeCharacters(nodeType.asString());
writer.writeEndElement();
}
writer.writeEndElement();
}
}
private void writeWorkspaces( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
boolean started = false;
// Write these model attributes of 'repository' onto the 'workspaces' XML element ...
if (ModelAttributes.DEFAULT_WORKSPACE.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.WORKSPACES, started);
ModelAttributes.DEFAULT_WORKSPACE.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.ALLOW_WORKSPACE_CREATION.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.WORKSPACES, started);
ModelAttributes.ALLOW_WORKSPACE_CREATION.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.WORKSPACES_CACHE_SIZE.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.WORKSPACES, started);
ModelAttributes.WORKSPACES_CACHE_SIZE.marshallAsAttribute(repository, writer);
}
if (has(repository, ModelKeys.PREDEFINED_WORKSPACE_NAMES)) {
started = startIfNeeded(writer, Element.WORKSPACES, started);
ModelNode names = repository.get(ModelKeys.PREDEFINED_WORKSPACE_NAMES);
if (names.isDefined()) {
Map<String, String> workspacesInitialContent = new HashMap<String, String>();
if (has(repository, ModelKeys.WORKSPACES_INITIAL_CONTENT)) {
List<ModelNode> initialContentNodes = repository.get(ModelKeys.WORKSPACES_INITIAL_CONTENT).asList();
for (ModelNode modelNode : initialContentNodes) {
Property property = modelNode.asProperty();
workspacesInitialContent.put(property.getName(), property.getValue().asString());
}
}
for (ModelNode workspace : repository.get(ModelKeys.PREDEFINED_WORKSPACE_NAMES).asList()) {
writer.writeStartElement(Element.WORKSPACE.getLocalName());
String name = workspace.asString();
writer.writeAttribute(Attribute.NAME.getLocalName(), name);
if (workspacesInitialContent.containsKey(name)) {
writer.writeStartElement(Element.INITIAL_CONTENT.getLocalName());
writer.writeCharacters(workspacesInitialContent.get(name));
writer.writeEndElement();
}
writer.writeEndElement();
}
}
}
if (has(repository, ModelKeys.DEFAULT_INITIAL_CONTENT)) {
started = startIfNeeded(writer, Element.WORKSPACES, started);
writer.writeStartElement(Element.INITIAL_CONTENT.getLocalName());
writer.writeCharacters(repository.get(ModelKeys.DEFAULT_INITIAL_CONTENT).asString());
writer.writeEndElement();
}
if (started) {
writer.writeEndElement();
}
}
private void writeReindexing( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
boolean started = false;
// Write these model attributes of 'repository' onto the 'reindexing' XML element ...
if (ModelAttributes.REINDEXING_ASYNC.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.REINDEXIG, started);
ModelAttributes.REINDEXING_ASYNC.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.REINDEXING_MODE.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.REINDEXIG, started);
ModelAttributes.REINDEXING_MODE.marshallAsAttribute(repository, writer);
}
if (started) {
writer.writeEndElement();
}
}
private void writeJournaling( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
boolean started = false;
// Write these model attributes of 'repository' onto the 'journaling' XML element ...
if (ModelAttributes.JOURNAL_ENABLED.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.JOURNALING, started);
ModelAttributes.JOURNAL_ENABLED.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.JOURNAL_PATH.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.JOURNALING, started);
ModelAttributes.JOURNAL_PATH.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.JOURNAL_RELATIVE_TO.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.JOURNALING, started);
ModelAttributes.JOURNAL_RELATIVE_TO.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.MAX_DAYS_TO_KEEP_RECORDS.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.JOURNALING, started);
ModelAttributes.MAX_DAYS_TO_KEEP_RECORDS.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.ASYNC_WRITES.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.JOURNALING, started);
ModelAttributes.ASYNC_WRITES.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.JOURNAL_GC_INITIAL_TIME.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.JOURNALING, started);
ModelAttributes.JOURNAL_GC_INITIAL_TIME.marshallAsAttribute(repository, writer);
}
if (ModelAttributes.JOURNAL_GC_THREAD_POOL.isMarshallable(repository, false)) {
started = startIfNeeded(writer, Element.JOURNALING, started);
ModelAttributes.JOURNAL_GC_THREAD_POOL.marshallAsAttribute(repository, writer);
}
if (started) {
writer.writeEndElement();
}
}
private boolean startIfNeeded( XMLExtendedStreamWriter writer,
Element name,
boolean alreadyStarted ) throws XMLStreamException {
if (!alreadyStarted) {
writer.writeStartElement(name.getLocalName());
}
return true;
}
private void writeBinaryStorage( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
if (has(repository, ModelKeys.CONFIGURATION, ModelKeys.BINARY_STORAGE)) {
ModelNode configuration = repository.get(ModelKeys.CONFIGURATION);
ModelNode binaryStorage = configuration.get(ModelKeys.BINARY_STORAGE);
ModelNode binaryStorageType = binaryStorage.get(ModelKeys.STORAGE_TYPE);
String storageType = binaryStorageType.isDefined() && binaryStorageType.keys().size() == 1 ? (String)binaryStorageType.keys()
.toArray()[0] : null;
ModelNode storage = storageType != null ? binaryStorageType.get((String)binaryStorageType.keys().toArray()[0]) : new ModelNode();
writeBinaryStorageModel(writer, storageType, storage);
}
}
private void writeBinaryStorageModel(XMLExtendedStreamWriter writer,
String storageType,
ModelNode storage) throws XMLStreamException {
if (ModelKeys.TRANSIENT_BINARY_STORAGE.equals(storageType)) {
writer.writeStartElement(Element.TRANSIENT_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
writer.writeEndElement();
} else if (ModelKeys.FILE_BINARY_STORAGE.equals(storageType)) {
// This is the default, but there is no default value for the ModelAttributes.PATH (which is required),
// which means we always have to write this out. If it is the default binary storage, then there
// won't even be a 'binary-storage=BINARIES' model node.
writer.writeStartElement(Element.FILE_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.PATH.marshallAsAttribute(storage, false, writer);
ModelAttributes.TRASH.marshallAsAttribute(storage, false, writer);
ModelAttributes.RELATIVE_TO.marshallAsAttribute(storage, false, writer);
ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
writer.writeEndElement();
} else if (ModelKeys.DB_BINARY_STORAGE.equals(storageType)) {
writer.writeStartElement(Element.DB_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.DATA_SOURCE_JNDI_NAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
writer.writeEndElement();
} else if (ModelKeys.CASSANDRA_BINARY_STORAGE.equals(storageType)) {
writer.writeStartElement(Element.CASSANDRA_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
ModelAttributes.CASSANDRA_HOST.marshallAsAttribute(storage, false, writer);
writer.writeEndElement();
} else if (ModelKeys.MONGO_BINARY_STORAGE.equals(storageType)) {
writer.writeStartElement(Element.MONGO_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
ModelAttributes.MONGO_HOST.marshallAsAttribute(storage, false, writer);
ModelAttributes.MONGO_PORT.marshallAsAttribute(storage, false, writer);
ModelAttributes.MONGO_DATABASE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MONGO_USERNAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.MONGO_PASSWORD.marshallAsAttribute(storage, false, writer);
ModelAttributes.MONGO_HOST_ADDRESSES.marshallAsAttribute(storage, false, writer);
writer.writeEndElement();
} else if (ModelKeys.S3_BINARY_STORAGE.equals(storageType)) {
writer.writeStartElement(Element.S3_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
ModelAttributes.S3_BUCKET_NAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.S3_USERNAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.S3_PASSWORD.marshallAsAttribute(storage, false, writer);
ModelAttributes.S3_ENDPOINT_URL.marshallAsAttribute(storage, false, writer);
writer.writeEndElement();
} else if (ModelKeys.COMPOSITE_BINARY_STORAGE.equals(storageType)) {
writer.writeStartElement(Element.COMPOSITE_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
writeNestedStoresOfType(storage, ModelKeys.NESTED_STORAGE_TYPE_FILE, ModelKeys.FILE_BINARY_STORAGE, writer);
writeNestedStoresOfType(storage, ModelKeys.NESTED_STORAGE_TYPE_DB, ModelKeys.DB_BINARY_STORAGE, writer);
writeNestedStoresOfType(storage, ModelKeys.NESTED_STORAGE_TYPE_CUSTOM, ModelKeys.CUSTOM_BINARY_STORAGE, writer);
writer.writeEndElement();
} else if (ModelKeys.CUSTOM_BINARY_STORAGE.equals(storageType)) {
writer.writeStartElement(Element.CUSTOM_BINARY_STORAGE.getLocalName());
ModelAttributes.MINIMUM_BINARY_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.MINIMUM_STRING_SIZE.marshallAsAttribute(storage, false, writer);
ModelAttributes.STORE_NAME.marshallAsAttribute(storage, false, writer);
ModelAttributes.MIME_TYPE_DETECTION.marshallAsAttribute(storage, false, writer);
List<String> toSkip = Arrays.asList(ModelKeys.MINIMUM_BINARY_SIZE, ModelKeys.MINIMUM_STRING_SIZE,
ModelKeys.STORE_NAME, ModelKeys.MIME_TYPE_DETECTION);
storage.keys().stream().filter(key -> !toSkip.contains(key)).forEach(key -> {
try {
switch (key) {
case ModelKeys.CLASSNAME:
ModelAttributes.CLASSNAME.marshallAsAttribute(storage, false, writer);
break;
case ModelKeys.MODULE:
ModelAttributes.MODULE.marshallAsAttribute(storage, false, writer);
break;
default:
writer.writeAttribute(key, storage.get(key).asString());
break;
}
} catch (XMLStreamException e) {
throw new RuntimeException(e);
}
});
writer.writeEndElement();
}
}
private void writeNestedStoresOfType( ModelNode storage,
String nestedStorageType,
String storeType,
XMLExtendedStreamWriter writer ) throws XMLStreamException {
if (has(storage, nestedStorageType)) {
List<ModelNode> nestedCacheStores = storage.get(nestedStorageType).asList();
for (ModelNode nestedStore : nestedCacheStores) {
String storeName = (String)nestedStore.keys().toArray()[0];
writeBinaryStorageModel(writer, storeType, nestedStore.get(storeName));
}
}
}
private void writeAuthenticators( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
if (has(repository, ModelKeys.AUTHENTICATOR)) {
writer.writeStartElement(Element.AUTHENTICATORS.getLocalName());
for (Property authenticator : repository.get(ModelKeys.AUTHENTICATOR).asPropertyList()) {
writer.writeStartElement(Element.AUTHENTICATOR.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), authenticator.getName());
ModelNode prop = authenticator.getValue();
ModelAttributes.AUTHENTICATOR_CLASSNAME.marshallAsAttribute(prop, writer);
ModelAttributes.MODULE.marshallAsAttribute(prop, writer);
// Write out the extra properties ...
if (has(prop, ModelKeys.PROPERTIES)) {
ModelNode properties = prop.get(ModelKeys.PROPERTIES);
for (Property property : properties.asPropertyList()) {
writer.writeAttribute(property.getName(), property.getValue().asString());
}
}
writer.writeEndElement();
}
writer.writeEndElement();
}
}
private void writeSequencing( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
if (has(repository, ModelKeys.SEQUENCER)) {
writer.writeStartElement(Element.SEQUENCERS.getLocalName());
if (repository.hasDefined(ModelKeys.SEQUENCERS_THREAD_POOL_NAME)) {
writer.writeAttribute(Attribute.THREAD_POOL_NAME.getLocalName(), repository.get(
ModelKeys.SEQUENCERS_THREAD_POOL_NAME).asString());
}
if (repository.hasDefined(ModelKeys.SEQUENCERS_MAX_POOL_SIZE)) {
writer.writeAttribute(Attribute.MAX_POOL_SIZE.getLocalName(), repository.get(ModelKeys.SEQUENCERS_MAX_POOL_SIZE)
.asString());
}
ModelNode sequencerNode = repository.get(ModelKeys.SEQUENCER);
for (Property sequencer : sequencerNode.asPropertyList()) {
writer.writeStartElement(Element.SEQUENCER.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), sequencer.getName());
ModelNode prop = sequencer.getValue();
ModelAttributes.SEQUENCER_CLASSNAME.marshallAsAttribute(prop, writer);
ModelAttributes.MODULE.marshallAsAttribute(prop, writer);
// Write out the extra properties ...
if (has(prop, ModelKeys.PROPERTIES)) {
ModelNode properties = prop.get(ModelKeys.PROPERTIES);
for (Property property : properties.asPropertyList()) {
writer.writeAttribute(property.getName(), property.getValue().asString());
}
}
if (has(prop, ModelKeys.PATH_EXPRESSIONS)) {
List<ModelNode> pathExpressions = prop.get(ModelKeys.PATH_EXPRESSIONS).asList();
switch (pathExpressions.size()) {
case 0:
break;
case 1:
ModelNode pathExpression = pathExpressions.iterator().next();
writer.writeAttribute(Attribute.PATH_EXPRESSION.getLocalName(), pathExpression.asString());
break;
default:
for (ModelNode pathExpr : pathExpressions) {
writer.writeStartElement(Element.PATH_EXPRESSION.getLocalName());
writer.writeCharacters(pathExpr.asString());
writer.writeEndElement();
}
}
}
writer.writeEndElement();
}
writer.writeEndElement();
}
}
private void writeIndexProviders( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
if (has(repository, ModelKeys.INDEX_PROVIDER)) {
writer.writeStartElement(Element.INDEX_PROVIDERS.getLocalName());
ModelNode providerNode = repository.get(ModelKeys.INDEX_PROVIDER);
for (Property provider : providerNode.asPropertyList()) {
writer.writeStartElement(Element.INDEX_PROVIDER.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), provider.getName());
ModelNode prop = provider.getValue();
ModelAttributes.CLASSNAME.marshallAsAttribute(prop, writer);
ModelAttributes.MODULE.marshallAsAttribute(prop, writer);
ModelAttributes.RELATIVE_TO.marshallAsAttribute(prop, writer);
ModelAttributes.PATH.marshallAsAttribute(prop, writer);
// Write out the extra properties ...
if (has(prop, ModelKeys.PROPERTIES)) {
ModelNode properties = prop.get(ModelKeys.PROPERTIES);
for (Property property : properties.asPropertyList()) {
writer.writeAttribute(property.getName(), property.getValue().asString());
}
}
writer.writeEndElement();
}
writer.writeEndElement();
}
}
private void writeIndexes( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
if (has(repository, ModelKeys.INDEX)) {
writer.writeStartElement(Element.INDEXES.getLocalName());
ModelNode providerNode = repository.get(ModelKeys.INDEX);
for (Property index : providerNode.asPropertyList()) {
writer.writeStartElement(Element.INDEX.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), index.getName());
ModelNode prop = index.getValue();
ModelAttributes.PROVIDER_NAME.marshallAsAttribute(prop, writer);
ModelAttributes.INDEX_KIND.marshallAsAttribute(prop, writer);
ModelAttributes.SYNCHRONOUS.marshallAsAttribute(prop, writer);
ModelAttributes.NODE_TYPE_NAME.marshallAsAttribute(prop, writer);
ModelAttributes.INDEX_COLUMNS.marshallAsAttribute(prop, writer);
ModelAttributes.WORKSPACES.marshallAsAttribute(prop, writer);
// Write out the extra properties ...
if (has(prop, ModelKeys.PROPERTIES)) {
ModelNode properties = prop.get(ModelKeys.PROPERTIES);
for (Property property : properties.asPropertyList()) {
writer.writeAttribute(property.getName(), property.getValue().asString());
}
}
writer.writeEndElement();
}
writer.writeEndElement();
}
}
private void writeExternalSources( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
if (has(repository, ModelKeys.SOURCE)) {
writer.writeStartElement(Element.EXTERNAL_SOURCES.getLocalName());
ModelNode externalSourceNode = repository.get(ModelKeys.SOURCE);
for (Property externalSource : externalSourceNode.asPropertyList()) {
writer.writeStartElement(Element.SOURCE.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), externalSource.getName());
ModelNode prop = externalSource.getValue();
ModelAttributes.CONNECTOR_CLASSNAME.marshallAsAttribute(prop, writer);
ModelAttributes.MODULE.marshallAsAttribute(prop, writer);
ModelAttributes.CACHEABLE.marshallAsAttribute(prop, writer);
ModelAttributes.QUERYABLE.marshallAsAttribute(prop, writer);
ModelAttributes.READONLY.marshallAsAttribute(prop, writer);
ModelAttributes.EXPOSE_AS_WORKSPACE.marshallAsAttribute(prop, writer);
// Write out the extra properties ...
if (has(prop, ModelKeys.PROPERTIES)) {
ModelNode properties = prop.get(ModelKeys.PROPERTIES);
for (Property property : properties.asPropertyList()) {
writer.writeAttribute(property.getName(), property.getValue().asString());
}
}
if (has(prop, ModelKeys.PROJECTIONS)) {
List<ModelNode> projections = prop.get(ModelKeys.PROJECTIONS).asList();
for (ModelNode projection : projections) {
writer.writeStartElement(Element.PROJECTION.getLocalName());
writer.writeCharacters(projection.asString());
writer.writeEndElement();
}
}
writer.writeEndElement();
}
writer.writeEndElement();
}
}
private void writeTextExtraction( XMLExtendedStreamWriter writer,
ModelNode repository ) throws XMLStreamException {
if (has(repository, ModelKeys.TEXT_EXTRACTOR)) {
writer.writeStartElement(Element.TEXT_EXTRACTORS.getLocalName());
if (repository.hasDefined(ModelKeys.TEXT_EXTRACTORS_THREAD_POOL_NAME)) {
writer.writeAttribute(Attribute.THREAD_POOL_NAME.getLocalName(), repository.get(
ModelKeys.TEXT_EXTRACTORS_THREAD_POOL_NAME).asString());
}
if (repository.hasDefined(ModelKeys.TEXT_EXTRACTORS_MAX_POOL_SIZE)) {
writer.writeAttribute(Attribute.MAX_POOL_SIZE.getLocalName(), repository.get(ModelKeys.TEXT_EXTRACTORS_MAX_POOL_SIZE)
.asString());
}
for (Property extractor : repository.get(ModelKeys.TEXT_EXTRACTOR).asPropertyList()) {
writer.writeStartElement(Element.TEXT_EXTRACTOR.getLocalName());
writer.writeAttribute(Attribute.NAME.getLocalName(), extractor.getName());
ModelNode prop = extractor.getValue();
ModelAttributes.TEXT_EXTRACTOR_CLASSNAME.marshallAsAttribute(prop, writer);
ModelAttributes.MODULE.marshallAsAttribute(prop, writer);
// Write out the extra properties ...
if (has(prop, ModelKeys.PROPERTIES)) {
ModelNode properties = prop.get(ModelKeys.PROPERTIES);
for (Property property : properties.asPropertyList()) {
writer.writeAttribute(property.getName(), property.getValue().asString());
}
}
writer.writeEndElement();
}
writer.writeEndElement();
}
}
private boolean has( ModelNode node,
String name ) {
return node.isDefined() && node.has(name) && node.get(name).isDefined();
}
private boolean has( ModelNode node,
String... names ) {
for (String name : names) {
if (!node.isDefined() || !node.has(name)) return false;
node = node.get(name);
}
return true;
}
private void writeAttributeAsList( XMLExtendedStreamWriter writer,
final ModelNode node,
final ListAttributeDefinition modelAttribute ) throws XMLStreamException {
if (modelAttribute.isMarshallable(node, false)) {
StringBuilder sb = new StringBuilder();
Iterator<ModelNode> iter = node.get(modelAttribute.getName()).asList().iterator();
if (iter.hasNext()) {
sb.append(iter.next().asString());
while (iter.hasNext()) {
sb.append(" ").append(iter.next().asString());
}
writer.writeAttribute(modelAttribute.getXmlName(), sb.toString());
}
}
}
}