Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.plugin / org.gvsig.app / org.gvsig.app.mainplugin / src / main / java / org / gvsig / app / project / documents / actions / CopyPasteDocsUtils.java @ 40984

History | View | Annotate | Download (9.08 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
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 3
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
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.app.project.documents.actions;
25

    
26
import java.io.File;
27
import java.io.FileInputStream;
28
import java.io.FileOutputStream;
29
import java.io.IOException;
30
import java.io.InputStream;
31
import java.io.OutputStream;
32
import java.util.ArrayList;
33
import java.util.HashMap;
34
import java.util.Iterator;
35
import java.util.List;
36
import java.util.Map;
37

    
38
import org.slf4j.Logger;
39
import org.slf4j.LoggerFactory;
40

    
41
import org.gvsig.andami.PluginsLocator;
42
import org.gvsig.app.project.documents.Document;
43
import org.gvsig.tools.ToolsLocator;
44
import org.gvsig.tools.persistence.PersistenceManager;
45
import org.gvsig.tools.persistence.PersistentState;
46
import org.gvsig.tools.persistence.exception.PersistenceException;
47

    
48
/**
49
 * This class provides utility methods to manage the clipboard
50
 * for documents (it's file-based, it's not the system clipboard)
51
 * which will contain one or more documents for copy/cut/paste
52
 * operations. It is currently implemented using persistence
53
 * 
54
 * Each document type uses it's own "clipboard". Some actions
55
 * can affect all those clipboards at the same time
56
 * 
57
 * @author jldominguez
58
 * 
59
 */
60
public class CopyPasteDocsUtils {
61

    
62
    private static Logger logger = LoggerFactory
63
        .getLogger(CopyPasteDocsUtils.class);
64

    
65
    /**
66
     * The folder where docs are temporarily persisted
67
     */
68
    private static File clipboardFolder = null;
69
    private static String CLIPBOARD_FILE_NAME_PREFIX = "gvSIG_docs_clipboard_";
70
    private static String CLIPBOARD_FILE_NAME_EXTENSION = "tmp";
71
    private static int MAX_FILE_COUNT = 1000;
72

    
73
    private CopyPasteDocsUtils() {
74
    }
75
    
76
    private static PersistenceManager getPersMan() {
77
        return ToolsLocator.getPersistenceManager();
78
    }
79
    
80
    private static File getClipboardFolder() {
81
        if (clipboardFolder == null) {
82
            File appf = PluginsLocator.getManager().getApplicationHomeFolder();
83
            clipboardFolder = new File(appf, "clipboard-documents");
84
            clipboardFolder.mkdirs();
85
        }
86
        return clipboardFolder;
87
    }
88
    
89
    /**
90
     * Gets all if parameter is null
91
     * 
92
     */
93
    public static List<File> getClipboardFiles(String typeName) {
94
        
95
        List<File> resp = new ArrayList<File>();
96
        
97
        String filebase = CLIPBOARD_FILE_NAME_PREFIX;
98
        if (typeName != null) {
99
            filebase = filebase + typeName;
100
        }
101
        
102
        File folder = getClipboardFolder();
103
        
104
        if (!folder.exists() || !folder.isDirectory()) {
105
            return resp;
106
        }
107
        
108
        File[] ff = folder.listFiles();
109
        for (int i=0; i<ff.length; i++) {
110
            if (ff[i].getName().startsWith(filebase)) {
111
                resp.add(ff[i]);
112
            }
113
        }
114
        return resp;
115
    }
116
    
117
    
118
    private static File getFirstUnusedClipboardFile(String docTypeName)
119
    throws IOException {
120
        
121
        if (docTypeName == null || docTypeName.length() == 0) {
122
            throw new IOException("Doc type name cannot be empty");
123
        }
124
        
125
        String filename = null;
126
        for (int i=0; i<MAX_FILE_COUNT; i++) {
127
            filename = CLIPBOARD_FILE_NAME_PREFIX + docTypeName + "_" +
128
                Integer.toString(i)
129
                + "." + CLIPBOARD_FILE_NAME_EXTENSION;
130
            File resp = new File(getClipboardFolder(), filename);
131
            if (!resp.exists()) {
132
                /*
133
                 * Removed when JVM terminates
134
                 */
135
                resp.deleteOnExit();
136
                return resp;
137
            }
138
        }
139
        // This should never happen
140
        throw new IOException("Clipboard is full for documents: " + docTypeName);
141
    }
142
    
143
    /**
144
     * Clears clipboard of the provided doc type,
145
     * or clears all document clipboard if parameter is null.
146
     * 
147
     * @param docTypeName
148
     */
149
    public static void clearClipboard(String docTypeName) throws IOException {
150
        
151
        String filebase = CLIPBOARD_FILE_NAME_PREFIX;
152
        if (docTypeName != null) {
153
            filebase = filebase + docTypeName;
154
        }
155
        
156
        File folder = getClipboardFolder();
157
        
158
        if (!folder.exists() || !folder.isDirectory()) {
159
            /*
160
             * Nothing to do
161
             */
162
            return;
163
        }
164
        
165
        File[] ff = folder.listFiles();
166
        Exception exc = null;
167
        for (int i=0; i<ff.length; i++) {
168
            if (ff[i].getName().startsWith(filebase)) {
169
                try {
170
                    ff[i].delete();
171
                } catch (Exception e) {
172
                    // Keep first exception and try to go on
173
                    if (exc == null) {
174
                        exc = e;
175
                    }
176
                }
177
            }
178
        }
179
        // =================================
180
        if (exc != null) {
181
            throw new IOException(exc.getMessage());
182
        }
183
    }
184

    
185

    
186

    
187
    /**
188
     * Returns the content of the clipboard as a list of
189
     * documents or null if clipboard is empty or does not
190
     * contain documents of the specified type
191
     * 
192
     * 
193
     * 
194
     * @return
195
     * @throws PersistenceException
196
     */
197
    public static List<Document> getClipboardDocuments(String typeName)
198
        throws IOException, PersistenceException {
199

    
200
        List<Document> resp = new ArrayList<Document>();
201
        
202
        List<File> ff = getClipboardFiles(typeName);
203
        File infile = null;
204
        InputStream is = null;
205
        Object obj = null;
206
        Document doc = null;
207
        for (int i=0; i<ff.size(); i++) {
208
            infile = ff.get(i);
209
            is = new FileInputStream(infile);
210
            obj = getPersMan().getObject(is);
211
            is.close();
212
            if (obj instanceof Document) {
213
                doc = (Document) obj;
214
                // Checking, but it should not be necessary
215
                if (typeName == null || doc.getTypeName().compareTo(typeName) == 0) {
216
                    resp.add(doc);
217
                }
218
            }
219
        }
220
        return resp;
221
    }
222

    
223
    /**
224
     * Stores doc list to their clipboard
225
     * to clipboard
226
     * 
227
     * @param st
228
     * @throws PersistenceException
229
     */
230
    public static void saveToClipboard(List<Document> docs)
231
        throws IOException, PersistenceException {
232
        
233
        if (docs == null || docs.size() == 0) {
234
            return;
235
        }
236
        
237
        Map<String, List<Document>> separ =
238
            new HashMap<String, List<Document>>();
239
        Document doc = null;
240
        List<Document> list = null;
241
        for (int i=0; i<docs.size(); i++) {
242
            doc = docs.get(i);
243
            if (doc != null && doc.getTypeName() != null) {
244
                list = separ.get(doc.getTypeName());
245
                if (list == null) {
246
                    list = new ArrayList<Document>();
247
                    list.add(doc);
248
                    separ.put(doc.getTypeName(), list);
249
                } else {
250
                    list.add(doc);
251
                }
252
            }
253
        }
254
        
255
        Iterator<String> iter = separ.keySet().iterator();
256
        String k = null;
257
        while (iter.hasNext()) {
258
            k = iter.next();
259
            saveToClipboard(k, separ.get(k));
260
        }
261
    }
262
    
263
    /**
264
     * docs in list are of same type
265
     * @param typeName
266
     * @param docs
267
     */
268
    private static void saveToClipboard(String typeName, List<Document> docs)
269
    throws IOException, PersistenceException {
270
        
271
        clearClipboard(typeName);
272
        File f = null;
273
        OutputStream os = null;
274
        PersistentState state = null;
275
            
276
        for (int i=0; i<docs.size(); i++) {
277
            state = getPersMan().getState(docs.get(i), true);
278
            if (state.getContext().getErrors() != null) {
279
                throw state.getContext().getErrors();
280
            }
281
            f = getFirstUnusedClipboardFile(typeName);
282
            os = new FileOutputStream(f);
283
            getPersMan().saveState(state, os);
284
            os.close();
285
        }
286
    }
287
    
288
    
289

    
290
    public static String getLastMessage(Throwable ex) {
291
        
292
        if (ex == null) {
293
            return "-";
294
        }
295
        
296
        Throwable p = ex;
297
        while (p.getCause() != null && p.getCause() != p) {
298
            p = p.getCause();
299
        }
300
        return p.getMessage();
301
    }
302

    
303

    
304

    
305

    
306

    
307
}