001/*
002 * Copyright 2007-2021 The jdeb developers.
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 implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016
017package org.vafer.jdeb.maven;
018
019import java.io.File;
020import java.io.FileNotFoundException;
021import java.io.IOException;
022import java.util.ArrayList;
023import java.util.List;
024import java.util.StringTokenizer;
025
026import org.apache.maven.plugins.annotations.Parameter;
027import org.vafer.jdeb.DataConsumer;
028import org.vafer.jdeb.DataProducer;
029import org.vafer.jdeb.producers.DataProducerArchive;
030import org.vafer.jdeb.producers.DataProducerDirectory;
031import org.vafer.jdeb.producers.DataProducerFile;
032import org.vafer.jdeb.producers.DataProducerFiles;
033import org.vafer.jdeb.producers.DataProducerLink;
034import org.vafer.jdeb.producers.DataProducerPathTemplate;
035
036import static org.vafer.jdeb.maven.MissingSourceBehavior.*;
037
038/**
039 * Maven "data" element acting as a factory for DataProducers. So far Archive and
040 * Directory producers are supported. Both support the usual ant pattern set
041 * matching.
042 */
043public final class Data implements DataProducer {
044
045    @Parameter
046    private File src;
047
048    public void setSrc( File src ) {
049        this.src = src;
050    }
051
052    @Parameter
053    private String dst;
054
055    public void setDst( String dst ) {
056        this.dst = dst;
057    }
058
059    @Parameter
060    private String type;
061
062    public void setType( String type ) {
063        this.type = type;
064    }
065
066    @Parameter
067    private MissingSourceBehavior missingSrc = FAIL;
068
069    public void setMissingSrc( String missingSrc ) {
070        this.missingSrc = MissingSourceBehavior.valueOf(missingSrc.trim().toUpperCase());
071    }
072
073    @Parameter
074    private String linkName;
075
076    public void setLinkName(String linkName) {
077        this.linkName = linkName;
078    }
079
080    @Parameter
081    private String linkTarget;
082
083    public void setLinkTarget(String linkTarget) {
084        this.linkTarget = linkTarget;
085    }
086
087    @Parameter
088    private boolean symlink = true;
089
090    public void setSymlink(boolean symlink) {
091        this.symlink = symlink;
092    }
093
094    private boolean conffile = false;
095
096    /**
097     * @parameter expression="${conffile}"
098     */
099    public void setConffile(boolean conffile) {
100        this.conffile = conffile;
101    }
102
103    public boolean getConffile() {
104        return this.conffile;
105    }
106
107    @Parameter(alias = "includes")
108    private String[] includePatterns;
109
110    public void setIncludes( String includes ) {
111        includePatterns = splitPatterns(includes);
112    }
113
114    @Parameter(alias = "excludes")
115    private String[] excludePatterns;
116
117    public void setExcludes( String excludes ) {
118        excludePatterns = splitPatterns(excludes);
119    }
120
121    @Parameter
122    private Mapper mapper;
123
124    @Parameter
125    private String[] paths;
126
127    /* For testing only */
128    void setPaths( String[] paths ) {
129        this.paths = paths;
130    }
131
132    public String[] splitPatterns( String patterns ) {
133        String[] result = null;
134        if (patterns != null && patterns.length() > 0) {
135            List<String> tokens = new ArrayList<>();
136            StringTokenizer tok = new StringTokenizer(patterns, ", ", false);
137            while (tok.hasMoreTokens()) {
138                tokens.add(tok.nextToken());
139            }
140            result = tokens.toArray(new String[tokens.size()]);
141        }
142        return result;
143    }
144
145    public void produce( final DataConsumer pReceiver ) throws IOException {
146        org.vafer.jdeb.mapping.Mapper[] mappers = null;
147        if (mapper != null) {
148            mappers = new org.vafer.jdeb.mapping.Mapper[] { mapper.createMapper() };
149        }
150
151        // link type
152
153        if (typeIs("link")) {
154            if (linkName == null) {
155                throw new RuntimeException("linkName is not set");
156            }
157            if (linkTarget == null) {
158                throw new RuntimeException("linkTarget is not set");
159            }
160
161            new DataProducerLink(linkName, linkTarget, symlink, includePatterns, excludePatterns, mappers).produce(pReceiver);
162            return;
163        }
164
165        // template type
166
167        if (typeIs("template")) {
168            checkPaths();
169            new DataProducerPathTemplate(paths, includePatterns, excludePatterns, mappers).produce(pReceiver);
170            return;
171        }
172
173        if (typeIs("files")) {
174            checkPaths();
175            new DataProducerFiles(paths, dst, mappers).produce(pReceiver);
176            return;
177        }
178
179        // Types that require src to exist
180
181        if (src == null || !src.exists()) {
182            if (missingSrc == IGNORE) {
183                return;
184            } else {
185                throw new FileNotFoundException("Data source not found : " + src);
186            }
187        }
188
189        if (typeIs("file")) {
190            new DataProducerFile(src, dst, includePatterns, excludePatterns, mappers).produce(pReceiver);
191            return;
192        }
193
194        if (typeIs("archive")) {
195            new DataProducerArchive(src, includePatterns, excludePatterns, mappers).produce(pReceiver);
196            return;
197        }
198
199        if (typeIs("directory")) {
200            new DataProducerDirectory(src, includePatterns, excludePatterns, mappers).produce(pReceiver);
201            return;
202        }
203
204        throw new IOException("Unknown type '" + type + "' (file|directory|archive|template|link) for " + src);
205    }
206
207    private boolean typeIs( final String type ) {
208        return type.equalsIgnoreCase(this.type);
209    }
210
211    private void checkPaths() {
212        if (paths == null || paths.length == 0) {
213            throw new RuntimeException("paths parameter is not set");
214        }
215    }
216}