package org.tessell.generators.views;
import static org.apache.commons.lang.StringUtils.splitPreserveAllTokens;
import static org.apache.commons.lang.StringUtils.substringAfter;
import static org.apache.commons.lang.StringUtils.substringBefore;
import static org.apache.commons.lang.StringUtils.substringBeforeLast;
import static org.apache.commons.lang.StringUtils.substringBetween;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Collections;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import org.apache.commons.io.IOUtils;
import org.tessell.gwt.dom.client.IsElement;
import org.tessell.gwt.dom.client.StubElement;
import com.google.gwt.dom.client.Element;
/** Holds mappings of ui.xml type -> interface type, stub type, and subclass type. */
public class Config {
private static String[] viewgenFiles = new String[] { "viewgen.properties", "viewgen-root.properties" };
private final Map<String, String> typeToInterface = new HashMap<String, String>();
private final Map<String, String> typeToStub = new HashMap<String, String>();
private final Map<String, List<String>> stubToCstrParams = new HashMap<String, List<String>>();
public Config() {
loadViewGenDotProperties();
}
public String getInterface(final String type) {
if (Element.class.getName().equals(type)) {
return IsElement.class.getName();
}
if (typeToInterface.get(type) != null) {
return typeToInterface.get(type);
}
throw new RuntimeException("No interface for " + type);
}
public String getStub(final String type) {
if (Element.class.getName().equals(type)) {
return StubElement.class.getName();
}
if (typeToStub.get(type) != null) {
return typeToStub.get(type);
}
throw new RuntimeException("No stub for " + type);
}
public List<String> getStubCstrParams(final String type) {
List<String> t = stubToCstrParams.get(type);
if (t == null) {
return Collections.emptyList();
}
return t;
}
public String getViewgenTimestamp() {
return Integer.toString(typeToInterface.hashCode() + typeToStub.hashCode() + stubToCstrParams.hashCode());
}
private void loadViewGenDotProperties() {
try {
for (String file : viewgenFiles) {
Enumeration<URL> urls = Config.class.getClassLoader().getResources(file);
while (urls.hasMoreElements()) {
URL url = urls.nextElement();
// System.out.println("Loading " + url);
InputStream in = url.openStream();
try {
final Properties p = new Properties();
p.load(url.openStream());
for (final Entry<Object, Object> e : p.entrySet()) {
final String type = e.getKey().toString();
final String packageName = substringBeforeLast(type, ".");
String line = e.getValue().toString();
typeToInterface.put(type, prependPackageIfNeeded(packageName, substringBefore(line, ",")));
// watch for stub with cstr params, e.g. TextLine(AppRegistry)
String stub = substringAfter(line, ",");
String[] params = new String[] {};
if (stub.contains("(")) {
params = splitPreserveAllTokens(substringBetween(stub, "(", ")"), ",");
stub = substringBefore(stub, "(");
}
stub = prependPackageIfNeeded(packageName, stub);
typeToStub.put(type, stub);
stubToCstrParams.put(stub, Arrays.asList(params));
}
} finally {
IOUtils.closeQuietly(in);
}
}
}
} catch (IOException io) {
throw new RuntimeException(io);
}
}
/** Prepends {@code packageName} if the class name {@name} has no existing package. */
private static String prependPackageIfNeeded(final String packageName, final String name) {
if (name.contains(".")) {
return name;
} else {
return packageName + "." + name;
}
}
}