package com.sissi.io.read.sax; import java.util.HashMap; import java.util.Map; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import com.sissi.commons.ScanUtil; import com.sissi.io.read.Mapping; import com.sissi.io.read.Metadata; /** * @author kim 2013-10-25 */ public class XMLMapping implements Mapping { private final String loading = "com.sissi.protocol"; private final Log log = LogFactory.getLog(this.getClass()); private final Selector selector = new Selector(); private final Map<String, Class<?>> cached = new HashMap<String, Class<?>>(); public XMLMapping() { super(); for (Class<?> each : ScanUtil.getClasses(this.loading)) { Metadata metadata = each.getAnnotation(Metadata.class); if (metadata != null) { this.selector.install(metadata.uri(), metadata.localName(), each); } } } public Object instance(String uri, String localName) { String uriTrim = uri != null ? uri : ""; Class<?> clazz = this.instance4Cached(localName, uriTrim); this.log.debug("Request uri: " + uriTrim + " / localName: " + localName + " and found: " + clazz); try { return clazz != null ? this.instance2Cached(localName, uriTrim, clazz) : null; } catch (Exception e) { this.log.error(e.toString()); return null; } } private Object instance2Cached(String localName, String uriTrim, Class<?> clazz) throws Exception { this.cached.put(uriTrim + localName, clazz); return clazz.newInstance(); } private Class<?> instance4Cached(String localName, String uriTrim) { Class<?> clazz = this.cached.get(uriTrim + localName); if (clazz == null) { clazz = this.selector.find(uriTrim, localName); } return clazz; } public boolean cached(String uri, String localName) { String uriTrim = uri != null ? uri : ""; boolean isCached = this.cached.containsKey(uriTrim + localName); if (isCached) { this.log.debug("URI: " + uri + " / LocalName: " + localName + " is exists"); } return isCached; } private class Selector { private final Map<String, Class<?>> mapping = new HashMap<String, Class<?>>(); public void install(String[] uris, String localName, Class<?> clazz) { for (String uri : uris) { this.mapping.put((uri != null ? uri : "") + localName, clazz); XMLMapping.this.log.debug("Insert Mapping: " + (uri != null ? uri : "") + " / " + localName + " / " + clazz); } } public Class<?> find(String uri, String localName) { return this.mapping.get((uri + localName).intern()); } } }