001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 *
019 */
020 package org.apache.directory.server.schema.bootstrap.partition;
021
022
023 import java.io.BufferedReader;
024 import java.io.IOException;
025 import java.io.InputStream;
026 import java.io.InputStreamReader;
027 import java.net.URL;
028 import java.util.Enumeration;
029 import java.util.HashMap;
030 import java.util.HashSet;
031 import java.util.Iterator;
032 import java.util.Map;
033 import java.util.Set;
034
035
036 /**
037 * Parses the dbfile listing file within this jar.
038 *
039 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
040 * @version $Rev: 780345 $
041 */
042 public class DbFileListing
043 {
044 Map<String, DbFileType> name2type = new HashMap<String, DbFileType>();
045 private static final String BASE_PATH = DbFileListing.class.getName()
046 .substring( 0, DbFileListing.class.getName().lastIndexOf( "." ) + 1 ).replace( '.', '/' );
047
048
049 public DbFileListing() throws IOException
050 {
051 init();
052 }
053
054
055 /**
056 * Reads the DBFILES resource within some jar on the classpath that
057 * has this file and loaded it's db files into the name2type map with
058 * something like the following entries ( key => value ):
059 * <pre>
060 * schema/master.db => MASTER_FILE
061 * schema/apacheOnealias.db => SYSTEM_INDEX
062 * schema/apacheSubalias.db => SYSTEM_INDEX
063 * schema/apacheNdn.db => SYSTEM_INDEX
064 * schema/apacheExistence.db => SYSTEM_INDEX
065 * schema/apacheAlias.db => SYSTEM_INDEX
066 * schema/apacheOneLevel.db => SYSTEM_INDEX
067 * schema/apacheUpdn.db => SYSTEM_INDEX
068 * schema/objectClass.db => USER_INDEX
069 * schema/ou.db => USER_INDEX
070 * schema/cn.db => USER_INDEX
071 * schema/m-oid.db => USER_INDEX
072 * schema/m-disabled.db => USER_INDEX
073 * </pre>
074 *
075 * @throws IOException
076 */
077 private void init() throws IOException
078 {
079
080 boolean userIndexMode = false;
081 String line = null;
082 BufferedReader in = new BufferedReader(
083 new InputStreamReader(
084 getUniqueResourceAsStream(
085 "DBFILES",
086 "bootstrap partition database file list. " +
087 "Be sure there is exactly one bootstrap partition jar in your classpath." ) ) );
088 try
089 {
090 while ( ( line = in.readLine() ) != null )
091 {
092 if ( line.indexOf( "master.db" ) != -1 )
093 {
094 name2type.put( line.trim(), DbFileType.MASTER_FILE );
095 continue;
096 }
097
098 if ( line.indexOf( "USER INDICES" ) != -1 )
099 {
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 }