package com.cloudhopper.commons.xbean; /* * #%L * ch-commons-xbean * %% * Copyright (C) 2012 Cloudhopper by Twitter * %% * 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. * #L% */ // third party imports import java.net.MalformedURLException; import java.net.URL; import org.junit.*; import org.apache.log4j.Logger; // my imports /** * Tests that the XmlBean uses the runtime class of the object instead of the * declared type in the object. Allows inherited properties to be automatically * available for configuration even if the type is a "super class" as defined * in the object. * * @author joelauer */ public class XmlBeanRuntimeClassTest { private static final Logger logger = Logger.getLogger(XmlBeanRuntimeClassTest.class); @Test public void configureWithRuntimeClass() throws Exception { // build xml StringBuilder xml = new StringBuilder(200) // NOTE: leave out xml version on purpose since it should have // no effect on processing the configuration file //.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n") .append("<root>\n") // the type actually uses a factory to create a default instance // of the configuration object so that those properties are supported! .append(" <type>complex</type>\n") .append(" <configuration>\n") .append(" <port>80</port>\n") .append(" <host>www.google.com</host>\n") .append(" <url>http://www.google.com/</url>\n") .append(" </configuration>\n") .append("</root>") .append(""); // object we'll configure CombinedConfiguration config = new CombinedConfiguration(); // configure it using default options XmlBean bean = new XmlBean(); bean.configure(xml.toString(), config); // confirm properties Assert.assertEquals(ComplexConfiguration.class, config.config.getClass()); ComplexConfiguration complex = (ComplexConfiguration)config.config; Assert.assertEquals(80, complex.port); Assert.assertEquals("www.google.com", config.config.host); Assert.assertEquals("http://www.google.com/", config.config.url); } /** @Test public void configureWithTypeLastThrowsException() throws Exception { // build xml StringBuilder xml = new StringBuilder(200) // NOTE: leave out xml version on purpose since it should have // no effect on processing the configuration file //.append("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n") .append("<root>\n") .append(" <configuration>\n") .append(" <port>80</port>\n") .append(" <host>www.google.com</host>\n") .append(" <url>http://www.google.com/</url>\n") .append(" </configuration>\n") // the type has to be defined before the configuration would be .append(" <type>complex</type>\n") .append("</root>") .append(""); // object we'll configure CombinedConfiguration config = new CombinedConfiguration(); // configure it using default options XmlBean bean = new XmlBean(); bean.configure(xml.toString(), config); } */ public static class SimpleConfiguration { private String host; private String url; public SimpleConfiguration() { // do nothing } public void setHost(String value) throws MalformedURLException { this.host = value; } public void setUrl(String value) throws MalformedURLException { URL aURL = new URL(value); this.url = value; } } public static class ComplexConfiguration extends SimpleConfiguration { private int port; public ComplexConfiguration() { super(); } public void setPort(int value) throws ConfigurationException { if (value <= 0) { throw new ConfigurationException("Port must be > 0"); } this.port = value; } } public static class CombinedConfiguration { private String type; private SimpleConfiguration config; public CombinedConfiguration() { // do nothing } public void setType(String type) throws ConfigurationException { // based on the "type", create a default instance of the configuration // that will be used... if (type.equals("complex")) { this.config = new ComplexConfiguration(); } else if (type.equals("simple")) { this.config = new SimpleConfiguration(); } else { throw new ConfigurationException("Type '" + type + "' not supported"); } this.type = type; } public String getType() { return this.type; } public void setConfiguration(SimpleConfiguration config) throws ConfigurationException { // if "type" isn't set, then this can't be c if (this.type == null) { throw new ConfigurationException("Must set <type> before <configuration>"); } this.config = config; } public SimpleConfiguration getConfiguration() { return this.config; } } public static class ConfigurationException extends Exception { public ConfigurationException(String msg) { super(msg); } } }