001    /**
002     *  Licensed to the Apache Software Foundation (ASF) under one or more
003     *  contributor license agreements.  See the NOTICE file distributed with
004     *  this work for additional information regarding copyright ownership.
005     *  The ASF licenses this file to You under the Apache License, Version 2.0
006     *  (the "License"); you may not use this file except in compliance with
007     *  the License.  You may obtain a copy of the License at
008     *
009     *     http://www.apache.org/licenses/LICENSE-2.0
010     *
011     *  Unless required by applicable law or agreed to in writing, software
012     *  distributed under the License is distributed on an "AS IS" BASIS,
013     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     *  See the License for the specific language governing permissions and
015     *  limitations under the License.
016     */
017    package org.apache.geronimo.console.jmsmanager.wizard;
018    
019    import java.io.BufferedOutputStream;
020    import java.io.ByteArrayOutputStream;
021    import java.io.File;
022    import java.io.FileOutputStream;
023    import java.io.IOException;
024    import java.util.ArrayList;
025    import java.util.Iterator;
026    import java.util.List;
027    import java.util.Map;
028    import java.util.Properties;
029    import javax.enterprise.deploy.model.DDBean;
030    import javax.enterprise.deploy.model.DDBeanRoot;
031    import javax.enterprise.deploy.spi.DeploymentConfiguration;
032    import javax.enterprise.deploy.spi.DeploymentManager;
033    import javax.enterprise.deploy.spi.Target;
034    import javax.enterprise.deploy.spi.TargetModuleID;
035    import javax.enterprise.deploy.spi.status.ProgressObject;
036    import javax.portlet.ActionResponse;
037    import javax.portlet.PortletRequest;
038    import javax.portlet.PortletSession;
039    import org.apache.commons.logging.Log;
040    import org.apache.commons.logging.LogFactory;
041    import org.apache.geronimo.connector.deployment.jsr88.AdminObjectDCB;
042    import org.apache.geronimo.connector.deployment.jsr88.AdminObjectInstance;
043    import org.apache.geronimo.connector.deployment.jsr88.ConnectionDefinition;
044    import org.apache.geronimo.connector.deployment.jsr88.ConnectionDefinitionInstance;
045    import org.apache.geronimo.connector.deployment.jsr88.Connector15DCBRoot;
046    import org.apache.geronimo.connector.deployment.jsr88.ConnectorDCB;
047    import org.apache.geronimo.connector.deployment.jsr88.ResourceAdapter;
048    import org.apache.geronimo.connector.deployment.jsr88.ResourceAdapterInstance;
049    import org.apache.geronimo.connector.deployment.jsr88.SinglePool;
050    import org.apache.geronimo.console.MultiPageAbstractHandler;
051    import org.apache.geronimo.console.MultiPageModel;
052    import org.apache.geronimo.console.jmsmanager.ManagementHelper;
053    import org.apache.geronimo.console.util.PortletManager;
054    import org.apache.geronimo.deployment.service.jsr88.EnvironmentData;
055    import org.apache.geronimo.deployment.tools.loader.ConnectorDeployable;
056    import org.apache.geronimo.kernel.repository.Artifact;
057    import org.apache.geronimo.naming.deployment.jsr88.GBeanLocator;
058    
059    /**
060     * Base class for portlet helpers
061     *
062     * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
063     */
064    public abstract class AbstractHandler extends MultiPageAbstractHandler {
065        private final static Log log = LogFactory.getLog(AbstractHandler.class);
066        // ********** This part specific to JMS portlets **********
067    
068        protected final static String LIST_MODE="list";
069        protected final static String SELECT_PROVIDER_MODE="provider";
070        protected final static String CONFIGURE_RA_MODE="ra";
071        protected final static String ADD_FACTORY_MODE="factory";
072        protected final static String SELECT_FACTORY_TYPE_MODE="factoryType";
073        protected final static String ADD_DESTINATION_MODE="destination";
074        protected final static String SELECT_DESTINATION_TYPE_MODE="destinationType";
075        protected final static String REVIEW_MODE="review";
076        protected final static String SHOW_PLAN_MODE="plan";
077        protected final static String DEPLOY_MODE="deploy";
078    
079        protected final static String PROVIDER_PARAMETER="provider";
080        protected final static String RAR_FILE_PARAMETER="rar";
081        protected final static String DEPENDENCY_PARAMETER="dependency";
082        protected final static String INSTANCE_NAME_PARAMETER="instanceName";
083        protected final static String NAME_PARAMETER="name";
084        protected final static String CURRENT_FACTORY_PARAMETER="currentFactoryID";
085        protected final static String CURRENT_DEST_PARAMETER="currentDestinationID";
086        protected final static String FACTORY_TYPE_PARAMETER="factoryType";
087        protected final static String DEST_TYPE_PARAMETER="destinationType";
088        protected final static String TRANSACTION_PARAMETER="transaction";
089        protected final static String XA_TRANSACTION_PARAMETER="xaTransaction";
090        protected final static String XA_THREAD_PARAMETER="xaThread";
091        protected final static String MIN_SIZE_PARAMETER="poolMinSize";
092        protected final static String MAX_SIZE_PARAMETER="poolMaxSize";
093        protected final static String IDLE_TIME_PARAMETER="poolIdleTimeout";
094        protected final static String BLOCK_TIME_PARAMETER="poolBlockingTimeout";
095    
096        public AbstractHandler(String mode, String viewName) {
097            super(mode, viewName);
098        }
099    
100        public static class JMSResourceData implements MultiPageModel {
101            private String rarURI;
102            private String dependency;
103            private String instanceName;
104            private Properties instanceProps = new Properties();
105            private String workManager;
106            private int currentFactory = -1;
107            private int currentDestination = -1;
108            private int factoryType = -1;
109            private int destinationType = -1;
110            private List connectionFactories = new ArrayList();
111            private List adminObjects = new ArrayList();
112            // Used for editing an existing resource
113            private String objectName;
114    
115            public JMSResourceData(PortletRequest request) {
116                Map map = request.getParameterMap();
117                rarURI = request.getParameter(RAR_FILE_PARAMETER);
118                dependency = request.getParameter(DEPENDENCY_PARAMETER);
119                instanceName = request.getParameter(INSTANCE_NAME_PARAMETER);
120                factoryType = isEmpty(request.getParameter(FACTORY_TYPE_PARAMETER)) ? -1 : Integer.parseInt(request.getParameter(FACTORY_TYPE_PARAMETER));
121                currentFactory = isEmpty(request.getParameter(CURRENT_FACTORY_PARAMETER)) ? -1 : Integer.parseInt(request.getParameter(CURRENT_FACTORY_PARAMETER));
122                destinationType = isEmpty(request.getParameter(DEST_TYPE_PARAMETER)) ? -1 : Integer.parseInt(request.getParameter(DEST_TYPE_PARAMETER));
123                currentDestination = isEmpty(request.getParameter(CURRENT_DEST_PARAMETER)) ? -1 : Integer.parseInt(request.getParameter(CURRENT_DEST_PARAMETER));
124                for(int i=0; i<20; i++) {
125                    String key = "instance-config-" + i;
126                    if(map.containsKey(key)) {
127                        instanceProps.setProperty(key, request.getParameter(key));
128                    }
129                }
130                workManager = "DefaultWorkManager"; //todo
131                int index = 0;
132                while(true) {
133                    String key = "factory."+(index++)+".";
134                    if(!map.containsKey(key+FACTORY_TYPE_PARAMETER)) {
135                        break;
136                    }
137                    JMSConnectionFactoryData data = new JMSConnectionFactoryData();
138                    data.load(request, key);
139                    connectionFactories.add(data);
140                }
141                index = 0;
142                while(true) {
143                    String key = "destination."+(index++)+".";
144                    if(!map.containsKey(key+DEST_TYPE_PARAMETER)) {
145                        break;
146                    }
147                    JMSAdminObjectData data = new JMSAdminObjectData();
148                    data.load(request, key);
149                    adminObjects.add(data);
150                }
151                createIfNecessary();
152            }
153    
154            public void createIfNecessary() {
155                while(currentFactory >= connectionFactories.size()) {
156                    connectionFactories.add(new JMSConnectionFactoryData());
157                }
158                while(currentDestination >= adminObjects.size()) {
159                    adminObjects.add(new JMSAdminObjectData());
160                }
161            }
162    
163            public void save(ActionResponse response, PortletSession session) {
164                if(!isEmpty(rarURI)) response.setRenderParameter(RAR_FILE_PARAMETER, rarURI);
165                if(!isEmpty(dependency)) response.setRenderParameter(DEPENDENCY_PARAMETER, dependency);
166                if(!isEmpty(instanceName)) response.setRenderParameter(INSTANCE_NAME_PARAMETER, instanceName);
167                for (Iterator it = instanceProps.entrySet().iterator(); it.hasNext();) {
168                    Map.Entry entry = (Map.Entry) it.next();
169                    if(!isEmpty((String)entry.getValue())) {
170                        response.setRenderParameter((String)entry.getKey(), (String)entry.getValue());
171                    }
172                }
173                if(!isEmpty(workManager)) response.setRenderParameter("workManager", workManager);
174                response.setRenderParameter(FACTORY_TYPE_PARAMETER, Integer.toString(factoryType));
175                response.setRenderParameter(DEST_TYPE_PARAMETER, Integer.toString(destinationType));
176                response.setRenderParameter(CURRENT_DEST_PARAMETER, Integer.toString(currentDestination));
177                response.setRenderParameter(CURRENT_FACTORY_PARAMETER, Integer.toString(currentFactory));
178                for (int i = 0; i < connectionFactories.size(); i++) {
179                    JMSConnectionFactoryData data = (JMSConnectionFactoryData) connectionFactories.get(i);
180                    String key = "factory."+i+".";
181                    data.save(response, key);
182                }
183                for (int i = 0; i < adminObjects.size(); i++) {
184                    JMSAdminObjectData data = (JMSAdminObjectData) adminObjects.get(i);
185                    String key = "destination."+i+".";
186                    data.save(response, key);
187                }
188            }
189    
190            public int getFactoryType() {
191                return factoryType;
192            }
193    
194            public void setFactoryType(int factoryType) {
195                this.factoryType = factoryType;
196            }
197    
198            public int getDestinationType() {
199                return destinationType;
200            }
201    
202            public void setDestinationType(int destinationType) {
203                this.destinationType = destinationType;
204            }
205    
206            public int getCurrentFactoryID() {
207                return currentFactory;
208            }
209    
210            public void setCurrentFactoryID(int id) {
211                currentFactory = id;
212            }
213    
214            public int getCurrentDestinationID() {
215                return currentDestination;
216            }
217    
218            public void setCurrentDestinationID(int id) {
219                currentDestination = id;
220            }
221    
222            public String getRarURI() {
223                return rarURI;
224            }
225    
226            public void setRarURI(String rarURI) {
227                this.rarURI = rarURI;
228            }
229    
230            public String getDependency() {
231                return dependency;
232            }
233    
234            public void setDependency(String dependency) {
235                this.dependency = dependency;
236            }
237    
238            public String getInstanceName() {
239                return instanceName;
240            }
241    
242            public void setInstanceName(String instanceName) {
243                this.instanceName = instanceName;
244            }
245    
246            public String getWorkManager() {
247                return workManager;
248            }
249    
250            public void setWorkManager(String workManager) {
251                this.workManager = workManager;
252            }
253    
254            public Properties getInstanceProps() {
255                return instanceProps;
256            }
257    
258            public List getConnectionFactories() {
259                return connectionFactories;
260            }
261    
262            public List getAdminObjects() {
263                return adminObjects;
264            }
265    
266            public JMSConnectionFactoryData getCurrentFactory() {
267                return (JMSConnectionFactoryData) connectionFactories.get(currentFactory);
268            }
269    
270            public JMSAdminObjectData getCurrentDestination() {
271                return (JMSAdminObjectData) adminObjects.get(currentDestination);
272            }
273    
274            public int getConnectionFactoryCount() {
275                return connectionFactories.size();
276            }
277    
278            public int getDestinationCount() {
279                return adminObjects.size();
280            }
281        }
282    
283        public static class JMSConnectionFactoryData {
284            private int factoryType;
285            private String instanceName;
286            private String transaction; //none, local, xa
287            private boolean xaTransactionCaching;
288            private boolean xaThreadCaching;
289            private Integer poolMinSize;
290            private Integer poolMaxSize;
291            private Integer poolBlockingTimeout;
292            private Integer poolIdleTimeout;
293            private Properties instanceProps = new Properties();
294    
295            public void load(PortletRequest request, String prefix) {
296                factoryType = isEmpty(request.getParameter(prefix+FACTORY_TYPE_PARAMETER)) ? -1 : Integer.parseInt(request.getParameter(prefix+FACTORY_TYPE_PARAMETER));
297                instanceName = request.getParameter(prefix+INSTANCE_NAME_PARAMETER);
298                transaction = request.getParameter(prefix+TRANSACTION_PARAMETER);
299                xaThreadCaching = !isEmpty(request.getParameter(prefix+XA_THREAD_PARAMETER)) && request.getParameter(prefix+XA_THREAD_PARAMETER).equals("true");
300                xaTransactionCaching = isEmpty(request.getParameter(prefix+XA_TRANSACTION_PARAMETER)) || request.getParameter(prefix+XA_TRANSACTION_PARAMETER).equals("true");
301                poolMinSize = isEmpty(request.getParameter(prefix+MIN_SIZE_PARAMETER)) ? null : new Integer(request.getParameter(prefix+MIN_SIZE_PARAMETER));
302                poolMaxSize = isEmpty(request.getParameter(prefix+MAX_SIZE_PARAMETER)) ? null : new Integer(request.getParameter(prefix+MAX_SIZE_PARAMETER));
303                poolIdleTimeout = isEmpty(request.getParameter(prefix+IDLE_TIME_PARAMETER)) ? null : new Integer(request.getParameter(prefix+IDLE_TIME_PARAMETER));
304                poolBlockingTimeout = isEmpty(request.getParameter(prefix+BLOCK_TIME_PARAMETER)) ? null : new Integer(request.getParameter(prefix+BLOCK_TIME_PARAMETER));
305                Map map = request.getParameterMap();
306                for(int i=0; i<20; i++) {
307                    String key = prefix+"instance-config-" + i;
308                    if(map.containsKey(key)) {
309                        instanceProps.setProperty(key.substring(prefix.length()), request.getParameter(key));
310                    }
311                }
312            }
313    
314            public void save(ActionResponse response, String prefix) {
315                if(factoryType > -1) response.setRenderParameter(prefix+FACTORY_TYPE_PARAMETER, Integer.toString(factoryType));
316                if(!isEmpty(instanceName)) response.setRenderParameter(prefix+INSTANCE_NAME_PARAMETER, instanceName);
317                if(!isEmpty(transaction)) response.setRenderParameter(prefix+TRANSACTION_PARAMETER, transaction);
318                response.setRenderParameter(prefix+XA_THREAD_PARAMETER, Boolean.toString(xaThreadCaching));
319                response.setRenderParameter(prefix+XA_TRANSACTION_PARAMETER, Boolean.toString(xaTransactionCaching));
320                if(poolMinSize != null) response.setRenderParameter(prefix+MIN_SIZE_PARAMETER, poolMinSize.toString());
321                if(poolMaxSize != null) response.setRenderParameter(prefix+MAX_SIZE_PARAMETER, poolMaxSize.toString());
322                if(poolBlockingTimeout != null) response.setRenderParameter(prefix+BLOCK_TIME_PARAMETER, poolBlockingTimeout.toString());
323                if(poolIdleTimeout != null) response.setRenderParameter(prefix+IDLE_TIME_PARAMETER, poolIdleTimeout.toString());
324                for (Iterator it = instanceProps.entrySet().iterator(); it.hasNext();) {
325                    Map.Entry entry = (Map.Entry) it.next();
326                    if(!isEmpty((String)entry.getValue())) {
327                        response.setRenderParameter(prefix+entry.getKey(), (String)entry.getValue());
328                    }
329                }
330            }
331    
332            public int getFactoryType() {
333                return factoryType;
334            }
335    
336            public void setFactoryType(int factoryType) {
337                this.factoryType = factoryType;
338            }
339    
340            public String getInstanceName() {
341                return instanceName;
342            }
343    
344            public void setInstanceName(String instanceName) {
345                this.instanceName = instanceName;
346            }
347    
348            public String getTransaction() {
349                return transaction;
350            }
351    
352            public void setTransaction(String transaction) {
353                this.transaction = transaction;
354            }
355    
356            public boolean isXaTransactionCaching() {
357                return xaTransactionCaching;
358            }
359    
360            public void setXaTransactionCaching(boolean xaTransactionCaching) {
361                this.xaTransactionCaching = xaTransactionCaching;
362            }
363    
364            public boolean isXaThreadCaching() {
365                return xaThreadCaching;
366            }
367    
368            public void setXaThreadCaching(boolean xaThreadCaching) {
369                this.xaThreadCaching = xaThreadCaching;
370            }
371    
372            public Integer getPoolMinSize() {
373                return poolMinSize;
374            }
375    
376            public void setPoolMinSize(Integer poolMinSize) {
377                this.poolMinSize = poolMinSize;
378            }
379    
380            public Integer getPoolMaxSize() {
381                return poolMaxSize;
382            }
383    
384            public void setPoolMaxSize(Integer poolMaxSize) {
385                this.poolMaxSize = poolMaxSize;
386            }
387    
388            public Integer getPoolBlockingTimeout() {
389                return poolBlockingTimeout;
390            }
391    
392            public void setPoolBlockingTimeout(Integer poolBlockingTimeout) {
393                this.poolBlockingTimeout = poolBlockingTimeout;
394            }
395    
396            public Integer getPoolIdleTimeout() {
397                return poolIdleTimeout;
398            }
399    
400            public void setPoolIdleTimeout(Integer poolIdleTimeout) {
401                this.poolIdleTimeout = poolIdleTimeout;
402            }
403    
404            public Properties getInstanceProps() {
405                return instanceProps;
406            }
407        }
408    
409        public static class JMSAdminObjectData {
410            private int destinationType;
411            private String name;
412            private Properties instanceProps = new Properties();
413    
414            public void load(PortletRequest request, String prefix) {
415                destinationType = isEmpty(request.getParameter(prefix+DEST_TYPE_PARAMETER)) ? -1 : Integer.parseInt(request.getParameter(prefix+DEST_TYPE_PARAMETER));
416                name = request.getParameter(prefix+NAME_PARAMETER);
417                Map map = request.getParameterMap();
418                for(int i=0; i<20; i++) {
419                    String key = prefix+"instance-config-" + i;
420                    if(map.containsKey(key)) {
421                        instanceProps.setProperty(key.substring(prefix.length()), request.getParameter(key));
422                    }
423                }
424            }
425    
426            public void save(ActionResponse response, String prefix) {
427                if(destinationType > -1) response.setRenderParameter(prefix+DEST_TYPE_PARAMETER, Integer.toString(destinationType));
428                if(!isEmpty(name)) response.setRenderParameter(prefix+NAME_PARAMETER, name);
429                for (Iterator it = instanceProps.entrySet().iterator(); it.hasNext();) {
430                    Map.Entry entry = (Map.Entry) it.next();
431                    if(!isEmpty((String)entry.getValue())) {
432                        response.setRenderParameter(prefix+entry.getKey(), (String)entry.getValue());
433                    }
434                }
435            }
436    
437            public int getDestinationType() {
438                return destinationType;
439            }
440    
441            public void setDestinationType(int destinationType) {
442                this.destinationType = destinationType;
443            }
444    
445            public String getName() {
446                return name;
447            }
448    
449            public void setName(String name) {
450                this.name = name;
451            }
452    
453            public Properties getInstanceProps() {
454                return instanceProps;
455            }
456        }
457    
458        private static String getPropertyName(String propertyKey, JMSProviderData.ConfigPropertyData[] configs) {
459            int pos = propertyKey.lastIndexOf('-');
460            String num = propertyKey.substring(pos+1);
461            return configs[Integer.parseInt(num)].getName();
462        }
463    
464        protected static String save(PortletRequest request, ActionResponse response, JMSResourceData data, boolean planOnly) throws IOException {
465            JMSProviderData provider = JMSProviderData.getProviderData(data.rarURI, request);
466            if(data.objectName == null || data.objectName.equals("")) { // we're creating a new pool
467                //data.instanceName = data.instanceName.replaceAll("\\s", "");
468                DeploymentManager mgr = ManagementHelper.getManagementHelper(request).getDeploymentManager();
469                try {
470                    File rarFile = PortletManager.getRepositoryEntry(request, data.getRarURI());
471                    ConnectorDeployable deployable = new ConnectorDeployable(rarFile.toURL());
472                    DeploymentConfiguration config = mgr.createConfiguration(deployable);
473                    final DDBeanRoot ddBeanRoot = deployable.getDDBeanRoot();
474                    Connector15DCBRoot root = (Connector15DCBRoot) config.getDConfigBeanRoot(ddBeanRoot);
475                    ConnectorDCB connector = (ConnectorDCB) root.getDConfigBean(ddBeanRoot.getChildBean(root.getXpaths()[0])[0]);
476    
477                    EnvironmentData environment = new EnvironmentData();
478                    connector.setEnvironment(environment);
479                    org.apache.geronimo.deployment.service.jsr88.Artifact configId = new org.apache.geronimo.deployment.service.jsr88.Artifact();
480                    environment.setConfigId(configId);
481                    configId.setGroupId("console.jms");
482                    configId.setArtifactId(data.instanceName);
483                    configId.setVersion("1.0");
484                    configId.setType("rar");
485                    if(data.dependency != null && !data.dependency.trim().equals("")) {
486                        Artifact artifact = Artifact.create(data.dependency.trim());
487                        org.apache.geronimo.deployment.service.jsr88.Artifact dep = new org.apache.geronimo.deployment.service.jsr88.Artifact();
488                        environment.setDependencies(new org.apache.geronimo.deployment.service.jsr88.Artifact[]{dep});
489                        dep.setArtifactId(artifact.getArtifactId());
490                        if(artifact.getGroupId() != null) {
491                            dep.setGroupId(artifact.getGroupId());
492                        }
493                        if(artifact.getType() != null) {
494                            dep.setType(artifact.getType());
495                        }
496                        if(artifact.getVersion() != null) {
497                            dep.setVersion(artifact.getVersion().toString());
498                        }
499                    }
500                    
501                    // Basic settings on RA plan and RA instance
502                    ResourceAdapter ra;
503                    if(connector.getResourceAdapter().length > 0) {
504                        ra = connector.getResourceAdapter(0);
505                    } else {
506                        ra = new ResourceAdapter();
507                        connector.setResourceAdapter(new ResourceAdapter[]{ra});
508                    }
509                    ResourceAdapterInstance raInstance = new ResourceAdapterInstance();
510                    ra.setResourceAdapterInstance(raInstance);
511                    raInstance.setResourceAdapterName(data.instanceName);
512                    for (Iterator it = data.instanceProps.entrySet().iterator(); it.hasNext();) {
513                        Map.Entry entry = (Map.Entry) it.next();
514                        String name = getPropertyName((String)entry.getKey(), provider.getInstanceConfigProperties());
515                        for(int i=0; i<raInstance.getConfigPropertySetting().length; i++) {
516                            if(raInstance.getConfigPropertySetting(i).getName().equals(name)) {
517                                raInstance.getConfigPropertySetting(i).setValue((String)entry.getValue());
518                                break;
519                            }
520                        }
521                    }
522                    GBeanLocator workManager = new GBeanLocator();
523                    raInstance.setWorkManager(workManager);
524                    workManager.setGBeanLink(data.workManager); //todo
525                    // Connection Factories
526                    if(data.getConnectionFactoryCount() > 0) {
527                        ConnectionDefinition[] defs = new ConnectionDefinition[data.getConnectionFactoryCount()];
528                        for (int i = 0; i < defs.length; i++) {
529                            defs[i] = new ConnectionDefinition();
530                        }
531                        ra.setConnectionDefinition(defs);
532                        for (int i = 0; i < data.getConnectionFactories().size(); i++) {
533                            JMSConnectionFactoryData factoryData = (JMSConnectionFactoryData) data.getConnectionFactories().get(i);
534                            JMSProviderData.ConnectionDefinition providerData = provider.getConnectionDefinitions()[factoryData.getFactoryType()];
535                            ConnectionDefinition def = defs[i];
536                            def.setConnectionFactoryInterface(providerData.getConnectionFactoryInterface());
537                            ConnectionDefinitionInstance instance = new ConnectionDefinitionInstance();
538                            def.setConnectionInstance(new ConnectionDefinitionInstance[]{instance});
539                            if(providerData.getConnectionFactoryInterface().equals("javax.jms.ConnectionFactory")) {
540                                instance.setImplementedInterface(new String[]{"javax.jms.QueueConnectionFactory","javax.jms.TopicConnectionFactory"});
541                            }
542                            instance.setName(factoryData.getInstanceName());
543                            SinglePool pool = new SinglePool();
544                            instance.getConnectionManager().setPoolSingle(pool);
545                            pool.setMatchOne(true);
546                            pool.setMaxSize(factoryData.getPoolMaxSize());
547                            pool.setMinSize(factoryData.getPoolMinSize());
548                            pool.setBlockingTimeoutMillis(factoryData.getPoolBlockingTimeout());
549                            pool.setIdleTimeoutMinutes(factoryData.getPoolIdleTimeout());
550                            if(factoryData.getTransaction().equals("none")) {
551                                instance.getConnectionManager().setTransactionNone(true);
552                            } else if(factoryData.getTransaction().equals("local")) {
553                                instance.getConnectionManager().setTransactionLocal(true);
554                            } else if(factoryData.getTransaction().equals("xa")) {
555                                instance.getConnectionManager().setTransactionXA(true);
556                                instance.getConnectionManager().setTransactionXACachingThread(factoryData.isXaThreadCaching());
557                                instance.getConnectionManager().setTransactionXACachingTransaction(factoryData.isXaTransactionCaching());
558                            }
559                            for (Iterator it = factoryData.instanceProps.entrySet().iterator(); it.hasNext();) {
560                                Map.Entry entry = (Map.Entry) it.next();
561                                String name = getPropertyName((String)entry.getKey(), providerData.getConfigProperties());
562                                for(int j=0; j<instance.getConfigPropertySetting().length; j++) {
563                                    if(instance.getConfigPropertySetting(j).getName().equals(name)) {
564                                        instance.getConfigPropertySetting(j).setValue((String)entry.getValue());
565                                        break;
566                                    }
567                                }
568                            }
569                        }
570                    }
571    
572                    // Destinations
573                    DDBean[] ddBeans = connector.getDDBean().getChildBean(connector.getXpaths()[0]);
574                    AdminObjectDCB[] adminDCBs = new AdminObjectDCB[ddBeans.length];
575                    for (int i = 0; i < adminDCBs.length; i++) {
576                        adminDCBs[i] = (AdminObjectDCB) connector.getDConfigBean(ddBeans[i]);
577                    }
578                    for (int i = 0; i < data.getAdminObjects().size(); i++) {
579                        JMSAdminObjectData admin = (JMSAdminObjectData) data.getAdminObjects().get(i);
580                        JMSProviderData.AdminObjectDefinition providerData = provider.getAdminObjectDefinitions()[admin.getDestinationType()];
581                        for (int j = 0; j < adminDCBs.length; j++) {
582                            AdminObjectDCB adminDCB = adminDCBs[j];
583                            if(adminDCB.getAdminObjectInterface().equals(providerData.getAdminObjectInterface())) {
584                                AdminObjectInstance[] before = adminDCB.getAdminObjectInstance();
585                                AdminObjectInstance[] after = new AdminObjectInstance[before.length+1];
586                                System.arraycopy(before, 0, after, 0, before.length);
587                                AdminObjectInstance instance = new AdminObjectInstance();
588                                after[before.length] = instance;
589                                adminDCB.setAdminObjectInstance(after);
590                                instance.setMessageDestinationName(admin.getName());
591                                for (Iterator it = admin.instanceProps.entrySet().iterator(); it.hasNext();) {
592                                    Map.Entry entry = (Map.Entry) it.next();
593                                    String name = getPropertyName((String)entry.getKey(), providerData.getConfigProperties());
594                                    for(int k=0; k<instance.getConfigPropertySetting().length; k++) {
595                                        if(instance.getConfigPropertySetting(k).getName().equals(name)) {
596                                            instance.getConfigPropertySetting(k).setValue((String)entry.getValue());
597                                            break;
598                                        }
599                                    }
600                                }
601                                break;
602                            }
603                        }
604                    }
605    
606                    // Save
607                    if(planOnly) {
608                        ByteArrayOutputStream out = new ByteArrayOutputStream();
609                        config.save(out);
610                        out.close();
611                        return new String(out.toByteArray(), "US-ASCII");
612                    } else {
613                        File tempFile = File.createTempFile("console-deployment",".xml");
614                        tempFile.deleteOnExit();
615                        log.debug("Writing JMS Resource deployment plan to "+tempFile.getAbsolutePath());
616                        BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(tempFile));
617                        config.save(out);
618                        out.flush();
619                        out.close();
620                        Target[] targets = mgr.getTargets();
621                        if (null == targets) {
622                            throw new IllegalStateException("No target to distribute to");
623                        }
624                        targets = new Target[] {targets[0]};
625                        
626                        ProgressObject po = mgr.distribute(targets, rarFile, tempFile);
627                        waitForProgress(po);
628                        if(po.getDeploymentStatus().isCompleted()) {
629                            TargetModuleID[] ids = po.getResultTargetModuleIDs();
630                            po = mgr.start(ids);
631                            waitForProgress(po);
632                            if(po.getDeploymentStatus().isCompleted()) {
633                                ids = po.getResultTargetModuleIDs();
634                                log.info("Deployment completed successfully!");
635                            }
636                        }
637                    }
638                } catch (Exception e) {
639                    log.error("Unable to save connection pool", e);
640                } finally {
641                    if(mgr != null) mgr.release();
642                }
643            } else { // We're saving updates to an existing pool
644                if(planOnly) {
645                    throw new UnsupportedOperationException("Can't update a plan for an existing deployment");
646                }
647                throw new UnsupportedOperationException("Can't edit existing configurations yet");
648            }
649            return null;
650        }
651    
652        protected static void waitForProgress(ProgressObject po) {
653            while(po.getDeploymentStatus().isRunning()) {
654                try {
655                    Thread.sleep(100);
656                } catch (InterruptedException e) {
657                    e.printStackTrace();
658                }
659            }
660        }
661        
662    }
663    
664