001/*
002 * Copyright (c) 2004-2012, Willem Cazander
003 * All rights reserved.
004 *
005 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
006 * that the following conditions are met:
007 * 
008 * * Redistributions of source code must retain the above copyright notice, this list of conditions and the
009 *   following disclaimer.
010 * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
011 *   the following disclaimer in the documentation and/or other materials provided with the distribution.
012 * 
013 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
014 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
015 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
016 * THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
017 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
018 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
019 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
020 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
021 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
022 */
023
024package org.x4o.xml.element;
025
026import java.util.List;
027import java.util.Map;
028import java.util.HashMap;
029import java.util.ArrayList;
030import java.util.logging.Logger;
031
032/**
033 * An AbstractElementLanguageModule.
034 * 
035 * @author Willem Cazander
036 * @version 1.0 Aug 2, 2012
037 */
038public abstract class AbstractElementLanguageModule extends AbstractElementMetaBase implements ElementLanguageModule {
039
040        private Logger logger = null;
041
042        private String name=null;
043        private String providerName=null;
044        private String sourceResource = null;
045        
046        /** The globalAttribute handlers */
047        private List<ElementAttributeHandler> elementAttributeHandlers = null;
048
049        /** The binding rules */
050        private List<ElementBindingHandler> elementBindingHandlers = null;
051
052        private List<ElementConfiguratorGlobal> elementConfiguratorGlobals = null;
053
054        private List<ElementInterface> elementInterfaces = null;
055
056        private Map<String,ElementNamespaceContext> elementNamespaceContexts = null;
057
058        private ElementLanguageModuleLoader elementLanguageModuleLoader = null;
059
060        /**
061         * Creates a new empty ElementLanguage.
062         */
063        public AbstractElementLanguageModule() {
064                logger = Logger.getLogger(AbstractElementLanguage.class.getName());
065                logger.finest("Creating new ParsingContext");
066                elementAttributeHandlers = new ArrayList<ElementAttributeHandler>(4);
067                elementBindingHandlers = new ArrayList<ElementBindingHandler>(4);
068                elementConfiguratorGlobals = new ArrayList<ElementConfiguratorGlobal>(4);
069                elementInterfaces = new ArrayList<ElementInterface>(20);
070                elementNamespaceContexts = new HashMap<String,ElementNamespaceContext>(10);
071        }
072
073        /**
074         * @return the name
075         */
076        public String getName() {
077                return name;
078        }
079
080        /**
081         * @param name the name to set
082         */
083        public void setName(String name) {
084                this.name = name;
085        }
086
087        /**
088         * @return the providerName
089         */
090        public String getProviderName() {
091                return providerName;
092        }
093
094        /**
095         * @param providerName the providerName to set
096         */
097        public void setProviderName(String providerName) {
098                this.providerName = providerName;
099        }
100
101        /**
102         * @see org.x4o.xml.element.ElementLanguageModule#addElementAttributeHandler(ElementAttributeHandler)
103         */
104        public void addElementAttributeHandler(ElementAttributeHandler elementAttributeHandler) {
105                if (elementAttributeHandler==null) {
106                        throw new NullPointerException("Can't add null object");
107                }
108                if (elementAttributeHandler.getId()==null) {
109                        throw new NullPointerException("Can't add with null id property.");
110                }
111                logger.finer("Adding ElementAttributeHandler: "+elementAttributeHandler.getAttributeName());
112                elementAttributeHandlers.add(elementAttributeHandler);
113        }
114
115        /**
116         * @see org.x4o.xml.element.ElementLanguageModule#getElementAttributeHandlers()
117         */
118        public List<ElementAttributeHandler> getElementAttributeHandlers() {
119                return elementAttributeHandlers;
120        }
121
122        /**
123         * @see org.x4o.xml.element.ElementLanguageModule#addElementBindingHandler(ElementBindingHandler)
124         */
125        public void addElementBindingHandler(ElementBindingHandler elementBindingHandler) {
126                if (elementBindingHandler==null) {
127                        throw new NullPointerException("Can't add null binding handler.");
128                }
129                if (elementBindingHandler.getId()==null) {
130                        throw new NullPointerException("Can't add with null id property.");
131                }
132                // Check so doc tree does not loop; see EldDocHtmlWriter.findChilderen()
133                for (Class<?> cl:elementBindingHandler.getBindChildClasses()) {
134                        if (elementBindingHandler.getBindParentClass().equals(cl)) {
135                                throw new IllegalStateException("Can't add binding handler: "+elementBindingHandler.getId()+" with same parent as child class.");
136                        }
137                }
138                logger.finer("Adding ElementBindingHandler: "+elementBindingHandler);
139                elementBindingHandlers.add(elementBindingHandler);
140        }
141
142        /**
143         * @see org.x4o.xml.element.ElementLanguageModule#getElementBindingHandlers()
144         */
145        public List<ElementBindingHandler> getElementBindingHandlers() {
146                return elementBindingHandlers;
147        }
148
149        /**
150         * @see org.x4o.xml.element.ElementLanguageModule#addElementConfiguratorGlobal(ElementConfiguratorGlobal)
151         */
152        public void addElementConfiguratorGlobal(ElementConfiguratorGlobal elementConfigurator) {
153                if (elementConfigurator==null) {
154                        throw new NullPointerException("Can't add null");
155                }
156                if (elementConfigurator.getId()==null) {
157                        throw new NullPointerException("Can't add with null id property.");
158                }
159                logger.finer("Adding ElementConfiguratorGlobal: "+elementConfigurator);
160                elementConfiguratorGlobals.add(elementConfigurator);
161        }
162        
163        /**
164         * @see org.x4o.xml.element.ElementLanguageModule#getElementConfiguratorGlobals()
165         */
166        public List<ElementConfiguratorGlobal> getElementConfiguratorGlobals() {
167                return elementConfiguratorGlobals;
168        }
169
170        /**
171         * @see org.x4o.xml.element.ElementLanguageModule#addElementInterface(org.x4o.xml.element.ElementInterface)
172         */
173        public void addElementInterface(ElementInterface elementInterface) {
174                if (elementInterface==null) {
175                        throw new NullPointerException("Can't add null.");
176                }
177                if (elementInterface.getId()==null) {
178                        throw new NullPointerException("Can't add with null id property.");
179                }
180                if (elementInterface.getInterfaceClass()==null) {
181                        throw new NullPointerException("ElementInterface not correctly configured getInterfaceClass returns null.");
182                }
183                elementInterfaces.add(elementInterface);
184        }
185
186        /**
187         * @see org.x4o.xml.element.ElementLanguageModule#getElementInterfaces()
188         */
189        public List<ElementInterface> getElementInterfaces() {
190                return elementInterfaces;
191        }
192
193        /**
194         * @see org.x4o.xml.element.ElementLanguageModule#addElementNamespaceContext(org.x4o.xml.element.ElementNamespaceContext)
195         */
196        public void addElementNamespaceContext(ElementNamespaceContext elementNamespaceContext) {
197                if (elementNamespaceContext==null) {
198                        throw new NullPointerException("Can't add null.");
199                }
200                if (elementNamespaceContext.getUri()==null) {
201                        throw new NullPointerException("Can add ElementNamespaceContext without uri.");
202                }
203                if (elementNamespaceContext.getId()==null) {
204                        StringBuffer buf = new StringBuffer(30);
205                        for (char c:elementNamespaceContext.getUri().toLowerCase().toCharArray()) {
206                                if (Character.isLetter(c))      {buf.append(c);}
207                                if (Character.isDigit(c))       {buf.append(c);}
208                        }
209                        String id = buf.toString();
210                        if (id.startsWith("http"))              {id = id.substring(4);}
211                        elementNamespaceContext.setId(id);
212                }
213                // TODO: no language here so move to EL default on eld attribute tag 
214                //if (elementNamespaceContext.getSchemaUri()==null) {
215                //      elementNamespaceContext.setSchemaUri(elementNamespaceContext.getUri()+elementNamespaceContext.)
216                //}
217                logger.fine("Adding namespaceUri: "+elementNamespaceContext.getUri());
218                elementNamespaceContexts.put(elementNamespaceContext.getUri(), elementNamespaceContext);
219        }
220
221        /**
222         * @see org.x4o.xml.element.ElementLanguageModule#getElementNamespaceContext(java.lang.String)
223         */
224        public ElementNamespaceContext getElementNamespaceContext(String namespaceUri) {
225                return elementNamespaceContexts.get(namespaceUri);
226        }
227
228        /**
229         * @see org.x4o.xml.element.ElementLanguageModule#getElementNamespaceContexts()
230         */
231        public List<ElementNamespaceContext> getElementNamespaceContexts() {
232                return new ArrayList<ElementNamespaceContext>(elementNamespaceContexts.values());
233        }
234
235        /**
236         * @return the elementLanguageModuleLoader
237         */
238        public ElementLanguageModuleLoader getElementLanguageModuleLoader() {
239                return elementLanguageModuleLoader;
240        }
241
242        /**
243         * @param elementLanguageModuleLoader the elementLanguageModuleLoader to set
244         */
245        public void setElementLanguageModuleLoader(ElementLanguageModuleLoader elementLanguageModuleLoader) {
246                this.elementLanguageModuleLoader = elementLanguageModuleLoader;
247        }
248
249        /**
250         * @return the sourceResource
251         */
252        public String getSourceResource() {
253                return sourceResource;
254        }
255
256        /**
257         * @param sourceResource the sourceResource to set
258         */
259        public void setSourceResource(String sourceResource) {
260                this.sourceResource = sourceResource;
261        }
262        
263        /**
264         * Reloads the module, experiment !!
265         */
266        public void reloadModule(ElementLanguage elementLanguage,ElementLanguageModule elementLanguageModule) throws ElementLanguageModuleLoaderException {
267                elementAttributeHandlers.clear();
268                elementBindingHandlers.clear();
269                elementInterfaces.clear();
270                elementNamespaceContexts.clear();
271                
272                getElementLanguageModuleLoader().loadLanguageModule(elementLanguage, elementLanguageModule);
273        }
274}