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.swing.table.SimpleTableModel;
022import java.util.Collections;
023import java.util.regex.Matcher;
024import java.util.regex.Pattern;
025import java.util.regex.PatternSyntaxException;
026import lombok.Getter;
027import lombok.NoArgsConstructor;
028import lombok.Setter;
029import lombok.ToString;
030import lombok.experimental.Accessors;
031import org.apache.tools.ant.BuildException;
032import org.apache.tools.ant.Project;
033import org.apache.tools.ant.Task;
034import org.apache.tools.ant.util.ClasspathUtils;
035
036import static lombok.AccessLevel.PROTECTED;
037import static org.apache.commons.lang3.StringUtils.EMPTY;
038import static org.apache.commons.lang3.StringUtils.SPACE;
039
040/**
041 * Abstract {@link.uri http://ant.apache.org/ Ant} {@link Task} base class
042 * for {@link Pattern}-specific tasks.
043 *
044 * {@ant.task}
045 *
046 * @author {@link.uri mailto:ball@hcf.dev Allen D. Ball}
047 */
048@NoArgsConstructor(access = PROTECTED)
049public abstract class PatternTask extends Task implements AnnotatedAntTask,
050                                                          ClasspathDelegateAntTask, ConfigurableAntTask {
051    @Getter @Setter @Accessors(chain = true, fluent = true)
052    private ClasspathUtils.Delegate delegate = null;
053    @NotNull @Getter @Setter
054    private String pattern = null;
055    @NotNull @Getter @Setter
056    private String input = null;
057
058    @Override
059    public void init() throws BuildException {
060        super.init();
061        ClasspathDelegateAntTask.super.init();
062        ConfigurableAntTask.super.init();
063    }
064
065    @Override
066    public void execute() throws BuildException {
067        super.execute();
068        AnnotatedAntTask.super.execute();
069    }
070
071    /**
072     * {@link Pattern} {@link Matcher#matches()} {@link Task}.
073     *
074     * {@ant.task}
075     */
076    @NoArgsConstructor @ToString
077    @AntTask("pattern-matches")
078    public static class Matches extends PatternTask {
079        @Override
080        public void execute() throws BuildException {
081            super.execute();
082
083            try {
084                SimpleTableModel table = new SimpleTableModel(new Object[][] { }, 2);
085                Pattern pattern = Pattern.compile(getPattern());
086
087                table.row(EMPTY, String.valueOf(pattern));
088
089                String input = getInput();
090
091                table.row(EMPTY, String.valueOf(input));
092
093                Matcher matcher = pattern.matcher(input);
094                boolean matches = matcher.matches();
095
096                table.row(EMPTY, String.valueOf(matches));
097
098                if (matches) {
099                    for (int i = 0, n = matcher.groupCount(); i <= n; i += 1) {
100                        table.row(String.valueOf(i), tab(matcher.start(i)) + matcher.group(i));
101                    }
102                }
103
104                log(table);
105            } catch (PatternSyntaxException exception) {
106                log(exception.getMessage(), Project.MSG_ERR);
107                throw new BuildException();
108            } catch (BuildException exception) {
109                throw exception;
110            } catch (RuntimeException exception) {
111                throw exception;
112            } catch (Exception exception) {
113                throw new BuildException(exception);
114            }
115        }
116
117        private String tab(int count) {
118            return String.join(EMPTY, Collections.nCopies(count, SPACE));
119        }
120    }
121
122    /**
123     * {@link Pattern#split(CharSequence)} {@link Task}.
124     *
125     * {@ant.task}
126     */
127    @NoArgsConstructor @ToString
128    @AntTask("pattern-split")
129    public static class Split extends PatternTask {
130        @Override
131        public void execute() throws BuildException {
132            super.execute();
133
134            try {
135                SimpleTableModel table = new SimpleTableModel(new Object[][] { }, 2);
136                Pattern pattern = Pattern.compile(getPattern());
137
138                table.row(EMPTY, String.valueOf(pattern));
139
140                String input = getInput();
141
142                table.row(EMPTY, String.valueOf(input));
143
144                String[] strings = pattern.split(input);
145
146                for (int i = 0; i < strings.length; i += 1) {
147                    table.row(String.valueOf(i), strings[i]);
148                }
149
150                log(table);
151            } catch (PatternSyntaxException exception) {
152                log(exception.getMessage(), Project.MSG_ERR);
153                throw new BuildException();
154            } catch (BuildException exception) {
155                throw exception;
156            } catch (RuntimeException exception) {
157                throw exception;
158            } catch (Exception exception) {
159                throw new BuildException(exception);
160            }
161        }
162    }
163}