001: /******************************************************************************
002: * JBoss, a division of Red Hat *
003: * Copyright 2006, Red Hat Middleware, LLC, and individual *
004: * contributors as indicated by the @authors tag. See the *
005: * copyright.txt in the distribution for a full listing of *
006: * individual contributors. *
007: * *
008: * This is free software; you can redistribute it and/or modify it *
009: * under the terms of the GNU Lesser General Public License as *
010: * published by the Free Software Foundation; either version 2.1 of *
011: * the License, or (at your option) any later version. *
012: * *
013: * This software is distributed in the hope that it will be useful, *
014: * but WITHOUT ANY WARRANTY; without even the implied warranty of *
015: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
016: * Lesser General Public License for more details. *
017: * *
018: * You should have received a copy of the GNU Lesser General Public *
019: * License along with this software; if not, write to the Free *
020: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA *
021: * 02110-1301 USA, or see the FSF site: http://www.fsf.org. *
022: ******************************************************************************/package org.jboss.portal.registration.policies;
023:
024: import org.jboss.portal.common.util.ParameterValidation;
025: import org.jboss.portal.jems.as.system.AbstractJBossService;
026: import org.jboss.portal.registration.Consumer;
027: import org.jboss.portal.registration.DuplicateRegistrationException;
028: import org.jboss.portal.registration.InvalidConsumerDataException;
029: import org.jboss.portal.registration.PropertyDescription;
030: import org.jboss.portal.registration.Registration;
031: import org.jboss.portal.registration.RegistrationException;
032: import org.jboss.portal.registration.RegistrationManager;
033: import org.jboss.portal.registration.RegistrationPolicy;
034:
035: import javax.xml.namespace.QName;
036: import java.util.Collections;
037: import java.util.HashSet;
038: import java.util.Map;
039: import java.util.Set;
040:
041: /**
042: * Provides a default implementation of RegistrationPolicy which should be enough for most user needs provided the
043: * appropriate {@link RegistrationPropertyValidator} has been configured to validate registration properties.
044: *
045: * @author <a href="mailto:chris.laprun@jboss.com">Chris Laprun</a>
046: * @version $Revision: 9180 $
047: * @since 2.6
048: */
049: public class DefaultRegistrationPolicy extends AbstractJBossService
050: implements RegistrationPolicy {
051: private RegistrationManager manager;
052: private RegistrationPropertyValidator validator;
053: private Map<QName, ? extends PropertyDescription> expectations;
054:
055: public RegistrationManager getManager() {
056: return manager;
057: }
058:
059: public void setManager(RegistrationManager manager) {
060: this .manager = manager;
061: }
062:
063: public void setExpectations(
064: Map<QName, ? extends PropertyDescription> registrationPropertyDescriptions) {
065: this .expectations = registrationPropertyDescriptions;
066: }
067:
068: /**
069: * Only accepts the registration if no registration with identical values exists for the Consumer identified by the
070: * specified identify and delegates the validation of properties to the configured RegistrationPropertyValidator.
071: *
072: * @throws DuplicateRegistrationException if a Consumer with the same identity has already registered with the same
073: * registration properties.
074: */
075: public void validateRegistrationDataFor(Map registrationProperties,
076: String consumerIdentity) throws IllegalArgumentException,
077: RegistrationException, DuplicateRegistrationException {
078: ParameterValidation.throwIllegalArgExceptionIfNull(
079: registrationProperties, "Registration properties");
080: ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(
081: consumerIdentity, "Consumer identity", null);
082:
083: StringBuilder message = new StringBuilder();
084:
085: // check that values are consistent with expectations
086: if (expectations != null) {
087: Set<QName> expectedNames = expectations.keySet();
088: boolean consistentWithExpectations = true;
089:
090: // check for extra properties
091: Set<QName> unexpected = new HashSet<QName>(
092: registrationProperties.keySet());
093: unexpected.removeAll(expectedNames);
094: if (!unexpected.isEmpty()) {
095: consistentWithExpectations = false;
096: message
097: .append("Consumer '")
098: .append(consumerIdentity)
099: .append(
100: "' provided values for unexpected registration properties:\n");
101: for (QName name : unexpected) {
102: message.append("\t- ").append(name).append("\n");
103: }
104: }
105:
106: for (Map.Entry<QName, ? extends PropertyDescription> entry : expectations
107: .entrySet()) {
108: QName name = entry.getKey();
109: Object value = registrationProperties.get(name);
110: try {
111: validator.validateValueFor(name, value);
112: } catch (IllegalArgumentException e) {
113: message.append("Missing value for expected '")
114: .append(name.getLocalPart()).append(
115: "' property.\n");
116: consistentWithExpectations = false;
117: }
118: }
119:
120: if (!consistentWithExpectations) {
121: log.debug(message);
122: throw new InvalidConsumerDataException(message
123: .toString());
124: }
125: }
126:
127: // check that this is not a duplicate registration
128: Consumer consumer = manager
129: .getConsumerByIdentity(consumerIdentity);
130: if (consumer != null) {
131: // allow the new registration only if the registration properties are different that existing registrations
132: // for this consumer...
133: for (Object o : consumer.getRegistrations()) {
134: Registration registration = (Registration) o;
135: if (registration
136: .hasEqualProperties(registrationProperties)) {
137: throw new DuplicateRegistrationException(
138: "Consumer named '"
139: + consumer.getName()
140: + "' has already been registered with the same set of registration properties. Registration rejected!");
141: }
142: }
143: }
144: }
145:
146: /** Simply returns the given registration id. */
147: public String createRegistrationHandleFor(String registrationId) {
148: ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(
149: registrationId, "Registration id", null);
150: return registrationId;
151: }
152:
153: /** Doesn't support automatic ConsumerGroups so always return <code>null</code>. */
154: public String getAutomaticGroupNameFor(String consumerName) {
155: ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(
156: consumerName, "Consumer name", null);
157: return null;
158: }
159:
160: /** Simply returns the given consumer name, trusted (!) to be unique. */
161: public String getConsumerIdFrom(String consumerName,
162: Map registrationProperties)
163: throws IllegalArgumentException,
164: InvalidConsumerDataException {
165: ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(
166: consumerName, "Consumer name", null);
167: return consumerName;
168: }
169:
170: /** Rejects registration if a Consumer with the specified name already exists. */
171: public void validateConsumerName(String consumerName)
172: throws IllegalArgumentException, RegistrationException {
173: ParameterValidation.throwIllegalArgExceptionIfNullOrEmpty(
174: consumerName, "Consumer name", null);
175:
176: Consumer consumer = manager
177: .getConsumerByIdentity(getConsumerIdFrom(consumerName,
178: Collections.EMPTY_MAP));
179: if (consumer != null) {
180: throw new DuplicateRegistrationException(
181: "A Consumer named '" + consumerName
182: + "' has already been registered.");
183: }
184: }
185:
186: /** Rejects name if a ConsumerGroup with the specified name already exists. */
187: public void validateConsumerGroupName(String groupName)
188: throws IllegalArgumentException, RegistrationException {
189: // this is already the behavior in the RegistrationPersistenceManager so no need to do anything
190: }
191:
192: /**
193: * Instructs this policy to use the specified RegistrationPropertyValidator. There shouldn't be any need to call this
194: * method manually, as the validator is configured via the WSRP Producer xml configuration file.
195: *
196: * @param validator
197: */
198: public void setValidator(RegistrationPropertyValidator validator) {
199: this .validator = validator;
200: }
201:
202: /**
203: * Retrieves the currently configured RegistrationPropertyValidator.
204: *
205: * @return
206: */
207: public RegistrationPropertyValidator getValidator() {
208: return validator;
209: }
210: }
|