View Javadoc
1   /*
2    * #%L
3    * EUGene :: EUGene
4    * %%
5    * Copyright (C) 2004 - 2010 CodeLutin
6    * %%
7    * This program is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU Lesser General Public License as 
9    * published by the Free Software Foundation, either version 3 of the 
10   * License, or (at your option) any later version.
11   * 
12   * This program is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Lesser Public License for more details.
16   * 
17   * You should have received a copy of the GNU General Lesser Public 
18   * License along with this program.  If not, see
19   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
20   * #L%
21   */
22  
23  package org.nuiton.eugene.writer;
24  
25  import org.apache.commons.logging.Log;
26  import org.apache.commons.logging.LogFactory;
27  
28  import java.io.File;
29  import java.io.IOException;
30  import java.util.ArrayList;
31  import java.util.Arrays;
32  import java.util.Collections;
33  import java.util.List;
34  import java.util.Map;
35  import java.util.Set;
36  import java.util.TreeMap;
37  
38  /**
39   * Abstract implementation of the {@link ChainedFileWriter}.
40   *
41   * @author Tony Chemit - chemit@codelutin.com
42   * @since 2.0.0
43   */
44  public abstract class AbstractChainedFileWriter implements ChainedFileWriter {
45  
46      /** Logger */
47      private static final Log log =
48              LogFactory.getLog(AbstractChainedFileWriter.class);
49  
50      /** entries to treate with this writer */
51      protected List<ChainedFileWriterEntry> entries;
52  
53      /** previous writer (can be null) */
54      protected ChainedFileWriter previousWriter;
55  
56      /** next writer (can be null) */
57      protected ChainedFileWriter nextWriter;
58  
59      /**
60       * universe of authorized properties (keys are property names, values are
61       * property descriptions).
62       */
63      protected final Map<String, String> authorizedPropertyDescriptions;
64  
65      /**
66       * real properties obtained fro a configuration in {@link
67       * #initWriter(ChainedFileWriterConfiguration)} method
68       */
69      protected Map<String, Object> properties;
70  
71      private WriterReport writerReport;
72  
73      /**
74       * Generates for all given files ({@code filesByRoot} and then copy
75       * resources given for his file reacted in the {@code resourcesByFile}
76       * dictionnary.
77       *
78       * @param configuration   the shared configuration for all writers
79       * @param outputDir       where to generate files
80       * @param filesByRoot     all files to treate
81       * @param resourcesByFile resources associated to files to treate
82       * @throws IOException for any IO pb.
83       * @since 2.1.3
84       */
85      protected abstract void generate(
86              ChainedFileWriterConfiguration configuration,
87              File outputDir,
88              Map<File, List<File>> filesByRoot,
89              Map<File, List<File>> resourcesByFile) throws IOException;
90  
91      protected AbstractChainedFileWriter(String... propertyNameAndDescriptions) {
92          if (propertyNameAndDescriptions.length % 2 != 0) {
93              throw new IllegalArgumentException(
94                      "propertyNameAndDescriptions must be couple of " +
95                      "(property key, property description), but was " +
96                      Arrays.toString(propertyNameAndDescriptions));
97          }
98          entries = new ArrayList<>();
99          properties = new TreeMap<>();
100         Map<String, String> authorizedPropertyDescriptions =
101                 new TreeMap<>();
102         for (int i = 0, max = propertyNameAndDescriptions.length / 2;
103              i < max; i++) {
104             authorizedPropertyDescriptions.put(
105                     propertyNameAndDescriptions[2 * i],
106                     propertyNameAndDescriptions[2 * i + 1]);
107         }
108         this.authorizedPropertyDescriptions =
109                 Collections.unmodifiableMap(authorizedPropertyDescriptions);
110     }
111 
112     @Override
113     public Map<String, String> getAuthorizedPropertyDescriptions() {
114         return authorizedPropertyDescriptions;
115     }
116 
117     @Override
118     public String[] getAuthorizedPropertyNames() {
119         Set<String> keys = authorizedPropertyDescriptions.keySet();
120         return keys.toArray(new String[keys.size()]);
121     }
122 
123     @Override
124     public void clear() {
125         entries.clear();
126         properties.clear();
127         previousWriter = nextWriter = null;
128     }
129 
130     @Override
131     public void addEntry(ChainedFileWriterEntry entry) {
132         entries.add(entry);
133     }
134 
135     @SuppressWarnings({"unchecked"})
136     @Override
137     public <T> T getProperty(String key, Class<T> type) {
138         return (T) properties.get(key);
139     }
140 
141     @Override
142     public void generate(ChainedFileWriterConfiguration configuration,
143                          ChainedFileWriterData data)
144             throws IOException {
145 
146         initWriter(configuration);
147 
148         try {
149             File outputDir = data.getOutputDirectory();
150             Map<File, List<File>> filesByRoot = data.getFilesByRoot();
151 
152             Map<File, List<File>> resourcesByFile = data.getResourcesByFile();
153 
154             // launch generation
155             generate(configuration, outputDir, filesByRoot, resourcesByFile);
156 
157         } finally {
158             clear();
159         }
160     }
161 
162     @Override
163     public String getInputProtocol(String modelType) {
164         // input protocol is the same for all model
165         return acceptModel(modelType) ? getInputProtocol() : null;
166     }
167 
168     @Override
169     public File getOutputDirectory(File outputBasedir, boolean testPhase) {
170         return new File(outputBasedir, testPhase ?
171                                        getDefaultTestOutputDirectory() :
172                                        getDefaultOutputDirectory()
173         );
174     }
175 
176     @Override
177     public File getExtractDirectory(File outputBasedir, boolean testPhase) {
178         return new File(outputBasedir, testPhase ?
179                                        "test-" + getInputProtocol() :
180                                        getInputProtocol()
181         );
182     }
183 
184     @Override
185     public List<ChainedFileWriterEntry> getEntries() {
186         return entries;
187     }
188 
189     @Override
190     public WriterReport getWriterReport() {
191         return writerReport;
192     }
193 
194     @Override
195     public void setWriterReport(WriterReport writerReport) {
196         this.writerReport = writerReport;
197     }
198 
199     protected ChainedFileWriter getNextWriter() {
200         return nextWriter;
201     }
202 
203     protected ChainedFileWriter getPreviousWriter() {
204         return previousWriter;
205     }
206 
207     protected void setNextWriter(ChainedFileWriter nextWriter) {
208         this.nextWriter = nextWriter;
209     }
210 
211     /**
212      * Initialize the writer before the generation.
213      *
214      * @param configuration the configuration to use for int
215      */
216     protected void initWriter(ChainedFileWriterConfiguration configuration) {
217         Map<String, Object> map = configuration.getProperties();
218 
219         boolean verbose = configuration.isVerbose();
220         for (String key : getAuthorizedPropertyNames()) {
221             //TODO-TC-20091217, should prefix keys by the inputProtocol to
222             //TODO-TC-20091217  avoid collisions ?
223 
224             if (map.containsKey(key)) {
225                 // keep this property
226                 Object value = map.get(key);
227                 if (verbose) {
228                     log.info("[" + getClass().getName() + "] add configuration property " + key + " = " + value);
229                 }
230                 properties.put(key, value);
231 
232             }
233         }
234     }
235 
236 }