1 | package com.framsticks.framclipse.script; |
---|
2 | |
---|
3 | import java.io.IOException; |
---|
4 | import java.io.InputStream; |
---|
5 | import java.util.Collections; |
---|
6 | import java.util.HashMap; |
---|
7 | import java.util.Map; |
---|
8 | |
---|
9 | import org.antlr.misc.MultiMap; |
---|
10 | import org.apache.commons.io.IOUtils; |
---|
11 | import org.eclipse.core.runtime.ILog; |
---|
12 | import org.eclipse.core.runtime.IStatus; |
---|
13 | import org.eclipse.core.runtime.Platform; |
---|
14 | import org.eclipse.core.runtime.Status; |
---|
15 | import org.osgi.framework.Bundle; |
---|
16 | |
---|
17 | import com.framsticks.framclipse.script.context.Context; |
---|
18 | import com.framsticks.framclipse.script.context.File; |
---|
19 | import com.framsticks.framclipse.script.context.Framscontext; |
---|
20 | import com.framsticks.framclipse.script.model.Framscript; |
---|
21 | import com.framsticks.framclipse.script.model.Type; |
---|
22 | import com.google.common.collect.Maps; |
---|
23 | import com.google.inject.Inject; |
---|
24 | import com.thoughtworks.xstream.XStream; |
---|
25 | |
---|
26 | public class XMLConstantProvider implements ConstantProvider { |
---|
27 | |
---|
28 | private static final Bundle BUNDLE = Platform.getBundle("com.framsticks.framclipse"); |
---|
29 | private static final ILog LOG = Platform.getLog(BUNDLE); |
---|
30 | |
---|
31 | private final static Map<String, Type> COMMON_TYPES; |
---|
32 | static { |
---|
33 | Map<String, Type> nullContext = new HashMap<String, Type>(Type.BUILT_IN.length); |
---|
34 | for (Type t : Type.BUILT_IN) { |
---|
35 | nullContext.put(t.getName(), t); |
---|
36 | } |
---|
37 | COMMON_TYPES = Collections.unmodifiableMap(nullContext); |
---|
38 | } |
---|
39 | |
---|
40 | private final Map<String, Map<String, Type>> types; |
---|
41 | |
---|
42 | @Inject |
---|
43 | public XMLConstantProvider(XStream xstream) { |
---|
44 | Framscript framscript = loadFile(xstream, "framscript.xml"); |
---|
45 | Framscontext framscontext = loadFile(xstream, "framscontext.xml"); |
---|
46 | if (framscript != null && framscontext != null) { |
---|
47 | types = createTypeMappings(framscontext, framscript); |
---|
48 | } else { |
---|
49 | types = Collections.emptyMap(); |
---|
50 | } |
---|
51 | } |
---|
52 | |
---|
53 | @SuppressWarnings("unchecked") |
---|
54 | private <T> T loadFile(XStream xstream, String filename) { |
---|
55 | InputStream input = null; |
---|
56 | try { |
---|
57 | input = BUNDLE.getResource(filename).openStream(); |
---|
58 | return (T) xstream.fromXML(input); |
---|
59 | } catch (IOException e) { |
---|
60 | LOG.log(new Status(IStatus.ERROR, BUNDLE.getSymbolicName(), e.getLocalizedMessage())); |
---|
61 | return null; |
---|
62 | } finally { |
---|
63 | IOUtils.closeQuietly(input); |
---|
64 | } |
---|
65 | } |
---|
66 | |
---|
67 | private Map<String, Map<String, Type>> createTypeMappings(Framscontext framscontext, Framscript framscript) { |
---|
68 | Map<String, Map<String, Type>> types = Maps.newHashMap(); |
---|
69 | MultiMap<String, String> ext2ctx = ext2Ctx(framscontext); |
---|
70 | MultiMap<String, Type> ctx2type = ctx2Type(framscript); |
---|
71 | for (String ext : ext2ctx.keySet()) { |
---|
72 | HashMap<String, Type> map = new HashMap<String, Type>(); |
---|
73 | types.put(ext, map); |
---|
74 | for (String ctx : ext2ctx.get(ext)) { |
---|
75 | for (Type type : ctx2type.get(ctx)) { |
---|
76 | map.put(type.getName(), type); |
---|
77 | } |
---|
78 | } |
---|
79 | } |
---|
80 | return types; |
---|
81 | } |
---|
82 | |
---|
83 | private MultiMap<String, String> ext2Ctx(Framscontext framscontext) { |
---|
84 | MultiMap<String, String> ext2ctx = new MultiMap<String, String>(); |
---|
85 | for (File file : framscontext.getFiles()) { |
---|
86 | String ext = file.getPattern(); |
---|
87 | ext = ext.substring(ext.lastIndexOf('.') + 1, ext.length()); |
---|
88 | if (file.getCode() != null) { |
---|
89 | for (Context context : file.getCode().getContexts()) { |
---|
90 | ext2ctx.map(ext, context.getName()); |
---|
91 | } |
---|
92 | } |
---|
93 | } |
---|
94 | return ext2ctx; |
---|
95 | } |
---|
96 | |
---|
97 | private MultiMap<String, Type> ctx2Type(Framscript framscript) { |
---|
98 | MultiMap<String, Type> ctx2type = new MultiMap<String, Type>(); |
---|
99 | for (Type type : framscript.getTypes()) { |
---|
100 | ctx2type.map(type.getContext(), type); |
---|
101 | } |
---|
102 | return ctx2type; |
---|
103 | } |
---|
104 | |
---|
105 | @Override |
---|
106 | public Type getType(String name, String extension) { |
---|
107 | Map<String, Type> types = this.types.get(extension); |
---|
108 | Type result = types != null ? types.get(name) : null; |
---|
109 | return result != null ? result : COMMON_TYPES.get(name); |
---|
110 | } |
---|
111 | |
---|
112 | @Override |
---|
113 | public Map<String, Map<String, Type>> getTypes() { |
---|
114 | return types; |
---|
115 | } |
---|
116 | |
---|
117 | } |
---|