001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.xbean.server.repository;
018    
019    import java.io.File;
020    import java.net.MalformedURLException;
021    import java.net.URI;
022    import java.net.URL;
023    
024    /**
025     * FileSystemRepository maps resource ids to a directory on the local file system.
026     *
027     * @org.apache.xbean.XBean namespace="http://xbean.apache.org/schemas/server" element="file-system-repository"
028     *     description="Maps resource ids to a directory on the local file system."
029     *
030     * @author Dain Sundstrom
031     * @version $Id$
032     * @since 2.0
033     */
034    public class FileSystemRepository implements Repository {
035        private File root;
036    
037        /**
038         * Creates a new repository without a specified root directory.  This repository is not usable until the root
039         * directory is specified.
040         */
041        public FileSystemRepository() {
042        }
043    
044        /**
045         * Creates a new repository using the specified root directory.
046         * @param root the root directory from which resources are resolved
047         */
048        public FileSystemRepository(File root) {
049            this.root = root;
050        }
051    
052        /**
053         * Gets the root directory from which resources are resolved.
054         * @return the root directory of this repository
055         */
056        public File getRoot() {
057            return root;
058        }
059    
060        /**
061         * Sets the root directory of this repository.
062         * Note: the setting of the root directory is not synchronized and is expected to be called immediately after the
063         * default constructor in the same thread.
064         * @param root the new root directory from which resources are to be resolved
065         */
066        public void setRoot(File root) {
067            this.root = root;
068        }
069    
070        /**
071         * Gets location of the resource realitive to the root directory.  This method simply resolves the location against
072         * the root directory using root.toURI().resolve(location).
073         * @param location the location of the resource
074         * @return the absolute location of the resource or null if the root directory does not contain a readable file at
075         * the specified location
076         */
077        public URL getResource(String location) {
078            File root = this.root;
079            if (root == null) {
080                throw new NullPointerException("root directory is null");
081            }
082    
083            URI uri = root.toURI().resolve(location);
084            File file = new File(uri);
085    
086            if (!file.canRead()) {
087                return null;
088            }
089    
090            try {
091                return file.toURL();
092            } catch (MalformedURLException e) {
093                throw new IllegalArgumentException("Malformed resource " + uri);
094            }
095        }
096    }