diff --git a/.hgtags b/.hgtags index b6f1545f2b7..2fc464b6481 100644 --- a/.hgtags +++ b/.hgtags @@ -227,3 +227,5 @@ bbe43d712fe08e650808d774861b256ccb34e500 jdk8-b102 30a1d677a20c6a95f98043d8f20ce570304e3818 jdk8-b103 b5ed503c26ad38869c247c5e32debec217fd056b jdk8-b104 589f4fdc584e373a47cde0162e9eceec9165c381 jdk8-b105 +514b0b69fb9683ef52062fd962a3e0644431f64d jdk8-b106 +892889f445755790ae90e61775bfb59ddc6182b5 jdk8-b107 diff --git a/.hgtags-top-repo b/.hgtags-top-repo index 505ac39fd54..d83fa5ca611 100644 --- a/.hgtags-top-repo +++ b/.hgtags-top-repo @@ -227,3 +227,5 @@ d2dcb110e9dbaf9903c05b211df800e78e4b394e jdk8-b100 b7e64be81c8a7690703df5711f4fc2375da8a9cb jdk8-b103 96c1b9b7524b52c3fcefc90ffad4c767396727c8 jdk8-b104 5166118c59178b5d31001bc4058e92486ee07d9b jdk8-b105 +8e7b4d9fb00fdf1334376aeac050c9bca6d1b383 jdk8-b106 +0874bb4707b723d5bb108d379c557cf41529d1a7 jdk8-b107 diff --git a/Makefile b/Makefile index f7b9d1b35e3..2ef4bb99853 100644 --- a/Makefile +++ b/Makefile @@ -404,7 +404,6 @@ COMPILER_PATH.desc = Compiler install directory CACERTS_FILE.desc = Location of certificates file DEVTOOLS_PATH.desc = Directory containing zip and gnumake CUPS_HEADERS_PATH.desc = Include directory location for CUPS header files -DXSDK_PATH.desc = Root directory of DirectX SDK # Make variables to print out (description and value) VARIABLE_PRINTVAL_LIST += \ @@ -429,17 +428,6 @@ VARIABLE_CHECKDIR_LIST += \ VARIABLE_CHECKFIL_LIST += \ CACERTS_FILE -# Some are windows specific -ifeq ($(PLATFORM), windows) - -VARIABLE_PRINTVAL_LIST += \ - DXSDK_PATH - -VARIABLE_CHECKDIR_LIST += \ - DXSDK_PATH - -endif - # For pattern rules below, so all are treated the same DO_PRINTVAL_LIST=$(VARIABLE_PRINTVAL_LIST:%=%.printval) DO_CHECKDIR_LIST=$(VARIABLE_CHECKDIR_LIST:%=%.checkdir) diff --git a/README-builds.html b/README-builds.html index 71c05c0fbf4..14796a27e87 100644 --- a/README-builds.html +++ b/README-builds.html @@ -444,10 +444,6 @@ Install Visual Studio 2010 -
--with-dxsdk=
pathDXSDK_DIR
to it's install location.
- --with-freetype=
pathA top-level Spliterator should not report {@code CONCURRENT} and + *
A top-level Spliterator should not report both {@code CONCURRENT} and
* {@code SIZED}, since the finite size, if known, may change if the source
* is concurrently modified during traversal. Such a Spliterator is
* inconsistent and no guarantees can be made about any computation using
diff --git a/jdk/src/share/classes/java/util/Spliterators.java b/jdk/src/share/classes/java/util/Spliterators.java
index afa2fd379cc..3f97a833a68 100644
--- a/jdk/src/share/classes/java/util/Spliterators.java
+++ b/jdk/src/share/classes/java/util/Spliterators.java
@@ -409,16 +409,16 @@ public final class Spliterators {
*
* @param Instances of {@code ThreadLocalRandom} are not cryptographically
* secure. Consider instead using {@link java.security.SecureRandom}
- * in security-sensitive applications.
+ * in security-sensitive applications. Additionally,
+ * default-constructed instances do not use a cryptographically random
+ * seed unless the {@linkplain System#getProperty system property}
+ * {@code java.util.secureRandomSeed} is set to {@code true}.
*
* @since 1.7
* @author Doug Lea
@@ -129,9 +134,49 @@ public class ThreadLocalRandom extends Random {
/**
* The next seed for default constructors.
*/
- private static final AtomicLong seeder =
- new AtomicLong(mix64(System.currentTimeMillis()) ^
- mix64(System.nanoTime()));
+ private static final AtomicLong seeder = new AtomicLong(initialSeed());
+
+ private static long initialSeed() {
+ String pp = java.security.AccessController.doPrivileged(
+ new sun.security.action.GetPropertyAction(
+ "java.util.secureRandomSeed"));
+ if (pp != null && pp.equalsIgnoreCase("true")) {
+ byte[] seedBytes = java.security.SecureRandom.getSeed(8);
+ long s = (long)(seedBytes[0]) & 0xffL;
+ for (int i = 1; i < 8; ++i)
+ s = (s << 8) | ((long)(seedBytes[i]) & 0xffL);
+ return s;
+ }
+ long h = 0L;
+ try {
+ Enumeration If this pattern does not match any subsequence of the input then
* the resulting stream has just one element, namely the input sequence in
@@ -5781,6 +5782,8 @@ NEXT: while (i <= last) {
private int current;
// null if the next element, if any, needs to obtained
private String nextElement;
+ // > 0 if there are N next empty elements
+ private int emptyElementCount;
MatcherIterator() {
this.matcher = matcher(input);
@@ -5790,26 +5793,46 @@ NEXT: while (i <= last) {
if (!hasNext())
throw new NoSuchElementException();
- String n = nextElement;
- nextElement = null;
- return n;
+ if (emptyElementCount == 0) {
+ String n = nextElement;
+ nextElement = null;
+ return n;
+ } else {
+ emptyElementCount--;
+ return "";
+ }
}
public boolean hasNext() {
- if (nextElement != null)
+ if (nextElement != null || emptyElementCount > 0)
return true;
if (current == input.length())
return false;
- if (matcher.find()) {
+ // Consume the next matching element
+ // Count sequence of matching empty elements
+ while (matcher.find()) {
nextElement = input.subSequence(current, matcher.start()).toString();
current = matcher.end();
- } else {
- nextElement = input.subSequence(current, input.length()).toString();
- current = input.length();
+ if (!nextElement.isEmpty()) {
+ return true;
+ } else {
+ emptyElementCount++;
+ }
+ }
+
+ // Consume last matching element
+ nextElement = input.subSequence(current, input.length()).toString();
+ current = input.length();
+ if (!nextElement.isEmpty()) {
+ return true;
+ } else {
+ // Ignore a terminal sequence of matching empty elements
+ emptyElementCount = 0;
+ nextElement = null;
+ return false;
}
- return true;
}
}
return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
diff --git a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java
index a70fb3a3571..7a3adaa5ad8 100644
--- a/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java
+++ b/jdk/src/share/classes/javax/management/MBeanAttributeInfo.java
@@ -286,10 +286,10 @@ public class MBeanAttributeInfo extends MBeanFeatureInfo implements Cloneable {
if (!(o instanceof MBeanAttributeInfo))
return false;
MBeanAttributeInfo p = (MBeanAttributeInfo) o;
- return (p.getName().equals(getName()) &&
- p.getType().equals(getType()) &&
- p.getDescription().equals(getDescription()) &&
- p.getDescriptor().equals(getDescriptor()) &&
+ return (Objects.equals(p.getName(), getName()) &&
+ Objects.equals(p.getType(), getType()) &&
+ Objects.equals(p.getDescription(), getDescription()) &&
+ Objects.equals(p.getDescriptor(), getDescriptor()) &&
p.isReadable() == isReadable() &&
p.isWritable() == isWritable() &&
p.isIs() == isIs());
diff --git a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java
index ad2176367d2..d02ffce3a8d 100644
--- a/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java
+++ b/jdk/src/share/classes/javax/management/MBeanConstructorInfo.java
@@ -191,10 +191,10 @@ public class MBeanConstructorInfo extends MBeanFeatureInfo implements Cloneable
if (!(o instanceof MBeanConstructorInfo))
return false;
MBeanConstructorInfo p = (MBeanConstructorInfo) o;
- return (p.getName().equals(getName()) &&
- p.getDescription().equals(getDescription()) &&
+ return (Objects.equals(p.getName(), getName()) &&
+ Objects.equals(p.getDescription(), getDescription()) &&
Arrays.equals(p.fastGetSignature(), fastGetSignature()) &&
- p.getDescriptor().equals(getDescriptor()));
+ Objects.equals(p.getDescriptor(), getDescriptor()));
}
/* Unlike attributes and operations, it's quite likely we'll have
diff --git a/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java b/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java
index a2349a8c69f..ec8e8b622b8 100644
--- a/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java
+++ b/jdk/src/share/classes/javax/management/MBeanFeatureInfo.java
@@ -30,6 +30,7 @@ import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.io.StreamCorruptedException;
+import java.util.Objects;
/**
* Provides general information for an MBean descriptor object.
@@ -147,9 +148,9 @@ public class MBeanFeatureInfo implements Serializable, DescriptorRead {
if (!(o instanceof MBeanFeatureInfo))
return false;
MBeanFeatureInfo p = (MBeanFeatureInfo) o;
- return (p.getName().equals(getName()) &&
- p.getDescription().equals(getDescription()) &&
- p.getDescriptor().equals(getDescriptor()));
+ return (Objects.equals(p.getName(), getName()) &&
+ Objects.equals(p.getDescription(), getDescription()) &&
+ Objects.equals(p.getDescriptor(), getDescriptor()));
}
public int hashCode() {
diff --git a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java
index b4bbbe80292..ad1c74f83d5 100644
--- a/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java
+++ b/jdk/src/share/classes/javax/management/MBeanNotificationInfo.java
@@ -26,6 +26,7 @@
package javax.management;
import java.util.Arrays;
+import java.util.Objects;
/**
* The MBeanNotificationInfo
class is used to describe the
@@ -191,9 +192,9 @@ public class MBeanNotificationInfo extends MBeanFeatureInfo implements Cloneable
if (!(o instanceof MBeanNotificationInfo))
return false;
MBeanNotificationInfo p = (MBeanNotificationInfo) o;
- return (p.getName().equals(getName()) &&
- p.getDescription().equals(getDescription()) &&
- p.getDescriptor().equals(getDescriptor()) &&
+ return (Objects.equals(p.getName(), getName()) &&
+ Objects.equals(p.getDescription(), getDescription()) &&
+ Objects.equals(p.getDescriptor(), getDescriptor()) &&
Arrays.equals(p.fastGetNotifTypes(), fastGetNotifTypes()));
}
diff --git a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java
index 8effa04f8d8..1be6d8f563a 100644
--- a/jdk/src/share/classes/javax/management/MBeanOperationInfo.java
+++ b/jdk/src/share/classes/javax/management/MBeanOperationInfo.java
@@ -294,12 +294,12 @@ public class MBeanOperationInfo extends MBeanFeatureInfo implements Cloneable {
if (!(o instanceof MBeanOperationInfo))
return false;
MBeanOperationInfo p = (MBeanOperationInfo) o;
- return (p.getName().equals(getName()) &&
- p.getReturnType().equals(getReturnType()) &&
- p.getDescription().equals(getDescription()) &&
+ return (Objects.equals(p.getName(), getName()) &&
+ Objects.equals(p.getReturnType(), getReturnType()) &&
+ Objects.equals(p.getDescription(), getDescription()) &&
p.getImpact() == getImpact() &&
Arrays.equals(p.fastGetSignature(), fastGetSignature()) &&
- p.getDescriptor().equals(getDescriptor()));
+ Objects.equals(p.getDescriptor(), getDescriptor()));
}
/* We do not include everything in the hashcode. We assume that
diff --git a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java
index df3d59087df..81f2eff840d 100644
--- a/jdk/src/share/classes/javax/management/MBeanParameterInfo.java
+++ b/jdk/src/share/classes/javax/management/MBeanParameterInfo.java
@@ -27,6 +27,7 @@ package javax.management;
import java.util.Objects;
+
/**
* Describes an argument of an operation exposed by an MBean.
* Instances of this class are immutable. Subclasses may be mutable
@@ -137,10 +138,10 @@ public class MBeanParameterInfo extends MBeanFeatureInfo implements Cloneable {
if (!(o instanceof MBeanParameterInfo))
return false;
MBeanParameterInfo p = (MBeanParameterInfo) o;
- return (p.getName().equals(getName()) &&
- p.getType().equals(getType()) &&
- p.getDescription().equals(getDescription()) &&
- p.getDescriptor().equals(getDescriptor()));
+ return (Objects.equals(p.getName(), getName()) &&
+ Objects.equals(p.getType(), getType()) &&
+ Objects.equals(p.getDescription(), getDescription()) &&
+ Objects.equals(p.getDescriptor(), getDescriptor()));
}
public int hashCode() {
diff --git a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java
index 1e24504b45a..fcaede43a94 100644
--- a/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java
+++ b/jdk/src/share/classes/sun/java2d/cmm/CMSManager.java
@@ -104,53 +104,53 @@ public class CMSManager {
cName = tcmm.getClass().getName();
}
- public long loadProfile(byte[] data) {
+ public Profile loadProfile(byte[] data) {
System.err.print(cName + ".loadProfile");
- long profileID = tcmm.loadProfile(data);
- System.err.printf("(ID=%x)\n", profileID);
- return profileID;
+ Profile p = tcmm.loadProfile(data);
+ System.err.printf("(ID=%s)\n", p.toString());
+ return p;
}
- public void freeProfile(long profileID) {
- System.err.printf(cName + ".freeProfile(ID=%x)\n", profileID);
- tcmm.freeProfile(profileID);
+ public void freeProfile(Profile p) {
+ System.err.printf(cName + ".freeProfile(ID=%s)\n", p.toString());
+ tcmm.freeProfile(p);
}
- public int getProfileSize(long profileID) {
- System.err.print(cName + ".getProfileSize(ID=" + profileID + ")");
- int size = tcmm.getProfileSize(profileID);
+ public int getProfileSize(Profile p) {
+ System.err.print(cName + ".getProfileSize(ID=" + p + ")");
+ int size = tcmm.getProfileSize(p);
System.err.println("=" + size);
return size;
}
- public void getProfileData(long profileID, byte[] data) {
- System.err.print(cName + ".getProfileData(ID=" + profileID + ") ");
+ public void getProfileData(Profile p, byte[] data) {
+ System.err.print(cName + ".getProfileData(ID=" + p + ") ");
System.err.println("requested " + data.length + " byte(s)");
- tcmm.getProfileData(profileID, data);
+ tcmm.getProfileData(p, data);
}
- public int getTagSize(long profileID, int tagSignature) {
+ public int getTagSize(Profile p, int tagSignature) {
System.err.printf(cName + ".getTagSize(ID=%x, TagSig=%s)",
- profileID, signatureToString(tagSignature));
- int size = tcmm.getTagSize(profileID, tagSignature);
+ p, signatureToString(tagSignature));
+ int size = tcmm.getTagSize(p, tagSignature);
System.err.println("=" + size);
return size;
}
- public void getTagData(long profileID, int tagSignature,
+ public void getTagData(Profile p, int tagSignature,
byte[] data) {
System.err.printf(cName + ".getTagData(ID=%x, TagSig=%s)",
- profileID, signatureToString(tagSignature));
+ p, signatureToString(tagSignature));
System.err.println(" requested " + data.length + " byte(s)");
- tcmm.getTagData(profileID, tagSignature, data);
+ tcmm.getTagData(p, tagSignature, data);
}
- public void setTagData(long profileID, int tagSignature,
+ public void setTagData(Profile p, int tagSignature,
byte[] data) {
- System.err.print(cName + ".setTagData(ID=" + profileID +
+ System.err.print(cName + ".setTagData(ID=" + p +
", TagSig=" + tagSignature + ")");
System.err.println(" sending " + data.length + " byte(s)");
- tcmm.setTagData(profileID, tagSignature, data);
+ tcmm.setTagData(p, tagSignature, data);
}
/* methods for creating ColorTransforms */
diff --git a/jdk/src/share/classes/sun/java2d/cmm/PCMM.java b/jdk/src/share/classes/sun/java2d/cmm/PCMM.java
index 6b6ce93546d..03f2fab6336 100644
--- a/jdk/src/share/classes/sun/java2d/cmm/PCMM.java
+++ b/jdk/src/share/classes/sun/java2d/cmm/PCMM.java
@@ -32,13 +32,13 @@ import java.awt.color.ICC_Profile;
public interface PCMM {
/* methods invoked from ICC_Profile */
- public long loadProfile(byte[] data);
- public void freeProfile(long profileID);
- public int getProfileSize(long profileID);
- public void getProfileData(long profileID, byte[] data);
- public void getTagData(long profileID, int tagSignature, byte[] data);
- public int getTagSize(long profileID, int tagSignature);
- public void setTagData(long profileID, int tagSignature, byte[] data);
+ public Profile loadProfile(byte[] data);
+ public void freeProfile(Profile p);
+ public int getProfileSize(Profile p);
+ public void getProfileData(Profile p, byte[] data);
+ public void getTagData(Profile p, int tagSignature, byte[] data);
+ public int getTagSize(Profile p, int tagSignature);
+ public void setTagData(Profile p, int tagSignature, byte[] data);
/* methods for creating ColorTransforms */
public ColorTransform createTransform(ICC_Profile profile, int renderType,
diff --git a/jdk/src/share/classes/sun/java2d/cmm/Profile.java b/jdk/src/share/classes/sun/java2d/cmm/Profile.java
new file mode 100644
index 00000000000..5b766b5d079
--- /dev/null
+++ b/jdk/src/share/classes/sun/java2d/cmm/Profile.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+package sun.java2d.cmm;
+
+import java.awt.color.CMMException;
+
+public class Profile {
+ private final long nativePtr;
+
+ protected Profile(long ptr) {
+ nativePtr = ptr;
+ }
+
+ protected final long getNativePtr() {
+ if (nativePtr == 0L) {
+ throw new CMMException("Invalid profile: ptr is null");
+ }
+ return nativePtr;
+ }
+}
diff --git a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java
index f7ecc0b67c9..d76d99638a9 100644
--- a/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java
+++ b/jdk/src/share/classes/sun/java2d/cmm/lcms/LCMS.java
@@ -25,96 +25,139 @@
package sun.java2d.cmm.lcms;
+import java.awt.color.CMMException;
import java.awt.color.ICC_Profile;
-import java.util.Arrays;
-import java.util.HashMap;
import sun.java2d.cmm.ColorTransform;
import sun.java2d.cmm.PCMM;
+import sun.java2d.cmm.Profile;
+import sun.java2d.cmm.lcms.LCMSProfile.TagData;
public class LCMS implements PCMM {
/* methods invoked from ICC_Profile */
@Override
- public long loadProfile(byte[] data) {
- long id = loadProfileNative(data);
+ public Profile loadProfile(byte[] data) {
+ final Object disposerRef = new Object();
- if (id != 0L) {
- if (profiles == null) {
- profiles = new HashMap<>();
- }
- profiles.put(id, new TagCache(id));
+ final long ptr = loadProfileNative(data, disposerRef);
+
+ if (ptr != 0L) {
+ return new LCMSProfile(ptr, disposerRef);
}
- return id;
+ return null;
}
- private native long loadProfileNative(byte[] data);
+ private native long loadProfileNative(byte[] data, Object ref);
- @Override
- public void freeProfile(long profileID) {
- TagCache c = profiles.remove(profileID);
- if (c != null) {
- c.clear();
+ private LCMSProfile getLcmsProfile(Profile p) {
+ if (p instanceof LCMSProfile) {
+ return (LCMSProfile)p;
}
- if (profiles.isEmpty()) {
- profiles = null;
- }
- freeProfileNative(profileID);
+ throw new CMMException("Invalid profile: " + p);
}
- private native void freeProfileNative(long profileID);
-
- public native synchronized int getProfileSize(long profileID);
-
- public native synchronized void getProfileData(long profileID, byte[] data);
@Override
- public synchronized int getTagSize(long profileID, int tagSignature) {
- TagCache cache = profiles.get(profileID);
-
- if (cache == null) {
- cache = new TagCache(profileID);
- profiles.put(profileID, cache);
- }
-
- TagData t = cache.getTag(tagSignature);
- return t == null ? 0 : t.getSize();
+ public void freeProfile(Profile p) {
+ // we use disposer, so this method does nothing
}
- private static native byte[] getTagNative(long profileID, int signature);
+ @Override
+ public int getProfileSize(final Profile p) {
+ synchronized (p) {
+ return getProfileSizeNative(getLcmsProfile(p).getLcmsPtr());
+ }
+ }
+
+ private native int getProfileSizeNative(long ptr);
@Override
- public synchronized void getTagData(long profileID, int tagSignature,
- byte[] data)
+ public void getProfileData(final Profile p, byte[] data) {
+ synchronized (p) {
+ getProfileDataNative(getLcmsProfile(p).getLcmsPtr(), data);
+ }
+ }
+
+ private native void getProfileDataNative(long ptr, byte[] data);
+
+ @Override
+ public int getTagSize(Profile p, int tagSignature) {
+ final LCMSProfile profile = getLcmsProfile(p);
+
+ synchronized (profile) {
+ TagData t = profile.getTag(tagSignature);
+ return t == null ? 0 : t.getSize();
+ }
+ }
+
+ static native byte[] getTagNative(long profileID, int signature);
+
+ @Override
+ public void getTagData(Profile p, int tagSignature, byte[] data)
{
- TagCache cache = profiles.get(profileID);
+ final LCMSProfile profile = getLcmsProfile(p);
- if (cache == null) {
- cache = new TagCache(profileID);
- profiles.put(profileID, cache);
- }
-
- TagData t = cache.getTag(tagSignature);
- if (t != null) {
- t.copyDataTo(data);
+ synchronized (profile) {
+ TagData t = profile.getTag(tagSignature);
+ if (t != null) {
+ t.copyDataTo(data);
+ }
}
}
@Override
- public synchronized void setTagData(long profileID, int tagSignature, byte[] data) {
- TagCache cache = profiles.get(profileID);
+ public synchronized void setTagData(Profile p, int tagSignature, byte[] data) {
+ final LCMSProfile profile = getLcmsProfile(p);
- if (cache != null) {
- cache.clear();
+ synchronized (profile) {
+ profile.clearTagCache();
+
+ // Now we are going to update the profile with new tag data
+ // In some cases, we may change the pointer to the native
+ // profile.
+ //
+ // If we fail to write tag data for any reason, the old pointer
+ // should be used.
+ setTagDataNative(profile.getLcmsPtr(),
+ tagSignature, data);
}
- setTagDataNative(profileID, tagSignature, data);
}
- private native synchronized void setTagDataNative(long profileID, int tagSignature,
+ /**
+ * Writes supplied data as a tag into the profile.
+ * Destroys old profile, if new one was successfully
+ * created.
+ *
+ * Returns valid pointer to new profile.
+ *
+ * Throws CMMException if operation fails, preserve old profile from
+ * destruction.
+ */
+ private native void setTagDataNative(long ptr, int tagSignature,
byte[] data);
- public static native long getProfileID(ICC_Profile profile);
+ public synchronized static native LCMSProfile getProfileID(ICC_Profile profile);
- public static native long createNativeTransform(
+ /* Helper method used from LCMSColorTransfrom */
+ static long createTransform(
+ LCMSProfile[] profiles, int renderType,
+ int inFormatter, boolean isInIntPacked,
+ int outFormatter, boolean isOutIntPacked,
+ Object disposerRef)
+ {
+ long[] ptrs = new long[profiles.length];
+
+ for (int i = 0; i < profiles.length; i++) {
+ if (profiles[i] == null) throw new CMMException("Unknown profile ID");
+
+ ptrs[i] = profiles[i].getLcmsPtr();
+ }
+
+ return createNativeTransform(ptrs, renderType, inFormatter,
+ isInIntPacked, outFormatter, isOutIntPacked, disposerRef);
+ }
+
+ private static native long createNativeTransform(
long[] profileIDs, int renderType,
int inFormatter, boolean isInIntPacked,
int outFormatter, boolean isOutIntPacked,
@@ -175,59 +218,4 @@ public class LCMS implements PCMM {
return theLcms;
}
-
- private static class TagData {
- private int signature;
- private byte[] data;
-
- TagData(int sig, byte[] data) {
- this.signature = sig;
- this.data = data;
- }
-
- int getSize() {
- return data.length;
- }
-
- byte[] getData() {
- return Arrays.copyOf(data, data.length);
- }
-
- void copyDataTo(byte[] dst) {
- System.arraycopy(data, 0, dst, 0, data.length);
- }
-
- int getSignature() {
- return signature;
- }
- }
-
- private static class TagCache {
- private long profileID;
- private HashMap
- * There may be an arbitrary number of intermediate realms
- * between cRealm and sRealm. The realms may be organized
- * organized hierarchically, or the paths between them may be
- * specified in the [capaths] stanza of the caller's
- * Kerberos configuration file. The configuration file is consulted
- * first. Then a hirarchical organization is assumed if no realms
- * are found in the configuration file.
+ * This method would read [capaths] to create a path, or generate a
+ * hierarchical path if [capaths] does not contain a sub-stanza for cRealm
+ * or the sub-stanza does not contain a tag for sRealm.
*
- * The returned list, if not null, contains cRealm as the first
- * entry. sRealm is not included unless it is mistakenly listed
- * in the configuration file as an intermediary realm.
+ * The returned list would never be null, and it always contains
+ * cRealm as the head entry. sRealm is not included as the tail.
*
- * @param cRealm the initiating realm
- * @param sRealm the target realm
- * @returns array of realms
- * @thows KrbException
+ * @param cRealm the initiating realm, not null
+ * @param sRealm the target realm, not null, not equals to cRealm
+ * @returns array of realms including at least cRealm as the first
+ * element
*/
- public static String[] getRealmsList(String cRealm, String sRealm)
- throws KrbException {
- String[] retList = doInitialParse(cRealm, sRealm);
- if (retList != null && retList.length != 0) {
- return retList;
- }
- /*
- * Try [capaths].
- */
- retList = parseCapaths(cRealm, sRealm);
- if (retList != null && retList.length != 0) {
- return retList;
- }
- /*
- * Now assume the realms are organized hierarchically.
- */
- retList = parseHierarchy(cRealm, sRealm);
- return retList;
+ public static String[] getRealmsList(String cRealm, String sRealm) {
+ try {
+ // Try [capaths]
+ return parseCapaths(cRealm, sRealm);
+ } catch (KrbException ke) {
+ // Now assume the realms are organized hierarchically.
+ return parseHierarchy(cRealm, sRealm);
}
+ }
/**
- * Parses the [capaths] stanza of the configuration file
- * for a list of realms to traverse
- * to obtain credentials from the initiating realm cRealm to
- * the target realm sRealm.
- * @param cRealm the initiating realm
- * @param sRealm the target realm
- * @returns array of realms
- * @ throws KrbException
- */
-
- /*
- * parseCapaths works for a capaths organized such that
- * for a given client realm C there is a tag C that
- * contains subtags Ci ... Cn that completely define intermediate
- * realms from C to target T. For example:
+ * Parses the [capaths] stanza of the configuration file for a
+ * list of realms to traverse to obtain credentials from the
+ * initiating realm cRealm to the target realm sRealm.
+ *
+ * For a given client realm C there is a tag C in [capaths] whose
+ * subtag S has a value which is a (possibly partial) path from C
+ * to S. When the path is partial, it contains only the tail of the
+ * full path. Values of other subtags will be used to build the full
+ * path. The value "." means a direct path from C to S. If realm S
+ * does not appear as a subtag, there is no path defined here.
+ *
+ * The implementation ignores all values which equals to C or S, or
+ * a "." in multiple values, or any duplicated realm names.
+ *
+ * When a path value has more than two realms, they can be specified
+ * with multiple key-value pairs each having a single value, but the
+ * order must not change.
+ *
+ * For example:
*
* [capaths]
* TIVOLI.COM = {
@@ -325,357 +285,130 @@ public class Realm implements Cloneable {
* LDAPCENTRAL.NET = .
* }
*
- * The tag TIVOLI.COM contains subtags IBM.COM, IBM_LDAPCENTRAL.COM
- * and LDAPCENTRAL.NET that completely define the path from TIVOLI.COM
- * to IBM.COM (TIVOLI.COM->LADAPCENTRAL.NET->IBM_LDAPCENTRAL.COM->IBM
- * or TIVOLI.COM->MOONLITE.ORG->IBM.COM).
+ * TIVOLI.COM has a direct path to LDAPCENTRAL.NET, which has a direct
+ * path to IBM_LDAPCENTRAL.COM. It also has a partial path to IBM.COM
+ * being "IBM_LDAPCENTRAL.COM MOONLITE.ORG". Merging these info together,
+ * a full path from TIVOLI.COM to IBM.COM will be
*
- * A direct path is assumed for an intermediary whose entry is not
- * "closed" by a "." In the above example, TIVOLI.COM is assumed
- * to have a direct path to MOONLITE.ORG and MOONLITE.COM
- * in turn to IBM.COM.
+ * TIVOLI.COM -> LDAPCENTRAL.NET -> IBM_LDAPCENTRAL.COM
+ * -> IBM_LDAPCENTRAL.COM -> MOONLITE.ORG
+ *
+ * Please note the sRealm IBM.COM does not appear in the path.
+ *
+ * @param cRealm the initiating realm
+ * @param sRealm the target realm, not the same as cRealm
+ * @returns array of realms including at least cRealm as the first
+ * element
+ * @throws KrbException if the config does not contain a sub-stanza
+ * for cRealm in [capaths] or the sub-stanza does not contain
+ * sRealm as a tag
*/
+ private static String[] parseCapaths(String cRealm, String sRealm)
+ throws KrbException {
- private static String[] parseCapaths(String cRealm, String sRealm) throws KrbException {
- String[] retList = null;
+ // This line could throw a KrbException
+ Config cfg = Config.getInstance();
- Config cfg = null;
- try {
- cfg = Config.getInstance();
- } catch (Exception exc) {
- if (DEBUG) {
- System.out.println ("Configuration information can not be " +
- "obtained " + exc.getMessage());
- }
- return null;
+ if (!cfg.exists("capaths", cRealm, sRealm)) {
+ throw new KrbException("No conf");
}
- String intermediaries = cfg.getAll("capaths", cRealm, sRealm);
+ LinkedList