001    /*
002     * (c) Copyright 2009 University of Bristol
003     * All rights reserved.
004     * [See end of file]
005     */
006    package net.rootdev.javardfa;
007    
008    import java.util.Collections;
009    import java.util.HashMap;
010    import java.util.Iterator;
011    import java.util.LinkedList;
012    import java.util.List;
013    import java.util.Map;
014    import javax.xml.namespace.NamespaceContext;
015    
016    public final class EvalContext implements NamespaceContext {
017    
018        EvalContext parent;
019        String base;
020        String parentSubject;
021        String parentObject;
022        String language;
023        String vocab;
024        List<String> forwardProperties;
025        List<String> backwardProperties;
026        Map<String, String> xmlnsMap = Collections.EMPTY_MAP;
027        Map<String, String> prefixMap = Collections.EMPTY_MAP;
028    
029        protected EvalContext(String base) {
030            super();
031            this.base = base;
032            this.parentSubject = base;
033            this.forwardProperties = new LinkedList<String>();
034            this.backwardProperties = new LinkedList<String>();
035        }
036    
037        public EvalContext(EvalContext toCopy) {
038            super();
039            this.base = toCopy.base;
040            this.parentSubject = toCopy.parentSubject;
041            this.parentObject = toCopy.parentObject;
042            this.language = toCopy.language;
043            this.forwardProperties = new LinkedList<String>(toCopy.forwardProperties);
044            this.backwardProperties = new LinkedList<String>(toCopy.backwardProperties);
045            this.parent = toCopy;
046            this.vocab = toCopy.vocab;
047        }
048    
049        public void setBase(String abase) {
050            // This is very dodgy. We want to check if ps and po have been changed
051            // from their typical values (base).
052            // Base changing happens very late in the day when we're streaming, and
053            // it is very fiddly to handle
054            boolean setPS = parentSubject == base;
055            boolean setPO = parentObject == base;
056    
057            if (abase.contains("#")) {
058                this.base = abase.substring(0, abase.indexOf("#"));
059            } else {
060                this.base = abase;
061            }
062    
063            if (setPS) this.parentSubject = base;
064            if (setPO) this.parentObject = base;
065            
066            if (parent != null) {
067                parent.setBase(base);
068            }
069        }
070    
071        @Override
072        public String toString() {
073            return
074                String.format("[\n\tBase: %s\n\tPS: %s\n\tPO: %s\n\tlang: %s\n\tIncomplete: -> %s <- %s\n]",
075                    base, parentSubject, parentObject, language,
076                    forwardProperties.size(), backwardProperties.size()
077                    );
078        }
079    
080        /**
081         * RDFa 1.1 prefix support
082         * @param prefix Prefix
083         * @param uri URI
084         */
085        public void setPrefix(String prefix, String uri) {
086            if (uri.length() == 0) {
087                uri = base;
088            }
089            if (prefixMap == Collections.EMPTY_MAP) prefixMap = new HashMap<String, String>();
090            prefixMap.put(prefix, uri);
091        }
092    
093        /**
094         * RDFa 1.1 prefix support.
095         * @param prefix
096         * @return
097         */
098        public String getURIForPrefix(String prefix) {
099            if (prefixMap.containsKey(prefix)) {
100                return prefixMap.get(prefix);
101            } else if (xmlnsMap.containsKey(prefix)) {
102                return xmlnsMap.get(prefix);
103            } else if (parent != null) {
104                return parent.getURIForPrefix(prefix);
105            } else {
106                return null;
107            }
108        }
109    
110        // Namespace methods
111        public void setNamespaceURI(String prefix, String uri) {
112            if (uri.length() == 0) {
113                uri = base;
114            }
115            if (xmlnsMap == Collections.EMPTY_MAP) xmlnsMap = new HashMap<String, String>();
116            xmlnsMap.put(prefix, uri);
117        }
118    
119        public String getNamespaceURI(String prefix) {
120            if (xmlnsMap.containsKey(prefix)) {
121                return xmlnsMap.get(prefix);
122            } else if (parent != null) {
123                return parent.getNamespaceURI(prefix);
124            } else {
125                return null;
126            }
127        }
128    
129        public String getPrefix(String uri) {
130            throw new UnsupportedOperationException("Not supported yet.");
131        }
132    
133        public Iterator getPrefixes(String uri) {
134            throw new UnsupportedOperationException("Not supported yet.");
135        }
136        
137        // I'm not sure about this 1.1 term business. Reuse prefix map
138        public void setTerm(String term, String uri) {
139           setPrefix(term + ":", uri);
140        }
141    
142        public String getURIForTerm(String term) {
143            return getURIForPrefix(term + ":");
144        }
145    
146        public String getBase() {
147            return base;
148        }
149    
150        public String getVocab() {
151            return vocab;
152        }
153    }
154    
155    /*
156     * (c) Copyright 2009 University of Bristol
157     * All rights reserved.
158     *
159     * Redistribution and use in source and binary forms, with or without
160     * modification, are permitted provided that the following conditions
161     * are met:
162     * 1. Redistributions of source code must retain the above copyright
163     *    notice, this list of conditions and the following disclaimer.
164     * 2. Redistributions in binary form must reproduce the above copyright
165     *    notice, this list of conditions and the following disclaimer in the
166     *    documentation and/or other materials provided with the distribution.
167     * 3. The name of the author may not be used to endorse or promote products
168     *    derived from this software without specific prior written permission.
169     *
170     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
171     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
172     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
173     * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
174     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
175     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
176     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
177     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
178     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
179     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
180     */