001    /*
002     * Copyright (c) 2005 Stephen J. McConnell
003     *
004     * Licensed  under the  Apache License,  Version 2.0  (the "License");
005     * you may not use  this file  except in  compliance with the License.
006     * You may obtain a copy of the License at
007     *
008     *   http://www.apache.org/licenses/LICENSE-2.0
009     *
010     * Unless required by applicable law or agreed to in writing, software
011     * distributed  under the  License is distributed on an "AS IS" BASIS,
012     * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
013     * implied.
014     *
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     */
018    
019    package net.dpml.metro.tools;
020    
021    import java.util.ArrayList;
022    import java.util.List;
023    
024    import net.dpml.lang.Value;
025    
026    import net.dpml.metro.data.ValueDirective;
027    
028    import org.apache.tools.ant.BuildException;
029    
030    /**
031     * Defintion of a context entry parameter directive.
032     *
033     * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
034     * @version 1.2.0
035     */
036    public class ValueDataType implements ValueBuilder
037    {
038        private String m_classname;
039        private String m_method;
040        private String m_value;
041        private List m_params = new ArrayList();
042    
043       /**
044        * Set the context entry classname.
045        * @param classname the context entry classname
046        */
047        public void setClass( final String classname )
048        {
049            m_classname = classname;
050        }
051    
052       /**
053        * Set the method name.
054        * @param method the name of a static method
055        */
056        public void setMethod( final String method )
057        {
058            m_method = method;
059        }
060    
061       /**
062        * Return the context entry parameter classname.
063        * @return the classname
064        */
065        public String getClassname()
066        {
067            return m_classname;
068        }
069    
070       /**
071        * Return the context entry parameter classname.
072        * @return the classname
073        */
074        String getMethodName()
075        {
076            return m_method;
077        }
078    
079       /**
080        * Set the value of the context entry parameter.
081        * @param value the param value
082        */
083        public void setValue( final String value )
084        {
085            m_value = value;
086        }
087    
088       /**
089        * Return the value of the context entry param.
090        * @return the value
091        */
092        public String getValue()
093        {
094            return m_value;
095        }
096    
097       /**
098        * Create, assign and return a new nested entry constructor parameter.
099        * @return the new context entry param
100        */
101        public ValueDataType createValue()
102        {
103            final ValueDataType param = new ValueDataType();
104            m_params.add( param );
105            return param;
106        }
107    
108       /**
109        * Return the set of nested param directives.
110        * @return the params
111        */
112        public ValueBuilder[] getValueBuilders()
113        {
114            return (ValueBuilder[]) m_params.toArray( new ValueBuilder[0] );
115        }
116    
117       /**
118        * Build a value datastructure.
119        * @param classloader the working classloader
120        * @return the serializable value descriptor
121        */
122        public Value buildValue( ClassLoader classloader )
123        {
124            String classname = getClassname();
125            String method = getMethodName();
126            String value = getValue();
127            if( null != value )
128            {
129                return new ValueDirective( classname, method, value );
130            }
131            else
132            {
133                ValueBuilder[] params = getValueBuilders();
134                Value[] values = new Value[ params.length ];
135                for( int i=0; i<values.length; i++ )
136                {
137                    ValueBuilder p = params[i];
138                    values[i] = p.buildValue( classloader );
139                }
140                return new ValueDirective( classname, method, values );
141            }
142        }
143    
144       /**
145        * Return the base classname.
146        * @param classloader the working classloader
147        * @return the target class
148        */
149        public Class getTargetClass( ClassLoader classloader )
150        {
151            String classname = getClassname();
152            return getBaseClass( classloader, classname );
153        }
154        
155        private Class getBaseClass( ClassLoader classloader, String classname )
156        {
157            if( null == classname )
158            {
159                return String.class;
160            }
161            else
162            {
163                try
164                {
165                    return classloader.loadClass( classname );
166                }
167                catch( ClassNotFoundException e )
168                {
169                    final String error = 
170                      "The value type base class [" + classname + "] is unknown.";
171                    throw new BuildException( error, e );
172                }
173            }
174        }
175    }