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