1 /* 2 * Copyright 2012-2013 smartics, Kronseder & Reiner GmbH 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package de.smartics.properties.spi.config.proxy; 17 18 import de.smartics.properties.api.config.domain.SerializableConfigurationProperties; 19 import de.smartics.properties.api.core.annotations.PropertySet; 20 21 /** 22 * This factory creates a implementation object via a java dynamic proxy for a 23 * given properties interface. Using this object it is possible to access the 24 * properties and when defined in the given interface the keys and property 25 * descriptions can be accessed. 26 */ 27 public final class PropertyConfigurationObjectBuilder 28 { 29 // ********************************* Fields ********************************* 30 31 // --- constants ------------------------------------------------------------ 32 33 // --- members -------------------------------------------------------------- 34 35 // ****************************** Initializer ******************************* 36 37 // ****************************** Constructors ****************************** 38 39 /** 40 * The default message suffix. 41 */ 42 private static final String MESSAGE = 43 "Only classes that represent an" 44 + " interface and that interface must have a 'PropertySet'" 45 + " annotation are allowed."; 46 47 /** 48 * Default constructor. 49 */ 50 public PropertyConfigurationObjectBuilder() 51 { 52 } 53 54 // ****************************** Inner Classes ***************************** 55 56 // ********************************* Methods ******************************** 57 58 // --- init ----------------------------------------------------------------- 59 60 // --- get&set -------------------------------------------------------------- 61 62 // --- business ------------------------------------------------------------- 63 64 /** 65 * Build the object that contains the properties information for the given 66 * properties interface. The interface must be provided through its class 67 * object and has to have a {@link PropertySet} annotation. 68 * 69 * @param propertiesInterface the properties interface as class object with an 70 * {@link PropertySet} annotation. 71 * @param configurationProperties the configuration properties that shall be 72 * used to access the properties. 73 * @param <T> to provide a type safe access to the properties the returned 74 * object implements the given properties interface. 75 * @return the object that contains the properties information for the given 76 * properties interface. 77 * @throws NotAPropertySetAnnotatedInterfaceException when the given class 78 * does not represent an interface and this interface is not 79 * annotated with {@link PropertySet} or when null. 80 */ 81 public <T> T build(final Class<T> propertiesInterface, 82 final SerializableConfigurationProperties configurationProperties) 83 throws NotAPropertySetAnnotatedInterfaceException 84 { 85 checkForValidPropertiesInterface(propertiesInterface); 86 final T propertiesObject = 87 buildObject(propertiesInterface, configurationProperties); 88 return propertiesObject; 89 } 90 91 @SuppressWarnings("unchecked") 92 private <T> T buildObject(final Class<T> propertiesInterface, 93 final SerializableConfigurationProperties configurationProperties) 94 { 95 final T propertiesObject = 96 (T) java.lang.reflect.Proxy.newProxyInstance( 97 propertiesInterface.getClassLoader(), 98 new Class[] { propertiesInterface }, 99 new PropertiesProxyInvocationHandler(configurationProperties)); 100 return propertiesObject; 101 } 102 103 private <T> void checkForValidPropertiesInterface( 104 final Class<T> propertiesInterface) 105 { 106 checkNull(propertiesInterface); 107 checkIfInterface(propertiesInterface); 108 checkIfCorrectAnnotated(propertiesInterface); 109 } 110 111 private <T> void checkNull(final Class<T> propertiesInterface) 112 { 113 if (propertiesInterface == null) 114 { 115 throw new NotAPropertySetAnnotatedInterfaceException( 116 "Null is not allowed." + MESSAGE); 117 } 118 } 119 120 private <T> void checkIfInterface(final Class<T> propertiesInterface) 121 { 122 if (!propertiesInterface.isInterface()) 123 { 124 throw new NotAPropertySetAnnotatedInterfaceException("Not an interface." 125 + MESSAGE); 126 } 127 } 128 129 private <T> void checkIfCorrectAnnotated(final Class<T> propertiesInterface) 130 { 131 final PropertySet propertySetAnnotation = 132 propertiesInterface.getAnnotation(PropertySet.class); 133 if (propertySetAnnotation == null) 134 { 135 throw new NotAPropertySetAnnotatedInterfaceException( 136 "Not a valid annotated interface." + MESSAGE); 137 } 138 } 139 140 // --- object basics -------------------------------------------------------- 141 142 }