1/*
2 * reserved comment block
3 * DO NOT REMOVE OR ALTER!
4 */
5/**
6 * Licensed to the Apache Software Foundation (ASF) under one
7 * or more contributor license agreements. See the NOTICE file
8 * distributed with this work for additional information
9 * regarding copyright ownership. The ASF licenses this file
10 * to you under the Apache License, Version 2.0 (the
11 * "License"); you may not use this file except in compliance
12 * with the License. You may obtain a copy of the License at
13 *
14 * http://www.apache.org/licenses/LICENSE-2.0
15 *
16 * Unless required by applicable law or agreed to in writing,
17 * software distributed under the License is distributed on an
18 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
19 * KIND, either express or implied. See the License for the
20 * specific language governing permissions and limitations
21 * under the License.
22 */
23package com.sun.org.apache.xml.internal.security.utils.resolver;
24
25import java.util.HashMap;
26import java.util.Map;
27
28import com.sun.org.apache.xml.internal.security.signature.XMLSignatureInput;
29import org.w3c.dom.Attr;
30
31/**
32 * During reference validation, we have to retrieve resources from somewhere.
33 *
34 * @author $Author: coheigea $
35 */
36public abstract class ResourceResolverSpi {
37
38    /** {@link org.apache.commons.logging} logging facility */
39    private static java.util.logging.Logger log =
40        java.util.logging.Logger.getLogger(ResourceResolverSpi.class.getName());
41
42    /** Field properties */
43    protected java.util.Map<String, String> properties = null;
44
45    /**
46     * Deprecated - used to carry state about whether resolution was being done in a secure fashion,
47     * but was not thread safe, so the resolution information is now passed as parameters to methods.
48     *
49     * @deprecated Secure validation flag is now passed to methods.
50     */
51    @Deprecated
52    protected final boolean secureValidation = true;
53
54    /**
55     * This is the workhorse method used to resolve resources.
56     *
57     * @param uri
58     * @param BaseURI
59     * @return the resource wrapped around a XMLSignatureInput
60     *
61     * @throws ResourceResolverException
62     *
63     * @deprecated New clients should override {@link #engineResolveURI(ResourceResolverContext)}
64     */
65    @Deprecated
66    public XMLSignatureInput engineResolve(Attr uri, String BaseURI)
67        throws ResourceResolverException {
68        throw new UnsupportedOperationException();
69    }
70
71    /**
72     * This is the workhorse method used to resolve resources.
73     * @param context Context to use to resolve resources.
74     *
75     * @return the resource wrapped around a XMLSignatureInput
76     *
77     * @throws ResourceResolverException
78     */
79    public XMLSignatureInput engineResolveURI(ResourceResolverContext context)
80        throws ResourceResolverException {
81        // The default implementation, to preserve backwards compatibility in the
82        // test cases, calls the old resolver API.
83        return engineResolve(context.attr, context.baseUri);
84    }
85
86    /**
87     * Method engineSetProperty
88     *
89     * @param key
90     * @param value
91     */
92    public void engineSetProperty(String key, String value) {
93        if (properties == null) {
94            properties = new HashMap<String, String>();
95        }
96        properties.put(key, value);
97    }
98
99    /**
100     * Method engineGetProperty
101     *
102     * @param key
103     * @return the value of the property
104     */
105    public String engineGetProperty(String key) {
106        if (properties == null) {
107            return null;
108        }
109        return properties.get(key);
110    }
111
112    /**
113     *
114     * @param newProperties
115     */
116    public void engineAddProperies(Map<String, String> newProperties) {
117        if (newProperties != null && !newProperties.isEmpty()) {
118            if (properties == null) {
119                properties = new HashMap<String, String>();
120            }
121            properties.putAll(newProperties);
122        }
123    }
124
125    /**
126     * Tells if the implementation does can be reused by several threads safely.
127     * It normally means that the implementation does not have any member, or there is
128     * member change between engineCanResolve & engineResolve invocations. Or it maintains all
129     * member info in ThreadLocal methods.
130     */
131    public boolean engineIsThreadSafe() {
132        return false;
133    }
134
135    /**
136     * This method helps the {@link ResourceResolver} to decide whether a
137     * {@link ResourceResolverSpi} is able to perform the requested action.
138     *
139     * @param uri
140     * @param BaseURI
141     * @return true if the engine can resolve the uri
142     *
143     * @deprecated See {@link #engineCanResolveURI(ResourceResolverContext)}
144     */
145    @Deprecated
146    public boolean engineCanResolve(Attr uri, String BaseURI) {
147        // This method used to be abstract, so any calls to "super" are bogus.
148        throw new UnsupportedOperationException();
149    }
150
151    /**
152     * This method helps the {@link ResourceResolver} to decide whether a
153     * {@link ResourceResolverSpi} is able to perform the requested action.
154     *
155     * <p>New clients should override this method, and not override {@link #engineCanResolve(Attr, String)}
156     * </p>
157     * @param context Context in which to do resolution.
158     * @return true if the engine can resolve the uri
159     */
160    public boolean engineCanResolveURI(ResourceResolverContext context) {
161        // To preserve backward compatibility with existing resolvers that might override the old method,
162        // call the old deprecated API.
163        return engineCanResolve( context.attr, context.baseUri );
164    }
165
166    /**
167     * Method engineGetPropertyKeys
168     *
169     * @return the property keys
170     */
171    public String[] engineGetPropertyKeys() {
172        return new String[0];
173    }
174
175    /**
176     * Method understandsProperty
177     *
178     * @param propertyToTest
179     * @return true if understands the property
180     */
181    public boolean understandsProperty(String propertyToTest) {
182        String[] understood = this.engineGetPropertyKeys();
183
184        if (understood != null) {
185            for (int i = 0; i < understood.length; i++) {
186                if (understood[i].equals(propertyToTest)) {
187                    return true;
188                }
189            }
190        }
191
192        return false;
193    }
194
195
196    /**
197     * Fixes a platform dependent filename to standard URI form.
198     *
199     * @param str The string to fix.
200     *
201     * @return Returns the fixed URI string.
202     */
203    public static String fixURI(String str) {
204
205        // handle platform dependent strings
206        str = str.replace(java.io.File.separatorChar, '/');
207
208        if (str.length() >= 4) {
209
210            // str =~ /^\W:\/([^/])/ # to speak perl ;-))
211            char ch0 = Character.toUpperCase(str.charAt(0));
212            char ch1 = str.charAt(1);
213            char ch2 = str.charAt(2);
214            char ch3 = str.charAt(3);
215            boolean isDosFilename = ((('A' <= ch0) && (ch0 <= 'Z'))
216                && (ch1 == ':') && (ch2 == '/')
217                && (ch3 != '/'));
218
219            if (isDosFilename && log.isLoggable(java.util.logging.Level.FINE)) {
220                log.log(java.util.logging.Level.FINE, "Found DOS filename: " + str);
221            }
222        }
223
224        // Windows fix
225        if (str.length() >= 2) {
226            char ch1 = str.charAt(1);
227
228            if (ch1 == ':') {
229                char ch0 = Character.toUpperCase(str.charAt(0));
230
231                if (('A' <= ch0) && (ch0 <= 'Z')) {
232                    str = "/" + str;
233                }
234            }
235        }
236
237        // done
238        return str;
239    }
240}
241