1/*
2 * Copyright (c) 2009-2010 jMonkeyEngine
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
8 *
9 * * Redistributions of source code must retain the above copyright
10 *   notice, this list of conditions and the following disclaimer.
11 *
12 * * Redistributions in binary form must reproduce the above copyright
13 *   notice, this list of conditions and the following disclaimer in the
14 *   documentation and/or other materials provided with the distribution.
15 *
16 * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17 *   may be used to endorse or promote products derived from this software
18 *   without specific prior written permission.
19 *
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33package com.jme3.asset.plugins;
34
35import com.jme3.asset.*;
36import com.jme3.system.JmeSystem;
37import java.io.File;
38import java.io.IOException;
39import java.net.URISyntaxException;
40import java.net.URL;
41import java.util.logging.Logger;
42
43/**
44 * The <code>ClasspathLocator</code> looks up an asset in the classpath.
45 * @author Kirill Vainer
46 */
47public class ClasspathLocator implements AssetLocator {
48
49    private static final Logger logger = Logger.getLogger(ClasspathLocator.class.getName());
50    private String root = "";
51
52    public ClasspathLocator(){
53    }
54
55    public void setRootPath(String rootPath) {
56        this.root = rootPath;
57        if (root.equals("/"))
58            root = "";
59        else if (root.length() > 1){
60            if (root.startsWith("/")){
61                root = root.substring(1);
62            }
63            if (!root.endsWith("/"))
64                root += "/";
65        }
66    }
67
68    public AssetInfo locate(AssetManager manager, AssetKey key) {
69        URL url;
70        String name = key.getName();
71        if (name.startsWith("/"))
72            name = name.substring(1);
73
74        name = root + name;
75//        if (!name.startsWith(root)){
76//            name = root + name;
77//        }
78
79        if (JmeSystem.isLowPermissions()){
80            url = ClasspathLocator.class.getResource("/" + name);
81        }else{
82            url = Thread.currentThread().getContextClassLoader().getResource(name);
83        }
84        if (url == null)
85            return null;
86
87        if (url.getProtocol().equals("file")){
88            try {
89                String path = new File(url.toURI()).getCanonicalPath();
90
91                // convert to / for windows
92                if (File.separatorChar == '\\'){
93                    path = path.replace('\\', '/');
94                }
95
96                // compare path
97                if (!path.endsWith(name)){
98                    throw new AssetNotFoundException("Asset name doesn't match requirements.\n"+
99                                                     "\"" + path + "\" doesn't match \"" + name + "\"");
100                }
101            } catch (URISyntaxException ex) {
102                throw new AssetLoadException("Error converting URL to URI", ex);
103            } catch (IOException ex){
104                throw new AssetLoadException("Failed to get canonical path for " + url, ex);
105            }
106        }
107
108        try{
109            return UrlAssetInfo.create(manager, key, url);
110        }catch (IOException ex){
111            // This is different handling than URL locator
112            // since classpath locating would return null at the getResource()
113            // call, otherwise there's a more critical error...
114            throw new AssetLoadException("Failed to read URL " + url, ex);
115        }
116    }
117}
118