001package ball.util.ant.taskdefs;
002/*-
003 * ##########################################################################
004 * Utilities
005 * $Id: InstanceOfTask.html 5431 2020-02-12 19:03:17Z ball $
006 * $HeadURL: svn+ssh://svn.hcf.dev/var/spool/scm/repository.svn/hcf-dev/blog/2019-07-08-fivethirtyeight-best-scrabble-string/src/main/resources/javadoc/src-html/ball/util/ant/taskdefs/InstanceOfTask.html $
007 * %%
008 * Copyright (C) 2008 - 2020 Allen D. Ball
009 * %%
010 * Licensed under the Apache License, Version 2.0 (the "License");
011 * you may not use this file except in compliance with the License.
012 * You may obtain a copy of the License at
013 *
014 *      http://www.apache.org/licenses/LICENSE-2.0
015 *
016 * Unless required by applicable law or agreed to in writing, software
017 * distributed under the License is distributed on an "AS IS" BASIS,
018 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
019 * See the License for the specific language governing permissions and
020 * limitations under the License.
021 * ##########################################################################
022 */
023import ball.activation.ReaderWriterDataSource;
024import ball.util.Factory;
025import ball.util.ant.types.TypedAttributeType;
026import java.beans.ExceptionListener;
027import java.beans.XMLEncoder;
028import java.lang.reflect.Member;
029import java.util.ArrayList;
030import java.util.List;
031import lombok.NoArgsConstructor;
032import lombok.ToString;
033import org.apache.tools.ant.BuildException;
034
035/**
036 * {@link.uri http://ant.apache.org/ Ant} {@link org.apache.tools.ant.Task}
037 * to get an instance of a specified {@link Class}.
038 *
039 * {@ant.task}
040 *
041 * @see Factory
042 *
043 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
044 * @version $Revision: 5431 $
045 */
046@AntTask("instance-of")
047@NoArgsConstructor @ToString
048public class InstanceOfTask extends TypeTask {
049    private final List<TypedAttributeType> list = new ArrayList<>();
050    protected Object instance = null;
051
052    public void addConfiguredArgument(TypedAttributeType argument) {
053        list.add(argument);
054    }
055
056    public List<TypedAttributeType> getArgumentList() { return list; }
057
058    public void setArgument(String string) {
059        list.add(new TypedAttributeType(string));
060    }
061
062    @Override
063    public void execute() throws BuildException {
064        super.execute();
065
066        try {
067            Class<?> type = getClassForName(getType());
068
069            log(type.getName());
070
071            ClassList parameters = new ClassList();
072            List<Object> arguments = new ArrayList<>();
073
074            for (TypedAttributeType argument : list) {
075                Factory<?> factory =
076                    new Factory<>(getClassForName(argument.getType()));
077
078                parameters.add(factory.getType());
079
080                String string =
081                    getProject().replaceProperties(argument.getValue());
082
083                arguments.add(factory.getInstance(string));
084            }
085
086            log(String.valueOf(parameters));
087            log(String.valueOf(arguments));
088
089            Factory<?> factory = new Factory<>(type);
090            Member member = factory.getFactoryMethod(parameters.toArray());
091
092            log(String.valueOf(member));
093
094            instance = factory.apply(member, arguments.toArray());
095
096            log(String.valueOf(instance));
097
098            if (getClass().isAssignableFrom(InstanceOfTask.class)) {
099                ReaderWriterDataSourceImpl ds =
100                    new ReaderWriterDataSourceImpl();
101
102                try (XMLEncoder encoder =
103                         new XMLEncoder(ds.getOutputStream())) {
104                    encoder.setExceptionListener(ds);
105                    encoder.writeObject(instance);
106                    encoder.flush();
107                }
108
109                if (ds.length() > 0) {
110                    log();
111                    log(ds.getBufferedReader().lines());
112                }
113            }
114        } catch (BuildException exception) {
115            throw exception;
116        } catch (Throwable throwable) {
117            throwable.printStackTrace();
118            throw new BuildException(throwable);
119        }
120    }
121
122    @NoArgsConstructor
123    private class ClassList extends ArrayList<Class<?>> {
124        private static final long serialVersionUID = -4504828433924386345L;
125
126        @Override
127        public Class<?>[] toArray() { return toArray(new Class<?>[] { }); }
128    }
129
130    private class ReaderWriterDataSourceImpl extends ReaderWriterDataSource
131                                             implements ExceptionListener {
132        public ReaderWriterDataSourceImpl() { super(null, null); }
133
134        @Override
135        public void exceptionThrown(Exception exception) { clear(); }
136    }
137}