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.activemq.store.amq;
018    
019    import java.util.ArrayList;
020    
021    import org.apache.activemq.util.IntrospectionSupport;
022    
023    /**
024     * Helper utility that can be used to set the properties on any object using
025     * command line arguments.
026     */
027    public final class CommandLineSupport {
028    
029        private CommandLineSupport() {
030        }
031        
032        /**
033         * Sets the properties of an object given the command line args.
034         * 
035         * if args contains: --ack-mode=AUTO --url=tcp://localhost:61616 --persistent 
036         * 
037         * then it will try to call the following setters on the target object.
038         * 
039         * target.setAckMode("AUTO");
040         * target.setURL(new URI("tcp://localhost:61616") );
041         * target.setPersistent(true);
042         * 
043         * Notice the the proper conversion for the argument is determined by examining the 
044         * setter argument type.
045         * 
046         * @param target the object that will have it's properties set
047         * @param args the command line options
048         * @return any arguments that are not valid options for the target
049         */
050        public static String[] setOptions(Object target, String[] args) {
051            ArrayList<String> rc = new ArrayList<String>();
052    
053            for (int i = 0; i < args.length; i++) {
054                if (args[i] == null) {
055                    continue;
056                }
057    
058                if (args[i].startsWith("--")) {
059    
060                    // --options without a specified value are considered boolean
061                    // flags that are enabled.
062                    String value = "true";
063                    String name = args[i].substring(2);
064    
065                    // if --option=value case
066                    int p = name.indexOf("=");
067                    if (p > 0) {
068                        value = name.substring(p + 1);
069                        name = name.substring(0, p);
070                    }
071    
072                    // name not set, then it's an unrecognized option
073                    if (name.length() == 0) {
074                        rc.add(args[i]);
075                        continue;
076                    }
077    
078                    String propName = convertOptionToPropertyName(name);
079                    if (!IntrospectionSupport.setProperty(target, propName, value)) {
080                        rc.add(args[i]);
081                        continue;
082                    }
083                } else {
084                    rc.add(args[i]);
085                }
086    
087            }
088    
089            String r[] = new String[rc.size()];
090            rc.toArray(r);
091            return r;
092        }
093    
094        /**
095         * converts strings like: test-enabled to testEnabled
096         */
097        private static String convertOptionToPropertyName(String name) {
098            String rc = "";
099    
100            // Look for '-' and strip and then convert the subsequent char to
101            // uppercase
102            int p = name.indexOf("-");
103            while (p > 0) {
104                // strip
105                rc += name.substring(0, p);
106                name = name.substring(p + 1);
107    
108                // can I convert the next char to upper?
109                if (name.length() > 0) {
110                    rc += name.substring(0, 1).toUpperCase();
111                    name = name.substring(1);
112                }
113    
114                p = name.indexOf("-");
115            }
116            return rc + name;
117        }
118    }