001: /*
002: * The contents of this file are subject to the Sapient Public License
003: * Version 1.0 (the "License"); you may not use this file except in compliance
004: * with the License. You may obtain a copy of the License at
005: * http://carbon.sf.net/License.html.
006: *
007: * Software distributed under the License is distributed on an "AS IS" basis,
008: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
009: * the specific language governing rights and limitations under the License.
010: *
011: * The Original Code is The Carbon Component Framework.
012: *
013: * The Initial Developer of the Original Code is Sapient Corporation
014: *
015: * Copyright (C) 2003 Sapient Corporation. All Rights Reserved.
016: */
017:
018: package org.sape.carbon.services.config.jndi;
019:
020: import javax.naming.Name;
021: import javax.naming.NameNotFoundException;
022: import javax.naming.NamingException;
023: import javax.naming.directory.Attributes;
024: import javax.naming.directory.DirContext;
025:
026: import org.sape.carbon.core.config.format.ConfigurationFormatService;
027: import org.sape.carbon.core.config.format.DefaultConfigurationFormatService;
028: import org.sape.carbon.core.config.node.Node;
029: import org.sape.carbon.core.config.node.NodeCreationException;
030: import org.sape.carbon.core.config.node.NodeFactory;
031: import org.sape.carbon.core.exception.InvalidParameterException;
032:
033: /**
034: * This class provides most of the functionality for creating
035: * JNDIConfigurationDocument nodes. Extentions implement the
036: * getTypeAttributeValue method that provides the type of the document (link
037: * or document).
038: *
039: * <br>Copyright 2003 Sapient
040: * @since carbon 2.0
041: * @author Douglas Voet, March 2003
042: * @version $Revision: 1.8 $($Author: dvoet $ / $Date: 2003/05/05 21:21:10 $)
043: */
044: public abstract class AbstractJNDIConfigurationDocumentFactory
045: implements NodeFactory {
046:
047: private static final ConfigurationFormatService FORMAT_SERVICE = new DefaultConfigurationFormatService();
048:
049: protected JNDILinkNodeConfiguration config;
050:
051: /**
052: * Constructs a new factory
053: * @param config configuration used to get the names of the attributes
054: * that hold node name, node and document type, and document content as well
055: * as valid attribute values for node and document type.
056: */
057: public AbstractJNDIConfigurationDocumentFactory(
058: JNDILinkNodeConfiguration config) {
059:
060: if (config == null) {
061: throw new InvalidParameterException(this .getClass(),
062: "config cannot be null");
063: }
064:
065: this .config = config;
066: }
067:
068: /**
069: * Creates JNDIConfigurationDocument objects only as children
070: * of JNDIFolders.
071: *
072: * @param parent the parent node of the folder to be created, must be of
073: * type JNDIFolder
074: * @param name the name of the node to create
075: * @throws InvalidParameterException if parent is not
076: * assignable from JNDIFolder or name is null
077: */
078: public Node getInstance(Node parent, String name)
079: throws NodeCreationException {
080:
081: // these constants are defined in order to make the code below readable
082: final String NAME = this .config.getNodeNameAttributeName();
083: final String EQUALS = this .config
084: .getAttributeNameValueSeparator();
085: final String NODE_TYPE = this .config.getNodeTypeAttributeName();
086: final String FOLDER = this .config
087: .getFolderNodeTypeAttributeValue();
088: final String DOCUMENT = this .config
089: .getDocumentNodeTypeAttributeValue();
090: final String DOC_TYPE = this .config
091: .getDocumentTypeAttributeName();
092: final String CONTENT = this .config
093: .getDocumentContectAttributeName();
094:
095: if (name == null) {
096: throw new InvalidParameterException(this .getClass(),
097: "name parameter cannot be null");
098: }
099:
100: JNDIFolder parentJNDIFolder;
101: try {
102: parentJNDIFolder = (JNDIFolder) parent;
103: } catch (ClassCastException cce) {
104: throw new InvalidParameterException(this .getClass(),
105: "parent is not assignable from JNDIFolder", cce);
106: }
107:
108: try {
109: // create the context name for the new node
110: Name nodeContextName = (Name) parentJNDIFolder
111: .getNodeContextName().clone();
112: nodeContextName.add(NAME + EQUALS + name);
113:
114: DirContext initialContext = parentJNDIFolder
115: .getInitialContext();
116:
117: try {
118: // lookup the document's attributes and validate them
119: String[] docAttributesIDs = new String[] { NODE_TYPE,
120: DOC_TYPE };
121: Attributes docAttributes = initialContext
122: .getAttributes(nodeContextName,
123: docAttributesIDs);
124:
125: if (!docAttributes.get(NODE_TYPE).contains(DOCUMENT)) {
126: // the backing data was not the correct node type
127: throw new NodeCreationException(
128: this .getClass(),
129: parent,
130: name,
131: "Context ["
132: + nodeContextName.toString()
133: + "] exists, but is missing required document attribute: ["
134: + NODE_TYPE + EQUALS + DOCUMENT
135: + "]");
136: }
137: if (!docAttributes.get(DOC_TYPE).contains(
138: getTypeAttributeValue())) {
139: // the backing data was not the correct document type
140: throw new NodeCreationException(
141: this .getClass(),
142: parent,
143: name,
144: "Context ["
145: + nodeContextName.toString()
146: + "] exists, but has incorrect type, expected type: ["
147: + getTypeAttributeValue()
148: + "], actual type: ["
149: + docAttributes.get(DOC_TYPE) + "]");
150: }
151:
152: } catch (NameNotFoundException nnfe) {
153: // context does not exist yet, but that is ok, it will be
154: // created later
155: }
156:
157: // create the new JNDIConfigurationDocument and return it
158: return new JNDIConfigurationDocument(parent, name,
159: getConfigurationFormatService(), parentJNDIFolder
160: .getInitialContext(), nodeContextName,
161: this .config, getTypeAttributeValue());
162:
163: } catch (NamingException ne) {
164: throw new NodeCreationException(this .getClass(), parent,
165: name, "Problem reading JNDI directory", ne);
166: }
167: }
168:
169: /**
170: * Gets the value of the type attribute for the node being created by the
171: * factory.
172: * The attribute is used to identify the type of node contained
173: * within the document (ConfigurationDocument or LinkNode at this time).
174: *
175: * @return String the type attribute value
176: */
177: protected abstract String getTypeAttributeValue();
178:
179: /**
180: * Method that determines which ConfigurationFormatService will be used
181: * within the ConfigurationDocuments of this package. The default
182: * implementation returns a static instance of
183: * org.sape.carbon.core.config.format.DefaultConfigurationFormatService.
184: * Override this method to
185: * change the ConfigurationFormatService used by the
186: * JNDIConfigurationDocument.
187: *
188: * @return ConfigurationFormatService
189: */
190: protected ConfigurationFormatService getConfigurationFormatService() {
191: return AbstractJNDIConfigurationDocumentFactory.FORMAT_SERVICE;
192: }
193: }
|