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.core.identity.services.metadata;
023:
024: import java.io.IOException;
025: import java.io.InputStream;
026: import java.net.URL;
027: import java.util.Map;
028:
029: import org.jboss.portal.common.io.IOTools;
030: import org.jboss.portal.core.identity.services.IdentityConstants;
031: import org.jboss.portal.identity.IdentityContext;
032: import org.jboss.portal.identity.IdentityException;
033: import org.jboss.portal.identity.IdentityServiceController;
034: import org.jboss.portal.identity.UserProfileModule;
035: import org.jboss.portal.identity.info.PropertyInfo;
036: import org.jboss.portal.jems.as.JNDI;
037: import org.jboss.portal.jems.as.system.AbstractJBossService;
038: import org.jboss.portal.workflow.service.WorkflowService;
039: import org.jboss.xb.binding.JBossXBException;
040: import org.jboss.xb.binding.Unmarshaller;
041: import org.jboss.xb.binding.UnmarshallerFactory;
042: import org.jboss.xb.binding.sunday.unmarshalling.ElementBinding;
043: import org.jboss.xb.binding.sunday.unmarshalling.SchemaBinding;
044: import org.jboss.xb.binding.sunday.unmarshalling.TermBeforeSetParentCallback;
045: import org.jboss.xb.binding.sunday.unmarshalling.TypeBinding;
046: import org.jboss.xb.binding.sunday.unmarshalling.UnmarshallingContext;
047: import org.jboss.xb.binding.sunday.unmarshalling.XsdBinder;
048: import org.jbpm.JbpmContext;
049: import org.jbpm.graph.def.ProcessDefinition;
050:
051: /**
052: * @author <a href="mailto:emuckenh@redhat.com">Emanuel Muckenhuber</a>
053: * @version $Revision$
054: */
055: public class IdentityUIConfigurationServiceImpl extends
056: AbstractJBossService implements IdentityUIConfigurationService {
057:
058: /** XML configuration location */
059: private final static String xmlLocation = "conf/identity-ui-configuration.xml";
060:
061: /** XML schema location */
062: private final static String schemaLocation = "conf/schema/identity-ui-configuration.xsd";
063:
064: /** Core Identity configration */
065: private IdentityUIConfiguration configuration;
066:
067: /** jBPM Workflow service */
068: private WorkflowService workflowService;
069:
070: /** Identity service controller */
071: private IdentityServiceController identityServiceController;
072:
073: /** Identity user profile */
074: private UserProfileModule userProfileModule;
075:
076: /** The JNDI binding */
077: private JNDI.Binding jndiBinding;
078:
079: /** The jndi name */
080: private String jndiName = null;
081:
082: public void startWorkflow() throws Exception {
083: try {
084: // Loading workflow if subscriptionmodes != automatic
085: if (this .configuration.enableWorkflow()) {
086:
087: this .isValidConfiguration();
088:
089: String subscriptionMode = this .configuration
090: .getSubscriptionMode();
091: String adminSubscriptionMode = this .configuration
092: .getAdminSubscriptionMode();
093: String emailValidationProcess = IdentityConstants.jbp_identity_validate_email_process_name;
094: if (subscriptionMode != null
095: && adminSubscriptionMode != null
096: && emailValidationProcess != null) {
097: // automatically load email validation process
098: this .createJBPMContext(emailValidationProcess);
099:
100: this .createJBPMContext(subscriptionMode);
101: this .createJBPMContext(adminSubscriptionMode);
102: log.info("jBPM workflow started ...");
103: } else {
104: throw new CoreIdentityConfigurationException(
105: "processName must not be null.");
106: }
107: } else {
108: log.info("not starting jBPM workflow ...");
109: }
110: } catch (Exception e) {
111: log
112: .error("Error while starting core identity services ...");
113: super .stopService();
114: throw new CoreIdentityConfigurationException(e);
115: }
116: }
117:
118: public void stopWorkflow() {
119:
120: }
121:
122: public void startService() throws Exception {
123: super .startService();
124: // Creating IdentityUIConfiguration
125: this .configuration = this .createConfiguration();
126:
127: if (this .jndiName != null) {
128: jndiBinding = new JNDI.Binding(jndiName, this );
129: jndiBinding.bind();
130: }
131: }
132:
133: public void stopService() throws Exception {
134: super .stopService();
135:
136: if (jndiBinding != null) {
137: jndiBinding.unbind();
138: jndiBinding = null;
139: }
140: }
141:
142: public String getJNDIName() {
143: return this .jndiName;
144: }
145:
146: public void setJNDIName(String jndiName) {
147: this .jndiName = jndiName;
148: }
149:
150: public IdentityUIConfiguration getConfiguration() {
151: return this .configuration;
152: }
153:
154: public IdentityServiceController getIdentityServiceController() {
155: return identityServiceController;
156: }
157:
158: public void setIdentityServiceController(
159: IdentityServiceController identityServiceController) {
160: this .identityServiceController = identityServiceController;
161: }
162:
163: public UserProfileModule getUserProfileModule() {
164: if (userProfileModule == null) {
165: try {
166: this .userProfileModule = (UserProfileModule) identityServiceController
167: .getIdentityContext()
168: .getObject(
169: IdentityContext.TYPE_USER_PROFILE_MODULE);
170: } catch (IdentityException e) {
171: log.error("failed to load UserProfileModule", e);
172: }
173: }
174: return this .userProfileModule;
175: }
176:
177: public void setUserProfileModule(UserProfileModule userProfileModule) {
178: this .userProfileModule = userProfileModule;
179: }
180:
181: public WorkflowService getWorkflowService()
182: throws CoreIdentityConfigurationException {
183: if (workflowService == null) {
184: throw new CoreIdentityConfigurationException(
185: "Workflow service not found. Make sure that the workflow service is deploy.");
186: }
187: return workflowService;
188: }
189:
190: public void setWorkflowService(WorkflowService workflowService) {
191: this .workflowService = workflowService;
192: }
193:
194: private void createJBPMContext(String processName)
195: throws CoreIdentityConfigurationException {
196: if (!IdentityConstants.SUBSCRIPTION_MODE_AUTOMATIC
197: .equals(processName)) {
198: String fileName = "conf/processes/" + processName + ".xml";
199: JbpmContext jbpmContext = null;
200:
201: try {
202: jbpmContext = this .getWorkflowService()
203: .getJbpmConfiguration().createJbpmContext();
204:
205: ProcessDefinition processDefinition = jbpmContext
206: .getGraphSession().findLatestProcessDefinition(
207: processName);
208: if (processDefinition == null) {
209: processDefinition = ProcessDefinition
210: .parseXmlResource(fileName);
211: jbpmContext
212: .deployProcessDefinition(processDefinition);
213: log.debug("deloying process definition: "
214: + processName);
215: } else {
216: if (this .configuration.isOverwriteWorkflow()) {
217: ProcessDefinition fromConfig = ProcessDefinition
218: .parseXmlResource(fileName);
219: jbpmContext.deployProcessDefinition(fromConfig);
220: log.debug("overwriting process definition: "
221: + processName);
222: }
223: }
224: } catch (Exception e) {
225: throw new CoreIdentityConfigurationException(
226: "I don't like your subscription mode! Please make sure that the file and the process name match - also check the syntax.");
227: } finally {
228: // Closing JbpmContext
229: IOTools.safeClose(jbpmContext);
230: }
231: }
232: }
233:
234: private IdentityUIConfiguration createConfiguration()
235: throws CoreIdentityConfigurationException {
236: try {
237: SchemaBinding schema = XsdBinder
238: .bind(getURL(schemaLocation).toString());
239: schema.setIgnoreUnresolvedFieldOrClass(false);
240:
241: TermBeforeSetParentCallback componentCallback = new TermBeforeSetParentCallback() {
242: public Object beforeSetParent(Object o,
243: UnmarshallingContext ctx) {
244: UIComponentConfiguration uiComponent = null;
245: ElementBinding eb = (ElementBinding) ctx
246: .getParticle().getTerm();
247: String localPart = eb.getQName().getLocalPart();
248: if ("ui-component".equals(localPart)) {
249: uiComponent = (UIComponentConfiguration) o;
250: try {
251: // Getting property reference
252: PropertyInfo propertyInfo = getUserProfileModule()
253: .getProfileInfo().getPropertyInfo(
254: uiComponent
255: .getPropertyRef());
256: uiComponent.setPropertyInfo(propertyInfo);
257: } catch (IdentityException e) {
258: uiComponent = null;
259: throw new IllegalArgumentException(
260: "cannot resolve property: "
261: + uiComponent
262: .getPropertyRef());
263: }
264: }
265: return uiComponent;
266: }
267: };
268:
269: // Adding callback for ui-components
270: TypeBinding cb = schema
271: .getType(new javax.xml.namespace.QName(
272: "UIComponent"));
273: cb.setBeforeSetParentCallback(componentCallback);
274:
275: TermBeforeSetParentCallback valueCallback = new TermBeforeSetParentCallback() {
276: public Object beforeSetParent(Object o,
277: UnmarshallingContext ctx) {
278:
279: ElementBinding eb = (ElementBinding) ctx
280: .getParticle().getTerm();
281: String localPart = eb.getQName().getLocalPart();
282: Map m = (Map) o;
283: if ("values".equals(localPart)) {
284: UIComponentConfiguration uiComponent = (UIComponentConfiguration) ctx
285: .getParentValue();
286: if (m
287: .containsKey(IdentityConstants.COMPONENT_VALUE_LOCALE)) {
288: uiComponent
289: .setPredefinedMapValues(IdentityConstants.COMPONENT_VALUE_LOCALE);
290: m
291: .remove(IdentityConstants.COMPONENT_VALUE_LOCALE);
292: } else if (m
293: .containsKey(IdentityConstants.COMPONENT_VALUE_THEME)) {
294: uiComponent
295: .setPredefinedMapValues(IdentityConstants.COMPONENT_VALUE_THEME);
296: m
297: .remove(IdentityConstants.COMPONENT_VALUE_THEME);
298: } else if (m
299: .containsKey(IdentityConstants.COMPONENT_VALUE_TIMEZONE)) {
300: uiComponent
301: .setPredefinedMapValues(IdentityConstants.COMPONENT_VALUE_TIMEZONE);
302: m
303: .remove(IdentityConstants.COMPONENT_VALUE_TIMEZONE);
304: }
305: }
306: return m;
307: }
308: };
309:
310: // Adding callback for ui-component values
311: TypeBinding vb = schema
312: .getType(new javax.xml.namespace.QName(
313: "componentValues"));
314: vb.setBeforeSetParentCallback(valueCallback);
315:
316: // Unmarshalling && creating configuration
317: Unmarshaller unmarshaller = UnmarshallerFactory
318: .newInstance().newUnmarshaller();
319: return (IdentityUIConfiguration) unmarshaller.unmarshal(
320: getResource(xmlLocation), schema);
321: } catch (IOException e) {
322: throw new CoreIdentityConfigurationException(
323: "Could not find configuration file or schema.");
324: } catch (JBossXBException e) {
325: throw new CoreIdentityConfigurationException(
326: "Could not parse configuration file.");
327: } catch (Throwable e) {
328: throw new CoreIdentityConfigurationException(
329: "Could not parse configuration file. If you run JBoss Portal with JBoss AS 4.0.5 or minor please check the jboss portal wiki.");
330: }
331: }
332:
333: public boolean isValidConfiguration()
334: throws CoreIdentityConfigurationException {
335: if (this .configuration.enableWorkflow()) {
336: this .getWorkflowService();
337: }
338: return true;
339: }
340:
341: protected InputStream getResource(String path) throws IOException {
342: URL url = Thread.currentThread().getContextClassLoader()
343: .getResource(path);
344: if (url == null)
345: throw new IOException();
346: return url.openStream();
347: }
348:
349: private URL getURL(String path) throws IOException {
350: URL url = Thread.currentThread().getContextClassLoader()
351: .getResource(path);
352: if (url == null)
353: throw new IOException();
354: return url;
355: }
356: }
|