This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 208779
Collapse All | Expand All

(-)a/openide.loaders/src/org/openide/loaders/DataShadow.java (+52 lines)
Lines 393-401 Link Here
393
    /**
393
    /**
394
     * Tries to load the original file from a shadow.
394
     * Tries to load the original file from a shadow.
395
     * Looks for file contents as well as the originalFile/originalFileSystem attributes.
395
     * Looks for file contents as well as the originalFile/originalFileSystem attributes.
396
     * Attempts to discover locations for migrated files in configuration.
397
     * 
396
     * @param fileObject a data shadow
398
     * @param fileObject a data shadow
397
     * @return the original <code>DataObject</code> referenced by the shadow
399
     * @return the original <code>DataObject</code> referenced by the shadow
398
     * @throws IOException error during load or broken link
400
     * @throws IOException error during load or broken link
401
     * 
402
     * @see Utilities#translate
399
     */
403
     */
400
    protected static DataObject deserialize(FileObject fileObject) throws IOException {
404
    protected static DataObject deserialize(FileObject fileObject) throws IOException {
401
        String[] fileAndFileSystem = readOriginalFileAndFileSystem(fileObject);
405
        String[] fileAndFileSystem = readOriginalFileAndFileSystem(fileObject);
Lines 411-428 Link Here
411
        String fsname = fileAndFileSystem[1];
415
        String fsname = fileAndFileSystem[1];
412
        if (u != null && u.isAbsolute()) {
416
        if (u != null && u.isAbsolute()) {
413
            target = URLMapper.findFileObject(u.toURL());
417
            target = URLMapper.findFileObject(u.toURL());
418
            if (target == null) {
419
                FileObject cfgRoot = FileUtil.getConfigRoot();
420
                URI cfgURI = cfgRoot.toURI();
421
                String prefix = cfgURI.toString();
422
                String urlText = u.toString();
423
                // try to recover a broken shadow by translation, but only for 
424
                // configuration
425
                if (urlText.startsWith(prefix)) {
426
                    String rootPathFragment = cfgURI.getRawPath();
427
                    // get the file part with all the URL escaping, escapes e.g. # and = characters.
428
                    String cfgPart = u.getRawPath().substring(rootPathFragment.length());
429
                    String translated = Utilities.translate(cfgPart);
430
                    if (!translated.equals(cfgPart)) {
431
                        String translatedPath = rootPathFragment + translated;
432
                        URI newURI;
433
                        try {
434
                            // have URI parse the text, we'll extract the path component
435
                            URI temp = URI.create("scheme://host" + translatedPath); // NOI18N
436
                            newURI = new URI(u.getScheme(), u.getAuthority(), temp.getPath(), u.getFragment());
437
                            target = URLMapper.findFileObject(newURI.toURL());
438
                        } catch (URISyntaxException ex) {
439
                            LOG.log(Level.WARNING, "Could not form URI from {0}: {1}", new Object[] { translatedPath, ex });
440
                        }
441
                    }
442
                }
443
            }
414
        } else {
444
        } else {
415
            FileSystem fs;
445
            FileSystem fs;
446
            boolean sfs;
416
            if (SFS_NAME.equals(fsname)) {
447
            if (SFS_NAME.equals(fsname)) {
417
                fs = FileUtil.getConfigRoot().getFileSystem();
448
                fs = FileUtil.getConfigRoot().getFileSystem();
449
                sfs = true;
418
            } else {
450
            } else {
419
                // Even if it is specified, we no longer have mounts, so we can no longer find it.
451
                // Even if it is specified, we no longer have mounts, so we can no longer find it.
420
                fs = fileObject.getFileSystem();
452
                fs = fileObject.getFileSystem();
453
                sfs = false;
421
            }
454
            }
422
            target = fs.findResource(path);
455
            target = fs.findResource(path);
423
            if (target == null && fsname == null) {
456
            if (target == null && fsname == null) {
457
                sfs = true;
424
                target = FileUtil.getConfigFile(path);
458
                target = FileUtil.getConfigFile(path);
425
            }
459
            }
460
            
461
            // defect #208779 - if target is not found on SFS, try to translate the path:
462
            if (sfs && target == null) {
463
                // encode the path:
464
                URI cfgRootURI = FileUtil.getConfigRoot().toURI();
465
                try {
466
                    URI uri = new URI(null, null, "/" + path, null, null); // NOI18N
467
                    String rawPath = uri.toASCIIString().substring(1);
468
                    String translated = Utilities.translate(rawPath);
469
                    if (!rawPath.equals(translated)) {
470
                        // decode translated path back:
471
                        URI translatedUri = cfgRootURI.relativize(cfgRootURI.resolve(translated));
472
                        target = FileUtil.getConfigFile(translatedUri.getPath());
473
                    }
474
                } catch (URISyntaxException ex) {
475
                    LOG.log(Level.WARNING, "Could not form URI from {0}: {1}", new Object[] { path, ex });
476
                }
477
            }
426
        }
478
        }
427
        if (target != null) {
479
        if (target != null) {
428
            return DataObject.find(target);
480
            return DataObject.find(target);
(-)a/openide.loaders/test/unit/src/META-INF/netbeans/translate.names (+3 lines)
Line 0 Link Here
1
origFolder/regularFileName.txt.old=origFolder/regularFileName.txt
2
%C5%BDlu%C5%A5ou%C4%8Dk%C3%BD%20p%C5%99em%C3%ADst%C4%9Bn%C3%BD%20soubor%23333:ee.e=origFolder2/%C4%8Cesk%C3%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%A1%20akce%20%23234:bubu.txt
3
%C5%BDlu%C5%A5ou%C4%8Dk%C3%BD%20p%C5%99em%C3%ADst%C4%9Bn%C3%BD%20soubor%23333:ee.e3=origFolder3/%C4%8Cesk%C3%A1%20%C5%BElu%C5%A5ou%C4%8Dk%C3%A1%20akce%20%23234:bubu.txt
(-)a/openide.loaders/test/unit/src/org/netbeans/modules/openide/loaders/DataShadowTranslateTest.java (+238 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2012 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2012 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.openide.loaders;
43
44
import java.io.*;
45
import java.net.URI;
46
import java.net.URL;
47
import java.net.URLClassLoader;
48
import org.netbeans.junit.NbTestCase;
49
import org.openide.filesystems.FileObject;
50
import org.openide.filesystems.FileSystem.AtomicAction;
51
import org.openide.filesystems.FileUtil;
52
import org.openide.loaders.DataObject;
53
import org.openide.loaders.DataShadow;
54
import org.openide.util.Lookup;
55
import org.openide.util.test.MockLookup;
56
import org.openide.util.test.TestFileUtils;
57
58
/**
59
 * See defect #208779 - DataShadows should update themselves iff they could not find 
60
 * the target.
61
 * 
62
 * @author sdedic
63
 */
64
public class DataShadowTranslateTest extends NbTestCase {
65
66
    public DataShadowTranslateTest(String name) {
67
        super(name);
68
    }
69
    
70
    /**
71
     * Checks that file with just regular characters in name is translated OK
72
     * @throws Exception 
73
     */
74
    public void testRegularURI() throws Exception {
75
        
76
        FileObject fo = FileUtil.getConfigRoot();
77
        
78
        FileObject origDir = fo.createFolder("origFolder");
79
        FileObject newFile = origDir.createData("regularFileName.txt");
80
        
81
        final FileObject d = fo.createFolder("subfolder");
82
        OutputStream ostm = d.createAndOpen("regularShadowURI.shadow");
83
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(ostm));
84
        
85
        URI uri = newFile.toURI();
86
        String urlString = newFile.toURI().toASCIIString();
87
        bw.write(urlString + ".old");
88
        bw.newLine();
89
        bw.newLine();
90
        bw.close();
91
        
92
        FileObject fob = d.getFileObject("regularShadowURI.shadow");
93
        DataObject dd = DataObject.find(fob);
94
        
95
        assertTrue("Shadow must be translated, not broken", dd instanceof DataShadow);
96
        
97
        DataShadow ds = (DataShadow)dd;
98
        assertEquals("Shadow's original must be on the translated location", newFile, ds.getOriginal().getPrimaryFile());
99
    }
100
    
101
    /**
102
     * Checks that file with national and special characters in name is processed OK
103
     * 
104
     * @throws Exception 
105
     */
106
    public void testUriWithSpecialChars() throws Exception {
107
        FileObject fo = FileUtil.getConfigRoot();
108
        
109
        FileObject origDir = fo.createFolder("origFolder2");
110
        
111
        // create empty real file with special and non-ASCII chars
112
        FileObject newFile = origDir.createData("Česká žluťoučká akce #234:bubu.txt");
113
        
114
        // createa a fake file, just to get its URI right:
115
        FileObject fake = fo.createData("Žluťoučký přemístěný soubor#333:ee.e");
116
        
117
        String deprecatedURI = fake.toURI().toASCIIString();
118
        
119
        fake.delete();
120
        
121
        final FileObject d = fo.createFolder("subfolder2");
122
        OutputStream ostm = d.createAndOpen("regularShadowURI.shadow");
123
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(ostm));
124
        
125
        URI uri = newFile.toURI();
126
        
127
        bw.write(deprecatedURI);
128
        bw.newLine();
129
        bw.newLine();
130
        bw.close();
131
        
132
        FileObject fob = d.getFileObject("regularShadowURI.shadow");
133
        DataObject dd = DataObject.find(fob);
134
        
135
        assertTrue("Shadow must be translated, not broken", dd instanceof DataShadow);
136
        
137
        DataShadow ds = (DataShadow)dd;
138
        assertEquals("Shadow's original must be on the translated location", newFile, ds.getOriginal().getPrimaryFile());
139
    }
140
    
141
    public void testFSNameAndPath() throws Exception {
142
        FileObject fo = FileUtil.getConfigRoot();
143
        
144
        FileObject origDir = fo.createFolder("origFolder3");
145
        
146
        // create empty real file with special and non-ASCII chars
147
        FileObject newFile = origDir.createData("Česká žluťoučká akce #234:bubu.txt");
148
        
149
        // createa a fake file, just to get its URI right:
150
        FileObject fake = fo.createData("Žluťoučký přemístěný soubor#333:ee.e3");
151
        
152
        final FileObject d = fo.createFolder("subfolder3");
153
        OutputStream ostm = d.createAndOpen("regularShadowURI.shadow");
154
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(ostm));
155
        
156
        bw.write(fake.getPath());
157
        bw.newLine();
158
        bw.write(fake.getFileSystem().getSystemName());
159
        bw.newLine();
160
        
161
        fake.delete();
162
        
163
        bw.close();
164
        
165
        FileObject fob = d.getFileObject("regularShadowURI.shadow");
166
        DataObject dd = DataObject.find(fob);
167
        
168
        assertTrue("Shadow must be translated, not broken", dd instanceof DataShadow);
169
        
170
        DataShadow ds = (DataShadow)dd;
171
        assertEquals("Shadow's original must be on the translated location", newFile, ds.getOriginal().getPrimaryFile());
172
    }
173
    
174
    /**
175
     * Checks that DataShadows to regular (non-SFS) files are not translated
176
     * even if a translation is defined for their path
177
     * 
178
     * @throws Exception 
179
     */
180
    public void testNonSFSUriNotAffected() throws Exception {
181
        File wd = getWorkDir();
182
        
183
        clearWorkDir();
184
        
185
        FileObject origDir = FileUtil.toFileObject(wd);
186
        
187
        FileObject dirWithSpace = origDir.createFolder("Space Dir");
188
        FileObject newFile = dirWithSpace.createData("testFile.txt");
189
        
190
191
        File subDir = new File(wd, "translate");
192
        
193
        subDir.mkdirs();
194
        
195
        File metaTranslate = new File(subDir, "META-INF/netbeans");
196
        metaTranslate.mkdirs();
197
        
198
        String workPath = newFile.toURI().getRawPath();
199
        FileWriter wr = new FileWriter(new File(metaTranslate, "translate.names"));
200
        BufferedWriter bw = new BufferedWriter(wr);
201
        
202
        bw.write(workPath.substring(1) + "/testFile.txt=" + workPath.substring(1) + "/moved/testFile.txt");
203
        bw.close();
204
        
205
        
206
        FileObject fo = FileUtil.toFileObject(wd);
207
        
208
        ClassLoader orig = Lookup.getDefault().lookup(ClassLoader.class);
209
        
210
        ClassLoader my = new URLClassLoader(new URL[] {
211
            subDir.toURL()
212
        }, orig);
213
        
214
        MockLookup.setInstances(my);
215
        
216
        
217
        FileObject cfgRoot = FileUtil.getConfigRoot();
218
        
219
        
220
        OutputStream ostm = cfgRoot.createAndOpen("nonSFSFile.shadow");
221
        
222
        bw = new BufferedWriter(new OutputStreamWriter(ostm));
223
        
224
        bw.write(newFile.toURI().toASCIIString());
225
        bw.newLine();
226
        bw.newLine();
227
        
228
        newFile.delete();
229
        
230
        bw.close();
231
        
232
        FileObject fob = cfgRoot.getFileObject("nonSFSFile.shadow");
233
        DataObject dd = DataObject.find(fob);
234
        
235
        assertFalse("Shadow must be still broken", dd instanceof DataShadow);
236
    }
237
}
238
(-)a/openide.util/src/org/openide/util/Utilities.java (-1 / +10 lines)
Lines 2468-2474 Link Here
2468
    }
2468
    }
2469
2469
2470
    /** Provides support for parts of the system that deal with classnames
2470
    /** Provides support for parts of the system that deal with classnames
2471
     * (use <code>Class.forName</code>, <code>NbObjectInputStream</code>, etc.).
2471
     * (use <code>Class.forName</code>, <code>NbObjectInputStream</code>, etc.) or filenames
2472
     * in layers.
2472
     * <P>
2473
     * <P>
2473
     * Often class names (especially package names) changes during lifecycle
2474
     * Often class names (especially package names) changes during lifecycle
2474
     * of a module. When some piece of the system stores the name of a class
2475
     * of a module. When some piece of the system stores the name of a class
Lines 2513-2518 Link Here
2513
     * className is not listed as one that is to be renamed, the returned
2514
     * className is not listed as one that is to be renamed, the returned
2514
     * string == className, if the className is registered to be renamed
2515
     * string == className, if the className is registered to be renamed
2515
     * than the className != returned value, even in a case when className.equals (retValue)
2516
     * than the className != returned value, even in a case when className.equals (retValue)
2517
     * <p/>
2518
     * Similar behaviour applies to <b>filenames</b> provided by layers (system filesystem). Filenames
2519
     * can be also translated to adapt to location changes e.g. in action registrations.
2520
     *
2521
     * <pre>
2522
     * # registration ID has changed
2523
     * Actions/Refactoring/RefactoringWhereUsed.instance=Actions/Refactoring/org-netbeans-modules-refactoring-api-ui-WhereUsedAction.instance
2524
     * </pre>
2516
     *
2525
     *
2517
     * @param className fully qualified name of a class to translate
2526
     * @param className fully qualified name of a class to translate
2518
     * @return new name of the class according to renaming rules.
2527
     * @return new name of the class according to renaming rules.

Return to bug 208779