source: java/main/src/main/java/com/framsticks/parsers/XmlLoader.java @ 193

Last change on this file since 193 was 193, checked in by Maciej Komosinski, 10 years ago

Set svn:eol-style native for all textual files

  • Property svn:eol-style set to native
File size: 5.3 KB
Line 
1package com.framsticks.parsers;
2
3import java.io.File;
4import java.io.FileInputStream;
5import java.io.FileNotFoundException;
6import java.io.InputStream;
7import java.util.LinkedList;
8import java.util.List;
9
10import javax.xml.parsers.DocumentBuilder;
11import javax.xml.parsers.DocumentBuilderFactory;
12
13import org.apache.logging.log4j.Logger;
14import org.apache.logging.log4j.LogManager;
15import org.w3c.dom.Document;
16import org.w3c.dom.Element;
17import org.w3c.dom.NamedNodeMap;
18import org.w3c.dom.Node;
19import org.w3c.dom.NodeList;
20
21import com.framsticks.params.Access;
22import com.framsticks.params.ParamFlags;
23import com.framsticks.params.PrimitiveParam;
24import com.framsticks.params.Registry;
25import com.framsticks.util.AutoAttacher;
26import com.framsticks.util.AutoBuilder;
27import com.framsticks.util.FramsticksException;
28import com.framsticks.util.lang.Strings;
29import static com.framsticks.params.ParamsUtil.getParam;
30
31public class XmlLoader {
32        private static final Logger log = LogManager.getLogger(XmlLoader.class);
33
34        protected Registry registry = new Registry();
35
36        /**
37         *
38         */
39        public XmlLoader() {
40                registry.registerAndBuild(AutoInjector.class);
41        }
42
43        /**
44         * @return the registry
45         */
46        public Registry getRegistry() {
47                return registry;
48        }
49
50        boolean useLowerCase = false;
51
52        /**
53         * @param useLowerCase the useLowerCase to set
54         */
55        public void setUseLowerCase(boolean useLowerCase) {
56                this.useLowerCase = useLowerCase;
57        }
58
59        public String mangleName(String name) {
60                return useLowerCase ? name.toLowerCase() : name;
61        }
62
63        public String mangleAttribute(String name) {
64                return useLowerCase ? name.toLowerCase() : Strings.uncapitalize(name);
65        }
66
67        public Object processElement(Element element, Class<?> enclosingClass) {
68                final String name = mangleName(element.getNodeName());
69                if (name.equals("import")) {
70                        String className = element.getAttribute("class");
71                        try {
72                                registry.registerAndBuild(Class.forName(className));
73                                return null;
74                        } catch (ClassNotFoundException e) {
75                                throw new FramsticksException().msg("failed to import class").arg("name", name).cause(e);
76                        }
77                }
78                if (name.equals("include")) {
79                        String fileName = element.getAttribute("file");
80                        if (Strings.notEmpty(fileName)) {
81                                try {
82                                        return load(new FileInputStream(new File(fileName)), enclosingClass);
83                                } catch (FileNotFoundException e) {
84                                        throw new FramsticksException().msg("failed to include file").arg("file", fileName).cause(e);
85                                }
86                        }
87                        String resourceName = element.getAttribute("resource");
88                        if (Strings.notEmpty(resourceName)) {
89                                Class<?> javaClass = enclosingClass;
90                                String className = element.getAttribute("class");
91                                if (Strings.notEmpty(className)) {
92                                        try {
93                                                javaClass = Class.forName(className);
94                                        } catch (ClassNotFoundException e) {
95                                                throw new FramsticksException().msg("failed to find class for resource loading").arg("class name", className).cause(e);
96                                        }
97                                }
98
99                                return load(javaClass.getResourceAsStream(resourceName), enclosingClass);
100                        }
101                        throw new FramsticksException().msg("invalid <include/> node");
102                }
103
104                Access access = registry.createAccess(name);
105
106                Object object = access.createAccessee();
107                assert object != null;
108                access.select(object);
109
110                NamedNodeMap attributes = element.getAttributes();
111                for (int i = 0; i < attributes.getLength(); ++i) {
112                        Node attributeNode = attributes.item(i);
113                        PrimitiveParam<?> param = getParam(access, mangleAttribute(attributeNode.getNodeName()), PrimitiveParam.class);
114                        if (param.hasFlag(ParamFlags.READONLY)) {
115                                throw new FramsticksException().msg("cannot configure readonly param").arg("param", param).arg("in", access);
116                        }
117                        access.set(param, attributeNode.getNodeValue());
118                }
119
120                NodeList children = element.getChildNodes();
121                log.debug("found {} children in {}", children.getLength(), object);
122                for (int i = 0; i < children.getLength(); ++i) {
123                        Node childNode = children.item(i);
124                        if (!(childNode instanceof Element)) {
125                                continue;
126                        }
127                        Object childObject = processElement((Element) childNode, object.getClass());
128                        if (childObject == null) {
129                                continue;
130                        }
131
132                        List<Object> childrenObjects = new LinkedList<>();
133
134                        if (childObject instanceof AutoBuilder) {
135                                childrenObjects.addAll(((AutoBuilder) childObject).autoFinish());
136                        } else {
137                                childrenObjects.add(childObject);
138                        }
139
140                        for (Object child : childrenObjects) {
141                                if (child instanceof AutoAttacher) {
142                                        ((AutoAttacher) child).attachTo(access.getSelected());
143                                } else {
144                                        access.tryAutoAppend(child);
145                                }
146                        }
147                }
148                log.debug("loaded {}", object);
149
150                return object;
151        }
152
153        protected Object load(InputStream stream, Class<?> enclosingClass) {
154                try {
155                        DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
156                        DocumentBuilder db = factory.newDocumentBuilder();
157
158                        Document document = db.parse(stream);
159                        document.getDocumentElement().normalize();
160                        Element element = document.getDocumentElement();
161                        assert element != null;
162
163                        return processElement(element, enclosingClass);
164
165                } catch (Exception e) {
166                        throw new FramsticksException().msg("failed to load").cause(e);
167                }
168        }
169
170        public <T> T load(Class<T> type, InputStream stream) {
171                registry.registerAndBuild(type);
172
173                Object object = load(stream, type);
174                if (type.isAssignableFrom(object.getClass())) {
175                        return type.cast(object);
176                }
177                throw new FramsticksException().msg("invalid type has been loaded");
178        }
179}
180
Note: See TracBrowser for help on using the repository browser.