SchemaLoad.java
/*
** Module : SchemaLoad.java
** Abstract : helper class to load the directory schema
**
** Copyright (c) 2010-2023, Golden Code Development Corporation.
**
** -#- -I- --Date-- ----------------Description-----------------
** 001 GES 20101116 Created initial version.
** 002 HC 20180821 Added double to the list of required object classes.
** 003 GBB 20230825 Static final field `required` to uppercase.
*/
/*
** This program is free software: you can redistribute it and/or modify
** it under the terms of the GNU Affero General Public License as
** published by the Free Software Foundation, either version 3 of the
** License, or (at your option) any later version.
**
** This program is distributed in the hope that it will be useful,
** but WITHOUT ANY WARRANTY; without even the implied warranty of
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
** GNU Affero General Public License for more details.
**
** You may find a copy of the GNU Affero GPL version 3 at the following
** location: https://www.gnu.org/licenses/agpl-3.0.en.html
**
** Additional terms under GNU Affero GPL version 3 section 7:
**
** Under Section 7 of the GNU Affero GPL version 3, the following additional
** terms apply to the works covered under the License. These additional terms
** are non-permissive additional terms allowed under Section 7 of the GNU
** Affero GPL version 3 and may not be removed by you.
**
** 0. Attribution Requirement.
**
** You must preserve all legal notices or author attributions in the covered
** work or Appropriate Legal Notices displayed by works containing the covered
** work. You may not remove from the covered work any author or developer
** credit already included within the covered work.
**
** 1. No License To Use Trademarks.
**
** This license does not grant any license or rights to use the trademarks
** Golden Code, FWD, any Golden Code or FWD logo, or any other trademarks
** of Golden Code Development Corporation. You are not authorized to use the
** name Golden Code, FWD, or the names of any author or contributor, for
** publicity purposes without written authorization.
**
** 2. No Misrepresentation of Affiliation.
**
** You may not represent yourself as Golden Code Development Corporation or FWD.
**
** You may not represent yourself for publicity purposes as associated with
** Golden Code Development Corporation, FWD, or any author or contributor to
** the covered work, without written authorization.
**
** 3. No Misrepresentation of Source or Origin.
**
** You may not represent the covered work as solely your work. All modified
** versions of the covered work must be marked in a reasonable way to make it
** clear that the modified work is not originating from Golden Code Development
** Corporation or FWD. All modified versions must contain the notices of
** attribution required in this license.
*/
package com.goldencode.p2j.directory;
import java.io.*;
import java.util.*;
import java.net.*;
import com.goldencode.p2j.cfg.*;
/**
* Provides a bootstrap loader for the directory schema. This class defines
* the filenames of the resources that are loaded and the order in which those
* resources are loaded.
* <p>
* The directory schema can be read from multiple input files. The main
* schema (which defines the standard object classes that must always exist for
* P2J) will be loaded from {@link #SYS_SCHEMA_NAME}. The J2SE method
* <code>ClassLoader.getSystemResource()</code> will be used to search the
* classpath and load the first instance of this file. The file should be
* found in the jar for P2J and it should not be modified since the P2J code
* has heavy dependencies upon those definitions.
* <p>
* Applications may optionally add their own extensions to the directory schema.
* This is done for such purposes as supporting custom security plugins using
* data stored in the directory. Application schema extensions are loaded from
* {@link #EXT_SCHEMA_NAME} using <code>ClassLoader.getSystemResources()</code>
* which will return the list of all found resources. There can be more than
* one, if there are enough jar files in the classpath that each contain that
* file. It is valid for this file to be missing, it is completely optional.
* <p>
* Since there is no pathing information in either resource name, the associated
* files must be present in the root directory of the jar files being searched
* OR in the topmost directory of a path in the CLASSPATH.
* <p>
* This search process occurs regardless of any configuration. The core P2J
* schema will be read first and then any application extensions will be read.
* This is done very early in the initialization of the runtime environment,
* before the directory itself is active. The reason loading from resources is
* a reasonable approach is that the source code for P2J (and optionally for
* applications that have their own directory schema extensions) is already
* hard coded to the specific schema. For that reason, the schema upon which
* the code is dependent should be included with the code and there should be
* no need to require configuration in order to find it.
* <p>
* The format for both files is the same (see above), but the contents should
* generally not overlap. If the application extension specifies an object class
* name that is the same as one that is already defined, it will replace that
* object class. Please note that this is VERY DANGEROUS unless you know exactly
* what you are doing.
*/
class SchemaLoad
{
/** File name for the system directory schema. */
public static final String SYS_SCHEMA_NAME = "dir_schema.xml";
/** File name for directory schema extensions. */
public static final String EXT_SCHEMA_NAME = "dir_schema_ext.xml";
/** List of object classes that must be present in the schema. */
public static final String[] REQUIRED =
{
"authMode", "auditResource", "bytes", "binding", "boolean",
"container", "dates", "double", "group", "integer", "process", "strings",
"systemRights", "string", "user"
};
/**
* Initialize the directory schema.
*
* @throws ConfigurationException
* in case of configuration error.
*/
static void initSchema()
throws ConfigurationException
{
URL[] schemas = null;
URL system = ClassLoader.getSystemResource(SYS_SCHEMA_NAME);
if (system == null)
{
String spec1 = "System directory schema (%s) cannot be found.";
throw new ConfigurationException(String.format(spec1,
SYS_SCHEMA_NAME));
}
try
{
Enumeration<URL> ext = ClassLoader.getSystemResources(EXT_SCHEMA_NAME);
if (ext != null)
{
List<URL> list = Collections.list(ext);
schemas = new URL[list.size() + 1];
schemas[0] = system;
int i = 1;
for (URL next : list)
{
schemas[i++] = next;
}
}
else
{
schemas = new URL[1];
schemas[0] = system;
}
}
catch (IOException ioe)
{
String spec2 = "Failure loading directory schema extensions (%s).";
throw new ConfigurationException(String.format(spec2,
EXT_SCHEMA_NAME));
}
try
{
SchemaStorage.initSchema(schemas, REQUIRED);
}
catch (Exception e)
{
throw new ConfigurationException("Can't initialise directory schema.",
e);
}
}
}