View Javadoc

1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *  
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *  
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License. 
18   *  
19   */
20  package org.apache.directory.server.schema.bootstrap.partition;
21  
22  
23  import java.io.BufferedReader;
24  import java.io.IOException;
25  import java.io.InputStream;
26  import java.io.InputStreamReader;
27  import java.net.URL;
28  import java.util.Enumeration;
29  import java.util.HashMap;
30  import java.util.HashSet;
31  import java.util.Iterator;
32  import java.util.Map;
33  import java.util.Set;
34  
35  
36  /**
37   * Parses the dbfile listing file within this jar.
38   *
39   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
40   * @version $Rev: 664295 $
41   */
42  public class DbFileListing
43  {
44      Map<String, DbFileType> name2type = new HashMap<String, DbFileType>();
45      private static final String BASE_PATH = DbFileListing.class.getName()
46          .substring( 0, DbFileListing.class.getName().lastIndexOf( "." ) + 1 ).replace( '.', '/' );
47  
48  
49      public DbFileListing() throws IOException
50      {
51          init();
52      }
53  
54  
55      /**
56       * Reads the DBFILES resource within some jar on the classpath that 
57       * has this file and loaded it's db files into the name2type map with
58       * something like the following entries ( key => value ):
59       * <pre>
60       * schema/master.db => MASTER_FILE
61       * schema/apacheOnealias.db => SYSTEM_INDEX
62       * schema/apacheSubalias.db => SYSTEM_INDEX
63       * schema/apacheNdn.db => SYSTEM_INDEX
64       * schema/apacheExistance.db => SYSTEM_INDEX
65       * schema/apacheAlias.db => SYSTEM_INDEX
66       * schema/apacheHierarchy.db => SYSTEM_INDEX
67       * schema/apacheUpdn.db => SYSTEM_INDEX
68       * schema/objectClass.db => USER_INDEX
69       * schema/ou.db => USER_INDEX
70       * schema/cn.db => USER_INDEX
71       * schema/m-oid.db => USER_INDEX
72       * schema/m-disabled.db => USER_INDEX
73       * </pre>
74       *
75       * @throws IOException
76       */
77      private void init() throws IOException
78      {
79  
80          boolean userIndexMode = false;
81          String line = null;
82          BufferedReader in = new BufferedReader( 
83              new InputStreamReader( 
84                  getUniqueResourceAsStream( 
85                      "DBFILES", 
86                      "bootstrap partition database file list. " + 
87                      "Be sure there is exactly one bootstrap partition jar in your classpath." ) ) );
88          try
89          {
90              while ( ( line = in.readLine() ) != null )
91              {
92                  if ( line.indexOf( "master.db" ) != -1 )
93                  {
94                      name2type.put( line.trim(), DbFileType.MASTER_FILE );
95                      continue;
96                  }
97  
98                  if ( line.indexOf( "USER INDICES" ) != -1 )
99                  {
100                     userIndexMode = true;
101                     continue;
102                 }
103 
104                 if ( userIndexMode )
105                 {
106                     name2type.put( line.trim(), DbFileType.USER_INDEX );
107                 } 
108                 else
109                 {
110                     name2type.put( line.trim(), DbFileType.SYSTEM_INDEX );
111                 }
112             }
113         }
114         finally
115         {
116             in.close();
117         }
118     }
119 
120     
121     /**
122      * Gets the DBFILE resource from within a jar off the base path.  If another jar
123      * with such a DBFILE resource exists then an error will result since the resource
124      * is not unique across all the jars.
125      *
126      * @param resourceName the file name of the resource to load
127      * @param resourceDescription
128      * @return the InputStream to read the contents of the resource
129      * @throws IOException if there are problems reading or finding a unique copy of the resource
130      */                                                                                                
131     public static InputStream getUniqueResourceAsStream( String resourceName, String resourceDescription ) throws IOException
132     {
133         resourceName = BASE_PATH + resourceName;
134         URL result = getUniqueResource( resourceName, resourceDescription );
135         return result.openStream();
136     }
137 
138     static URL getUniqueResource( String resourceName, String resourceDescription )
139             throws IOException
140     {
141         Enumeration<URL> resources = DbFileListing.class.getClassLoader().getResources( resourceName );
142         if ( !resources.hasMoreElements() )
143         {
144             throw new UniqueResourceException( resourceName, resourceDescription );
145         }
146         URL result = resources.nextElement();
147         if ( resources.hasMoreElements() )
148         {
149             throw new UniqueResourceException( resourceName, result, resources, resourceDescription);
150         }
151         return result;
152     }
153 
154 
155     public DbFileType getType( String dbfile )
156     {
157         return name2type.get( dbfile );
158     }
159 
160 
161     public Iterator<String> iterator()
162     {
163         return name2type.keySet().iterator();
164     }
165 
166 
167     public String getIndexAttributeName( String dbfile )
168     {
169         if ( dbfile.length() < 10 )
170         {
171             throw new IllegalArgumentException( "db file must have a relative jar path name of over 10 characters" );
172         }
173 
174         // remove 'schema/'
175         String dbfileName = dbfile.substring( 7 );
176         return dbfileName.substring( 0, dbfileName.length() - 3 );
177     }
178 
179 
180     /**
181      * Gets the user indices WITHOUT the system indices.
182      *
183      * @return set of user index names
184      */
185     public Set<String> getIndexedAttributes()
186     {
187         Set<String> attributes = new HashSet<String>();
188         Iterator<String> ii = iterator();
189         while( ii.hasNext() )
190         {
191             String name = ii.next();
192             if ( name2type.get( name ) == DbFileType.USER_INDEX )
193             {
194                 attributes.add( getIndexAttributeName( name ) );
195             }
196         }
197         return attributes;
198     }
199 }