001    /*
002     * (c) Copyright 2010 University of Bristol
003     * All rights reserved.
004     * [See end of file]
005     */
006    package net.rootdev.javardfa.uri;
007    
008    import java.util.LinkedList;
009    import java.util.List;
010    import java.util.Set;
011    import javax.xml.namespace.QName;
012    import javax.xml.stream.events.Attribute;
013    import javax.xml.stream.events.StartElement;
014    import net.rootdev.javardfa.Constants;
015    import net.rootdev.javardfa.EvalContext;
016    import net.rootdev.javardfa.Resolver;
017    import net.rootdev.javardfa.Setting;
018    
019    /**
020     * This uses the RDFa 1.1 URI logic
021     *
022     * @author pldms
023     */
024    public class URIExtractor11 implements URIExtractor {
025        private Set<Setting> settings;
026        private final Resolver resolver;
027    
028        public URIExtractor11(Resolver resolver) {
029            this.resolver = resolver;
030        }
031    
032        public void setSettings(Set<Setting> settings) {
033            this.settings = settings;
034        }
035    
036        public String getURI(StartElement element, Attribute attr, EvalContext context) {
037            QName attrName = attr.getName();
038            if (attrName.equals(Constants.href) || attrName.equals(Constants.src)) // A URI
039            {
040                if (attr.getValue().length() == 0) return context.getBase();
041                else return resolver.resolve(context.getBase(), attr.getValue());
042            }
043            if (attrName.equals(Constants.about) || attrName.equals(Constants.resource)) // Safe CURIE or URI
044            {
045                return expandSafeCURIE(element, attr.getValue(), context);
046            }
047            if (attrName.equals(Constants.datatype)) // A CURIE
048            {
049                return expandCURIE(element, attr.getValue(), context);
050            }
051            throw new RuntimeException("Unexpected attribute: " + attr);
052        }
053    
054        public List<String> getURIs(StartElement element, Attribute attr, EvalContext context) {
055            List<String> uris = new LinkedList<String>();
056            String[] curies = attr.getValue().split("\\s+");
057            boolean permitReserved = Constants.rel.equals(attr.getName()) ||
058                    Constants.rev.equals(attr.getName());
059            for (String curie : curies) {
060                if (Constants.SpecialRels.contains(curie.toLowerCase())) {
061                    if (permitReserved)
062                        uris.add("http://www.w3.org/1999/xhtml/vocab#" + curie.toLowerCase());
063                } else {
064                    String uri = expandCURIE(element, curie, context);
065                    if (uri != null) {
066                        uris.add(uri);
067                    }
068                }
069            }
070            return uris;
071        }
072    
073        public String expandCURIE(StartElement element, String value, EvalContext context) {
074            if (value.startsWith("_:")) {
075                if (!settings.contains(Setting.ManualNamespaces)) return value;
076                if (context.getPrefix("_") == null) return value;
077            }
078            if (settings.contains(Setting.FormMode) && // variable
079                    value.startsWith("?")) {
080                return value;
081            }
082            int offset = value.indexOf(":") + 1;
083            if (offset == 0) {
084                if (context.getURIForTerm(value) != null) return context.getURIForTerm(value);
085                String vocab = context.getVocab();
086                if (vocab != null) {
087                    return vocab + value;
088                } else {
089                    return null;
090                }
091            }
092            String prefix = value.substring(0, offset - 1);
093    
094            // Apparently these are not allowed to expand
095            if ("xml".equals(prefix) || "xmlns".equals(prefix)) return null;
096    
097            String namespaceURI = prefix.length() == 0 ? "http://www.w3.org/1999/xhtml/vocab#" : context.getURIForPrefix(prefix);
098            if (namespaceURI == null) {
099                // Assume this is some kind of URI
100                return value;
101            }
102            
103            return namespaceURI + value.substring(offset);
104        }
105    
106        public String expandSafeCURIE(StartElement element, String value, EvalContext context) {
107            if (value.startsWith("[") && value.endsWith("]")) {
108                return expandCURIE(element, value.substring(1, value.length() - 1), context);
109            } else {
110                if (value.length() == 0) {
111                    return context.getBase();
112                }
113    
114                if (settings.contains(Setting.FormMode) &&
115                        value.startsWith("?")) {
116                    return value;
117                }
118    
119                return resolver.resolve(context.getBase(), value);
120            }
121        }
122    
123        public String resolveURI(String uri, EvalContext context) {
124            return resolver.resolve(context.getBase(), uri);
125        }
126    
127    }
128    
129    /*
130     * (c) Copyright 2010 University of Bristol
131     * All rights reserved.
132     *
133     * Redistribution and use in source and binary forms, with or without
134     * modification, are permitted provided that the following conditions
135     * are met:
136     * 1. Redistributions of source code must retain the above copyright
137     *    notice, this list of conditions and the following disclaimer.
138     * 2. Redistributions in binary form must reproduce the above copyright
139     *    notice, this list of conditions and the following disclaimer in the
140     *    documentation and/or other materials provided with the distribution.
141     * 3. The name of the author may not be used to endorse or promote products
142     *    derived from this software without specific prior written permission.
143     *
144     * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
145     * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
146     * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
147     * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
148     * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
149     * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
150     * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
151     * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
152     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
153     * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
154     */