001package org.biopax.paxtools.controller; 002 003import org.apache.commons.logging.Log; 004import org.apache.commons.logging.LogFactory; 005import org.biopax.paxtools.model.BioPAXElement; 006import org.biopax.paxtools.model.BioPAXLevel; 007import org.biopax.paxtools.util.IllegalBioPAXArgumentException; 008 009import java.io.BufferedReader; 010import java.io.IOException; 011import java.io.InputStream; 012import java.io.InputStreamReader; 013import java.util.*; 014 015/** 016 * Provides a simple editor map for a level with a given factory. 017 * 018 * This class initializes 3 singletons( 1 for each level) from a tab delimited text resources that lists the 019 * properties and their domains. This is done to remove any dependencies to Jena. 020 * 021 * The recommended usage is to use the {@link #get(org.biopax.paxtools.model.BioPAXLevel)} method. 022 * @author Emek Demir 023 */ 024public enum SimpleEditorMap implements EditorMap 025{ 026 027 L1(BioPAXLevel.L1), 028 L2(BioPAXLevel.L2), 029 L3(BioPAXLevel.L3); 030 031 private static final Log log = LogFactory.getLog(EditorMapImpl.class); 032 033 private final SimpleEditorMapImpl impl; 034 035 036 SimpleEditorMap(BioPAXLevel level) 037 { 038 this.impl = new SimpleEditorMapImpl(level); 039 } 040 041 /** 042 * To obtain a copy of the editor map for the corresponding level, use the 043 * @param level the BioPAX level 044 * @return SimpleEditorMap implementation for the BioPAX L1, L2, or L3 045 */ 046 public static SimpleEditorMap get(BioPAXLevel level) 047 { 048 for (SimpleEditorMap value : values()) 049 { 050 if (value.getLevel().equals(level)) return value; 051 } 052 //should never reach here 053 throw new IllegalBioPAXArgumentException("Unknown level:" + level); 054 } 055 056 static class SimpleEditorMapImpl extends EditorMapImpl implements EditorMap 057 { 058 SimpleEditorMapImpl(BioPAXLevel level) 059 { 060 super(level); 061 InputStream stream = this.getClass().getResourceAsStream(level + "Editor.properties"); 062 readEditors(level, stream, this); 063 } 064 } 065 066 067 public <D extends BioPAXElement> PropertyEditor<? super D, ?> getEditorForProperty(String property, 068 Class<D> javaClass) 069 070 { 071 return impl.getEditorForProperty(property, javaClass); 072 } 073 074 @Override public Set<PropertyEditor> getEditorsForProperty(String property) 075 { 076 return impl.getEditorsForProperty(property); 077 } 078 079 @Override 080 public <D extends BioPAXElement> Set<PropertyEditor<? extends D, ?>> getSubclassEditorsForProperty(String property, 081 Class<D> domain) 082 { 083 return impl.getSubclassEditorsForProperty(property, domain); 084 } 085 086 @Override public Set<PropertyEditor> getEditorsOf(BioPAXElement bpe) 087 { 088 return impl.getEditorsOf(bpe); 089 090 } 091 092 @Override public Set<ObjectPropertyEditor> getInverseEditorsOf(BioPAXElement bpe) 093 { 094 return impl.getInverseEditorsOf(bpe); 095 } 096 097 @Override public <E extends BioPAXElement> Set<? extends Class<E>> getKnownSubClassesOf(Class<E> javaClass) 098 { 099 return impl.getKnownSubClassesOf(javaClass); 100 } 101 102 103 public BioPAXLevel getLevel() 104 { 105 return impl.getLevel(); 106 107 } 108 109 @Override public Set<PropertyEditor> getEditorsOf(Class<? extends BioPAXElement> domain) 110 { 111 return impl.getEditorsOf(domain); 112 } 113 114 @Override public Set<ObjectPropertyEditor> getInverseEditorsOf(Class<? extends BioPAXElement> domain) 115 { 116 return impl.getInverseEditorsOf(domain); 117 } 118 119 @Override 120 public Iterator<PropertyEditor> iterator() 121 { 122 return impl.iterator(); 123 } 124 125 126 static void readEditors(BioPAXLevel level, InputStream stream, EditorMapImpl map) 127 { 128 BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); 129 try 130 { 131 String line = reader.readLine(); 132 StringTokenizer st = new StringTokenizer(line); 133 while (st.hasMoreElements()) 134 { 135 map.registerModelClass(st.nextToken()); 136 } 137 138 while ((line = reader.readLine()) != null) 139 { 140 if (!line.startsWith("#")) 141 { 142 st = new StringTokenizer(line); 143 String domain = st.nextToken(); 144 Class<? extends BioPAXElement> domainInterface = map.getLevel().getInterfaceForName(domain); 145 146 String propertyName = st.nextToken(); 147 Map<Class<? extends BioPAXElement>, Set<Class<? extends BioPAXElement>>> rangeRestrictions = 148 new HashMap<Class<? extends BioPAXElement>, Set<Class<? extends BioPAXElement>>>(); 149 while (st.hasMoreTokens()) 150 { 151 String rToken = st.nextToken(); 152 if (rToken.startsWith("R:")) 153 { 154 StringTokenizer rt = new StringTokenizer(rToken.substring(2), "="); 155 Class<? extends BioPAXElement> rDomain = level.getInterfaceForName(rt.nextToken()); 156 Set<Class<? extends BioPAXElement>> rRanges = new HashSet<Class<? extends 157 BioPAXElement>>(); 158 for (StringTokenizer dt = new StringTokenizer(rt.nextToken(), ","); dt.hasMoreTokens(); ) 159 { 160 rRanges.add(level.getInterfaceForName(dt.nextToken())); 161 } 162 rangeRestrictions.put(rDomain, rRanges); 163 } 164 165 } 166 map.createAndRegisterBeanEditor(propertyName, domainInterface, rangeRestrictions); 167 } 168 } 169 } 170 catch (IOException e) 171 { 172 log.error("Could not initialize " + "Editor Map", e); 173 } 174 finally 175 { 176 try 177 { 178 stream.close(); 179 } 180 catch (IOException ignore) 181 { 182 log.error("Could not close stream! Exiting"); 183 System.exit(1); 184 } 185 } 186 187 } 188 189 public static EditorMap buildCustomEditorMap(BioPAXLevel level, InputStream stream) 190 { 191 EditorMapImpl editorMap = new EditorMapImpl(level); 192 readEditors(level,stream,editorMap); 193 return editorMap; 194 195 } 196 197}