geronimo-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jason Dillon <ja...@coredevelopers.net>
Subject Re: cvs commit: incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/cli DConfigBeanConfigurator.java Deployer.java
Date Thu, 04 Sep 2003 07:16:26 GMT
My opinion is that these are Twiddle bits and do not belong here.   
Especially not in a console/cli package.

I looked at this and almost committed but noticed that it only handled  
jars and was not very happy about that.  But I guess it is just the  
start.  The deploy commands should be able to deploy anything which is  
deployable IMO.

--jason


On Thursday, September 4, 2003, at 12:26  PM, jboynes@apache.org wrote:

> jboynes     2003/09/03 22:26:19
>
>   Added:       modules/core/src/java/org/apache/geronimo/console/cli
>                         DConfigBeanConfigurator.java Deployer.java
>   Log:
>   GERONIMO-10 patch (v5)  from Aaron Mulder
>   Not sure on these and their relationship to twiddle - is this  
> duplicate functionality?
>
>   Revision  Changes    Path
>   1.1                   
> incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/ 
> cli/DConfigBeanConfigurator.java
>
>   Index: DConfigBeanConfigurator.java
>   ===================================================================
>   /*  
> ====================================================================
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above  
> copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution,
>    *    if any, must include the following acknowledgment:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgment may appear in the software  
> itself,
>    *    if and wherever such third-party acknowledgments normally  
> appear.
>    *
>    * 4. The names "Apache" and "Apache Software Foundation" and
>    *    "Apache Geronimo" must not be used to endorse or promote  
> products
>    *    derived from this software without prior written permission.  
> For
>    *    written permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache",
>    *    "Apache Geronimo", nor may "Apache" appear in their name,  
> without
>    *    prior written permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  
> AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    *  
> ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    *  
> ====================================================================
>    */
>   package org.apache.geronimo.console.cli;
>
>   import java.beans.*;
>   import java.io.*;
>   import java.util.*;
>   import java.lang.reflect.InvocationTargetException;
>   import javax.enterprise.deploy.spi.DConfigBean;
>   import javax.enterprise.deploy.spi.DConfigBeanRoot;
>   import javax.enterprise.deploy.spi.exceptions.ConfigurationException;
>   import javax.enterprise.deploy.model.DDBean;
>   import org.apache.commons.logging.Log;
>   import org.apache.commons.logging.LogFactory;
>   import org.apache.geronimo.common.propertyeditor.PropertyEditors;
>
>   /**
>    * Knows how to configure a DConfigBean at the command line.  The  
> editing process
>    * is a series of reads and writes to the provided input and output  
> streams,
>    * which basically presents information and a prompt to the user,  
> gathers their
>    * input, and repeats.  They can navigate through a tree of  
> DConfigBeans and
>    * Java Beans, adding, removing, and editing properies on beans where
>    * appropriate.
>    * <p>
>    * Note: it might make sense to break this class up eventually.   
> Particularly if
>    * we want to allow the user to navigate between arbitrary DDBeans  
> (standard DD)
>    * and their matching DConfigBeans (server-specific DD).  Right now  
> they can only
>    * edit one tree at a time, either the whole DDBean tree, or the  
> whole
>    * DConfigBean tree.
>    * </p>
>    * @version $Revision: 1.1 $ $Date: 2003/09/04 05:26:19 $
>    */
>   public class DConfigBeanConfigurator {
>       private final static Log log =  
> LogFactory.getLog(DConfigBeanConfigurator.class);
>       private PrintWriter out;
>       private BufferedReader in;
>       private Stack beans = new Stack();
>
>       /**
>        * Creates a new instance, based on the supplied config bean  
> root and
>        * input and output streams.
>        */
>       public DConfigBeanConfigurator(DConfigBeanRoot bean, PrintWriter  
> out, BufferedReader in) {
>           this.out = out;
>           this.in = in;
>           beans.push(bean);
>       }
>
>       /**
>        * Begins the process of configuring the DConfigBean tree.  When  
> this method
>        * returns, the user has finished editing the DConfigBeans (or a  
> fatal error
>        * caused the editing to abort).
>        *
>        * @return <code>true</code> if the editing completed normally
>        *        (<code>false</code> if there was a fatal error).
>        */
>       public boolean configure() {
>           try {
>               initialize();
>               return true;
>           } catch(IntrospectionException e) {
>               log.error("Unable to introspect a JavaBean", e);
>           } catch(IOException e) {
>               log.error("Unable to gather input from user", e);
>           } catch(InvocationTargetException e) {
>               log.error("Unable to read or write a JavaBean property",  
> e.getTargetException());
>           } catch(IllegalAccessException e) {
>               log.error("Unable to read or write a JavaBean property",  
> e);
>           } catch(ConfigurationException e) {
>               log.error("Unable to generate a child DConfigBean", e);
>           } catch(InstantiationException e) {
>               log.error("Unable to generate a child bean", e);
>           }
>           return false;
>       }
>
>       /**
>        * The main logic loop for the editing process.  This starts an  
> endless loop,
>        * where each iteration prints information on the current bean  
> and prompts
>        * the user for an action.  A stack is maintained of the current  
> beans from
>        * root (bottom of the stack) to the current leaf node (top of  
> the stack).
>        * The main options offered here are to move to a parent or  
> child bean (if
>        * available) or to edit a property on the current bean.
>        */
>       private void initialize() throws IntrospectionException,  
> IOException, InvocationTargetException, IllegalAccessException,  
> ConfigurationException, InstantiationException {
>           boolean forward = true;
>           BeanInfo info;
>           PropertyDescriptor[] properties = new PropertyDescriptor[0];
>           PropertyDescriptor[] readOnly = new PropertyDescriptor[0];
>           PropertyDescriptor[] childProps = new PropertyDescriptor[0];
>           Map childTypes = new HashMap();
>           while(true) {
>               out.println("\n\n");
>               Object bean = beans.peek();
>               int count;
>
>               // Load top-level info
>               info = Introspector.getBeanInfo(bean.getClass());
>               String indent = printLocation();
>
>               // Load children
>               childTypes.clear();
>               if(bean instanceof DConfigBean) {
>                   DConfigBean dcb = (DConfigBean) bean;
>                   String[] xpaths = dcb.getXpaths();
>                   for(int i=0; i<xpaths.length; i++) {
>                       DDBean[] ddbs =  
> dcb.getDDBean().getChildBean(xpaths[i]);
>                       if(ddbs.length != 0) {
>                           DConfigBean[] list = new  
> DConfigBean[ddbs.length];
>                           for(int j = 0; j < ddbs.length; j++) {
>                               list[j] = dcb.getDConfigBean(ddbs[j]);
>                           }
>                            
> childTypes.put(Introspector.getBeanInfo(list[0].getClass()).getBeanDesc 
> riptor().getDisplayName(), list);
>                       }
>                   }
>                   for(Iterator iterator =  
> childTypes.keySet().iterator(); iterator.hasNext();) {
>                       String s = (String)iterator.next();
>                       int number =  
> ((DConfigBean[])childTypes.get(s)).length;
>                       out.println(indent+"+ "+s+" ("+number+"  
> entr"+(number == 1 ? "y" : "ies")+")");
>                   }
>               }
>               childProps =  
> getChildProperties(info.getPropertyDescriptors());
>               for(int i = 0; i < childProps.length; i++) {
>                   PropertyDescriptor prop = childProps[i];
>                   if(prop instanceof IndexedPropertyDescriptor) {
>                       int number =  
> ((Object[])prop.getReadMethod().invoke(bean, new Object[0])).length;
>                       out.println(indent+"+ "+prop.getDisplayName()+"  
> ("+number+" entr"+(number == 1 ? "y" : "ies")+")");
>                   } else {
>                       out.println(indent+"+ "+prop.getDisplayName()+"  
> (child property)");
>                   }
>               }
>               out.println();
>
>               // Load properties todo: handle properties of type bean  
> but not DConfigBean and indexed properties
>               count = 0;
>               properties =  
> getNormalProperties(info.getPropertyDescriptors());
>               readOnly = getReadOnly(info.getPropertyDescriptors());
>               for(int i = 0; i < readOnly.length; i++) {
>                   PropertyDescriptor property = readOnly[i];
>                   out.println(property.getDisplayName()+":  
> "+property.getReadMethod().invoke(bean, new Object[0]));
>               }
>               if(properties.length > 0) {
>                   out.println("Properties for "+getFullName(bean)+":");
>               }
>               for(int i = 0; i < properties.length; i++) {
>                   PropertyDescriptor property = properties[i];
>                   out.println("  "+(++count)+":  
> "+property.getDisplayName()+" ("+property.getReadMethod().invoke(bean,  
> new Object[0])+")");
>               }
>               out.flush();
>
>               // Auto-navigate
>               if(properties.length == 0 && childTypes.size() == 1 &&  
> childProps.length == 0) {
>                   DConfigBean[] children =  
> (DConfigBean[])childTypes.values().iterator().next();
>                   if(children.length == 1) {
>                       if(forward) {
>                           out.println("Nothing interesting to do here.  
>  Moving on.");
>                           beans.push(children[0]);
>                           continue;
>                       } else if(beans.size() > 1) {
>                           out.println("Nothing interesting to do here.  
>  Moving on.");
>                           beans.pop();
>                           continue;
>                       }
>                   }
>               } else if(properties.length == 0 && childTypes.size() ==  
> 0 && childProps.length == 1) {
>                   if(!(childProps[0] instanceof  
> IndexedPropertyDescriptor)) {
>                       if(forward) {
>                           out.println("Nothing interesting to do here.  
>  Moving on.");
>                            
> beans.push(childProps[0].getReadMethod().invoke(bean, new Object[0]));
>                           continue;
>                       } else if(beans.size() > 1) {
>                           out.println("Nothing interesting to do here.  
>  Moving on.");
>                           beans.pop();
>                           continue;
>                       }
>                   }
>               }
>               if(properties.length > 0) {
>                   out.println();
>               }
>
>               // Show navigation options
>               out.print("Action (");
>               boolean first = true;
>               if(properties.length > 0) {
>                   if(!first) {out.print(" / ");}
>                   out.print("Edit [P]roperty");
>                   first = false;
>               }
>               if(childTypes.size() > 0 || childProps.length > 0) {
>                   if(!first) {out.print(" / ");}
>                   out.print("Move [D]own");
>                   first = false;
>               }
>               if(beans.size() > 1) {
>                   if(!first) {out.print(" / ");}
>                   out.print("Move [U]p");
>                   first = false;
>               }
>               if(!first) {out.print(" / ");}
>               out.print("[Q]uit");
>               first = false;
>               out.print("): ");
>               out.flush();
>               String choice = in.readLine().trim().toLowerCase();
>               if(choice.equals("u")) {
>                   forward = false;
>                   beans.pop();
>                   continue;
>               } else if(choice.equals("d")) {
>                   forward = true;
>                   if(childTypes.size() == 0 && childProps.length == 0)  
> {
>                       log.warn("No children available here.");
>                       continue;
>                   } else {
>                       selectChildBean(childTypes, bean, childProps);
>                       continue;
>                   }
>               } else if(choice.equals("q")) {
>                   return;
>               } else if(choice.equals("p")) {
>                   if(properties.length == 0) {
>                       log.warn("No editable properties available  
> here.");
>                       continue;
>                   } else {
>                       editProperty(bean, properties);
>                       continue;
>                   }
>               } else if(isNumber(choice)) {
>                   int value = Integer.parseInt(choice);
>                   if(value > 0 && value <= properties.length) {
>                       editProperty(bean, properties[value-1]);
>                       continue;
>                   }
>               }
>               log.error("I don't know how to do that (yet)");
>           }
>       }
>
>       /**
>        * The user wants to edit a property.  This method figures out  
> which one (of
>        * the properties available for the bean).
>        */
>       private void editProperty(Object bean, PropertyDescriptor[]  
> properties) throws IOException, InvocationTargetException,  
> IllegalAccessException {
>           if(properties.length == 1) {
>               editProperty(bean, properties[0]);
>               return;
>           }
>           String choice = null;
>           while(true) {
>               out.print("Edit which property  
> (1-"+properties.length+")? ");
>               out.flush();
>               choice = in.readLine();
>               try {
>                   int value = Integer.parseInt(choice);
>                   if(value > 0 && value <= properties.length) {
>                       editProperty(bean, properties[value-1]);
>                       return;
>                   }
>               } catch(NumberFormatException e) {}
>           }
>       }
>
>       /**
>        * Manages the editing of a single property.
>        */
>       private void editProperty(final Object bean, final  
> PropertyDescriptor property) throws InvocationTargetException,  
> IllegalAccessException, IOException {
>           final PropertyEditor pe =  
> PropertyEditors.findEditor(property.getPropertyType());
>           pe.addPropertyChangeListener(new PropertyChangeListener() {
>               public void propertyChange(PropertyChangeEvent evt) {
>                   try {
>                       property.getWriteMethod().invoke(bean, new  
> Object[]{pe.getValue()});
>                       pe.removePropertyChangeListener(this);
>                   } catch(IllegalAccessException e) {
>                       log.error("Not allowed to set property", e);
>                   } catch(IllegalArgumentException e) {
>                       log.error("Invalid value for property", e);
>                   } catch(InvocationTargetException e) {
>                       log.error("Exception occured while setting  
> property", e.getTargetException());
>                   }
>               }
>           });
>           out.println("\nEditing Property "+property.getDisplayName());
>           Object value = property.getReadMethod().invoke(bean, new  
> Object[0]);
>           if(value == null) {
>               value = pe.getJavaInitializationString();
>           }
>           out.println("  Old value is: '"+value+"'");
>           out.println("  Specify a new value.  Enter nothing to keep  
> the current value.\n" +
>                       "  Type (empty) for an empty string or (null)  
> for a null.");
>           out.print("New Value: ");
>           out.flush();
>           String choice = in.readLine();
>           if(choice.equals("")) {
>               return;
>           } else if(choice.equals("(null)")) {
>               choice = null;
>           } else if(choice.equals("(empty)")) {
>               choice = "";
>           }
>           pe.setAsText(choice);
>       }
>
>       /**
>        * The user wants to move to a child bean.  This method figures  
> out which
>        * one.  It may be a child DConfigBean or a child property where  
> we don't
>        * have a property editor for that property type so we treat the  
> whole
>        * thing as a child bean.
>        */
>       private void selectChildBean(Map types, Object bean,  
> PropertyDescriptor[] props) throws IOException,  
> InvocationTargetException, IllegalAccessException,  
> InstantiationException {
>           DConfigBean[] cbs = null;
>           PropertyDescriptor prop = null;
>           int count;
>           String choice;
>           if(types.size()+props.length > 1) {
>               count = 0;
>               out.println("\nAvailable Children:");
>               for(Iterator iterator = types.keySet().iterator();  
> iterator.hasNext();) {
>                   String name = (String) iterator.next();
>                   out.println("  ["+(++count)+"] "+name);
>               }
>               for(int i = 0; i < props.length; i++) {
>                   out.println("  ["+(++count)+"]  
> "+props[i].getDisplayName());
>               }
>               while(true) {
>                   out.print("Select child type  
> (1-"+(types.size()+props.length)+"): ");
>                   out.flush();
>                   choice = in.readLine();
>                   try {
>                       int value = Integer.parseInt(choice);
>                       if(value > 0 && value <= types.size()) {
>                           count = 0;
>                           String key = null;
>                           for(Iterator iterator =  
> types.keySet().iterator(); iterator.hasNext() && count++ < value;) {
>                               key = (String) iterator.next();
>                           }
>                           cbs = (DConfigBean[]) types.get(key);
>                           if(cbs != null) {
>                               break;
>                           }
>                       } else if(value > types.size() && value <=  
> (types.size()+props.length)) {
>                           prop = props[value-types.size()-1];
>                           break;
>                       }
>                   } catch(NumberFormatException e) {}
>               }
>           } else {
>               if(types.size() == 1) {
>                   cbs =  
> (DConfigBean[])types.values().iterator().next();
>               } else if(props.length == 1) {
>                   prop = props[0];
>               } else {
>                   log.error("You've confused me.  Please try again.");
>               }
>           }
>           if(cbs != null) {
>               selectChildDConfigBean(cbs);
>           } else if(prop != null) {
>               selectChildProperty(bean, prop);
>           }
>       }
>
>       /**
>        * It turns out the user wants navigate to a child property  
> (where we don't
>        * have an editor for the property type, so we treat it as a  
> child bean).
>        * If the is a plain property, this method will just go there.   
> If it's an
>        * indexed property, this method presents CRUD options.
>        */
>       private void selectChildProperty(Object bean, PropertyDescriptor  
> prop) throws InvocationTargetException, IllegalAccessException,  
> IOException, InstantiationException {
>           //todo: consider handling indexed properties that are  
> themselves arrays?
>           if(!(prop instanceof IndexedPropertyDescriptor)) {
>               beans.push(prop.getReadMethod().invoke(bean, new  
> Object[0]));
>               return;
>           }
>           String choice;
>           Object[] values;
>           while(true) {
>               out.println("\nEditing list of "+prop.getDisplayName());
>               values = (Object[]) prop.getReadMethod().invoke(bean,  
> new Object[0]);
>               if(values.length == 0) {
>                   out.println("  (list is currently empty)");
>               }
>               for(int i = 0; i < values.length; i++) {
>                   out.println("  "+(i+1)+": "+values[i]);
>               }
>               out.print("Action ([C]reate entry");
>               if(values.length > 0) {
>                   out.print(" / [D]elete entry / edit entry  
> [1"+(values.length > 1 ? "-"+values.length : "")+"]");
>               }
>               out.print(" / [B]ack): ");
>               out.flush();
>               choice = in.readLine().trim().toLowerCase();
>               if(choice.equals("c")) {
>                   Object[] newv =  
> (Object[])java.lang.reflect.Array.newInstance(values.getClass().getComp 
> onentType(), values.length+1);
>                   System.arraycopy(values, 0, newv, 0, values.length);
>                   newv[values.length] =  
> values.getClass().getComponentType().newInstance();
>                   prop.getWriteMethod().invoke(bean, new  
> Object[]{newv});
>                   continue;
>               } else if(choice.equals("b")) {
>                   return;
>               } else if(isNumber(choice)) {
>                   int number = Integer.parseInt(choice);
>                   if(number > 0 && number <= values.length) {
>                       beans.push(values[number-1]);
>                       return;
>                   }
>               } else {
>                   log.warn("I didn't understand that");
>               }
>           }
>       }
>
>       /**
>        * Checks whether a value entered by the user is composed  
> entirely of digits.
>        */
>       private boolean isNumber(String choice) {
>           for(int i=0; i<choice.length(); i++) {
>               if(!Character.isDigit(choice.charAt(i))) {
>                   return false;
>               }
>           }
>           return choice.length() > 0;
>       }
>
>       /**
>        * It turns out the user wants to edit a child DConfigBean.  So  
> far, we just
>        * know what type of child bean they want (e.g. "one of the  
> resource
>        * references").  This method figures out which specific  
> instance of that
>        * they want to edit (identify a specific resource reference).
>        */
>       private void selectChildDConfigBean(DConfigBean[] cbs) throws  
> IOException {
>           String choice;
>           if(cbs.length == 1) {
>               beans.push(cbs[0]);
>               return;
>           }
>           out.println("\nAvailable Children:");
>           for(int i = 0; i < cbs.length; i++) {
>               out.println("  ["+(i+1)+"] "+cbs[i]);
>           }
>           while(true) {
>               out.print("Select child (1-"+cbs.length+"): ");
>               out.flush();
>               choice = in.readLine();
>               try {
>                   int value = Integer.parseInt(choice);
>                   if(value > 0 && value <= cbs.length) {
>                       beans.push(cbs[value-1]);
>                       break;
>                   }
>               } catch(NumberFormatException e) {}
>           }
>       }
>
>       /**
>        * Displays the user's current position in the stack of beans.   
> This
>        * method shows everything down to the current position.  The  
> caller
>        * must add on the children of the current node.
>        *
>        * @return The String full of spaces representating the  
> indentation
>        *         for any children of the last bean displayed.
>        */
>       private String printLocation() throws IntrospectionException {
>           out.println("          ---------- Editing Server-Specific DD  
> ----------          ");
>           String here = "";
>           int count = 0;
>           for(Iterator iterator = beans.iterator();  
> iterator.hasNext();) {
>               ++count;
>               Object temp = iterator.next();
>               if(!here.equals("")) {
>                   out.print(here);
>                   out.print("+ ");
>               }
>               if(count == beans.size()) {out.print("[[[ ");}
>               out.print(getFullName(temp));
>               if(count == beans.size()) {out.print(" ]]]");}
>               here = here + "  ";
>               out.println();
>           }
>           return here;
>       }
>
>       /**
>        * Gets the name of a class of beans (e.g. "Resource Reference")
>        * followed by the description of the specific instances (e.g.
>        * jdbc/SomeDatabase).
>        */
>       private String getFullName(Object bean) throws  
> IntrospectionException {
>           String name = bean.toString();
>           if(name.length() > 40 || name.indexOf("@") > 0) {//todo:  
> check whether toString has been overridden
>               name = "";
>           } else {
>               name = " ("+name+")";
>           }
>           return  
> Introspector.getBeanInfo(bean.getClass()).getBeanDescriptor().getDispla 
> yName()+name;
>       }
>
>       /**
>        * Gets the sub-list of the supplied properties that are  
> readable, writable,
>        * have a property editor, and are not on the list to  
> specifically exclude.
>        */
>       private PropertyDescriptor[]  
> getNormalProperties(PropertyDescriptor[] descriptors) {
>           List list = new ArrayList(descriptors.length);
>           for(int i = 0; i < descriptors.length; i++) {
>               PropertyDescriptor descriptor = descriptors[i];
>               if(isInvisible(descriptor) || descriptor.getReadMethod()  
> == null || descriptor.getWriteMethod() == null ||  
> PropertyEditors.findEditor(descriptor.getPropertyType()) == null) {
>                   continue;
>               }
>               list.add(descriptors[i]);
>           }
>           return (PropertyDescriptor[]) list.toArray(new  
> PropertyDescriptor[list.size()]);
>       }
>
>       /**
>        * Gets the sub-list of the supplied properties that are  
> readable, not
>        * writable, and are not on the list to specifically exclude.
>        */
>       private PropertyDescriptor[] getReadOnly(PropertyDescriptor[]  
> descriptors) {
>           List list = new ArrayList(descriptors.length);
>           for(int i = 0; i < descriptors.length; i++) {
>               PropertyDescriptor descriptor = descriptors[i];
>               if(isInvisible(descriptor) ||  
> descriptor.getWriteMethod() != null || descriptor.getReadMethod() ==  
> null) {
>                   continue;
>               }
>               list.add(descriptors[i]);
>           }
>           return (PropertyDescriptor[]) list.toArray(new  
> PropertyDescriptor[list.size()]);
>       }
>
>       /**
>        * Gets the sub-list of the supplied properties that are  
> readable, writeable,
>        * and have no property editor.  These will be treated as child  
> properties,
>        * so their properties will in turn be presented for editing.
>        */
>       private PropertyDescriptor[]  
> getChildProperties(PropertyDescriptor[] descriptors) {
>           List list = new ArrayList(descriptors.length);
>           for(int i = 0; i < descriptors.length; i++) {
>               PropertyDescriptor descriptor = descriptors[i];
>               if(isInvisible(descriptor) ||  
> descriptor.getWriteMethod() == null || descriptor.getReadMethod() ==  
> null || PropertyEditors.findEditor(descriptor.getPropertyType()) !=  
> null) {
>                   continue;
>               }
>               list.add(descriptors[i]);
>           }
>           return (PropertyDescriptor[]) list.toArray(new  
> PropertyDescriptor[list.size()]);
>       }
>
>       /**
>        * Checks whether a property is one of the ones we want to  
> specifically
>        * ignore/suppress.
>        */
>       private boolean isInvisible(PropertyDescriptor descriptor) {
>           return descriptor.getName().equals("class") ||  
> descriptor.getName().equals("DDBean") ||  
> descriptor.getName().equals("xpaths");
>       }
>   }
>
>
>
>   1.1                   
> incubator-geronimo/modules/core/src/java/org/apache/geronimo/console/ 
> cli/Deployer.java
>
>   Index: Deployer.java
>   ===================================================================
>   /*  
> ====================================================================
>    * The Apache Software License, Version 1.1
>    *
>    * Copyright (c) 2003 The Apache Software Foundation.  All rights
>    * reserved.
>    *
>    * Redistribution and use in source and binary forms, with or without
>    * modification, are permitted provided that the following conditions
>    * are met:
>    *
>    * 1. Redistributions of source code must retain the above copyright
>    *    notice, this list of conditions and the following disclaimer.
>    *
>    * 2. Redistributions in binary form must reproduce the above  
> copyright
>    *    notice, this list of conditions and the following disclaimer in
>    *    the documentation and/or other materials provided with the
>    *    distribution.
>    *
>    * 3. The end-user documentation included with the redistribution,
>    *    if any, must include the following acknowledgment:
>    *       "This product includes software developed by the
>    *        Apache Software Foundation (http://www.apache.org/)."
>    *    Alternately, this acknowledgment may appear in the software  
> itself,
>    *    if and wherever such third-party acknowledgments normally  
> appear.
>    *
>    * 4. The names "Apache" and "Apache Software Foundation" and
>    *    "Apache Geronimo" must not be used to endorse or promote  
> products
>    *    derived from this software without prior written permission.  
> For
>    *    written permission, please contact apache@apache.org.
>    *
>    * 5. Products derived from this software may not be called "Apache",
>    *    "Apache Geronimo", nor may "Apache" appear in their name,  
> without
>    *    prior written permission of the Apache Software Foundation.
>    *
>    * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
>    * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
>    * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
>    * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
>    * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
>    * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
>    * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
>    * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED  
> AND
>    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
>    * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
>    * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
>    * SUCH DAMAGE.
>    *  
> ====================================================================
>    *
>    * This software consists of voluntary contributions made by many
>    * individuals on behalf of the Apache Software Foundation.  For more
>    * information on the Apache Software Foundation, please see
>    * <http://www.apache.org/>.
>    *
>    *  
> ====================================================================
>    */
>   package org.apache.geronimo.console.cli;
>
>   import java.util.jar.JarFile;
>   import java.io.*;
>   import java.net.URLClassLoader;
>   import java.net.URL;
>   import java.net.MalformedURLException;
>   import javax.enterprise.deploy.spi.*;
>   import  
> javax.enterprise.deploy.spi.exceptions.DeploymentManagerCreationExcepti 
> on;
>   import javax.enterprise.deploy.spi.exceptions.InvalidModuleException;
>   import javax.enterprise.deploy.spi.exceptions.ConfigurationException;
>   import  
> javax.enterprise.deploy.shared.factories.DeploymentFactoryManager;
>   import javax.enterprise.deploy.model.*;
>   import org.apache.commons.logging.Log;
>   import org.apache.commons.logging.LogFactory;
>   import  
> org.apache.geronimo.enterprise.deploy.tool.EjbDeployableObject;
>
>   /**
>    * Initializes a command-line JSR-88 deployer.
>    *
>    * @version $Revision: 1.1 $ $Date: 2003/09/04 05:26:19 $
>    */
>   public class Deployer {
>       private static final Log log = LogFactory.getLog(Deployer.class);
>       static {
>           try {
>                
> Class.forName("org.apache.geronimo.enterprise.deploy.provider.GeronimoD 
> eploymentFactory");
>           } catch(ClassNotFoundException e) {
>               log.error("Unable to load Geronimo JSR-88  
> implementation");
>           }
>       }
>
>       private DeploymentManager deployer;
>       private DeployableObject standardModule;
>       private DeploymentConfiguration serverModule;
>       private PrintWriter out;
>       private BufferedReader in;
>       private EjbJarInfo jarInfo;
>       private File saveDir = new File(System.getProperty("user.dir"));
>
>       /**
>        * Creates a new instance using System.out and System.in to  
> interact with
>        * the user.  The user will need ot begin by selecting an EJB  
> JAR file
>        * to work with.
>        */
>       public Deployer() throws IllegalStateException,  
> IllegalArgumentException {
>           this(new PrintWriter(new OutputStreamWriter(System.out),  
> true), new BufferedReader(new InputStreamReader(System.in)));
>       }
>
>       /**
>        * Creates a new instance for the provided EJB JAR file using  
> System.out
>        * and System.in to interact with the user.
>        */
>       public Deployer(File jarFile) throws IllegalStateException,  
> IllegalArgumentException {
>           this(jarFile, new PrintWriter(new  
> OutputStreamWriter(System.out), true), new BufferedReader(new  
> InputStreamReader(System.in)));
>       }
>
>       /**
>        * Creates a new instance using the provided input/output  
> streams to
>        * interact with the user.  The user will need ot begin by  
> selecting an EJB
>        * JAR file to work with.
>        */
>       public Deployer(PrintWriter out, Reader in) throws  
> IllegalStateException, IllegalArgumentException {
>           this.out = out;
>           this.in = in instanceof BufferedReader ? (BufferedReader)in  
> : new BufferedReader(in);
>           if(!connect()) {
>               throw new IllegalStateException("Unable to connect to  
> Deployment service");
>           }
>       }
>
>       /**
>        * Creates a new instance for the provided EJB JAR file and  
> input/output
>        * streams.
>        */
>       public Deployer(File jarFile, PrintWriter out, Reader in) throws  
> IllegalStateException, IllegalArgumentException {
>           this.out = out;
>           this.in = in instanceof BufferedReader ? (BufferedReader)in  
> : new BufferedReader(in);
>           try {
>               jarInfo = new EjbJarInfo();
>               jarInfo.file = jarFile;
>               jarInfo.jarFile = new JarFile(jarFile);
>           } catch(IOException e) {
>               throw new IllegalArgumentException(jarFile+" is not a  
> valid JAR file!");
>           }
>           if(!connect() || !initializeEjbJar()) {
>               throw new IllegalStateException("Unable to connect to  
> Deployment service or prepare deployment information");
>           }
>       }
>
>       /**
>        * Enters the deployment user interface.  When this method  
> returns, the
>        * user has finished their deployment activities.
>        */
>       public void run() {
>           workWithoutModule();
>           deployer.release();
>       }
>
>       /**
>        * Prompts the user to enter a Deployer URL and then gets a  
> DeploymentManager
>        * for that URL.
>        *
>        * @return <tt>true</tt> if the connection was successful.
>        */
>       private boolean connect() {
>           out.println("\n\nEnter the deployer URL.  Leave blank for  
> the default URL 'deployer:geronimo:'");
>           out.print("URL: ");
>           out.flush();
>           try {
>               String url = in.readLine();
>               if(url.equals("")) {
>                   url = "deployer:geronimo:";
>               }
>               deployer =  
> DeploymentFactoryManager.getInstance().getDisconnectedDeploymentManager 
> (url);
>           } catch(DeploymentManagerCreationException e) {
>               log.error("Can't create deployment manager",e);
>               return false;
>           } catch(IOException e) {
>               log.error("Unable to read user input", e);
>               return false;
>           }
>           return true;
>       }
>
>       /**
>        * Loads the deployment descriptor information from the specific  
> EJB JAR
>        * file.
>        *
>        * @return <tt>true</tt> if the deployment information was loaded
>        *         successfully.
>        */
>       private boolean initializeEjbJar() {
>           try {
>               ClassLoader loader = new URLClassLoader(new  
> URL[]{jarInfo.file.toURL()}, ClassLoader.getSystemClassLoader());
>               standardModule = new  
> EjbDeployableObject(jarInfo.jarFile, loader);
>           } catch(MalformedURLException e) {
>               out.println("ERROR: "+jarInfo.file+" is not a valid JAR  
> file!");
>               return false;
>           }
>           try {
>               serverModule =  
> deployer.createConfiguration(standardModule);
>           } catch(InvalidModuleException e) {
>               out.println("ERROR: Unable to initialize a Geronimo DD  
> for EJB JAR "+jarInfo.file);
>               return false;
>           }
>           jarInfo.ejbJar = standardModule.getDDBeanRoot();
>           jarInfo.editingEjbJar = true;
>           try {
>               jarInfo.ejbJarConfig =  
> serverModule.getDConfigBeanRoot(jarInfo.ejbJar);
>               initializeDConfigBean(jarInfo.ejbJarConfig);
>           } catch(ConfigurationException e) {
>               log.error("Unable to initialize server-specific  
> deployment information", e);
>               return false;
>           }
>           return true;
>       }
>
>       /**
>        * Presents a user interface to let the user take high-level  
> deployment
>        * actions.  This lets them do the things you do without  
> reference to a
>        * particular EJB JAR.
>        */
>       private void workWithoutModule() {
>           while(true) {
>               if(jarInfo != null) {
>                   workWithEjbJar();
>                   continue;
>               }
>               out.println("\n\nNo J2EE module is currently selected.");
>               out.println("  -- Select one or more servers or clusters  
> to work with"); // DM.getTargets()
>               out.println("  -- Start non-running modules on the  
> selected servers/clusters");
>               out.println("  -- Stop running modules on the selected  
> servers/clusters");
>               out.println("  -- Undeploy modules from the selected  
> servers/clusters");
>               out.println("  -- View modules on the selected  
> servers/clusters");
>               out.println("  6) Select an EJB JAR to configure,  
> deploy, or redeploy"); //todo: change text when other modules are  
> supported
>               out.println("  7) Disconnect from any servers.");
>               String choice;
>               while(true) {
>                   out.print("Action ([6-7] or [Q]uit): ");
>                   out.flush();
>                   try {
>                       choice = in.readLine().trim().toLowerCase();
>                   } catch(IOException e) {
>                       log.error("Unable to read user input", e);
>                       return;
>                   }
>                   if(choice.equals("6")) {
>                       selectModule();
>                       break;
>                   } else if(choice.equals("7")) {
>                       deployer.release();
>                       out.println("Released any server resources and  
> disconnected.");
>                       break;
>                   } else if(choice.equals("q")) {
>                       return;
>                   }
>               }
>           }
>       }
>
>       /**
>        * Prompts the user to select a J2EE module to work with.
>        *
>        * Currently handles EJB JAR modules only.
>        */
>       private void selectModule() {
>           out.println("\nCurrent directory is "+saveDir);
>           out.println("Select an EJB JAR file to load.");
>           String choice;
>           File file;
>           while(true) {
>               out.print("File Name: ");
>               out.flush();
>               try {
>                   choice = in.readLine().trim();
>               } catch(IOException e) {
>                   log.error("Unable to read user input", e);
>                   return;
>               }
>               file = new File(saveDir, choice);
>               if(!file.canRead() || file.isDirectory()) {
>                   out.println("ERROR: cannot read from this file.   
> Please try again.");
>                   continue;
>               }
>               saveDir = file.getParentFile();
>               break;
>           }
>
>           try {
>               jarInfo = new EjbJarInfo();
>               jarInfo.file = file;
>               jarInfo.jarFile = new JarFile(jarInfo.file);
>           } catch(IOException e) {
>               out.println("ERROR: "+file+" is not a valid JAR file!");
>               jarInfo = null;
>               return;
>           }
>           if(!initializeEjbJar()) {
>               jarInfo = null;
>               return;
>           }
>       }
>
>       /**
>        * Presents a user interface for a user to work with an EJB JAR.
>        */
>       private void workWithEjbJar() {
>           while(true) {
>               out.println("\n\nLoaded an EJB JAR.  Working with the  
> ejb-jar.xml deployment descriptor.");
>               out.println("  -- Edit the standard EJB deployment  
> descriptor (ejb-jar.xml)");
>               out.println("  2) Edit the corresponding server-specific  
> deployment information");
>               out.println("  3) Load a saved set of server-specific  
> deployment information");
>               out.println("  -- Save the current set of  
> server-specific deployment information");
>               out.println("  -- Edit web services deployment  
> information");
>               out.println("  -- Deploy or redeploy the JAR into the  
> application server");
>               out.println("  7) Select a new EJB JAR to work with");  
> //todo: adjust text when other modules are accepted
>               out.println("  8) Manage existing deployments in the  
> server");
>               String choice;
>               while(true) {
>                   out.print("Action ([2-3,7,8] or [Q]uit): ");
>                   out.flush();
>                   try {
>                       choice = in.readLine().trim().toLowerCase();
>                   } catch(IOException e) {
>                       log.error("Unable to read user input", e);
>                       return;
>                   }
>                   if(choice.equals("2")) {
>                       editServerSpecificDD();
>                       break;
>                   } else if(choice.equals("3")) {
>                       loadServerSpecificDD();
>                       break;
>                   } else if(choice.equals("4")) {
>                       saveServerSpecificDD();
>                       break;
>                   } else if(choice.equals("7")) {
>                       selectModule();
>                       if(jarInfo != null) {
>                           break;
>                       } else {
>                           return;
>                       }
>                   } else if(choice.equals("8")) { //todo: prompt to  
> save if modifications were made
>                       jarInfo = null;
>                       return;
>                   } else if(choice.equals("q")) {
>                       jarInfo = null;
>                       return;
>                   }
>               }
>           }
>       }
>
>       /**
>        * Loads the server-specific deployment information from a file  
> on disk.
>        * Note that in JSR-88, server-specific DDs are not saved in the
>        * JAR/EAR/whatever.
>        */
>       private void loadServerSpecificDD() {
>           out.println("\nCurrent directory is "+saveDir);
>           out.println("Select a file name.  The server-specific  
> deployment information for the ");
>           out.println((jarInfo.editingEjbJar ? "ejb-jar.xml" : "Web  
> Services DD")+" will be loaded from the file you specify.");
>           String choice;
>           while(true) {
>               out.print("File Name: ");
>               out.flush();
>               try {
>                   choice = in.readLine().trim();
>               } catch(IOException e) {
>                   log.error("Unable to read user input", e);
>                   return;
>               }
>               File file = new File(saveDir, choice);
>               if(!file.canRead() || file.isDirectory()) {
>                   out.println("ERROR: cannot read from this file.   
> Please try again.");
>                   continue;
>               }
>               saveDir = file.getParentFile();
>               try {
>                   BufferedInputStream fin = new  
> BufferedInputStream(new FileInputStream(file));
>                   DConfigBeanRoot root =  
> serverModule.restoreDConfigBean(fin, jarInfo.editingEjbJar ?  
> jarInfo.ejbJar : jarInfo.webServices);
>                   fin.close();
>                   if(jarInfo.editingEjbJar) {
>                       jarInfo.ejbJarConfig = root;
>                   } else {
>                       jarInfo.webServicesConfig = root;
>                   }
>                   out.println("Deployment information loaded from  
> "+file.getName());
>                   return;
>               } catch(IOException e) {
>                   log.error("Unable to read from file", e);
>                   return;
>               } catch(ConfigurationException e) {
>                   out.println("ERROR: "+e.getMessage());
>                   return;
>               }
>           }
>       }
>
>       /**
>        * Saves the server-specific deployment information to a file on  
> disk.
>        * Note that in JSR-88, server-specific DDs are not saved in the
>        * JAR/EAR/whatever.
>        */
>       private void saveServerSpecificDD() {
>           out.println("\nCurrent directory is "+saveDir);
>           out.println("Select a file name.  The server-specific  
> deployment information for the ");
>           out.println((jarInfo.editingEjbJar ? "ejb-jar.xml" : "Web  
> Services DD")+" will be saved to the file you specify.");
>           String choice;
>           try {
>               while(true) {
>                   out.print("File Name: ");
>                   out.flush();
>                       choice = in.readLine().trim();
>                   File file = new File(saveDir, choice);
>                   if((file.exists() && !file.canWrite()) ||  
> (!file.exists() && !file.getParentFile().canWrite()) ||  
> file.isDirectory()) {
>                       out.println("ERROR: cannot write to this file.   
> Please try again.");
>                       continue;
>                   }
>                   if(file.exists()) {
>                       out.print("File already exists.  Overwrite  
> (Y/N)? ");
>                       out.flush();
>                       choice = in.readLine().trim().toLowerCase();
>                       if(choice.equals("n")) { // todo: makre sure  
> they entered y or n
>                           continue;
>                       }
>                   }
>                   saveDir = file.getParentFile();
>                   try {
>                       BufferedOutputStream fout = new  
> BufferedOutputStream(new FileOutputStream(file));
>                       serverModule.saveDConfigBean(fout,  
> jarInfo.editingEjbJar ? jarInfo.ejbJarConfig :  
> jarInfo.webServicesConfig);
>                       fout.close();
>                       out.println("Deployment information saved to  
> "+file.getName());
>                       return;
>                   } catch(IOException e) {
>                       log.error("Unable to write to file", e);
>                       return;
>                   } catch(ConfigurationException e) {
>                       out.println("ERROR: "+e.getMessage());
>                       return;
>                   }
>               }
>           } catch(IOException e) {
>               log.error("Unable to read user input", e);
>               return;
>           }
>       }
>
>       /**
>        * Marches recursively through the DConfigBean tree to initialize
>        * DConfigBeans for all the interesting DDBeans.  Once this is  
> done, and
>        * DDBean changes need to be relayed to the DConfigBeans that  
> listn on them.
>        */
>       private void initializeDConfigBean(DConfigBean dcb) throws  
> ConfigurationException {
>           String[] xpaths = dcb.getXpaths();
>           for(int i=0; i<xpaths.length; i++) {
>               DDBean[] ddbs = dcb.getDDBean().getChildBean(xpaths[i]);
>               for(int j = 0; j < ddbs.length; j++) {
>                   initializeDConfigBean(dcb.getDConfigBean(ddbs[j]));
>               }
>           }
>       }
>
>       /**
>        * Hands over control to {@link DConfigBeanConfigurator} to let  
> the user edit
>        * the server-specific deployment information.
>        */
>       private void editServerSpecificDD() {
>           new DConfigBeanConfigurator(jarInfo.ejbJarConfig, out,  
> in).configure();
>       }
>
>       /**
>        * Holds all the relevent data for an EJB JAR.
>        */
>       private static class EjbJarInfo {
>           public File file;
>           public JarFile jarFile;
>           public DDBeanRoot ejbJar;
>           public DConfigBeanRoot ejbJarConfig;
>           public DDBeanRoot webServices;
>           public DConfigBeanRoot webServicesConfig;
>           public boolean editingEjbJar;
>       }
>   }
>
>
>
>


Mime
View raw message