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 */ 020package org.apache.directory.api.ldap.schemaextractor.impl; 021 022 023import java.io.BufferedReader; 024import java.io.File; 025import java.io.IOException; 026import java.io.InputStream; 027import java.io.InputStreamReader; 028import java.net.URL; 029import java.util.Enumeration; 030import java.util.HashMap; 031import java.util.Map; 032import java.util.regex.Pattern; 033import java.util.zip.ZipEntry; 034import java.util.zip.ZipException; 035import java.util.zip.ZipFile; 036 037import org.slf4j.Logger; 038import org.slf4j.LoggerFactory; 039 040 041/** 042 * Lists LDIF resources available from the classpath. 043 * 044 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 045 */ 046public final class ResourceMap 047{ 048 /** the system property which can be used to load schema from a user specified 049 * resource like a absolute path to a directory or jar file. 050 * This is useful to start embedded DirectoryService in a servlet container environment 051 * 052 * usage: -Dschema.resource.location=/tmp/schema 053 * OR 054 * -Dschema.resource.location=/tmp/api-ldap-schema-1.0.0-M13.jar 055 * */ 056 private static final String SCHEMA_RESOURCE_LOCATION = "schema.resource.location"; 057 058 /** The logger. */ 059 private static final Logger LOG = LoggerFactory.getLogger( ResourceMap.class ); 060 061 062 /** 063 * Private constructor. 064 */ 065 private ResourceMap() 066 { 067 } 068 069 070 /** 071 * For all elements of java.class.path OR from the resource name set in the 072 * system property 'schema.resource.location' get a Map of resources 073 * Pattern pattern = Pattern.compile(".*"). 074 * The keys represent resource names and the boolean parameter indicates 075 * whether or not the resource is in a Jar file. 076 * 077 * @param pattern the pattern to match 078 * @return the resources with markers - true if resource is in Jar 079 */ 080 public static Map<String, Boolean> getResources( Pattern pattern ) 081 { 082 HashMap<String, Boolean> retval = new HashMap<String, Boolean>(); 083 084 String schemaResourceLoc = System.getProperty( SCHEMA_RESOURCE_LOCATION, "" ); 085 086 if ( schemaResourceLoc.trim().length() > 0 ) 087 { 088 LOG.debug( "loading from the user provider schema resource {}", schemaResourceLoc ); 089 090 File file = new File( schemaResourceLoc ); 091 092 if ( file.exists() ) 093 { 094 getResources( retval, schemaResourceLoc, pattern ); 095 } 096 else 097 { 098 LOG.error( "unable to load schema from the given resource value {}", schemaResourceLoc ); 099 } 100 } 101 else 102 { 103 getResourcesFromClassloader( retval, pattern ); 104 } 105 106 return retval; 107 } 108 109 110 private static void getResources( HashMap<String, Boolean> map, 111 String element, Pattern pattern ) 112 { 113 File file = new File( element ); 114 115 if ( !file.exists() ) 116 { 117 // this may happen if the class path contains an element that doesn't exist 118 LOG.debug( "element {} does not exist", element ); 119 120 return; 121 } 122 123 if ( file.isDirectory() ) 124 { 125 getResourcesFromDirectory( map, file, pattern ); 126 } 127 else 128 { 129 getResourcesFromJarFile( map, file, pattern ); 130 } 131 } 132 133 134 private static void getResourcesFromJarFile( HashMap<String, Boolean> map, 135 File file, Pattern pattern ) 136 { 137 ZipFile zf; 138 139 try 140 { 141 zf = new ZipFile( file ); 142 } 143 catch ( ZipException e ) 144 { 145 throw new Error( e ); 146 } 147 catch ( IOException e ) 148 { 149 throw new Error( e ); 150 } 151 152 Enumeration<? extends ZipEntry> e = zf.entries(); 153 154 while ( e.hasMoreElements() ) 155 { 156 ZipEntry ze = e.nextElement(); 157 String fileName = ze.getName(); 158 boolean accept = pattern.matcher( fileName ).matches(); 159 160 if ( accept ) 161 { 162 map.put( fileName, Boolean.TRUE ); 163 } 164 } 165 try 166 { 167 zf.close(); 168 } 169 catch ( IOException e1 ) 170 { 171 throw new Error( e1 ); 172 } 173 } 174 175 176 private static void getResourcesFromDirectory( 177 HashMap<String, Boolean> map, File directory, Pattern pattern ) 178 { 179 File[] fileList = directory.listFiles(); 180 181 for ( File file : fileList ) 182 { 183 if ( file.isDirectory() ) 184 { 185 getResourcesFromDirectory( map, file, pattern ); 186 } 187 else 188 { 189 try 190 { 191 String fileName = file.getCanonicalPath(); 192 boolean accept = pattern.matcher( fileName ).matches(); 193 194 if ( accept ) 195 { 196 map.put( fileName, Boolean.FALSE ); 197 } 198 } 199 catch ( IOException e ) 200 { 201 LOG.error( "Cannot load file {} : {}", file.getAbsolutePath(), e.getMessage() ); 202 203 // Continue... 204 } 205 } 206 } 207 } 208 209 210 private static void getResourcesFromClassloader( HashMap<String, Boolean> map, Pattern pattern ) 211 { 212 try 213 { 214 ClassLoader cl = ResourceMap.class.getClassLoader(); 215 Enumeration<URL> indexes = cl.getResources( "META-INF/apacheds-schema.index" ); 216 217 while ( indexes.hasMoreElements() ) 218 { 219 URL index = null; 220 221 try 222 { 223 index = indexes.nextElement(); 224 InputStream in = index.openStream(); 225 BufferedReader reader = new BufferedReader( new InputStreamReader( in, "UTF-8" ) ); 226 String line = reader.readLine(); 227 228 while ( line != null ) 229 { 230 boolean accept = pattern.matcher( line ).matches(); 231 232 if ( accept ) 233 { 234 map.put( line, Boolean.TRUE ); 235 } 236 237 line = reader.readLine(); 238 } 239 240 reader.close(); 241 } 242 catch ( IOException ioe ) 243 { 244 LOG.debug( "Cannot load resource {} : {}", index, ioe.getMessage() ); 245 // Continue... 246 } 247 } 248 } 249 catch ( IOException e ) 250 { 251 LOG.debug( "Error while loading resuce from class loaded : {}", e.getMessage() ); 252 throw new Error( e ); 253 } 254 } 255}