You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by sm...@apache.org on 2014/10/22 17:44:59 UTC
[40/51] [partial] Rename packages from org.openldap.fortress to
org.apache.directory.fortress.core. Change default suffix to org.apache.
Switch default ldap api from unbound to apache ldap.
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
new file mode 100755
index 0000000..c865deb
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/PermAnt.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ant;
+
+
+import org.apache.directory.fortress.core.rbac.Permission;
+
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections. This is necessary because the
+ * Ant parser cannot deal with complex data attribute types. The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class PermAnt extends Permission
+{
+ private String antRoles;
+
+ /**
+ * Return the roles as a String.
+ *
+ * @return String contains a comma delimited set of role names assigned to permission.
+ */
+ public String getAntRoles()
+ {
+ return antRoles;
+ }
+
+ /**
+ * Accept a comma delimited String containing a list of Roles to be granted to a permission. This function
+ * will parse the String and call the setter on its parent.
+ *
+ * @param antRoles contains a comma delimited set of role names.
+ */
+ public void setAntRoles(String antRoles)
+ {
+ this.antRoles = antRoles;
+ // allow the setter to process comma delimited strings:
+ StringTokenizer tkn = new StringTokenizer(antRoles, ",");
+ if (tkn.countTokens() > 0)
+ {
+ while (tkn.hasMoreTokens())
+ {
+ String rTkn = tkn.nextToken();
+ setRole(rTkn);
+ }
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
new file mode 100755
index 0000000..c9dbda9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/SDSetAnt.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ant;
+
+
+import org.apache.directory.fortress.core.rbac.SDSet;
+
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections. This is necessary because the
+ * Ant parser cannot deal with complex data attribute types. The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class SDSetAnt extends SDSet
+{
+ private String type;
+ private String members;
+
+ /**
+ * Return the members as a String.
+ *
+ * @return String contain comma delimited list of members.
+ */
+ public String getSetMembers()
+ {
+ return members;
+ }
+
+ /**
+ * Accept a comma delimited list of members, iterate of each and call the setter on the parent class.
+ *
+ * @param members contains comma delimited set of members.
+ */
+ public void setSetMembers(String members)
+ {
+ this.members = members;
+ if (members != null)
+ {
+ StringTokenizer tkn = new StringTokenizer(members, ",");
+ if (tkn.countTokens() > 0)
+ {
+ while (tkn.hasMoreTokens())
+ {
+ String member = tkn.nextToken();
+ addMember(member);
+ }
+ }
+ }
+ }
+
+
+ /**
+ * Return the type of SD set in string format.
+ *
+ * @return String that represents static or dynamic relations.
+ */
+ public String getSetType()
+ {
+ return type;
+ }
+
+ /**
+ * Method accepts a String variable that maps to its parent's set type.
+ *
+ * @param type String value represents static or dynamic set relations.
+ */
+ public void setSetType(String type)
+ {
+ this.type = type;
+ if (type != null && type.equals("DYNAMIC"))
+ {
+ setType(SDSet.SDType.DYNAMIC);
+ }
+ else
+ {
+ setType(SDSet.SDType.STATIC);
+ }
+ }
+}
+
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java b/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
new file mode 100755
index 0000000..b75775a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/UserAnt.java
@@ -0,0 +1,301 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.ant;
+
+
+import org.apache.commons.io.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.directory.fortress.core.rbac.User;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.util.StringTokenizer;
+
+/**
+ * Entity is used by custom Apache Ant task for special handling of collections. This is necessary because the
+ * Ant parser cannot deal with complex data attribute types. The class extends a base entity.
+ *
+ * @author Shawn McKinney
+ */
+public class UserAnt extends User
+{
+ private String userProps;
+ private String email;
+ private String phone;
+ private String mobile;
+ private String city;
+ private String state;
+ private String addresses;
+ private String postalCode;
+ private String postOfficeBox;
+ private String building;
+ private String departmentNumber;
+ private String roomNumber;
+ private String photo;
+ private static final String CLS_NM = UserAnt.class.getName();
+ private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+ public String getAddresses()
+ {
+ return addresses;
+ }
+
+ public void setAddresses(String addresses)
+ {
+ this.addresses = addresses;
+ // allow the setter to process comma delimited strings:
+ StringTokenizer tkn = new StringTokenizer(addresses, ",");
+ if (tkn.countTokens() > 0)
+ {
+ while (tkn.hasMoreTokens())
+ {
+ String aTkn = tkn.nextToken();
+ getAddress().setAddress(aTkn);
+ }
+ }
+ }
+
+ public String getUserProps()
+ {
+ return userProps;
+ }
+
+ public void setUserProps( String userProps )
+ {
+ this.userProps = userProps;
+ addProperties(AttrHelper.getProperties(userProps));
+ }
+
+ public String getPostalCode()
+ {
+ return postalCode;
+ }
+
+ public void setPostalCode(String postalCode)
+ {
+ getAddress().setPostalCode(postalCode);
+ }
+
+ public String getPostOfficeBox()
+ {
+ return postOfficeBox;
+ }
+
+ public void setPostOfficeBox(String postOfficeBox)
+ {
+ getAddress().setPostOfficeBox(postOfficeBox);
+ }
+
+ public String getBuilding()
+ {
+ return building;
+ }
+
+ public void setBuilding(String building)
+ {
+ getAddress().setBuilding(building);
+ }
+
+ public String getDepartmentNumber()
+ {
+ return departmentNumber;
+ }
+
+ public void setDepartmentNumber(String departmentNumber)
+ {
+ getAddress().setDepartmentNumber(departmentNumber);
+ }
+
+ public String getRoomNumber()
+ {
+ return roomNumber;
+ }
+
+ public void setRoomNumber(String roomNumber)
+ {
+ getAddress().setRoomNumber(roomNumber);
+ }
+
+ public String getCity()
+ {
+ return city;
+ }
+
+ public void setCity(String city)
+ {
+ getAddress().setCity(city);
+ }
+
+ public String getState()
+ {
+ return state;
+ }
+
+ public void setState(String state)
+ {
+ getAddress().setState(state);
+ }
+
+ public String getCountry()
+ {
+ return country;
+ }
+
+ public void setCountry(String country)
+ {
+ getAddress().setCountry(country);
+ }
+
+ private String country;
+
+
+ /**
+ * Generally not good practice to handle passwords as Strings in Java but this method allows Ant's digester to consume field in String format from the xml input file.
+ * It subsequently converts to char[] as needed by the parent entity - {@link User}.
+ *
+ * @param password String format will be converted to char[].
+ */
+ public void setPassword(String password)
+ {
+ super.setPassword(password.toCharArray());
+ }
+
+ public String getPhone()
+ {
+ return phone;
+ }
+
+ public void setPhone(String phone)
+ {
+ this.phone = phone;
+ // allow the setter to process comma delimited strings:
+ StringTokenizer tkn = new StringTokenizer(phone, ",");
+ if (tkn.countTokens() > 0)
+ {
+ while (tkn.hasMoreTokens())
+ {
+ String pTkn = tkn.nextToken();
+ getPhones().add(pTkn);
+ }
+ }
+ }
+
+ public String getEmail()
+ {
+ return email;
+ }
+
+ public void setEmail(String email)
+ {
+ this.email = email;
+ // allow the setter to process comma delimited strings:
+ StringTokenizer tkn = new StringTokenizer(email, ",");
+ if (tkn.countTokens() > 0)
+ {
+ while (tkn.hasMoreTokens())
+ {
+ String eTkn = tkn.nextToken();
+ getEmails().add(eTkn);
+ }
+ }
+ }
+
+ public String getMobile()
+ {
+ return mobile;
+ }
+
+ public void setMobile(String mobile)
+ {
+ this.mobile = mobile;
+ // allow the setter to process comma delimited strings:
+ StringTokenizer tkn = new StringTokenizer(mobile, ",");
+ if (tkn.countTokens() > 0)
+ {
+ while (tkn.hasMoreTokens())
+ {
+ String pTkn = tkn.nextToken();
+ getMobiles().add(pTkn);
+ }
+ }
+ }
+
+ public String getPhoto()
+ {
+ return photo;
+ }
+
+ public void setPhoto( String photo )
+ {
+ this.photo = photo;
+ if( VUtil.isNotNullOrEmpty( photo ))
+ {
+ byte[] jpeg = getJpegPhoto( photo );
+ if( VUtil.isNotNullOrEmpty( jpeg ))
+ {
+ setJpegPhoto( jpeg );
+ }
+ }
+ }
+
+ private static byte[] getJpegPhoto( String fileName )
+ {
+ byte[] value = null;
+ try
+ {
+ value = readJpegFile( fileName );
+ }
+ catch ( ArrayIndexOutOfBoundsException ae )
+ {
+ // attribute is optional, do nothing here
+ }
+
+ return value;
+ }
+
+ public static byte[] readJpegFile( String fileName )
+ {
+ URL fUrl = UserAnt.class.getClassLoader().getResource( fileName );
+ byte[] image = null;
+ try
+ {
+ if ( fUrl != null )
+ {
+ image = FileUtils.readFileToByteArray( new File( fUrl.toURI() ) );
+ }
+ }
+ catch ( URISyntaxException se )
+ {
+ String warn = "readJpegFile caught URISyntaxException=" + se;
+ LOG.warn( warn );
+ }
+ catch ( IOException ioe )
+ {
+ String warn = "readJpegFile caught IOException=" + ioe;
+ LOG.warn( warn );
+ }
+ return image;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/ant/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/ant/package.html b/src/main/java/org/apache/directory/fortress/core/ant/package.html
new file mode 100755
index 0000000..ab32115
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/ant/package.html
@@ -0,0 +1,35 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+-->
+<html>
+ <head>
+ <title>Package Documentation for org.apache.directory.fortress.core.ant</title>
+ </head>
+ <body>
+ <p>
+ This package use <a href="http://ant.apache.org/">Apache Ant</a> to provide utility to provision fortress entities and policies
+ using XML files.
+ </p>
+ <p>
+ The <A HREF="package-summary.html">org.apache.directory.fortress.core.ant</a> package provides a provisioning utility that uses
+ xml files that use Apache Ant to drive fortress administrative APIs.
+ See the {@link org.apache.directory.fortress.core.ant.FortressAntTask FortressAntTask} java doc for more info on how it works.
+ </p>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/Config.java b/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
new file mode 100755
index 0000000..782c28e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/Config.java
@@ -0,0 +1,347 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.cfg;
+
+
+import java.net.URL;
+import java.util.Enumeration;
+import java.util.Properties;
+
+import org.apache.commons.configuration.PropertiesConfiguration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.CfgException;
+import org.apache.directory.fortress.core.CfgRuntimeException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.SecurityException;
+
+
+/**
+ * This class wraps <a href="http://commons.apache.org/cfg/">Apache Commons Config</a> utility and is used by internal components to retrieve name-value
+ * pair properties from its cfg context. The class will combine properties that it finds in its local property
+ * file along with data that is retrieved by name from the ldap server if name is specified within
+ * the {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM} switch.
+ * <p>
+ * The class will bootstrap itself during startup and must initialize correctly for the Fortress APIs to work correctly.
+ * <p>
+ * This object is thread safe but stores a static reference to Apache Commons Configuration {@link #config} object.
+ * </p>
+ *
+ * @author Shawn McKinney
+ */
+public class Config
+{
+ final private static String propFile = "fortress.properties";
+ final private static String userPropFile = "fortress.user.properties";
+ private static final PropertiesConfiguration config;
+ private static final String CLS_NM = Config.class.getName();
+ final private static Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+ static
+ {
+ try
+ {
+ // Load the system config bootstrap xml file.
+ URL fUrl = Config.class.getClassLoader().getResource( propFile );
+
+ if ( fUrl == null )
+ {
+ String error = "static init: Error, null cfg file: " + propFile;
+ LOG.error( error );
+ throw new java.lang.RuntimeException( error );
+ }
+
+ LOG.info( "static init: found from: {} path: {}", propFile, fUrl.getPath() );
+
+ config = new PropertiesConfiguration();
+ config.setDelimiterParsingDisabled( true );
+ config.load( fUrl );
+ LOG.info( "static init: loading from: {}", propFile );
+
+ URL fUserUrl = Config.class.getClassLoader().getResource( userPropFile );
+ if ( fUserUrl != null )
+ {
+ LOG.info( "static init: found user properties from: {} path: {}",
+ userPropFile, fUserUrl.getPath() );
+ config.load( fUserUrl );
+ }
+
+ String realmName = config.getString( GlobalIds.CONFIG_REALM );
+ if ( realmName != null && realmName.length() > 0 )
+ {
+ LOG.info( "static init: load config realm [{}]", realmName );
+ Properties props = getRemoteConfig( realmName );
+ if ( props != null )
+ {
+ for ( Enumeration e = props.propertyNames(); e.hasMoreElements(); )
+ {
+ String key = ( String ) e.nextElement();
+ String val = props.getProperty( key );
+ config.addProperty( key, val );
+ }
+ }
+ }
+ else
+ {
+ LOG.info( "static init: config realm not setup" );
+ }
+ }
+ catch ( org.apache.commons.configuration.ConfigurationException ex )
+ {
+ String error = "static init: Error loading from cfg file: [" + propFile
+ + "] ConfigurationException=" + ex;
+ LOG.error( error );
+ throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_BOOTSTRAP_FAILED, error, ex );
+ }
+ catch ( SecurityException se )
+ {
+ String error = "static init: Error loading from cfg file: [" + propFile + "] SecurityException="
+ + se;
+ LOG.error( error );
+ throw new CfgRuntimeException( GlobalErrIds.FT_CONFIG_INITIALIZE_FAILED, error, se );
+ }
+ }
+
+
+ /**
+ * Fetch the remote cfg params from ldap with given name.
+ *
+ * @param realmName required attribute contains the name of config node name on ldap.
+ * @return {@link Properties} containing collection of name/value pairs found in directory.
+ * @throws org.apache.directory.fortress.core.SecurityException
+ * in the event of system or validation error.
+ */
+ private static Properties getRemoteConfig( String realmName ) throws SecurityException
+ {
+ Properties props = null;
+ try
+ {
+ ConfigMgr cfgMgr = ConfigMgrFactory.createInstance();
+ props = cfgMgr.read( realmName );
+ }
+ catch ( CfgException ce )
+ {
+ if ( ce.getErrorId() == GlobalErrIds.FT_CONFIG_NOT_FOUND )
+ {
+ String warning = "getRemoteConfig could not find cfg entry";
+ LOG.warn( warning );
+ }
+ else
+ {
+ throw ce;
+ }
+ }
+ return props;
+ }
+
+
+ /**
+ * Gets the prop attribute as String value from the apache commons cfg component.
+ *
+ * @param name contains the name of the property.
+ * @return contains the value associated with the property or null if not not found.
+ */
+ public static String getProperty( String name )
+ {
+ String value = null;
+ if ( config != null )
+ {
+ value = ( String ) config.getProperty( name );
+ if ( LOG.isDebugEnabled() )
+ LOG.debug( "getProperty name [{}] value [{}]", name, value );
+ }
+ else
+ {
+ String error = "getProperty invalid config, can't read prop [" + name + "]";
+ LOG.error( error );
+ }
+ return value;
+ }
+
+
+ /**
+ * Get the property value from the apache commons config but specify a default value if not found.
+ *
+ * @param name contains the name of the property.
+ * @param defaultValue specified by client will be returned if property value is not found.
+ * @return contains the value for the property as a String.
+ */
+ public static String getProperty( String name, String defaultValue )
+ {
+ String value = null;
+ if ( config != null )
+ {
+ value = ( String ) config.getProperty( name );
+ }
+ else
+ {
+ String warn = "getProperty invalid config, can't read prop [" + name + "]";
+ LOG.warn( warn );
+ }
+ if ( value == null || value.length() == 0 )
+ {
+ value = defaultValue;
+ }
+ return value;
+ }
+
+
+ /**
+ * Gets the prop attribute as char value from the apache commons cfg component.
+ *
+ * @param name contains the name of the property.
+ * @return contains the value associated with the property or 0 if not not found.
+ */
+ public static char getChar( String name )
+ {
+ char value = 0;
+ if ( config != null )
+ {
+ value = ( char ) config.getProperty( name );
+ if ( LOG.isDebugEnabled() )
+ LOG.debug( "getChar name [{}] value [{}]", name, value );
+ }
+ else
+ {
+ String error = "getChar invalid config, can't read prop [" + name + "]";
+ LOG.error( error );
+ }
+ return value;
+ }
+
+
+ /**
+ * Get the property value from the apache commons config but specify a default value if not found.
+ *
+ * @param name contains the name of the property.
+ * @param defaultValue specified by client will be returned if property value is not found.
+ * @return contains the value for the property as a char.
+ */
+ public static char getChar( String name, char defaultValue )
+ {
+ char value = 0;
+ if ( config != null )
+ {
+ value = ( char ) config.getProperty( name );
+ }
+ else
+ {
+ String warn = "getChar invalid config, can't read prop [" + name + "]";
+ LOG.warn( warn );
+ }
+ if ( value == 0 )
+ {
+ value = defaultValue;
+ }
+ return value;
+ }
+
+
+ /**
+ * Gets the int attribute of the Config class, or 0 if not found.
+ *
+ * @param key name of the property name.
+ * @return The int value or 0 if not found.
+ */
+ public static int getInt( String key )
+ {
+ int value = 0;
+ if ( config != null )
+ {
+ value = config.getInt( key );
+ }
+ else
+ {
+ String warn = "getInt invalid config, can't read prop [" + key + "]";
+ LOG.warn( warn );
+ }
+ return value;
+ }
+
+
+ /**
+ * Gets the int attribute of the Config class or default value if not found.
+ *
+ * @param key name of the property name.
+ * @param defaultValue to use if property not found.
+ * @return The int value or default value if not found.
+ */
+ public static int getInt( String key, int defaultValue )
+ {
+ int value = 0;
+ if ( config != null )
+ {
+ value = config.getInt( key, defaultValue );
+ }
+ else
+ {
+ String warn = "getInt invalid config, can't read prop [" + key + "]";
+ LOG.warn( warn );
+ }
+ return value;
+ }
+
+
+ /**
+ * Gets the boolean attribute associated with the name or false if not found.
+ *
+ * @param key name of the property name.
+ * @return The boolean value or false if not found.
+ */
+ public static boolean getBoolean( String key )
+ {
+ boolean value = false;
+ if ( config != null )
+ {
+ value = config.getBoolean( key );
+ }
+ else
+ {
+ String warn = "getBoolean - invalid config, can't read prop [" + key + "]";
+ LOG.warn( warn );
+ }
+ return value;
+ }
+
+
+ /**
+ * Gets the boolean attribute associated with the name or false if not found.
+ *
+ * @param key name of the property name.
+ * @param defaultValue specified by client will be returned if property value is not found.
+ * @return The boolean value or false if not found.
+ */
+ public static boolean getBoolean( String key, boolean defaultValue )
+ {
+ boolean value = defaultValue;
+ if ( config != null )
+ {
+ value = config.getBoolean( key, defaultValue );
+ }
+ else
+ {
+ String warn = "getBoolean - invalid config, can't read prop [" + key + "]";
+ LOG.warn( warn );
+ }
+ return value;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
new file mode 100755
index 0000000..1d8f07a
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigDAO.java
@@ -0,0 +1,299 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.cfg;
+
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+
+import org.apache.directory.api.ldap.model.entry.DefaultEntry;
+import org.apache.directory.api.ldap.model.entry.Entry;
+import org.apache.directory.api.ldap.model.entry.Modification;
+import org.apache.directory.api.ldap.model.exception.LdapEntryAlreadyExistsException;
+import org.apache.directory.api.ldap.model.exception.LdapException;
+import org.apache.directory.api.ldap.model.exception.LdapNoSuchObjectException;
+import org.apache.directory.fortress.core.CreateException;
+import org.apache.directory.ldap.client.api.LdapConnection;
+import org.apache.directory.fortress.core.ldap.ApacheDsDataProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.FinderException;
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.RemoveException;
+import org.apache.directory.fortress.core.UpdateException;
+import org.apache.directory.fortress.core.util.attr.AttrHelper;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+/**
+ * This class provides data access for the standard ldap object device that has been extended to support name/value pairs.
+ * Fortress uses this data structure to store its remote cfg parameters.
+ * <p/>
+ * The Fortress Config node is a combination of:
+ * <p/>
+ * 'device' Structural Object Class is used to store basic attributes like cn which will be used for config node name.
+ * <ul>
+ * <li> ------------------------------------------
+ * <li> <code>objectclass ( 2.5.6.14 NAME 'device'</code>
+ * <li> <code>DESC 'RFC2256: a device''</code>
+ * <li> <code>SUP top STRUCTURAL</code>
+ * <li> <code>MUST cn</code>
+ * <li> <code>MAY ( serialNumber $ seeAlso $ owner $ ou $ o $ l $ description ) )</code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * 'ftProperties' AUXILIARY Object Class is used to store name/value pairs on target node.<br />
+ * <code>This aux object class can be used to store custom attributes.</code><br />
+ * <code>The properties collections consist of name/value pairs and are not constrainted by Fortress.</code><br />
+ * <ul>
+ * <li> ------------------------------------------
+ * <li> <code>objectclass ( 1.3.6.1.4.1.38088.3.2</code>
+ * <li> <code>NAME 'ftProperties'</code>
+ * <li> <code>DESC 'Fortress Properties AUX Object Class'</code>
+ * <li> <code>AUXILIARY</code>
+ * <li> <code>MAY ( ftProps ) ) </code>
+ * <li> ------------------------------------------
+ * </ul>
+ * <p/>
+ * <p/>
+ * This class is thread safe.
+ *
+ * @author Shawn McKinney
+ */
+final class ConfigDAO extends ApacheDsDataProvider
+
+{
+ private static final String CLS_NM = ConfigDAO.class.getName();
+ private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+ private static final String CONFIG_ROOT_PARAM = "config.root";
+ private static final String CONFIG_ROOT_DN = Config.getProperty( CONFIG_ROOT_PARAM );
+ private static final String DEVICE_OBJECT_CLASS_NM = "device";
+
+ private static final String CONFIG_OBJ_CLASS[] =
+ {
+ DEVICE_OBJECT_CLASS_NM, GlobalIds.PROPS_AUX_OBJECT_CLASS_NAME
+ };
+
+ private static final String[] CONFIG_ATRS =
+ {
+ GlobalIds.CN, GlobalIds.PROPS
+ };
+
+ /**
+ * Package private default constructor.
+ */
+ ConfigDAO()
+ {
+ }
+
+ /**
+ * @param name
+ * @param props
+ * @return
+ * @throws org.apache.directory.fortress.core.CreateException
+ */
+ final Properties create( String name, Properties props )
+ throws CreateException
+ {
+ LdapConnection ld = null;
+ String dn = getDn( name );
+ LOG.info( "create dn [" + dn + "]" );
+ try
+ {
+ Entry myEntry = new DefaultEntry( dn );
+ myEntry.add( GlobalIds.OBJECT_CLASS, CONFIG_OBJ_CLASS );
+ ld = getAdminConnection();
+ myEntry.add( GlobalIds.CN, name );
+ loadProperties( props, myEntry, GlobalIds.PROPS );
+ add( ld, myEntry );
+ }
+ catch ( LdapEntryAlreadyExistsException e )
+ {
+ String warning = "create config dn [" + dn + "] caught LdapEntryAlreadyExistsException="
+ + e.getMessage() + " msg=" + e.getMessage();
+ throw new CreateException( GlobalErrIds.FT_CONFIG_ALREADY_EXISTS, warning );
+ }
+ catch ( LdapException e )
+ {
+ String error;
+ error = "create config dn [" + dn + "] caught LDAPException=" + e.getMessage();
+ LOG.error( error, e );
+ throw new CreateException( GlobalErrIds.FT_CONFIG_CREATE_FAILED, error );
+ }
+ finally
+ {
+ closeAdminConnection( ld );
+ }
+ return props;
+ }
+
+
+ /**
+ * @param name
+ * @param props
+ * @return
+ * @throws org.apache.directory.fortress.core.UpdateException
+ */
+ final Properties update( String name, Properties props )
+ throws UpdateException
+ {
+ LdapConnection ld = null;
+ String dn = getDn( name );
+ LOG.info( "update dn [" + dn + "]" );
+ try
+ {
+ List<Modification> mods = new ArrayList<Modification>();
+ if ( VUtil.isNotNullOrEmpty( props ) )
+ {
+ loadProperties( props, mods, GlobalIds.PROPS, true );
+ }
+ ld = getAdminConnection();
+ if ( mods.size() > 0 )
+ {
+ ld = getAdminConnection();
+ modify( ld, dn, mods );
+ }
+ }
+ catch ( LdapException e )
+ {
+ String error = "update dn [" + dn + "] caught LDAPException=" + e.getMessage();
+ throw new UpdateException( GlobalErrIds.FT_CONFIG_UPDATE_FAILED, error );
+ }
+ finally
+ {
+ closeAdminConnection( ld );
+ }
+ return props;
+ }
+
+
+ /**
+ * @param name
+ * @throws org.apache.directory.fortress.core.RemoveException
+ */
+ final void remove( String name )
+ throws RemoveException
+ {
+ LdapConnection ld = null;
+ String dn = getDn( name );
+ LOG.info( "remove dn [" + dn + "]" );
+ try
+ {
+ ld = getAdminConnection();
+ delete( ld, dn );
+ }
+ catch ( LdapException e )
+ {
+ String error = "remove dn [" + dn + "] LDAPException=" + e.getMessage();
+ throw new RemoveException( GlobalErrIds.FT_CONFIG_DELETE_FAILED, error );
+ }
+ finally
+ {
+ closeAdminConnection( ld );
+ }
+ }
+
+
+ /**
+ * @param name
+ * @param props
+ * @return
+ * @throws org.apache.directory.fortress.core.UpdateException
+ */
+ final Properties remove( String name, Properties props )
+ throws UpdateException
+ {
+ LdapConnection ld = null;
+ String dn = getDn( name );
+ LOG.info( "remove props dn [" + dn + "]" );
+ try
+ {
+ List<Modification> mods = new ArrayList<Modification>();
+ if ( VUtil.isNotNullOrEmpty( props ) )
+ {
+ removeProperties( props, mods, GlobalIds.PROPS );
+ }
+ if ( mods.size() > 0 )
+ {
+ ld = getAdminConnection();
+ modify( ld, dn, mods );
+ }
+ }
+ catch ( LdapException e )
+ {
+ String error = "remove props dn [" + dn + "] caught LDAPException=" + e.getMessage();
+ throw new UpdateException( GlobalErrIds.FT_CONFIG_DELETE_PROPS_FAILED, error );
+ }
+ finally
+ {
+ closeAdminConnection( ld );
+ }
+ return props;
+ }
+
+
+ /**
+ * @param name
+ * @return
+ * @throws org.apache.directory.fortress.core.FinderException
+ */
+ final Properties getConfig( String name )
+ throws FinderException
+ {
+ Properties props = null;
+ LdapConnection ld = null;
+ String dn = getDn( name );
+ LOG.info( "getConfig dn [" + dn + "]" );
+ try
+ {
+ ld = getAdminConnection();
+ Entry findEntry = read( ld, dn, CONFIG_ATRS );
+ props = AttrHelper.getProperties( getAttributes( findEntry, GlobalIds.PROPS ) );
+ }
+ catch ( LdapNoSuchObjectException e )
+ {
+ String warning = "getConfig COULD NOT FIND ENTRY for dn [" + dn + "]";
+ throw new FinderException( GlobalErrIds.USER_NOT_FOUND, warning );
+ }
+ catch ( LdapException e )
+ {
+ String error = "getConfig dn [" + dn + "] caught LdapException=" + e.getMessage();
+ throw new FinderException( GlobalErrIds.FT_CONFIG_READ_FAILED, error );
+ }
+ finally
+ {
+ closeAdminConnection( ld );
+ }
+ return props;
+ }
+
+
+ /**
+ *
+ * @param name
+ * @return
+ */
+ private String getDn( String name )
+ {
+ return GlobalIds.CN + "=" + name + "," + CONFIG_ROOT_DN;
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
new file mode 100755
index 0000000..e0e15c9
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgr.java
@@ -0,0 +1,96 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.cfg;
+
+import org.apache.directory.fortress.core.SecurityException;
+
+import java.util.Properties;
+
+/**
+ * This interface prescribes CRUD methods used to manage properties stored within the ldap directory.
+ * The Fortress config nodes are used to remotely share Fortress client specific properties between processes.
+ * Fortress places no limits on the number of unique configurations that can be present at one time in the directory.
+ * The Fortress client will specify the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.
+ * Each process using Fortress client is free to share an existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public interface ConfigMgr
+{
+ /**
+ * Create a new cfg node with given name and properties. The name is required. If node already exists,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @param inProps contains {@link Properties} with list of name/value pairs to add to existing config node.
+ * @return {@link Properties} containing the collection of name/value pairs just added.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+ */
+ public Properties add(String name, Properties inProps) throws SecurityException;
+
+ /**
+ * Update existing cfg node with additional properties, or, replace existing properties. The name is required. If node does not exist,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+ * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+ */
+ public Properties update(String name, Properties inProps) throws SecurityException;
+
+ /**
+ * Completely removes named cfg node from the directory.
+ * <p/>
+ * <font size="3" color="red">This method is destructive and will remove the cfg node completely from directory.<BR>
+ * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+ * there is intended. There is no 'undo' for this operation.
+ * </font>
+ *
+ * @param name is required and maps to 'cn' attribute on 'device' object class of node targeted for operation.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event of system error.
+ */
+ public void delete(String name) throws SecurityException;
+
+ /**
+ * Delete properties from existing cfg node. The name is required. If node does not exist,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+ */
+ public void delete(String name, Properties inProps) throws SecurityException;
+
+ /**
+ * Read an existing cfg node with given name and return to caller. The name is required. If node doesn't exist,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry doesn't exist or other system error.
+ */
+ public Properties read(String name) throws SecurityException;
+}
+
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
new file mode 100755
index 0000000..8211769
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrFactory.java
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.cfg;
+
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.rbac.ClassUtil;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.rest.ConfigMgrRestImpl;
+
+/**
+ * Creates an instance of the ConfigMgr object.
+ * <p/>
+ * The default implementation class is specified as {@link ConfigMgrImpl} but can be overridden by
+ * adding the {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_IMPLEMENTATION} config property.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigMgrFactory
+{
+ private static String configClassName = Config.getProperty(GlobalIds.CONFIG_IMPLEMENTATION);
+ private final static String ENABLE_REST = "enable.mgr.impl.rest";
+ private static final boolean IS_REST = ((Config.getProperty(ENABLE_REST) != null) && (Config.getProperty(ENABLE_REST).equalsIgnoreCase("true")));
+
+ /**
+ * Create and return a reference to {@link ConfigMgr} object.
+ *
+ * @return instance of {@link ConfigMgr}.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event of failure during instantiation.
+ */
+ public static ConfigMgr createInstance()
+ throws SecurityException
+ {
+ // TODO: Don't reuse {@link VUtil#isNotNullOrEmpty} here until it is determined why it forces different execution path through GlobalIds.IS_OPENLDAP:
+ //if (!VUtil.isNotNullOrEmpty(configClassName))
+ if (configClassName == null || configClassName.compareTo("") == 0)
+ {
+ if(IS_REST)
+ {
+ configClassName = ConfigMgrRestImpl.class.getName();
+ }
+ else
+ {
+ configClassName = ConfigMgrImpl.class.getName();
+ }
+ }
+
+ return (ConfigMgr) ClassUtil.createInstance(configClassName);
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
new file mode 100755
index 0000000..1358f7e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigMgrImpl.java
@@ -0,0 +1,119 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.cfg;
+
+import org.apache.directory.fortress.core.SecurityException;
+
+import java.util.Properties;
+
+
+/**
+ * This Manager impl supplies CRUD methods used to manage properties stored within the ldap directory.
+ * The Fortress config nodes are used to remotely share Fortress client specific properties between processes.
+ * Fortress places no limits on the number of unique configurations that can be present at one time in the directory.
+ * The Fortress client will specify the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}.
+ * Each process using Fortress client is free to share an existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * <p/>
+ * This class is thread safe.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+public class ConfigMgrImpl implements ConfigMgr
+{
+ private static final ConfigP cfgP = new ConfigP();
+
+ /**
+ * Create a new cfg node with given name and properties. The name is required. If node already exists,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @param inProps contains {@link Properties} with list of name/value pairs to add to existing config node.
+ * @return {@link Properties} containing the collection of name/value pairs just added.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry already present or other system error.
+ */
+ @Override
+ public Properties add(String name, Properties inProps) throws SecurityException
+ {
+ return cfgP.add(name, inProps);
+ }
+
+
+ /**
+ * Update existing cfg node with additional properties, or, replace existing properties. The name is required. If node does not exist,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+ * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+ */
+ @Override
+ public Properties update(String name, Properties inProps) throws SecurityException
+ {
+ return cfgP.update(name, inProps);
+ }
+
+ /**
+ * Completely removes named cfg node from the directory.
+ * <p/>
+ * <font size="3" color="red">This method is destructive and will remove the cfg node completely from directory.<BR>
+ * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+ * there is intended. There is no 'undo' for this operation.
+ * </font>
+ *
+ * @param name is required and maps to 'cn' attribute on 'device' object class of node targeted for operation.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event of system error.
+ */
+ @Override
+ public void delete(String name) throws SecurityException
+ {
+ cfgP.delete(name);
+ }
+
+ /**
+ * Delete properties from existing cfg node. The name is required. If node does not exist,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+ */
+ @Override
+ public void delete(String name, Properties inProps) throws SecurityException
+ {
+ cfgP.delete(name, inProps);
+ }
+
+ /**
+ * Read an existing cfg node with given name and return to caller. The name is required. If node doesn't exist,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+ * @throws SecurityException in the event entry doesn't exist or other system error.
+ */
+ @Override
+ public Properties read(String name) throws SecurityException
+ {
+ return cfgP.read(name);
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
new file mode 100755
index 0000000..ad8b1d2
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/ConfigP.java
@@ -0,0 +1,202 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.directory.fortress.core.cfg;
+
+
+import java.util.Properties;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.directory.fortress.core.GlobalErrIds;
+import org.apache.directory.fortress.core.GlobalIds;
+import org.apache.directory.fortress.core.SecurityException;
+import org.apache.directory.fortress.core.ValidationException;
+import org.apache.directory.fortress.core.util.attr.VUtil;
+
+
+/**
+ * Process module for the configurations node used for remotely storing Fortress specific properties.
+ * Fortress places no limits on the number of unique configurations that can be present. The Fortress client will specify
+ * the preferred cfg node by name via a property named, {@link org.apache.directory.fortress.core.GlobalIds#CONFIG_REALM}. Each
+ * process using Fortress client is free to share existing node with other processes or create its own unique config
+ * instance using the methods within this class.<BR>
+ * This class does perform simple data validations to ensure data reasonability and the required fields are present.<BR>
+ * The {@link org.apache.directory.fortress.core.ant.FortressAntTask#addConfig()} method calls the {@link #add} from this class during initial base loads.
+ * Removal {@link org.apache.directory.fortress.core.ant.FortressAntTask#deleteConfig()} is performed when removal of properties is the aim.<BR>
+ * This class will accept {@link Properties}, and forward on to it's corresponding DAO class {@link ConfigDAO} for updating properties stored on behalf of Fortress.
+ * <p>
+ * Class will throw {@link SecurityException} to caller in the event of security policy, data constraint violation or system
+ * error internal to DAO object. This class will forward DAO exceptions ({@link org.apache.directory.fortress.core.FinderException},
+ * {@link org.apache.directory.fortress.core.CreateException},{@link org.apache.directory.fortress.core.UpdateException},{@link org.apache.directory.fortress.core.RemoveException}),
+ * or {@link org.apache.directory.fortress.core.ValidationException} as {@link org.apache.directory.fortress.core.SecurityException}s with appropriate
+ * error id from {@link org.apache.directory.fortress.core.GlobalErrIds}.
+ * <p>
+ * This class performs simple data validation on properties to ensure length does not exceed 100 and contents are safe text.
+ * <p/>
+
+ *
+ * @author Shawn McKinney
+ */
+final class ConfigP
+{
+ private static final String CLS_NM = ConfigP.class.getName();
+ private static final Logger LOG = LoggerFactory.getLogger( CLS_NM );
+
+
+ /**
+ * Package private constructor
+ */
+ ConfigP()
+ {
+ }
+
+
+ /**
+ * Create a new cfg node with given name and properties. The name is required. If node already exists,
+ * a {@link org.apache.directory.fortress.core.SecurityException} with error {@link GlobalErrIds#FT_CONFIG_ALREADY_EXISTS} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @param inProps contains {@link Properties} with list of name/value pairs to remove from existing config node.
+ * @return {@link Properties} containing the collection of name/value pairs just added.
+ * @throws SecurityException in the event entry already present or other system error.
+ */
+ final Properties add( String name, Properties inProps )
+ throws SecurityException
+ {
+ validate( name, inProps );
+ ConfigDAO cfgDao = new ConfigDAO();
+ return cfgDao.create( name, inProps );
+ }
+
+
+ /**
+ * Update existing cfg node with additional properties, or, replace existing properties. The name is required. If node does not exist,
+ * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @param inProps contains {@link Properties} with list of name/value pairs to add or udpate from existing config node.
+ * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+ */
+ final Properties update( String name, Properties inProps )
+ throws SecurityException
+ {
+ validate( name, inProps );
+ ConfigDAO cfgDao = new ConfigDAO();
+ return cfgDao.update( name, inProps );
+ }
+
+
+ /**
+ * Delete existing cfg node which will remove all properties associated with that node.
+ * The name is required. If node does not exist, a {@link SecurityException} with error
+ * {@link GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ * <p/>
+ * <font size="2" color="red">
+ * This method is destructive and will remove the cfg node completely from directory.<BR>
+ * Care should be taken during execution to ensure target name is correct and permanent removal of all parameters located
+ * there is intended. There is no 'undo' for this operation.
+ * </font>
+ * <p/>
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @return {@link Properties} containing the collection of name/value pairs to be added to existing node.
+ * @throws SecurityException in the event entry not present or other system error.
+ */
+ final void delete( String name )
+ throws SecurityException
+ {
+ if ( !VUtil.isNotNullOrEmpty( name ) )
+ {
+ String error = "delete detected null config realm name";
+ LOG.warn( error );
+ throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_NULL, error );
+ }
+ ConfigDAO cfgDao = new ConfigDAO();
+ cfgDao.remove( name );
+ }
+
+
+ /**
+ * Delete existing cfg node with additional properties, or, replace existing properties. The name is required. If node does not exist,
+ * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry not present or other system error.
+ */
+ final void delete( String name, Properties inProps )
+ throws SecurityException
+ {
+ validate( name, inProps );
+ ConfigDAO cfgDao = new ConfigDAO();
+ cfgDao.remove( name, inProps );
+ }
+
+
+ /**
+ * Read an existing cfg node with given name and return to caller. The name is required. If node doesn't exist,
+ * a {@link SecurityException} with error {@link org.apache.directory.fortress.core.GlobalErrIds#FT_CONFIG_NOT_FOUND} will be thrown.
+ *
+ * @param name attribute is required and maps to 'cn' attribute in 'device' object class.
+ * @return {@link Properties} containing the collection of name/value pairs just added. Maps to 'ftProps' attribute in 'ftProperties' object class.
+ * @throws org.apache.directory.fortress.core.SecurityException in the event entry doesn't exist or other system error.
+ */
+ final Properties read( String name )
+ throws SecurityException
+ {
+ Properties outProps;
+ ConfigDAO cfgDao = new ConfigDAO();
+ outProps = cfgDao.getConfig( name );
+ return outProps;
+ }
+
+
+ /**
+ * Method will perform simple validations to ensure the integrity of the {@link Properties} entity targeted for insertion
+ * or deletion in directory.
+ *
+ * @param name contains the name of the cfg node.
+ * @param entity contains the name/value properties targeted for operation.
+ * @throws org.apache.directory.fortress.core.ValidationException thrown in the event the validations fail.
+ */
+ private void validate( String name, Properties entity )
+ throws ValidationException
+ {
+ if ( !VUtil.isNotNullOrEmpty( name ) )
+ {
+ String error = "validate detected null config realm name";
+ LOG.warn( error );
+ throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_NULL, error );
+ }
+ if ( name.length() > GlobalIds.OU_LEN )
+ {
+ String error = "validate name [" + name + "] invalid length [" + name.length() + "]";
+ LOG.warn( error );
+ throw new ValidationException( GlobalErrIds.FT_CONFIG_NAME_INVLD, error );
+ }
+ if ( entity == null || entity.size() == 0 )
+ {
+ String error = "validate name [" + name + "] config props null";
+ LOG.warn( error );
+ throw new ValidationException( GlobalErrIds.FT_CONFIG_PROPS_NULL, error );
+ }
+ VUtil.properties( entity );
+ }
+}
http://git-wip-us.apache.org/repos/asf/directory-fortress-core/blob/687ee1ad/src/main/java/org/apache/directory/fortress/core/cfg/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/directory/fortress/core/cfg/package.html b/src/main/java/org/apache/directory/fortress/core/cfg/package.html
new file mode 100755
index 0000000..0bc922e
--- /dev/null
+++ b/src/main/java/org/apache/directory/fortress/core/cfg/package.html
@@ -0,0 +1,37 @@
+<!--
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+-->
+<html>
+ <head>
+ <title>Package Documentation for org.apache.directory.fortress.config</title>
+ </head>
+ <body>
+ <p>
+ This package uses <a href="http://commons.apache.org/configuration/">Apache Commons Configuration</a> APIs to provide configuration data to fortress along with CRUD APIs for storing config data on the ldap server.
+ </p>
+ <p>
+ The <b>org.apache.directory.fortress.config</b> can store its data both in a flat file or within the LDAP directory itself.
+ The <b>oamConfig.xml</b> contains the location of the bootstrap property file. The bootstrap properties
+ can then point to a remote LDAP configuration node, called a 'realm', and referenced with this property:
+ <b>config.realm</b>. An empty or null value for the config.realm property means the properties will all be stored locally in the file specified within oamConfig.xml.
+ The package also contains entities and apis that are used to perform CRUD on remote configuration parameters.
+ See the corresponding javadoc contained with this package for more info.
+ </p>
+ </body>
+</html>