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.tools; 021 022 023 import java.io.File; 024 025 import jdbm.helper.MRU; 026 import jdbm.recman.BaseRecordManager; 027 import jdbm.recman.CacheRecordManager; 028 029 import org.apache.commons.cli.CommandLine; 030 import org.apache.commons.cli.Option; 031 import org.apache.commons.cli.Options; 032 import org.apache.directory.server.constants.ApacheSchemaConstants; 033 import org.apache.directory.server.core.DefaultDirectoryService; 034 import org.apache.directory.server.core.DirectoryService; 035 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmIndex; 036 import org.apache.directory.server.core.partition.impl.btree.jdbm.JdbmMasterTable; 037 import org.apache.directory.server.i18n.I18n; 038 import org.apache.directory.server.xdbm.Tuple; 039 import org.apache.directory.server.xdbm.tools.IndexUtils; 040 import org.apache.directory.shared.ldap.cursor.Cursor; 041 import org.apache.directory.shared.ldap.entry.DefaultServerEntry; 042 import org.apache.directory.shared.ldap.entry.EntryAttribute; 043 import org.apache.directory.shared.ldap.entry.ServerEntry; 044 import org.apache.directory.shared.ldap.schema.AttributeType; 045 import org.apache.directory.shared.ldap.schema.SchemaManager; 046 047 048 /** 049 * Simple tool used to dump the contents of a jdbm based partition. 050 * 051 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 052 * @version $Rev: 442600 $ 053 */ 054 public class IndexCommand extends ToolCommand 055 { 056 private SchemaManager schemaManager; 057 058 private DirectoryService directoryService; 059 060 public IndexCommand() 061 { 062 super( "index" ); 063 } 064 065 066 private SchemaManager loadSchemaManager() throws Exception 067 { 068 // -------------------------------------------------------------------- 069 // Load the bootstrap schemas to start up the schema partition 070 // -------------------------------------------------------------------- 071 directoryService = new DefaultDirectoryService(); 072 directoryService.setWorkingDirectory( getInstanceLayout().getPartitionsDir() ); 073 directoryService.startup(); 074 075 SchemaManager schemaManager = directoryService.getSchemaManager(); 076 077 return schemaManager; 078 } 079 080 081 public void execute( CommandLine cmdline ) throws Exception 082 { 083 // getLayout().verifyInstallation(); 084 schemaManager = loadSchemaManager(); 085 086 String[] partitions = cmdline.getOptionValues( 'p' ); 087 String attribute = cmdline.getOptionValue( 'a' ); 088 String indexDirPath = cmdline.getOptionValue( 'w' ); 089 090 for ( int ii = 0; ii < partitions.length; ii++ ) 091 { 092 File partitionDirectory = new File( getInstanceLayout().getPartitionsDir(), partitions[ii] ); 093 File indexDir = null; 094 095 if( indexDirPath != null ) 096 { 097 indexDir = new File( indexDirPath ); 098 } 099 100 AttributeType attrType = schemaManager.lookupAttributeTypeRegistry( attribute ); 101 102 System.out.println( "building index for attribute type: " + attrType + ", of the partition: " + partitions[ii] ); 103 if( indexDir != null ) 104 { 105 System.out.println( "The index file location is: " + indexDir.getAbsolutePath() ); 106 } 107 108 buildIndex( partitionDirectory, indexDir, attrType ); 109 } 110 111 directoryService.shutdown(); 112 } 113 114 115 @SuppressWarnings("unchecked") 116 private void buildIndex( File partitionDirectory, File indexDirectory, AttributeType attributeType ) throws Exception 117 { 118 if ( !partitionDirectory.exists() ) 119 { 120 System.err.println( I18n.err( I18n.ERR_196, partitionDirectory ) ); 121 System.exit( 1 ); 122 } 123 124 String path = partitionDirectory.getPath() + File.separator + "master"; 125 BaseRecordManager base = new BaseRecordManager( path ); 126 base.disableTransactions(); 127 CacheRecordManager recMan = new CacheRecordManager( base, new MRU( 1000 ) ); 128 129 JdbmMasterTable<ServerEntry> master = new JdbmMasterTable<ServerEntry>( recMan, schemaManager ); 130 JdbmIndex index = new JdbmIndex(); 131 index.setAttributeId( attributeType.getName() ); 132 index.setCacheSize( JdbmIndex.DEFAULT_INDEX_CACHE_SIZE ); 133 index.setNumDupLimit( JdbmIndex.DEFAULT_DUPLICATE_LIMIT ); 134 135 if( indexDirectory == null ) 136 { 137 indexDirectory = partitionDirectory; 138 } 139 140 index.setWkDirPath( indexDirectory ); 141 index.init( schemaManager, attributeType, indexDirectory ); 142 143 IndexUtils.printContents( index ); 144 145 JdbmIndex existenceIdx = new JdbmIndex(); 146 existenceIdx.setAttributeId( ApacheSchemaConstants.APACHE_EXISTENCE_AT_OID ); 147 existenceIdx.setCacheSize( JdbmIndex.DEFAULT_INDEX_CACHE_SIZE ); 148 existenceIdx.setNumDupLimit( JdbmIndex.DEFAULT_DUPLICATE_LIMIT ); 149 150 existenceIdx.setWkDirPath( partitionDirectory ); 151 existenceIdx.init( schemaManager, schemaManager.lookupAttributeTypeRegistry( ApacheSchemaConstants.APACHE_EXISTENCE_AT_OID ), partitionDirectory ); 152 153 Cursor<Tuple<Long,ServerEntry>> list = master.cursor(); 154 155 while ( list.next() ) 156 { 157 Tuple<Long,ServerEntry> tuple = list.get(); 158 Long id = tuple.getKey(); 159 DefaultServerEntry entry = ( DefaultServerEntry ) tuple.getValue(); 160 161 EntryAttribute attr = entry.get( attributeType ); 162 if ( attr == null ) 163 { 164 continue; 165 } 166 167 for ( int ii = 0; ii < attr.size(); ii++ ) 168 { 169 index.add( attr.get( ii ).get(), id ); 170 } 171 172 existenceIdx.add( attributeType.getOid(), id ); 173 } 174 175 index.sync(); 176 index.close(); 177 existenceIdx.sync(); 178 existenceIdx.close(); 179 } 180 181 182 public Options getOptions() 183 { 184 Options opts = new Options(); 185 Option op = null; 186 op = new Option( "p", "partitions", true, "the partitions to add the attribute indices to" ); 187 op.setRequired( true ); 188 op.setValueSeparator( File.pathSeparatorChar ); 189 opts.addOption( op ); 190 op = new Option( "a", "attributes", true, "the attribute to index" ); 191 op.setRequired( true ); 192 op.setValueSeparator( File.pathSeparatorChar ); 193 opts.addOption( op ); 194 op = new Option( "i", "install-path", true, "path to apacheds installation directory" ); 195 op.setRequired( true ); 196 opts.addOption( op ); 197 op = new Option( "w", "index-path", true, "path to the directory where index should be stored" ); 198 op.setRequired( false ); 199 opts.addOption( op ); 200 201 return opts; 202 } 203 }