diff -r dc5d5539dbfc core.startup/nbproject/project.xml --- a/core.startup/nbproject/project.xml Thu Feb 23 13:23:26 2012 +0100 +++ b/core.startup/nbproject/project.xml Thu Feb 23 15:50:29 2012 +0100 @@ -55,7 +55,7 @@ 1 - 2.49 + 2.50 diff -r dc5d5539dbfc core.startup/src/org/netbeans/core/startup/NbInstaller.java --- a/core.startup/src/org/netbeans/core/startup/NbInstaller.java Thu Feb 23 13:23:26 2012 +0100 +++ b/core.startup/src/org/netbeans/core/startup/NbInstaller.java Thu Feb 23 15:50:29 2012 +0100 @@ -1199,8 +1199,7 @@ } for (Map.Entry entry : m.entrySet()) { File jar = entry.getKey(); - os.write(jar.getAbsolutePath().getBytes("UTF-8")); // NOI18N - os.write(0); + Stamps.writeRelativePath(jar.getAbsolutePath(), os); long time = entry.getValue().date; for (int i = 7; i >= 0; i--) { os.write((int) ((time >> (i * 8)) & 0xFF)); @@ -1264,9 +1263,9 @@ if (pos == data.limit()) { return; } - int end = findNullByte(data, pos); - if (end == -1) throw new IOException("Could not find next manifest JAR name from " + pos); // NOI18N - File jar = new File(new String(toArray(data, pos, end - pos), "UTF-8")); // NOI18N + data.position(pos); + File jar = new File(Stamps.readRelativePath(data)); // NOI18N + int end = data.position(); long time = 0L; if (end + 8 >= data.limit()) throw new IOException("Ran out of space for timestamp for " + jar); // NOI18N for (int i = 0; i < 8; i++) { diff -r dc5d5539dbfc core.startup/src/org/netbeans/core/startup/layers/BinaryCacheManager.java --- a/core.startup/src/org/netbeans/core/startup/layers/BinaryCacheManager.java Thu Feb 23 13:23:26 2012 +0100 +++ b/core.startup/src/org/netbeans/core/startup/layers/BinaryCacheManager.java Thu Feb 23 15:50:29 2012 +0100 @@ -62,6 +62,7 @@ import java.util.Map.Entry; import java.util.Set; import java.util.logging.Level; +import org.netbeans.Stamps; import org.openide.filesystems.FileSystem; import org.openide.filesystems.FileUtil; @@ -206,7 +207,7 @@ // int contentLength | -1, byte[contentLength] content | String URL if (file.ref != null) { bw.writeInt(-1); // uri - bw.writeString(file.ref.toString()); + bw.writeString(toRelativeURL(file.ref)); } else if (file.contents != null) { bw.writeInt(file.contents.length); bw.writeBytes(file.contents); @@ -237,7 +238,11 @@ for (int i = 0; i < ATTR_TYPES.length; i++) { if(ATTR_TYPES[i].equals(attr.type)) { bw.writeByte((byte)i); - bw.writeString(attr.data); + if (i == 9) { + bw.writeString(toRelativeURL(attr.data)); + } else { + bw.writeString(attr.data); + } return; } } @@ -265,7 +270,7 @@ MemFile file = (MemFile)mf; size += 4; // int contentLength if (file.ref != null) { - size += computeSize(file.ref.toString(), text); // String uri + size += computeSize(toRelativeURL(file.ref), text); // String uri } else if (file.contents != null) { size += file.contents.length; } // else size += 0; // no content, no uri @@ -301,6 +306,9 @@ } private int computeSize(MemAttr attr, Map text) { //String name, byte type, String value + if (attr.data.startsWith("jar:file:")) { + attr.data = ""; + } return computeSize(attr.name, text) + 1 + computeSize(attr.data, text); } @@ -308,7 +316,7 @@ private OutputStream os; private int position; /** map from base URL to int[1] value */ - private final Map urls; + private final Map urls; private final Map strings; BinaryWriter(OutputStream os, MemFolder root, int fsSize, Map strings) throws IOException { this.os = os; @@ -317,7 +325,7 @@ urls = writeBaseUrls (root, fsSize, strings, map); position = 0; } - + int getPosition() { return position; } @@ -351,7 +359,8 @@ writeBaseURL(url, false); } void writeBaseURL (java.net.URL url, boolean negative) throws IOException { - int[] number = (int[])urls.get (url); + String relUrl = toRelativeURL(url); + int[] number = (int[])urls.get (relUrl); assert number != null : "Should not be null, because it was collected: " + url + " map: " + urls; int index = number[0]; if (negative) { @@ -360,23 +369,23 @@ writeInt (index); } - private java.util.Map writeBaseUrls( + private Map writeBaseUrls( MemFileOrFolder root, int fsSize, Map texts, Map fillIn ) throws IOException { - java.util.LinkedHashMap map = new java.util.LinkedHashMap (); + java.util.LinkedHashMap map = new java.util.LinkedHashMap (); int[] counter = new int[1]; collectBaseUrls (root, map, counter); int size = 0; - java.util.Iterator it = map.entrySet ().iterator (); + Iterator> it = map.entrySet ().iterator (); for (int i = 0; i < counter[0]; i++) { - java.util.Map.Entry entry = (java.util.Map.Entry)it.next (); - java.net.URL u = (java.net.URL)entry.getKey (); + Entry entry = it.next (); + String u = entry.getKey (); assert ((int[])entry.getValue ())[0] == i : i + "th key should be it " + ((int[])entry.getValue ())[0]; - size += computeSize (u.toExternalForm (), texts); + size += computeSize (u, texts); } ByteArrayOutputStream arr = new ByteArrayOutputStream(); @@ -397,23 +406,21 @@ it = map.entrySet ().iterator (); for (int i = 0; i < counter[0]; i++) { - java.util.Map.Entry entry = (java.util.Map.Entry)it.next (); - java.net.URL u = (java.net.URL)entry.getKey (); - - writeString (u.toExternalForm ()); + Entry entry = it.next (); + writeString (entry.getKey()); } return map; } - private void collectBaseUrls (MemFileOrFolder f, java.util.Map map, int[] counter) { + private void collectBaseUrls (MemFileOrFolder f, Map map, int[] counter) { for (URL u : f.getURLs()) { - int[] exists = (int[])map.get (u); + String tmp = toRelativeURL(u); + int[] exists = (int[])map.get(tmp); if (exists == null) { - map.put (u, counter.clone ()); + map.put (tmp, counter.clone ()); counter[0]++; } } - if (f instanceof MemFolder && ((MemFolder)f).children != null) { Iterator it = ((MemFolder)f).children.iterator (); while (it.hasNext ()) { @@ -439,4 +446,15 @@ } } + + private static String toRelativeURL(URL u) { + return toRelativeURL(u.toExternalForm()); + } + private static String toRelativeURL(String tmp) { + if (tmp.startsWith("jar:file:")) { + String path = tmp.substring(9); + tmp = Stamps.findRelativePath(path); + } + return tmp; + } } diff -r dc5d5539dbfc core.startup/src/org/netbeans/core/startup/layers/BinaryFS.java --- a/core.startup/src/org/netbeans/core/startup/layers/BinaryFS.java Thu Feb 23 13:23:26 2012 +0100 +++ b/core.startup/src/org/netbeans/core/startup/layers/BinaryFS.java Thu Feb 23 15:50:29 2012 +0100 @@ -166,7 +166,7 @@ urls = new ArrayList(); List _modifications = new ArrayList(); while (buff.position() < stop) { - urls.add(getString(buff)); + urls.add(toAbsoluteURL(getString(buff))); _modifications.add(null); } modifications = Collections.synchronizedList(_modifications); @@ -262,6 +262,21 @@ return s; } } + private static String toAbsoluteURL(String relURL) { + if (relURL.startsWith("home@")) { + return "jar:file:" + System.getProperty("netbeans.home") + relURL.substring(5); + } + if (relURL.startsWith("user@")) { + return "jar:file:" + System.getProperty("netbeans.user") + relURL.substring(5); + } + int indx = relURL.indexOf('@'); + if (indx == -1) { + assert relURL.indexOf("jar:file:") == -1; + return relURL; + } + int cluster = Integer.parseInt(relURL.substring(0, indx)); + return "jar:file:" + Stamps.cluster(cluster) + relURL.substring(indx + 1); + } @Override public void readFully(byte[] b, int off, int len) throws IOException { @@ -861,7 +876,7 @@ new URL(uri).openConnection().getInputStream() : // len from URI new ByteArrayInputStream(data()); } catch (Exception e) { - throw (FileNotFoundException) new FileNotFoundException(e.toString()).initCause(e); + throw (FileNotFoundException) new FileNotFoundException("Cannot find '" + uri + "'").initCause(e); } } @@ -942,7 +957,7 @@ len = sub.getInt(); contentOffset = sub.position(); if (len == -1) { - uri = getString(sub); + uri = toAbsoluteURL(getString(sub)); } else { sub.position(contentOffset+len); } diff -r dc5d5539dbfc core.startup/test/unit/src/org/netbeans/core/startup/layers/CachingPreventsFileTouchesTest.java --- a/core.startup/test/unit/src/org/netbeans/core/startup/layers/CachingPreventsFileTouchesTest.java Thu Feb 23 13:23:26 2012 +0100 +++ b/core.startup/test/unit/src/org/netbeans/core/startup/layers/CachingPreventsFileTouchesTest.java Thu Feb 23 15:50:29 2012 +0100 @@ -44,7 +44,11 @@ package org.netbeans.core.startup.layers; +import java.beans.PropertyVetoException; +import java.io.File; import java.io.IOException; +import java.util.Arrays; +import java.util.Collections; import java.util.HashSet; import java.util.Set; import java.util.logging.Level; @@ -55,6 +59,9 @@ import org.netbeans.junit.NbTestSuite; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; +import org.openide.filesystems.LocalFileSystem; +import org.openide.modules.InstalledFileLocator; +import org.openide.modules.Places; import org.openide.util.Lookup; /** @@ -94,10 +101,12 @@ CachingPreventsFileTouchesTest.class ).reuseUserDir(true).enableModules("platform\\d*", ".*").enableClasspathModules(false) .honorAutoloadEager(true); - conf = conf.addTest("testReadAccess").gui(false); + conf = conf.addTest("testReadAccess", "testRememberCacheDir").gui(false); suite.addTest(conf.suite()); } - + + suite.addTest(new CachingPreventsFileTouchesTest("testCachesDontUseAbsolutePaths")); + return suite; } @@ -110,8 +119,6 @@ } FileObject fo = FileUtil.getConfigFile("Services/Browsers"); fo.delete(); - // will be reset next time the system starts - System.getProperties().remove("netbeans.dirs"); // initializes counting, but waits till netbeans.dirs are provided // by NbModuleSuite initCheckReadAccess(); @@ -139,5 +146,46 @@ throw e; } } + + public void testRememberCacheDir() { + File cacheDir = Places.getCacheDirectory(); + assertTrue("It is a directory", cacheDir.isDirectory()); + System.setProperty("mycache", cacheDir.getPath()); + + File boot = InstalledFileLocator.getDefault().locate("lib/boot.jar", "org.netbeans.bootstrap", false); + assertNotNull("Boot.jar found", boot); + System.setProperty("myinstall", boot.getParentFile().getParentFile().getParentFile().getPath()); + } + public void testCachesDontUseAbsolutePaths() throws Exception { + String cache = System.getProperty("mycache"); + String install = System.getProperty("myinstall"); + + assertNotNull("Cache found", cache); + assertNotNull("Install found", install); + + File cacheDir = new File(cache); + assertTrue("Cache dir is dir", cacheDir.isDirectory()); + int cnt = 0; + final File[] arr = cacheDir.listFiles(); + Collections.shuffle(Arrays.asList(arr)); + for (File f : arr) { + if (!f.isDirectory()) { + cnt++; + assertFileDoesNotContain(f, install); + } + } + assertTrue("Some cache files found", cnt > 4); + } + + private static void assertFileDoesNotContain(File file, String text) throws IOException, PropertyVetoException { + LocalFileSystem lfs = new LocalFileSystem(); + lfs.setRootDirectory(file.getParentFile()); + FileObject fo = lfs.findResource(file.getName()); + assertNotNull("file object for " + file + " found", fo); + String content = fo.asText(); + if (content.contains(text)) { + fail("File " + file + " seems to contain '" + text + "'!"); + } + } } diff -r dc5d5539dbfc o.n.bootstrap/src/org/netbeans/JarClassLoader.java --- a/o.n.bootstrap/src/org/netbeans/JarClassLoader.java Thu Feb 23 13:23:26 2012 +0100 +++ b/o.n.bootstrap/src/org/netbeans/JarClassLoader.java Thu Feb 23 15:50:29 2012 +0100 @@ -90,6 +90,7 @@ import java.util.logging.Logger; import java.util.zip.ZipEntry; import java.util.zip.ZipException; +import org.openide.util.Exceptions; /** * A ProxyClassLoader capable of loading classes from a set of jar files @@ -786,7 +787,12 @@ @Override public String getIdentifier() { - return getURL().toExternalForm(); + String tmp = getURL().toExternalForm(); + if (tmp.startsWith("jar:file:") && tmp.endsWith("!/")) { + String path = tmp.substring(9); + return Stamps.findRelativePath(path); + } + return tmp; } } diff -r dc5d5539dbfc o.n.bootstrap/src/org/netbeans/LocaleVariants.java --- a/o.n.bootstrap/src/org/netbeans/LocaleVariants.java Thu Feb 23 13:23:26 2012 +0100 +++ b/o.n.bootstrap/src/org/netbeans/LocaleVariants.java Thu Feb 23 15:50:29 2012 +0100 @@ -72,7 +72,7 @@ String locale = is.readUTF(); mapLocale = Locale.getDefault().toString().equals(locale) ? Locale.getDefault() : null; for (;;) { - String file = is.readUTF(); + String file = Stamps.readRelativePath(is); if (file.length() == 0) { break; } @@ -100,13 +100,13 @@ synchronized (map) { os.writeUTF(mapLocale.toString()); for (Map.Entry> entry : map.entrySet()) { - os.writeUTF(entry.getKey().getPath()); + Stamps.writeRelativePath(entry.getKey().getPath(), os); for (FileWithSuffix fws : entry.getValue()) { fws.write(os); } - os.writeUTF(""); + Stamps.writeRelativePath("", os); } - os.writeUTF(""); + Stamps.writeRelativePath("", os); } } @@ -131,6 +131,7 @@ return l; } + static final class FileWithSuffix { public final File file; public final String suffix; @@ -140,7 +141,7 @@ } static FileWithSuffix read(DataInputStream is) throws IOException { - String path = is.readUTF(); + String path = Stamps.readRelativePath(is); if (path.length() == 0) { return null; } @@ -149,7 +150,7 @@ } void write(DataOutputStream os) throws IOException { - os.writeUTF(file.getPath()); + Stamps.writeRelativePath(file.getPath(), os); os.writeUTF(suffix); } } diff -r dc5d5539dbfc o.n.bootstrap/src/org/netbeans/Stamps.java --- a/o.n.bootstrap/src/org/netbeans/Stamps.java Thu Feb 23 13:23:26 2012 +0100 +++ b/o.n.bootstrap/src/org/netbeans/Stamps.java Thu Feb 23 15:50:29 2012 +0100 @@ -42,28 +42,12 @@ package org.netbeans; -import java.io.BufferedOutputStream; -import java.io.ByteArrayInputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; +import java.io.*; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.nio.MappedByteBuffer; import java.nio.channels.FileChannel; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.Locale; -import java.util.Random; -import java.util.Set; -import java.util.StringTokenizer; +import java.util.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicLong; import java.util.concurrent.atomic.AtomicReference; @@ -84,6 +68,7 @@ private static final Logger LOG = Logger.getLogger(Stamps.class.getName()); private static AtomicLong moduleJARs; private static File moduleNewestFile; + private static String[] dirs; private Worker worker = new Worker(); @@ -97,16 +82,19 @@ static void main(String... args) { if (args.length == 1 && "reset".equals(args[0])) { // NOI18N moduleJARs = null; + dirs = null; stamp(false); return; } if (args.length == 1 && "init".equals(args[0])) { // NOI18N moduleJARs = null; + dirs = null; stamp(true); return; } if (args.length == 1 && "clear".equals(args[0])) { // NOI18N moduleJARs = null; + dirs = null; return; } } @@ -320,6 +308,25 @@ stamp(checkStampFile, result, newestFile); return result; } + + private static synchronized String[] dirs() { + if (dirs == null) { + List tmp = new ArrayList(); + String nbdirs = System.getProperty("netbeans.dirs"); // NOI18N + if (nbdirs != null) { + StringTokenizer tok = new StringTokenizer(nbdirs, File.pathSeparator); + while (tok.hasMoreTokens()) { + tmp.add(tok.nextToken()); + } + } + dirs = tmp.toArray(new String[0]); + } + return dirs; + } + public static String cluster(int cluster) { + return dirs()[cluster]; + } + private static void stamp(boolean checkStampFile, AtomicLong result, AtomicReference newestFile) { StringBuilder sb = new StringBuilder(); @@ -328,24 +335,20 @@ String home = System.getProperty ("netbeans.home"); // NOI18N if (home != null) { long stamp = stampForCluster (new File (home), result, newestFile, processedDirs, checkStampFile, true, null); - sb.append(home).append('=').append(stamp).append('\n'); + sb.append("home=").append(stamp).append('\n'); } - String nbdirs = System.getProperty("netbeans.dirs"); // NOI18N - if (nbdirs != null) { - StringTokenizer tok = new StringTokenizer(nbdirs, File.pathSeparator); - while (tok.hasMoreTokens()) { - String t = tok.nextToken(); - long stamp = stampForCluster(new File(t), result, newestFile, processedDirs, checkStampFile, true, null); - if (stamp != -1) { - sb.append(t).append('=').append(stamp).append('\n'); - } + for (String t : dirs()) { + final File clusterDir = new File(t); + long stamp = stampForCluster(clusterDir, result, newestFile, processedDirs, checkStampFile, true, null); + if (stamp != -1) { + sb.append(clusterDir.getName()).append('=').append(stamp).append('\n'); } } File user = Places.getUserDirectory(); if (user != null) { AtomicInteger crc = new AtomicInteger(); stampForCluster(user, result, newestFile, new HashSet(), false, false, crc); - sb.append(user).append('=').append(result.longValue()).append('\n'); + sb.append("user=").append(result.longValue()).append('\n'); sb.append("crc=").append(crc.intValue()).append('\n'); sb.append("locale=").append(Locale.getDefault()).append('\n'); sb.append("branding=").append(NbBundle.getBranding()).append('\n'); @@ -789,4 +792,170 @@ static String clusterLocalStamp(File cluster) { return cluster.getName().replaceAll("\\.\\.", "__"); } + + /** Utility method to read a relative path written down by {@link #writeRelativePath(java.io.File, java.io.DataOutputStream)} + * method from a stream. + * @param dis the stream to read from + * @return the read path + * @since 2.51 + */ + public static String readRelativePath(final ByteBuffer bb) throws IOException { + class IS extends InputStream { + @Override + public int read() throws IOException { + return bb.position() < bb.limit() ? bb.get() : -1; + } + } + final DataInputStream dis = new DataInputStream(new IS()); + return readRelativePath(dis); + } + + /** Utility method to read a relative path written down by {@link #writeRelativePath(java.io.File, java.io.DataOutputStream)} + * method from a stream. + * @param dis the stream to read from + * @return the read path + * @since 2.51 + */ + public static String readRelativePath(DataInputStream dis) throws IOException { + String index = dis.readUTF(); + if (index.isEmpty()) { + return index; + } + String relative = dis.readUTF(); + if ("user".equals(index)) { // NOI18N + return System.getProperty("netbeans.user").concat(relative); // NOI18N + } + if ("home".equals(index)) { // NOI18N + return System.getProperty("netbeans.home").concat(relative); // NOI18N + } + int indx = Integer.parseInt(index); + return dirs()[indx].concat(relative); // NOI18N + } + + /** Utility method to store a file path inside the installation directory + * as a relative (to user directory or clusters). + * @param path the file path inside the installation or "" + * @param dos the stream to write the path to + * @since 2.51 + */ + public static void writeRelativePath(String path, DataOutput dos) throws IOException { + if (path.isEmpty()) { + dos.writeUTF(path); + return; + } + if (testWritePath(path, System.getProperty("netbeans.user"), "user", dos)) { + return; + } + int cnt = 0; + for (String p : dirs()) { + if (testWritePath(path, p, "" + cnt, dos)) { + return; + } + cnt++; + } + if (testWritePath(path, System.getProperty("netbeans.home"), "home", dos)) { + return; + } + throw new IOException("Can't find relative path for '" + path + "'"); + } + public static String findRelativePath(String file) { + class Capture implements DataOutput { + final StringBuilder sb = new StringBuilder(); + + @Override + public void write(int b) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void write(byte[] b) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void write(byte[] b, int off, int len) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeBoolean(boolean v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeByte(int v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeShort(int v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeChar(int v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeInt(int v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeLong(long v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeFloat(float v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeDouble(double v) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeBytes(String s) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeChars(String s) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public void writeUTF(String s) throws IOException { + if (sb.length() == 0) { + sb.append(s).append('@'); + } else { + sb.append(s); + } + } + } + Capture c = new Capture(); + try { + writeRelativePath(file, c); + } catch (IOException ex) { + // no real I/O, means the file can't be converted + return file; + } + return c.sb.toString(); + } + + + private static boolean testWritePath(String path, String prefix, String codeName, DataOutput dos) throws IOException { + if (prefix == null || prefix.isEmpty()) { + return false; + } + if (path.startsWith(prefix)) { + dos.writeUTF(codeName); + dos.writeUTF(path.substring(prefix.length())); + return true; + } + return false; + } } diff -r dc5d5539dbfc o.n.bootstrap/test/unit/src/org/netbeans/StampsRenameTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/o.n.bootstrap/test/unit/src/org/netbeans/StampsRenameTest.java Thu Feb 23 15:50:29 2012 +0100 @@ -0,0 +1,141 @@ +/* + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. + * + * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved. + * + * Oracle and Java are registered trademarks of Oracle and/or its affiliates. + * Other names may be trademarks of their respective owners. + * + * The contents of this file are subject to the terms of either the GNU + * General Public License Version 2 only ("GPL") or the Common + * Development and Distribution License("CDDL") (collectively, the + * "License"). You may not use this file except in compliance with the + * License. You can obtain a copy of the License at + * http://www.netbeans.org/cddl-gplv2.html + * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the + * specific language governing permissions and limitations under the + * License. When distributing the software, include this License Header + * Notice in each file and include the License file at + * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the GPL Version 2 section of the License file that + * accompanied this code. If applicable, add the following below the + * License Header, with the fields enclosed by brackets [] replaced by + * your own identifying information: + * "Portions Copyrighted [year] [name of copyright owner]" + * + * If you wish your version of this file to be governed by only the CDDL + * or only the GPL Version 2, indicate your decision by adding + * "[Contributor] elects to include this software in this distribution + * under the [CDDL or GPL Version 2] license." If you do not indicate a + * single choice of license, a recipient has the option to distribute + * your version of this file under either the CDDL, the GPL Version 2 or + * to extend the choice of license to its licensees as provided above. + * However, if you add GPL Version 2 code and therefore, elected the GPL + * Version 2 license, then the option applies only if the new code is + * made subject to such option by the copyright holder. + * + * Contributor(s): + * + * Portions Copyrighted 2008 Sun Microsystems, Inc. + */ + +package org.netbeans; + +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.util.logging.Level; +import org.netbeans.junit.NbTestCase; + +/** + * + * @author Jaroslav Tulach + */ +public class StampsRenameTest extends NbTestCase implements Stamps.Updater{ + private File install; + private File userdir; + + public StampsRenameTest(String testName) { + super(testName); + } + + @Override + protected Level logLevel() { + return Level.FINE; + } + + public void testTimeStampsWhenSystemTimeDifferentThanFileSystem() throws Exception { + clearWorkDir(); + + install = new File(getWorkDir(), "install"); + userdir = new File(getWorkDir(), "tmp"); + userdir.mkdirs(); + setNetBeansProperties(install, userdir, -1); + + + Thread.sleep(500); + long between = System.currentTimeMillis(); + Thread.sleep(500); + + + Stamps.main("init"); + + Stamps.getModulesJARs().scheduleSave(this, "test-cache", false); + Stamps.getModulesJARs().waitFor(true); + int[] arr = { 0 }; + File f = Stamps.getModulesJARs().file("test-cache", arr); + assertNotNull("Cache found", f); + final long previousLastModified = Stamps.moduleJARs(); + assertEquals("Stamps of caches shall be the same as stamps of .lastModified", + f.lastModified(), previousLastModified + ); + + File i2 = new File(getWorkDir(), "inst2"); + assertTrue("Rename of the dir successful", install.renameTo(i2)); + + setNetBeansProperties(i2, userdir, Stamps.moduleJARs()); + + Thread.sleep(500); + + Stamps.main("clear"); + + //assertEquals("Modified time remains the same", previousLastModified, Stamps.moduleJARs()); + File newF = Stamps.getModulesJARs().file("test-cache", arr); + assertNotNull("Cache can still be found", newF); + } + + private static void setNetBeansProperties(File install, File userdir, long stamp) throws IOException { + File platform = new File(install, "platform"); + final File platformLast = new File(platform, ".lastModified"); + if (stamp == -1) { + platform.mkdirs(); + platformLast.createNewFile(); + } else { + platformLast.setLastModified(stamp); + } + File ide = new File(install, "ide"); + final File ideLast = new File(ide, ".lastModified"); + if (stamp == -1) { + ide.mkdirs(); + ideLast.createNewFile(); + } else { + ideLast.setLastModified(stamp); + } + File extra = new File(install, "extra"); + assertFalse("One cluster does not exists", extra.isDirectory()); + + System.setProperty("netbeans.home", platform.getPath()); + System.setProperty("netbeans.dirs", ide.getPath() + File.pathSeparator + extra.getPath()); + System.setProperty("netbeans.user", userdir.getPath()); + } + + @Override + public void flushCaches(DataOutputStream os) throws IOException { + os.write(1); + } + + @Override + public void cacheReady() { + } +}