Statistics
| Revision:

root / org.gvsig.educa.thematicmap / trunk / org.gvsig.educa.thematicmap / org.gvsig.educa.thematicmap.lib / org.gvsig.educa.thematicmap.lib.impl / src / main / java / org / gvsig / educa / thematicmap / impl / compilation / process / CopyAllLayersFiles.java @ 45

History | View | Annotate | Download (10.2 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.educa.thematicmap.impl.compilation.process;
23

    
24
import java.io.File;
25
import java.io.IOException;
26
import java.text.MessageFormat;
27
import java.util.List;
28

    
29
import org.apache.commons.lang3.StringUtils;
30

    
31
import org.gvsig.educa.thematicmap.compilation.CompilationException;
32
import org.gvsig.educa.thematicmap.compilation.ThematicMapCompiler;
33
import org.gvsig.educa.thematicmap.impl.util.FileUtils;
34
import org.gvsig.educa.thematicmap.impl.util.FilenameUtils;
35
import org.gvsig.educa.thematicmap.impl.util.PersistenceUtils;
36
import org.gvsig.fmap.mapcontext.layers.FLayer;
37
import org.gvsig.fmap.mapcontext.layers.FLayers;
38
import org.gvsig.fmap.mapcontext.layers.operations.SingleLayer;
39
import org.gvsig.tools.ToolsLocator;
40
import org.gvsig.tools.persistence.PersistenceManager;
41
import org.gvsig.tools.persistence.PersistentState;
42
import org.gvsig.tools.persistence.exception.PersistenceException;
43

    
44
/**
45
 * <p>
46
 * {@link ThematicMapCompiler} process step
47
 * </p>
48
 * <p>
49
 * This steps copy all layer data into workFolder. This process is:
50
 * <ul>
51
 * <li>Creates root base folder in workFolder</li>
52
 * <li>Iterates over every layer:
53
 * <ul>
54
 * <li>If is a layer's group, create a new folder and iterates over its children
55
 * </li>
56
 * <li>If is a layer, identify all files used by layer (data files,Symbology)
57
 * and do:
58
 * <ul>
59
 * <li>Copy file to layer work folder</li>
60
 * <li>register final location of file in {@link ProcessData#fileMapping}</li>
61
 * </ul>
62
 * </li>
63
 * </ul>
64
 * </li>
65
 * </ul>
66
 * </p>
67
 * <p>
68
 * From {@link ProcessData} Uses:
69
 * <ul>
70
 * <li>{@link ProcessData#workFolder}</li>
71
 * <li>{@link ProcessData#mapContext}</li>
72
 * </ul>
73
 * and Sets:
74
 * <ul>
75
 * <li>{@link ProcessData#fileMapping}</li>
76
 * <li>{@link ProcessData#mapContextFolder}</li>
77
 * <li>{@link ProcessData#rootLayersFolder}</li>
78
 * </ul>
79
 * </p>
80
 * 
81
 * @author gvSIG Team
82
 * @version $Id$
83
 * 
84
 */
85
public class CopyAllLayersFiles implements ProcessStep {
86

    
87
    private static final String ROOT_LAYERS_FOLDER_PATH_KEY =
88
        "RootLayersFolderPath";
89

    
90
    private static final String MAP_CONTEXT_FOLDER_PATH_KEY =
91
        "MapContextFolderPath";
92

    
93
    public static final String ROOT_LAYER_FOLDER_NAME = "layers";
94

    
95
    private final PersistenceManager persitenceMan;
96

    
97
    public CopyAllLayersFiles() {
98
        persitenceMan = ToolsLocator.getPersistenceManager();
99
    }
100

    
101
    /** {@inheridDoc} */
102
    public String getStepDescriptionKey() {
103
        return "coping_all_layers_files";
104
    }
105

    
106
    /** {@inheridDoc} */
107
    public String getStepDescription() {
108
        return "Coping all layers files";
109
    }
110

    
111
    @SuppressWarnings("unchecked")
112
    public void doProcess(ProcessData data, int stepPercent)
113
        throws CompilationException {
114
        LayerNamer namer = new LayerNamer();
115
        File mapContextFolder = new File(data.workFolder, "mapContext");
116
        mapContextFolder.mkdirs();
117
        File rootLayersFolder =
118
            new File(mapContextFolder, ROOT_LAYER_FOLDER_NAME);
119
        rootLayersFolder.mkdirs();
120
        data.mapContextFolder = mapContextFolder;
121
        data.rootLayersFolder = rootLayersFolder;
122

    
123
        data.values.put(MAP_CONTEXT_FOLDER_PATH_KEY,
124
            mapContextFolder.getAbsolutePath());
125
        data.values.put(ROOT_LAYERS_FOLDER_PATH_KEY,
126
            rootLayersFolder.getAbsolutePath());
127
        saveLayers(data, data.mapContext.getLayers(), mapContextFolder, namer);
128
    }
129

    
130
    /**
131
     * <p>
132
     * Copy all files related to a layer group into work folder
133
     * </p>
134
     * <p>
135
     * This creates a new folder (using layer's name) inside
136
     * <code>parentFolde</code> and iterates over children layers.
137
     * </p>
138
     * 
139
     * @param data
140
     *            Process data
141
     * @param layers
142
     *            layers to save
143
     * @param parentFolder
144
     *            parent folder to store al data
145
     * @param namer
146
     *            a layer-namer instance
147
     * @return
148
     * @throws CompilationException
149
     */
150
    private boolean saveLayers(ProcessData data, FLayers layers,
151
        File parentFolder, LayerNamer namer) throws CompilationException {
152
        // Get new folder for layer
153
        File myFolder = getLayerFolder(parentFolder, layers, namer);
154

    
155
        // Useful to show a layer identification
156
        String relativePath = getRelativePath(data, myFolder);
157

    
158
        // As this process could take long time, notify progress to listener.
159
        notifyStatus(data, relativePath);
160

    
161
        // Iterates children layers
162
        FLayer theLayer;
163
        for (int i = 0; i < layers.getLayersCount(); i++) {
164
            theLayer = layers.getLayer(i);
165
            if (theLayer instanceof SingleLayer) {
166
                // Layer
167
                saveLayer(data, (SingleLayer) theLayer, myFolder, namer);
168
            } else {
169
                // Group of layers
170
                saveLayers(data, (FLayers) theLayer, myFolder, namer);
171
            }
172
        }
173
        return true;
174
    }
175

    
176
    /**
177
     * Updates process status and notify it to process listener. Utility method.
178
     * 
179
     * @param data
180
     * @param relativePath
181
     */
182
    private void notifyStatus(ProcessData data, String relativePath) {
183
        data.status.setCurrentStepMessage(relativePath);
184
        data.notifyStatus();
185
    }
186

    
187
    /**
188
     * <p>
189
     * Copy all files related to a layer into work folder
190
     * </p>
191
     * <p>
192
     * This creates a new folder (using layer's name) inside
193
     * <code>parentFolde</code> and copies all related files.
194
     * </p>
195
     * 
196
     * @param data
197
     *            Process data
198
     * @param layers
199
     *            layers to save
200
     * @param parentFolder
201
     *            parent folder to store al data
202
     * @param namer
203
     *            a layer-namer instance
204
     * @return
205
     * @throws CompilationException
206
     */
207
    private void saveLayer(ProcessData data, SingleLayer layer,
208
        File parentFolder, LayerNamer namer) throws CompilationException {
209
        // Get new folder for layer
210
        File myFolder = getLayerFolder(parentFolder, layer, namer);
211

    
212
        // Useful to show a layer identification
213
        String relativePath = getRelativePath(data, myFolder);
214

    
215
        // As this process could take long time, notify progress to listener.
216
        notifyStatus(data, relativePath);
217

    
218
        PersistentState layerPerStatus;
219
        List<File> sourceFiles;
220
        try {
221
            // Gets status
222
            layerPerStatus = persitenceMan.getState(layer);
223

    
224
            // Gets related files
225
            sourceFiles = PersistenceUtils.getRelatedFiles(layerPerStatus);
226
        } catch (PersistenceException e) {
227
            throw new CompilationException(
228
                "problem getting info from layer: ".concat(relativePath), e);
229
        }
230

    
231
        File target;
232
        String targetRelativePath;
233
        // for every single layer
234
        for (File source : sourceFiles) {
235
            // get a new filename to copy file
236
            target = FileUtils.getNewFileName(myFolder, source.getName());
237
            // get relative file path to inform to the listener
238
            targetRelativePath = getRelativePath(data, target);
239
            notifyStatus(data, targetRelativePath);
240
            try {
241
                // Copy the file
242
                FileUtils.copyFile(source, target);
243
            } catch (IOException e) {
244
                throw new CompilationException(
245
                    MessageFormat.format(
246
                        "problem copying file related to  layer '{0}': '{1}' --> '{2}'",
247
                        relativePath, source.getAbsolutePath(),
248
                        target.getAbsolutePath()), e);
249
            }
250
            // Adds a new entry on finals file mapping
251
            data.fileMapping.put(source, target);
252
        }
253
    }
254

    
255
    /**
256
     * Gets file path relative to layer folder
257
     * 
258
     * @param data
259
     * @param file
260
     * @return
261
     */
262
    private String getRelativePath(ProcessData data, File file) {
263
        String rootLayerPath =
264
            (String) data.values.get(ROOT_LAYERS_FOLDER_PATH_KEY);
265
        String path = file.getAbsolutePath();
266
        if (FilenameUtils.equals(rootLayerPath, path)) {
267
            return "{Root Layer}";
268
        }
269
        return FilenameUtils.getRelativeTo(path, rootLayerPath);
270
    }
271

    
272
    /**
273
     * <p>
274
     * Generate a layer folder based on its name
275
     * </p>
276
     * <p>
277
     * Avoid problems of duplicate layer name
278
     * </p>
279
     * 
280
     * @param parentFolder
281
     * @param flayer
282
     * @param namer
283
     * @return
284
     */
285
    private File getLayerFolder(File parentFolder, FLayer flayer,
286
        LayerNamer namer) {
287
        // Uses FileUtils.getNewWritableFolder to avoid
288
        // duplicate names problem
289
        return FileUtils.getNewWritableFolder(parentFolder,
290
            namer.getLayerName(flayer));
291

    
292
    }
293

    
294
    /**
295
     * Utility class to get a layer name for those layers which hasn't
296
     * 
297
     * @author gvSIG Team
298
     * @version $Id$
299
     * 
300
     */
301
    private class LayerNamer {
302

    
303
        int count = 0;
304

    
305
        public String getLayerName(FLayer flayer) {
306
            if (flayer.getParentLayer() == null) {
307
                // root layer
308
                return ROOT_LAYER_FOLDER_NAME;
309
            }
310
            String name = flayer.getName();
311
            if (!StringUtils.isBlank(name)) {
312
                // has name
313
                return name;
314
            }
315
            count++;
316
            return "No_Name_Layer.".concat(StringUtils.right(
317
                "00".concat(String.valueOf(count)), 3));
318
        }
319
    }
320
}