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