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.shared.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/shared-ldap-schema-0.9.18.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 contstructor. 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 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 if ( !file.exists() ) 114 { 115 // this may happen if the class path contains an element that doesn't exist 116 LOG.debug( "element {} does not exist", element ); 117 return; 118 } 119 120 if ( file.isDirectory() ) 121 { 122 getResourcesFromDirectory( map, file, pattern ); 123 } 124 else 125 { 126 getResourcesFromJarFile( map, file, pattern ); 127 } 128 } 129 130 131 private static void getResourcesFromJarFile( HashMap<String, Boolean> map, 132 File file, Pattern pattern ) 133 { 134 ZipFile zf; 135 136 try 137 { 138 zf = new ZipFile( file ); 139 } 140 catch ( ZipException e ) 141 { 142 throw new Error( e ); 143 } 144 catch ( IOException e ) 145 { 146 throw new Error( e ); 147 } 148 149 Enumeration<? extends ZipEntry> e = zf.entries(); 150 151 while ( e.hasMoreElements() ) 152 { 153 ZipEntry ze = e.nextElement(); 154 String fileName = ze.getName(); 155 boolean accept = pattern.matcher( fileName ).matches(); 156 157 if ( accept ) 158 { 159 map.put( fileName, Boolean.TRUE ); 160 } 161 } 162 try 163 { 164 zf.close(); 165 } 166 catch ( IOException e1 ) 167 { 168 throw new Error( e1 ); 169 } 170 } 171 172 173 private static void getResourcesFromDirectory( 174 HashMap<String, Boolean> map, File directory, Pattern pattern ) 175 { 176 File[] fileList = directory.listFiles(); 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 throw new Error( e ); 199 } 200 } 201 } 202 } 203 204 205 private static void getResourcesFromClassloader( HashMap<String, Boolean> map, Pattern pattern ) 206 { 207 try 208 { 209 ClassLoader cl = ResourceMap.class.getClassLoader(); 210 Enumeration<URL> indexes = cl.getResources( "META-INF/apacheds-schema.index" ); 211 while(indexes.hasMoreElements()) { 212 URL index = indexes.nextElement(); 213 InputStream in = index.openStream(); 214 BufferedReader reader = new BufferedReader( new InputStreamReader( in, "UTF-8" ) ); 215 String line = reader.readLine(); 216 while ( line != null ) 217 { 218 boolean accept = pattern.matcher( line ).matches(); 219 if ( accept ) 220 { 221 map.put( line, Boolean.TRUE ); 222 } 223 line = reader.readLine(); 224 } 225 reader.close(); 226 } 227 } 228 catch ( IOException e ) 229 { 230 throw new Error( e ); 231 } 232 } 233 234}