001/*
002 * Copyright 2007-2018 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        MissingSourceBehavior value = MissingSourceBehavior.valueOf(missingSrc.trim().toUpperCase());
071        if (value == null) {
072            throw new IllegalArgumentException("Unknown " + MissingSourceBehavior.class.getSimpleName() + ": " + missingSrc);
073        }
074        this.missingSrc = value;
075    }
076
077    @Parameter
078    private String linkName;
079
080    public void setLinkName(String linkName) {
081        this.linkName = linkName;
082    }
083
084    @Parameter
085    private String linkTarget;
086
087    public void setLinkTarget(String linkTarget) {
088        this.linkTarget = linkTarget;
089    }
090
091    @Parameter
092    private boolean symlink = true;
093
094    public void setSymlink(boolean symlink) {
095        this.symlink = symlink;
096    }
097
098    private boolean conffile = false;
099
100    /**
101     * @parameter expression="${conffile}"
102     */
103    public void setConffile(boolean conffile) {
104        this.conffile = conffile;
105    }
106
107    public boolean getConffile() {
108        return this.conffile;
109    }
110
111    @Parameter(alias = "includes")
112    private String[] includePatterns;
113
114    public void setIncludes( String includes ) {
115        includePatterns = splitPatterns(includes);
116    }
117
118    @Parameter(alias = "excludes")
119    private String[] excludePatterns;
120
121    public void setExcludes( String excludes ) {
122        excludePatterns = splitPatterns(excludes);
123    }
124
125    @Parameter
126    private Mapper mapper;
127
128    @Parameter
129    private String[] paths;
130
131    /* For testing only */
132    void setPaths( String[] paths ) {
133        this.paths = paths;
134    }
135
136    public String[] splitPatterns( String patterns ) {
137        String[] result = null;
138        if (patterns != null && patterns.length() > 0) {
139            List<String> tokens = new ArrayList<String>();
140            StringTokenizer tok = new StringTokenizer(patterns, ", ", false);
141            while (tok.hasMoreTokens()) {
142                tokens.add(tok.nextToken());
143            }
144            result = tokens.toArray(new String[tokens.size()]);
145        }
146        return result;
147    }
148
149    public void produce( final DataConsumer pReceiver ) throws IOException {
150        org.vafer.jdeb.mapping.Mapper[] mappers = null;
151        if (mapper != null) {
152            mappers = new org.vafer.jdeb.mapping.Mapper[] { mapper.createMapper() };
153        }
154
155        // link type
156
157        if (typeIs("link")) {
158            if (linkName == null) {
159                throw new RuntimeException("linkName is not set");
160            }
161            if (linkTarget == null) {
162                throw new RuntimeException("linkTarget is not set");
163            }
164
165            new DataProducerLink(linkName, linkTarget, symlink, includePatterns, excludePatterns, mappers).produce(pReceiver);
166            return;
167        }
168
169        // template type
170
171        if (typeIs("template")) {
172            checkPaths();
173            new DataProducerPathTemplate(paths, includePatterns, excludePatterns, mappers).produce(pReceiver);
174            return;
175        }
176
177        if (typeIs("files")) {
178            checkPaths();
179            new DataProducerFiles(paths, dst, mappers).produce(pReceiver);
180            return;
181        }
182
183        // Types that require src to exist
184
185        if (src == null || !src.exists()) {
186            if (missingSrc == IGNORE) {
187                return;
188            } else {
189                throw new FileNotFoundException("Data source not found : " + src);
190            }
191        }
192
193        if (typeIs("file")) {
194            new DataProducerFile(src, dst, includePatterns, excludePatterns, mappers).produce(pReceiver);
195            return;
196        }
197
198        if (typeIs("archive")) {
199            new DataProducerArchive(src, includePatterns, excludePatterns, mappers).produce(pReceiver);
200            return;
201        }
202
203        if (typeIs("directory")) {
204            new DataProducerDirectory(src, includePatterns, excludePatterns, mappers).produce(pReceiver);
205            return;
206        }
207
208        throw new IOException("Unknown type '" + type + "' (file|directory|archive|template|link) for " + src);
209    }
210
211    private boolean typeIs( final String type ) {
212        return type.equalsIgnoreCase(this.type);
213    }
214
215    private void checkPaths() {
216        if (paths == null || paths.length == 0) {
217            throw new RuntimeException("paths parameter is not set");
218        }
219    }
220}