001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2008-2010 Sun Microsystems, Inc. 025 * Portions Copyright 2013-2015 ForgeRock AS. 026 */ 027package org.opends.guitools.controlpanel.util; 028 029import static org.opends.messages.ConfigMessages.*; 030 031import java.io.File; 032import java.io.FileFilter; 033import java.util.ArrayList; 034import java.util.Arrays; 035import java.util.List; 036 037import org.forgerock.i18n.LocalizableMessage; 038import org.forgerock.opendj.ldap.schema.Syntax; 039import org.forgerock.opendj.ldap.schema.MatchingRule; 040import org.opends.server.config.ConfigConstants; 041import org.forgerock.opendj.config.server.ConfigException; 042import org.opends.server.core.DirectoryServer; 043import org.opends.server.core.SchemaConfigManager; 044import org.opends.server.schema.SchemaConstants; 045import org.opends.server.types.AttributeType; 046import org.opends.server.types.DirectoryException; 047import org.opends.server.types.InitializationException; 048import org.opends.server.types.ObjectClass; 049import org.opends.server.types.Schema; 050 051import com.forgerock.opendj.util.OperatingSystem; 052 053/** Class used to retrieve the schema from the schema files. */ 054public class SchemaLoader 055{ 056 private Schema schema; 057 private static final String[] ATTRIBUTES_TO_KEEP = { 058 ConfigConstants.ATTR_ATTRIBUTE_TYPES_LC, 059 ConfigConstants.ATTR_OBJECTCLASSES_LC, 060 ConfigConstants.ATTR_NAME_FORMS_LC, 061 ConfigConstants.ATTR_DIT_CONTENT_RULES_LC, 062 ConfigConstants.ATTR_DIT_STRUCTURE_RULES_LC, 063 ConfigConstants.ATTR_MATCHING_RULE_USE_LC }; 064 private static final String[] OBJECTCLASS_TO_KEEP = { SchemaConstants.TOP_OBJECTCLASS_NAME }; 065 066 private final List<ObjectClass> objectclassesToKeep = new ArrayList<>(); 067 private final List<AttributeType> attributesToKeep = new ArrayList<>(); 068 /** List of matching rules to keep in the schema. */ 069 protected final List<MatchingRule> matchingRulesToKeep = new ArrayList<>(); 070 /** List of attribute syntaxes to keep in the schema. */ 071 protected final List<Syntax> syntaxesToKeep = new ArrayList<>(); 072 073 /** Constructor. */ 074 public SchemaLoader() 075 { 076 Schema sc = DirectoryServer.getSchema(); 077 for (String name : OBJECTCLASS_TO_KEEP) 078 { 079 ObjectClass oc = sc.getObjectClass(name.toLowerCase()); 080 if (oc != null) 081 { 082 objectclassesToKeep.add(oc); 083 } 084 } 085 for (String name : ATTRIBUTES_TO_KEEP) 086 { 087 AttributeType attr = sc.getAttributeType(name.toLowerCase()); 088 if (attr != null) 089 { 090 attributesToKeep.add(attr); 091 } 092 } 093 matchingRulesToKeep.addAll(sc.getMatchingRules().values()); 094 syntaxesToKeep.addAll(sc.getSyntaxes().values()); 095 } 096 097 private static String getSchemaDirectoryPath() 098 { 099 File schemaDir = DirectoryServer.getEnvironmentConfig().getSchemaDirectory(); 100 return schemaDir != null ? schemaDir.getAbsolutePath() : null; 101 } 102 103 /** 104 * Reads the schema. 105 * 106 * @throws ConfigException 107 * if an error occurs reading the schema. 108 * @throws InitializationException 109 * if an error occurs trying to find out the schema files. 110 * @throws DirectoryException 111 * if there is an error registering the minimal objectclasses. 112 */ 113 public void readSchema() throws DirectoryException, ConfigException, InitializationException 114 { 115 schema = getBaseSchema(); 116 117 String[] fileNames; 118 String schemaDirPath = getSchemaDirectoryPath(); 119 try 120 { 121 // Load install directory schema 122 File schemaDir = new File(schemaDirPath); 123 if (schemaDirPath == null || !schemaDir.exists()) 124 { 125 LocalizableMessage message = ERR_CONFIG_SCHEMA_NO_SCHEMA_DIR.get(schemaDirPath); 126 throw new InitializationException(message); 127 } 128 else if (!schemaDir.isDirectory()) 129 { 130 LocalizableMessage message = ERR_CONFIG_SCHEMA_DIR_NOT_DIRECTORY.get(schemaDirPath); 131 throw new InitializationException(message); 132 } 133 FileFilter ldifFilesFilter = new FileFilter() 134 { 135 @Override 136 public boolean accept(File f) 137 { 138 if (f != null) 139 { 140 if (f.isDirectory()) 141 { 142 return true; 143 } 144 return OperatingSystem.isWindows() ? f.getName().toLowerCase().endsWith(".ldif") 145 : f.getName().endsWith(".ldif"); 146 } 147 return false; 148 } 149 }; 150 File[] schemaFiles = schemaDir.listFiles(ldifFilesFilter); 151 List<String> fileList = new ArrayList<>(schemaFiles.length); 152 for (File f : schemaFiles) 153 { 154 if (f.isFile()) 155 { 156 fileList.add(f.getName()); 157 } 158 } 159 160 fileNames = new String[fileList.size()]; 161 fileList.toArray(fileNames); 162 Arrays.sort(fileNames); 163 } 164 catch (InitializationException ie) 165 { 166 throw ie; 167 } 168 catch (Exception e) 169 { 170 throw new InitializationException(ERR_CONFIG_SCHEMA_CANNOT_LIST_FILES.get(schemaDirPath, e.getMessage()), e); 171 } 172 173 // Iterate through the schema files and read them as an LDIF file 174 // containing a single entry. Then get the attributeTypes and 175 // objectClasses attributes from that entry and parse them to 176 // initialize the server schema. 177 for (String schemaFile : fileNames) 178 { 179 // no server context to pass 180 SchemaConfigManager.loadSchemaFile(null, schema, schemaFile); 181 } 182 } 183 184 /** 185 * Returns a basic version of the schema. The schema is created and contains 186 * enough definitions for the schema to be loaded. 187 * 188 * @return a basic version of the schema. 189 * @throws DirectoryException 190 * if there is an error registering the minimal objectclasses. 191 */ 192 protected Schema getBaseSchema() throws DirectoryException 193 { 194 Schema schema = new Schema(); 195 for (MatchingRule mr : matchingRulesToKeep) 196 { 197 schema.registerMatchingRule(mr, true); 198 } 199 for (Syntax syntax : syntaxesToKeep) 200 { 201 schema.registerSyntax(syntax, true); 202 } 203 for (AttributeType attr : attributesToKeep) 204 { 205 schema.registerAttributeType(attr, true); 206 } 207 for (ObjectClass oc : objectclassesToKeep) 208 { 209 schema.registerObjectClass(oc, true); 210 } 211 return schema; 212 } 213 214 /** 215 * Returns the schema that was read. 216 * 217 * @return the schema that was read. 218 */ 219 public Schema getSchema() 220 { 221 return schema; 222 } 223}