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