001    /*
002     * Copyright 2006 Stephen McConnell
003     *
004     * Licensed  under the  Apache License,  Version 2.0  (the "License");
005     * you may not use  this file  except in  compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *   http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed  under the  License is distributed on an "AS IS" BASIS,
012     * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
013     * implied.
014     *
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package net.dpml.transit;
020    
021    import java.util.Map;
022    import java.util.Hashtable;
023    import java.util.ServiceLoader;
024    
025    /**
026     * Definition of a repository layout.  Specialized layouts must extend from
027     * this base abstract class.  The class includes static methods supporting 
028     * the resolution of available layouts.  Each layout instance is associated with
029     * a unique identifier and represents the mapping between a layout strategy
030     * name and the physical structural representation of a repository.  Operations
031     * on the layout class support the translation of artifact addresses to their
032     * corresponding physicaly layout on remote systems.
033     * 
034     * @author <a href="http://www.dpml.net">Digital Product Management Laboratory</a>
035     * @version 2.0.2
036     */
037    public abstract class Layout
038    {
039        private static final Map<String, Layout> LAYOUTS = new Hashtable<String, Layout>();
040        static
041        {
042            ServiceLoader<Layout> loaders = ServiceLoader.load( Layout.class );
043            for( Layout layout : loaders )
044            {
045                String key = layout.getID();
046                if( !LAYOUTS.containsKey( key ) )
047                {
048                    LAYOUTS.put( key, layout );
049                }
050            }
051        }
052        
053       /**
054        * Return a location resolver capable for supporting the supplied id. If
055        * a handler is available the handler is returned otherwise the returned
056        * value is null.
057        *
058        * @param id the layout identifier
059        * @return the location resolver or null if not available
060        */
061        public static Layout getLayout( final String id )
062        {
063            return LAYOUTS.get( id );
064        }
065    
066        /**
067         * Return the layout identifier.  The id value is used
068         * to identify layout instances assigned to cache handlers and 
069         * resource host handlers.
070         *
071         * @return the layout id
072         */
073        public abstract String getID();
074        
075       /**
076        * Return the base path for an artifact.  The base path is the location
077        * where the file will be found. The base + "/" filename is equal to the
078        * full path.
079        *
080        * @param artifact the Artifact to resolve.
081        * @return the base path
082        */
083        public abstract String resolveBase( Artifact artifact );
084    
085        /**
086         * Returns the full path of the artifact relative to a logical root directory.
087         * The base + "/" filename is equal to the full path.
088         *
089         * @see #resolveBase
090         * @see #resolveFilename
091         * @param artifact the Artifact to resolve.
092         * @return the logical artifact path
093         */
094        public abstract String resolvePath( Artifact artifact );
095    
096        /**
097         * Return the filename for an artifact.  The base + "/" filename is equal
098         * to the full path.
099         *
100         * @see #resolveBase
101         * @see #resolveFilename
102         * @param artifact the Artifact to resolve.
103         * @return the logical artifact path
104         */
105        public abstract String resolveFilename( Artifact artifact );
106    }