/* * JBoss, Home of Professional Open Source * Copyright 2011 Red Hat Inc. and/or its affiliates and other contributors * as indicated by the @authors tag. All rights reserved. * See the copyright.txt in the distribution for a * full listing of individual contributors. * * 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.jboss.arquillian.config.impl.extension; import java.util.HashSet; import java.util.Map.Entry; import java.util.Properties; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org.jboss.arquillian.config.descriptor.api.ArquillianDescriptor; /** * Add/Override arquillian.xml based on SystemProperties. * <p> * arq.container.[qualifier].mode * arq.container.[qualifier].default * arq.container.[qualifier].configuration.[property_name] * arq.container.[qualifier].protocol.[type].[property_name] * <p> * arq.group.[qualifier].default * arq.group.[qualifier].container.[qualifier].configuration.[property_name] * arq.group.[qualifier].container.[qualifier].protocol.[type].[property_name] * <p> * arq.extension.[qualifier].[property_name] * <p> * arq.defaultprotocol.[type] * arq.defaultprotocol.[type].[property_name] * <p> * arq.engine.[property_name] * * @author <a href="mailto:aslak@redhat.com">Aslak Knutsen</a> * @version $Revision: $ */ public class PropertiesParser { private static String ARQ_PROPERTY = "arq\\..*"; private static String ARQ_ENGINE_PROPERTY = "arq\\.engine\\.(.*)"; private static String ARQ_CONTAINER = "arq\\.container\\.(.*)\\.(.*)"; private static String ARQ_CONTAINER_CONFIGURATION = "arq\\.container\\.(.*)\\.configuration\\.(.*)"; private static String ARQ_CONTAINER_PROTOCOL = "arq\\.container\\.(.*)\\.protocol\\.(.*)\\.(.*)"; private static String ARQ_GROUP = "arq\\.group\\.(.*)\\.(.*)"; private static String ARQ_GROUP_CONTAINER = "arq\\.group\\.(.*)\\.container\\.(.*)\\.(.*)"; private static String ARQ_GROUP_CONTAINER_CONFIGURATION = "arq\\.group\\.(.*)\\.container\\.(.*)\\.configuration\\.(.*)"; private static String ARQ_GROUP_CONTAINER_PROTOCOL = "arq\\.group\\.(.*)\\.container\\.(.*)\\.protocol\\.(.*)\\.(.*)"; private static String ARQ_DEFAULT_PROTOCOL = "arq\\.defaultprotocol\\.(.*)\\.(.*)"; private static String ARQ_EXTENSION = "arq\\.extension\\.(.*)\\.(.*)"; private Handler[] handlers = new Handler[] { new EngineProperty(ARQ_ENGINE_PROPERTY), new ContainerConfiguration(ARQ_CONTAINER_CONFIGURATION), new ContainerProtocol(ARQ_CONTAINER_PROTOCOL), new Container(ARQ_CONTAINER), new Extension(ARQ_EXTENSION), new GroupContainerConfiguration(ARQ_GROUP_CONTAINER_CONFIGURATION), new GroupContainerProtocol(ARQ_GROUP_CONTAINER_PROTOCOL), new GroupContainer(ARQ_GROUP_CONTAINER), new Group(ARQ_GROUP), new DefaultProtocol(ARQ_DEFAULT_PROTOCOL) }; public void addProperties(ArquillianDescriptor descriptor, Properties properties) { if (descriptor == null) { throw new IllegalArgumentException("Descriptor must be specified"); } if (properties == null) { throw new IllegalArgumentException("Properties must be specified"); } Set<Entry<Object, Object>> filteredProps = filterProperties(properties); for (Entry<Object, Object> entry : filteredProps) { for (Handler handler : handlers) { if (handler.handle(String.valueOf(entry.getKey()), String.valueOf(entry.getValue()), descriptor)) { break; } } } } private Set<Entry<Object, Object>> filterProperties(Properties properties) { Set<Entry<Object, Object>> filtered = new HashSet<Entry<Object, Object>>(); for (Entry<Object, Object> entry : properties.entrySet()) { if (String.valueOf(entry.getKey()).matches(ARQ_PROPERTY)) { filtered.add(entry); } } return filtered; } /******************************* * * Handlers * *******************************/ private class DefaultProtocol extends Handler { public DefaultProtocol(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String typeName = matcher.group(1); String propertyName = matcher.group(2); descriptor.defaultProtocol(typeName).property(propertyName, value); } } private class Group extends Handler { public Group(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String groupName = matcher.group(1); String attributeName = matcher.group(2); if ("default".equals(attributeName)) { descriptor.group(groupName).setGroupDefault(); } else { throw new RuntimeException( "Unknown arquillian container attribute[" + attributeName + "] with value[" + value + "]"); } } } private class GroupContainer extends Handler { public GroupContainer(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String groupName = matcher.group(1); String containerName = matcher.group(2); String attributeName = matcher.group(3); if ("mode".equals(attributeName)) { descriptor.group(groupName).container(containerName).setMode(value); } else if ("default".equals(attributeName)) { descriptor.group(groupName).container(containerName).setDefault(); } else { throw new RuntimeException( "Unknown arquillian container attribute[" + attributeName + "] with value[" + value + "]"); } } } private class GroupContainerProtocol extends Handler { public GroupContainerProtocol(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String groupName = matcher.group(1); String containerName = matcher.group(2); String protocolName = matcher.group(3); String propertyName = matcher.group(4); descriptor.group(groupName).container(containerName).protocol(protocolName).property(propertyName, value); } } private class GroupContainerConfiguration extends Handler { public GroupContainerConfiguration(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String groupName = matcher.group(1); String containerName = matcher.group(2); String propertyName = matcher.group(3); descriptor.group(groupName).container(containerName).property(propertyName, value); } } private class Extension extends Handler { public Extension(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String extensionName = matcher.group(1); String propertyName = matcher.group(2); descriptor.extension(extensionName).property(propertyName, value); } } private class Container extends Handler { public Container(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String containerName = matcher.group(1); String attributeName = matcher.group(2); if ("mode".equals(attributeName)) { descriptor.container(containerName).setMode(value); } else if ("default".equals(attributeName)) { descriptor.container(containerName).setDefault(); } else { throw new RuntimeException( "Unknown arquillian container attribute[" + attributeName + "] with value[" + value + "]"); } } } private class ContainerProtocol extends Handler { public ContainerProtocol(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String containerName = matcher.group(1); String protocolName = matcher.group(2); String propertyName = matcher.group(3); descriptor.container(containerName).protocol(protocolName).property(propertyName, value); } } private class ContainerConfiguration extends Handler { public ContainerConfiguration(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String containerName = matcher.group(1); String propertyName = matcher.group(2); descriptor.container(containerName).property(propertyName, value); } } private class EngineProperty extends Handler { public EngineProperty(String expression) { super(expression); } @Override protected void handle(Matcher matcher, String value, ArquillianDescriptor descriptor) { String propertyName = matcher.group(1); if ("deploymentExportPath".equals(propertyName)) { descriptor.engine().deploymentExportPath(value); } else if ("maxTestClassesBeforeRestart".equals(propertyName)) { descriptor.engine().maxTestClassesBeforeRestart(Integer.parseInt(value)); } else { throw new RuntimeException( "Unknown arquillian engine property[" + propertyName + "] with value[" + value + "]"); } } } private abstract class Handler { private Pattern expression; public Handler(String expression) { this.expression = Pattern.compile(expression); } public boolean handle(String propertyName, String value, ArquillianDescriptor descriptor) { Matcher matcher = expression.matcher(propertyName); if (matcher.matches()) { handle(matcher, value, descriptor); return true; } return false; } protected abstract void handle(Matcher matcher, String value, ArquillianDescriptor descriptor); } }