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
RevLine 
[87]1package com.framsticks.parsers;
2
[100]3import java.io.File;
4import java.io.FileInputStream;
5import java.io.FileNotFoundException;
[88]6import java.io.InputStream;
[90]7import java.util.LinkedList;
8import java.util.List;
[88]9
10import javax.xml.parsers.DocumentBuilder;
11import javax.xml.parsers.DocumentBuilderFactory;
12
[100]13import org.apache.logging.log4j.Logger;
14import org.apache.logging.log4j.LogManager;
[88]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
[100]21import com.framsticks.params.Access;
[101]22import com.framsticks.params.ParamFlags;
23import com.framsticks.params.PrimitiveParam;
[88]24import com.framsticks.params.Registry;
[102]25import com.framsticks.util.AutoAttacher;
[90]26import com.framsticks.util.AutoBuilder;
[88]27import com.framsticks.util.FramsticksException;
[99]28import com.framsticks.util.lang.Strings;
[105]29import static com.framsticks.params.ParamsUtil.getParam;
[88]30
[87]31public class XmlLoader {
[100]32        private static final Logger log = LogManager.getLogger(XmlLoader.class);
[87]33
[88]34        protected Registry registry = new Registry();
35
36        /**
37         *
38         */
39        public XmlLoader() {
[100]40                registry.registerAndBuild(AutoInjector.class);
[88]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
[99]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
[100]67        public Object processElement(Element element, Class<?> enclosingClass) {
[99]68                final String name = mangleName(element.getNodeName());
[88]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                }
[100]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                                }
[88]98
[100]99                                return load(javaClass.getResourceAsStream(resourceName), enclosingClass);
100                        }
101                        throw new FramsticksException().msg("invalid <include/> node");
102                }
[88]103
[100]104                Access access = registry.createAccess(name);
105
[88]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);
[105]113                        PrimitiveParam<?> param = getParam(access, mangleAttribute(attributeNode.getNodeName()), PrimitiveParam.class);
[101]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());
[88]118                }
119
120                NodeList children = element.getChildNodes();
[100]121                log.debug("found {} children in {}", children.getLength(), object);
[88]122                for (int i = 0; i < children.getLength(); ++i) {
123                        Node childNode = children.item(i);
124                        if (!(childNode instanceof Element)) {
125                                continue;
126                        }
[100]127                        Object childObject = processElement((Element) childNode, object.getClass());
[88]128                        if (childObject == null) {
129                                continue;
130                        }
131
[90]132                        List<Object> childrenObjects = new LinkedList<>();
133
134                        if (childObject instanceof AutoBuilder) {
135                                childrenObjects.addAll(((AutoBuilder) childObject).autoFinish());
136                        } else {
137                                childrenObjects.add(childObject);
[88]138                        }
[90]139
140                        for (Object child : childrenObjects) {
[102]141                                if (child instanceof AutoAttacher) {
142                                        ((AutoAttacher) child).attachTo(access.getSelected());
143                                } else {
144                                        access.tryAutoAppend(child);
145                                }
[90]146                        }
[88]147                }
[100]148                log.debug("loaded {}", object);
[88]149
150                return object;
151        }
152
[100]153        protected Object load(InputStream stream, Class<?> enclosingClass) {
[88]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
[100]163                        return processElement(element, enclosingClass);
[88]164
165                } catch (Exception e) {
166                        throw new FramsticksException().msg("failed to load").cause(e);
167                }
168        }
169
[90]170        public <T> T load(Class<T> type, InputStream stream) {
[88]171                registry.registerAndBuild(type);
172
[100]173                Object object = load(stream, type);
[88]174                if (type.isAssignableFrom(object.getClass())) {
175                        return type.cast(object);
176                }
177                throw new FramsticksException().msg("invalid type has been loaded");
178        }
[87]179}
[88]180
Note: See TracBrowser for help on using the repository browser.