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 }