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