View Javadoc

1   /**
2    * Copyright 2007 Björn Voß
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5    * use this file except in compliance with the License. You may obtain a copy of
6    * 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, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations under
14   * the License.
15   */
16  package net.sf.oxclient.mappings.xml;
17  
18  import java.io.IOException;
19  import java.lang.reflect.Modifier;
20  import java.util.HashMap;
21  import java.util.List;
22  import java.util.Map;
23  import java.util.Set;
24  
25  import net.sf.oval.constraint.NotNull;
26  import net.sf.oval.guard.Guarded;
27  import net.sf.oxclient.mappings.IMappingManager;
28  
29  import org.apache.commons.collections.MapUtils;
30  import org.apache.commons.lang.ClassUtils;
31  import org.springframework.beans.factory.InitializingBean;
32  import org.springframework.core.io.Resource;
33  
34  import com.thoughtworks.xstream.XStream;
35  
36  /**
37   * @author Björn Voß
38   *
39   */
40  @Guarded
41  public class XMLMappingManager implements IMappingManager, InitializingBean {
42  
43  	private Resource mappingFile;
44  	private List<Mapping> mappings;
45  
46  	/* (non-Javadoc)
47  	 * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
48  	 */
49  	public void afterPropertiesSet() throws Exception {
50  		if ((this.mappingFile == null) && (this.mappings == null) ) {
51  			throw new IllegalStateException("mapping file or mappings must be set");
52  		}
53  		if (this.mappings == null ) {
54  			readMappingsFromXML();
55  		}
56  	}
57  
58  	/**
59  	 * @throws IOException
60  	 */
61  	private void readMappingsFromXML() throws IOException {
62  		final XStream xStream = new XStream();
63  		xStream.alias("classmapping", Classmappings.class);
64  		xStream.alias("mapping", Mapping.class);
65  		xStream.alias("property", Property.class);
66  		xStream.useAttributeFor(Property.class, "name");
67  		xStream.useAttributeFor(Property.class, "oxcolumnid");
68  		xStream.useAttributeFor(Mapping.class, "clazz");
69  		xStream.aliasAttribute(Mapping.class, "clazz", "beanclass");
70  		xStream.addImplicitCollection(Classmappings.class, "mappings");
71  		xStream.addImplicitCollection(Mapping.class, "properties");
72  		final Classmappings classmappings =
73  			(Classmappings) xStream.fromXML(this.mappingFile.getInputStream());
74  		this.mappings = classmappings.getMappings();
75  	}
76  
77  	/**
78  	 * @return the mappingFile
79  	 */
80  	public Resource getMappingFile() {
81  		return this.mappingFile;
82  	}
83  
84  	/* (non-Javadoc)
85  	 * @see net.sf.oxclient.mappings.IMappingManager#getMappingForClass(java.lang.Class)
86  	 */
87  	@SuppressWarnings("unchecked")
88  	public Map<Integer, String> getMappingForClass(@NotNull final Class<?> clazz) {
89  		if (Modifier.isAbstract(clazz.getModifiers())) {
90  			throw new IllegalArgumentException("not allowed for abstract class " + clazz.getName());
91  		}
92  		final Mapping mapping = findMapping(clazz);
93  		if (mapping == null) {
94  			throw new IllegalArgumentException("unkowen class " + clazz.getName());
95  		}
96  		final Map<Integer, String> result = new SingelKeyMap<Integer, String>();
97  		addProperties(mapping.getProperties(), result);
98  		addPropertiesFromSuperClasses(result, clazz);
99  		return MapUtils.unmodifiableMap(result);
100 	}
101 
102 	/**
103 	 * @param result
104 	 * @param clazz
105 	 */
106 	@SuppressWarnings("unchecked")
107 	private void addPropertiesFromSuperClasses(
108 			final Map<Integer, String> result,
109 			final Class<?> clazz) {
110 		final List<Class<?>> superClasses = ClassUtils.getAllSuperclasses(clazz);
111 		for (final Class<?> superClass : superClasses) {
112 			final Mapping supperMapping = findMapping(superClass);
113 			if (supperMapping != null) {
114 				addProperties(supperMapping.getProperties(), result);
115 			}
116 		}
117 	}
118 
119 	/**
120 	 * @param properties
121 	 * @param result
122 	 */
123 	private void addProperties(
124 			final Set<Property> properties,
125 			final Map<Integer, String> result) {
126 		for (final Property property : properties) {
127 			result.put(property.getOxcolumnid(), property.getName());
128 		}
129 	}
130 
131 	/**
132 	 * @param clazz
133 	 */
134 	private Mapping findMapping(final Class<?> clazz) {
135 		for (final Mapping mapping : this.mappings) {
136 			if (clazz.equals(mapping.getClazz())) {
137 				return mapping;
138 			}
139 		}
140 		return null;
141 	}
142 
143 	/**
144 	 * @return the mappings
145 	 */
146 	public List<Mapping> getMappings() {
147 		return this.mappings;
148 	}
149 
150 	/**
151 	 * @param mappingFile the mappingFile to set
152 	 */
153 	public void setMappingFile(@NotNull final Resource mappingFile) {
154 		this.mappingFile = mappingFile;
155 	}
156 
157 	/**
158 	 * @param mappings the mappings to set
159 	 */
160 	public void setMappings(@NotNull final List<Mapping> mappings) {
161 		this.mappings = mappings;
162 	}
163 
164 	private class SingelKeyMap<K, V> extends HashMap<K, V> {
165 
166 		private static final long serialVersionUID = 1814634918815348649L;
167 
168 		SingelKeyMap() {
169 			super();
170 		}
171 
172 		/* (non-Javadoc)
173 		 * @see java.util.HashMap#put(java.lang.Object, java.lang.Object)
174 		 */
175 		@Override
176 		public V put(final K key, final V value) {
177 			if (containsKey(key)) {
178 				throw new IllegalArgumentException("already set key " + key);
179 			}
180 			return super.put(key, value);
181 		}
182 	}
183 
184 }