001package org.dllearner.confparser; 002 003import org.apache.commons.collections4.BidiMap; 004import org.dllearner.cli.ConfFileOption; 005import org.dllearner.configuration.IConfiguration; 006import org.dllearner.configuration.IConfigurationProperty; 007import org.dllearner.confparser.json.ConfParserJson; 008import org.dllearner.core.AnnComponentManager; 009import org.dllearner.core.Component; 010import org.dllearner.core.ComponentInitException; 011import org.dllearner.core.StringRenderer; 012import org.dllearner.core.StringRenderer.Rendering; 013import org.springframework.core.io.InputStreamResource; 014import org.springframework.core.io.Resource; 015 016import java.io.BufferedInputStream; 017import java.io.IOException; 018import java.util.*; 019import java.util.Map.Entry; 020 021/** 022 * Created by IntelliJ IDEA. 023 * User: Chris 024 * Date: 8/27/11 025 * Time: 7:21 AM 026 * <p/> 027 * Conf Parser Based implementation. 028 */ 029public class ConfParserConfiguration implements IConfiguration { 030 031 private final ConfParser parser; 032 private final String baseDir; 033 private final String typeProperty = "type"; 034 035 public ConfParserConfiguration(Resource source) { 036 try { 037// baseDir = source.getFile().getAbsoluteFile().getParent(); 038 if(!(source instanceof InputStreamResource)){ 039 baseDir = source.getFile().getAbsoluteFile().getParentFile().getAbsolutePath(); 040 } else { 041 baseDir = null; 042 } 043 BufferedInputStream bufferedInputStream = new BufferedInputStream(source.getInputStream()); 044 bufferedInputStream.mark(1); 045 int peek = bufferedInputStream.read(); 046 bufferedInputStream.reset(); 047 if (peek == '{') { 048 parser = new ConfParserJson(bufferedInputStream); 049 } else { 050 parser = new ConfParserLegacy(bufferedInputStream); 051 } 052 parser.init(); 053 054 // setup rendering TODO put it into CLI 055 ConfFileOption renderingOption = parser.getConfOptionsByProperty("rendering"); 056 if(renderingOption != null) { 057 StringRenderer.setRenderer((String) renderingOption.getValue()); 058 } else { 059 StringRenderer.setRenderer(Rendering.MANCHESTER_SYNTAX); 060 } 061 } catch (IOException | ComponentInitException e) { 062 throw new RuntimeException(e); 063 } 064 } 065 066 @Override 067 public Collection<String> getBeanNames() { 068 Set<String> result = new HashSet<>(); 069 Map<String,List<ConfFileOption>> beans = parser.getConfOptionsByBean(); 070 result.addAll(beans.keySet()); 071 return result; 072 } 073 074 @Override 075 public Class getClass(String beanName) { 076 077 List<ConfFileOption> confOptions = parser.getConfOptionsByBean(beanName); 078 079 ConfFileOption option = null; 080 for (ConfFileOption confOption : confOptions) { 081 if(typeProperty.equalsIgnoreCase(confOption.getPropertyName())){ 082 option = confOption; 083 } 084 } 085 086 if(option == null){ 087 throw new RuntimeException("No type property set for bean: " + beanName); 088 } 089 090 Class<?> result = null; 091 092 String value = (String) option.getValue(); 093 // first option: use long name of @ComponentAnn annotation (case insensitive) 094 BidiMap<Class<? extends Component>, String> componentsNamed = AnnComponentManager.getInstance().getComponentsNamed(); 095 for(Entry<Class<? extends Component>, String> entry : componentsNamed.entrySet()) { 096 if(entry.getValue().equalsIgnoreCase(value)) { 097 return entry.getKey(); 098 } 099 } 100 // second option: use short name of @ComponentAnn annotation 101 // by convention, short names should always be lower case, but we still do it case insensitive 102 BidiMap<Class<? extends Component>, String> componentsNamedShort = AnnComponentManager.getInstance().getComponentsNamedShort(); 103 for(Entry<Class<? extends Component>, String> entry : componentsNamedShort.entrySet()) { 104 if(entry.getValue().equalsIgnoreCase(value)) { 105 return entry.getKey(); 106 } 107 } 108 // third option: use specified class name 109 try { 110 result = Class.forName(value); 111 } catch (ClassNotFoundException e) { 112 // if all methods fail, throw an exception 113 throw new RuntimeException("Problem getting class type for bean: " + beanName + " - trying to instantiate class: " + value,e); 114 } 115 return result; 116 } 117 118 @Override 119 public String getBaseDir() { 120 return baseDir; 121 } 122 123 @Override 124 public Collection<IConfigurationProperty> getConfigurationProperties(String beanName) { 125 List<ConfFileOption> confFileOptions = parser.getConfOptionsByBean(beanName); 126 Collection<IConfigurationProperty> result = new ArrayList<>(); 127 128 for (ConfFileOption confFileOption : confFileOptions) { 129 130 if (!typeProperty.equalsIgnoreCase(confFileOption.getPropertyName())) { 131 result.add(confFileOption); 132 } 133 } 134 return result; 135 } 136}