diff --git a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip index 7f0d3a74c..c8c734189 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/_j2sclasslist.txt b/sources/net.sf.j2s.core/dist/swingjs/_j2sclasslist.txt index 2ac6d34b3..7fb43a5f8 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/_j2sclasslist.txt +++ b/sources/net.sf.j2s.core/dist/swingjs/_j2sclasslist.txt @@ -305,7 +305,6 @@ javax/swing/undo/UndoableEdit.js javax/swing/ViewportLayout.js javax/swing/WindowConstants.js sun/awt/AppContext.js -sun/awt/AWTAccessor.js sun/awt/AWTAutoShutdown.js sun/awt/CausedFocusEvent.js sun/awt/ComponentFactory.js @@ -339,10 +338,8 @@ swingjs/api/Interface.js swingjs/api/js/DOMNode.js swingjs/api/js/HTML5CanvasContext2D.js swingjs/api/js/JSInterface.js -swingjs/api/JSMinimalAbstractDocument.js swingjs/jquery/JQueryUI.js swingjs/JSApp.js -swingjs/JSApplet.js swingjs/JSAppletThread.js swingjs/JSAppletViewer.js swingjs/JSFocusPeer.js diff --git a/sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar b/sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar index 54e0f0cf0..87df1d9f8 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar and b/sources/net.sf.j2s.core/dist/swingjs/net.sf.j2s.core.jar differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/timestamp b/sources/net.sf.j2s.core/dist/swingjs/timestamp index ec9d260fc..0800566a9 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/timestamp +++ b/sources/net.sf.j2s.core/dist/swingjs/timestamp @@ -1 +1 @@ -20190817161814 +20190828094643 diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip index 7f0d3a74c..c8c734189 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip and b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/_j2sclasslist.txt b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/_j2sclasslist.txt index 2ac6d34b3..7fb43a5f8 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/_j2sclasslist.txt +++ b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/_j2sclasslist.txt @@ -305,7 +305,6 @@ javax/swing/undo/UndoableEdit.js javax/swing/ViewportLayout.js javax/swing/WindowConstants.js sun/awt/AppContext.js -sun/awt/AWTAccessor.js sun/awt/AWTAutoShutdown.js sun/awt/CausedFocusEvent.js sun/awt/ComponentFactory.js @@ -339,10 +338,8 @@ swingjs/api/Interface.js swingjs/api/js/DOMNode.js swingjs/api/js/HTML5CanvasContext2D.js swingjs/api/js/JSInterface.js -swingjs/api/JSMinimalAbstractDocument.js swingjs/jquery/JQueryUI.js swingjs/JSApp.js -swingjs/JSApplet.js swingjs/JSAppletThread.js swingjs/JSAppletViewer.js swingjs/JSFocusPeer.js diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/net.sf.j2s.core.jar b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/net.sf.j2s.core.jar index 54e0f0cf0..87df1d9f8 100644 Binary files a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/net.sf.j2s.core.jar and b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/net.sf.j2s.core.jar differ diff --git a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp index ec9d260fc..0800566a9 100644 --- a/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp +++ b/sources/net.sf.j2s.core/dist/swingjs/ver/3.2.4/timestamp @@ -1 +1 @@ -20190817161814 +20190828094643 diff --git a/sources/net.sf.j2s.core/src/net/sf/j2s/core/Java2ScriptCompilationParticipant.java b/sources/net.sf.j2s.core/src/net/sf/j2s/core/Java2ScriptCompilationParticipant.java index 4a4e5a9a2..5e8e92c7f 100644 --- a/sources/net.sf.j2s.core/src/net/sf/j2s/core/Java2ScriptCompilationParticipant.java +++ b/sources/net.sf.j2s.core/src/net/sf/j2s/core/Java2ScriptCompilationParticipant.java @@ -102,10 +102,13 @@ public void buildStarting(BuildContext[] files, boolean isBatch) { */ public void buildFinished(IJavaProject project) { if (javaFiles != null) { - System.out.println("building JavaScript " + project.getProject().getLocation()); Java2ScriptCompiler j2sCompiler = new Java2ScriptCompiler(); j2sCompiler.startBuild(isCleanBuild); - j2sCompiler.initializeProject(project, true); + if (!j2sCompiler.initializeProject(project, true)) { + System.out.println(".j2s disabled"); + return; + } + System.out.println("building JavaScript " + project.getProject().getLocation()); for (int i = 0; i < javaFiles.length; i++) { System.out.println("transpiling " + javaFiles[i]); // trying to keep the progess monitor running - didn't work diff --git a/sources/net.sf.j2s.java.core/.j2s b/sources/net.sf.j2s.java.core/.j2s index 98cbe32d2..0acf828b6 100644 --- a/sources/net.sf.j2s.java.core/.j2s +++ b/sources/net.sf.j2s.java.core/.j2s @@ -1,16 +1,18 @@ -j2s.compiler.status=enable - -#output file name for logging methods declared - delete the file to regenerate a listing -#j2s.log.methods.declared=methodsDeclared.csv - -#output file name for logging methods called - delete the file to regenerate a listing -#j2s.log.methods.called=methodsCalled.csv - -#if set, every instance of methods called will be logged -#otherwise, only the first call to a method will be logged -#output will be comma-separated: called method,caller class -#j2s.log.all.calls=true - -#a semicolon-separated list of package-level file paths to be excluded -#j2s.excluded.paths=test;testng - +j2s.compiler.status=enable + +#j2s.compiler.nonqualified.packages=org.w3c.dom + +#output file name for logging methods declared - delete the file to regenerate a listing +#j2s.log.methods.declared=methodsDeclared.csv + +#output file name for logging methods called - delete the file to regenerate a listing +#j2s.log.methods.called=methodsCalled.csv + +#if set, every instance of methods called will be logged +#otherwise, only the first call to a method will be logged +#output will be comma-separated: called method,caller class +#j2s.log.all.calls=true + +#a semicolon-separated list of package-level file paths to be excluded +#j2s.excluded.paths=test;testng + diff --git a/sources/net.sf.j2s.java.core/_j2sclasslist.txt b/sources/net.sf.j2s.java.core/_j2sclasslist.txt index 2ac6d34b3..7fb43a5f8 100644 --- a/sources/net.sf.j2s.java.core/_j2sclasslist.txt +++ b/sources/net.sf.j2s.java.core/_j2sclasslist.txt @@ -305,7 +305,6 @@ javax/swing/undo/UndoableEdit.js javax/swing/ViewportLayout.js javax/swing/WindowConstants.js sun/awt/AppContext.js -sun/awt/AWTAccessor.js sun/awt/AWTAutoShutdown.js sun/awt/CausedFocusEvent.js sun/awt/ComponentFactory.js @@ -339,10 +338,8 @@ swingjs/api/Interface.js swingjs/api/js/DOMNode.js swingjs/api/js/HTML5CanvasContext2D.js swingjs/api/js/JSInterface.js -swingjs/api/JSMinimalAbstractDocument.js swingjs/jquery/JQueryUI.js swingjs/JSApp.js -swingjs/JSApplet.js swingjs/JSAppletThread.js swingjs/JSAppletViewer.js swingjs/JSFocusPeer.js diff --git a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip index 7f0d3a74c..c8c734189 100644 Binary files a/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip and b/sources/net.sf.j2s.java.core/dist/SwingJS-site.zip differ diff --git a/sources/net.sf.j2s.java.core/dist/_j2sclasslist.txt b/sources/net.sf.j2s.java.core/dist/_j2sclasslist.txt index 2ac6d34b3..7fb43a5f8 100644 --- a/sources/net.sf.j2s.java.core/dist/_j2sclasslist.txt +++ b/sources/net.sf.j2s.java.core/dist/_j2sclasslist.txt @@ -305,7 +305,6 @@ javax/swing/undo/UndoableEdit.js javax/swing/ViewportLayout.js javax/swing/WindowConstants.js sun/awt/AppContext.js -sun/awt/AWTAccessor.js sun/awt/AWTAutoShutdown.js sun/awt/CausedFocusEvent.js sun/awt/ComponentFactory.js @@ -339,10 +338,8 @@ swingjs/api/Interface.js swingjs/api/js/DOMNode.js swingjs/api/js/HTML5CanvasContext2D.js swingjs/api/js/JSInterface.js -swingjs/api/JSMinimalAbstractDocument.js swingjs/jquery/JQueryUI.js swingjs/JSApp.js -swingjs/JSApplet.js swingjs/JSAppletThread.js swingjs/JSAppletViewer.js swingjs/JSFocusPeer.js diff --git a/sources/net.sf.j2s.java.core/src/java/awt/DefaultKeyboardFocusManager.java b/sources/net.sf.j2s.java.core/src/java/awt/DefaultKeyboardFocusManager.java index cfc2f523c..358d8ab0c 100644 --- a/sources/net.sf.j2s.java.core/src/java/awt/DefaultKeyboardFocusManager.java +++ b/sources/net.sf.j2s.java.core/src/java/awt/DefaultKeyboardFocusManager.java @@ -38,8 +38,6 @@ import javax.swing.JApplet; -import sun.awt.AWTAccessor; - //import sun.util.logging.PlatformLogger; import sun.awt.AppContext; diff --git a/sources/net.sf.j2s.java.core/src/java/awt/datatransfer/SystemFlavorMap.java b/sources/net.sf.j2s.java.core/src/java/awt/datatransfer/SystemFlavorMap.java index d35c850a7..326fa28f1 100644 --- a/sources/net.sf.j2s.java.core/src/java/awt/datatransfer/SystemFlavorMap.java +++ b/sources/net.sf.j2s.java.core/src/java/awt/datatransfer/SystemFlavorMap.java @@ -30,7 +30,7 @@ import java.io.BufferedReader; import java.io.IOException; -import java.lang.ref.SoftReference; +//import java.lang.ref.SoftReference; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -631,15 +631,15 @@ public synchronized List getNativesForFlavor(DataFlavor flav) { List retval = null; // Check cache, even for null flav - SoftReference ref = (SoftReference)getNativesForFlavorCache.get(flav); - if (ref != null) { - retval = (List)ref.get(); + Object refval = getNativesForFlavorCache.get(flav); +// if (ref != null) { +// retval = (List)ref.get(); if (retval != null) { // Create a copy, because client code can modify the returned // list. return new ArrayList(retval); } - } + // } if (flav == null) { retval = new ArrayList(nativeToFlavor.keySet()); @@ -723,7 +723,7 @@ public synchronized List getNativesForFlavor(DataFlavor flav) { retval = flavorToNativeLookup(flav, SYNTHESIZE_IF_NOT_FOUND); } - getNativesForFlavorCache.put(flav, new SoftReference(retval)); + getNativesForFlavorCache.put(flav, retval); // Create a copy, because client code can modify the returned list. return new ArrayList(retval); } @@ -763,13 +763,13 @@ public synchronized List getNativesForFlavor(DataFlavor flav) { public synchronized List getFlavorsForNative(String nat) { // Check cache, even for null nat - SoftReference ref = (SoftReference)getFlavorsForNativeCache.get(nat); - if (ref != null) { - ArrayList retval = (ArrayList)ref.get(); - if (retval != null) { - return (List)retval.clone(); +// SoftReference ref = (SoftReference)getFlavorsForNativeCache.get(nat); +// if (ref != null) { + ArrayList rval = (ArrayList) getFlavorsForNativeCache.get(nat); + if (rval != null) { + return (List)rval.clone(); } - } +// } LinkedList retval = new LinkedList(); @@ -903,7 +903,7 @@ public synchronized List getFlavorsForNative(String nat) { } ArrayList arrayList = new ArrayList(retval); - getFlavorsForNativeCache.put(nat, new SoftReference(arrayList)); + getFlavorsForNativeCache.put(nat, arrayList); return (List)arrayList.clone(); } diff --git a/sources/net.sf.j2s.java.core/src/java/awt/event/package.html b/sources/net.sf.j2s.java.core/src/java/awt/event/package.html deleted file mode 100644 index afa1700fd..000000000 --- a/sources/net.sf.j2s.java.core/src/java/awt/event/package.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - -Provides interfaces and classes for dealing with different -types of events fired by AWT components. See the jsjava.awt.AWTEvent -class for details on the AWT event model. Events are fired by event -sources. An event listener registers with an event source to receive -notifications about the events of a particular type. This package -defines events and event listeners, as well as event listener -adapters, which are convenience classes to make easier the process of -writing event listeners. - - - -@since JDK1.1 - - diff --git a/sources/net.sf.j2s.java.core/src/java/awt/font/package.html b/sources/net.sf.j2s.java.core/src/java/awt/font/package.html deleted file mode 100644 index 22e71ba1c..000000000 --- a/sources/net.sf.j2s.java.core/src/java/awt/font/package.html +++ /dev/null @@ -1,53 +0,0 @@ - - - - - - - -Provides classes and interface relating to fonts. It -contains support for representing Type 1, Type 1 Multiple Master -fonts, OpenType fonts, and TrueType fonts. - - - -@since 1.2 - - diff --git a/sources/net.sf.j2s.java.core/src/java/io/ByteArrayOutputStream.java b/sources/net.sf.j2s.java.core/src/java/io/ByteArrayOutputStream.java index 490a0acfd..4089ddcac 100644 --- a/sources/net.sf.j2s.java.core/src/java/io/ByteArrayOutputStream.java +++ b/sources/net.sf.j2s.java.core/src/java/io/ByteArrayOutputStream.java @@ -1,8 +1,5 @@ /* - * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017 - * for use in SwingJS via transpilation into JavaScript using Java2Script. - * - * Copyright (c) 1994, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -28,7 +25,7 @@ package java.io; -import java.io.IOException; +import java.util.Arrays; /** * This class implements an output stream in which the data is @@ -96,6 +93,14 @@ private void ensureCapacity(int minCapacity) { grow(minCapacity); } + /** + * The maximum size of array to allocate. + * Some VMs reserve some header words in an array. + * Attempts to allocate larger arrays may result in + * OutOfMemoryError: Requested array size exceeds VM limit + */ + private static final int MAX_ARRAY_SIZE = Integer.MAX_VALUE - 8; + /** * Increases the capacity to ensure that it can hold at least the * number of elements specified by the minimum capacity argument. @@ -108,22 +113,19 @@ private void grow(int minCapacity) { int newCapacity = oldCapacity << 1; if (newCapacity - minCapacity < 0) newCapacity = minCapacity; - if (newCapacity < 0) { - if (minCapacity < 0) // overflow - throw new OutOfMemoryError(); - newCapacity = minCapacity; - } - buf = arrayCopyByte(buf, newCapacity); + if (newCapacity - MAX_ARRAY_SIZE > 0) + newCapacity = hugeCapacity(minCapacity); + buf = Arrays.copyOf(buf, newCapacity); } - private static byte[] arrayCopyByte(byte[] array, int newLength) { - byte[] t = new byte[newLength]; - System.arraycopy(array, 0, t, 0, array.length < newLength ? array.length - : newLength); - return t; + private static int hugeCapacity(int minCapacity) { + if (minCapacity < 0) // overflow + throw new OutOfMemoryError(); + return (minCapacity > MAX_ARRAY_SIZE) ? + Integer.MAX_VALUE : + MAX_ARRAY_SIZE; } - /** * Writes the specified byte to this byte array output stream. * @@ -187,7 +189,7 @@ public synchronized void reset() { * @see java.io.ByteArrayOutputStream#size() */ public synchronized byte toByteArray()[] { - return (count == buf.length ? buf : arrayCopyByte(buf, count)); + return (count == buf.length ? buf : Arrays.copyOf(buf, count)); // BH why copy if buf is fine? } /** @@ -221,39 +223,64 @@ public synchronized String toString() { return new String(buf, 0, count); } -// /** -// * Converts the buffer's contents into a string by decoding the bytes using -// * the specified {@link java.nio.charset.Charset charsetName}. The length of -// * the new String is a function of the charset, and hence may not be -// * equal to the length of the byte array. -// * -// *

This method always replaces malformed-input and unmappable-character -// * sequences with this charset's default replacement string. The {@link -// * java.nio.charset.CharsetDecoder} class should be used when more control -// * over the decoding process is required. -// * -// * @param charsetName the name of a supported -// * {@linkplain java.nio.charset.Charset charset} -// * @return String decoded from the buffer's contents. -// * @exception UnsupportedEncodingException -// * If the named charset is not supported -// * @since JDK1.1 -// */ -// public synchronized String toString(String charsetName) -// throws UnsupportedEncodingException -// { -// return new String(buf, 0, count, charsetName); -// } + /** + * Converts the buffer's contents into a string by decoding the bytes using + * the named {@link java.nio.charset.Charset charset}. The length of the new + * String is a function of the charset, and hence may not be equal + * to the length of the byte array. + * + *

This method always replaces malformed-input and unmappable-character + * sequences with this charset's default replacement string. The {@link + * java.nio.charset.CharsetDecoder} class should be used when more control + * over the decoding process is required. + * + * @param charsetName the name of a supported + * {@link java.nio.charset.Charset charset} + * @return String decoded from the buffer's contents. + * @exception UnsupportedEncodingException + * If the named charset is not supported + * @since JDK1.1 + */ + public synchronized String toString(String charsetName) + throws UnsupportedEncodingException + { + return new String(buf, 0, count, charsetName); + } + + /** + * Creates a newly allocated string. Its size is the current size of + * the output stream and the valid contents of the buffer have been + * copied into it. Each character c in the resulting string is + * constructed from the corresponding element b in the byte + * array such that: + *

+     *     c == (char)(((hibyte & 0xff) << 8) | (b & 0xff))
+     * 
+ * + * @deprecated This method does not properly convert bytes into characters. + * As of JDK 1.1, the preferred way to do this is via the + * toString(String enc) method, which takes an encoding-name + * argument, or the toString() method, which uses the + * platform's default character encoding. + * + * @param hibyte the high byte of each resulting Unicode character. + * @return the current contents of the output stream, as a string. + * @see java.io.ByteArrayOutputStream#size() + * @see java.io.ByteArrayOutputStream#toString(String) + * @see java.io.ByteArrayOutputStream#toString() + */ + @Deprecated + public synchronized String toString(int hibyte) { + return new String(buf, hibyte, 0, count); + } /** * Closing a ByteArrayOutputStream has no effect. The methods in * this class can be called after the stream has been closed without * generating an IOException. - *

- * */ @Override public void close() throws IOException { } -} +} \ No newline at end of file diff --git a/sources/net.sf.j2s.java.core/src/java/io/DataInputStream.java b/sources/net.sf.j2s.java.core/src/java/io/DataInputStream.java index b799188d3..70877e883 100644 --- a/sources/net.sf.j2s.java.core/src/java/io/DataInputStream.java +++ b/sources/net.sf.j2s.java.core/src/java/io/DataInputStream.java @@ -565,7 +565,7 @@ public final String readLine() throws IOException { if (!(in instanceof PushbackInputStream)) { this.in = new PushbackInputStream(in, 1); } - ((PushbackInputStream) in).unreadByte(c2); + ((PushbackInputStream) in).unread(c2); } break loop; diff --git a/sources/net.sf.j2s.java.core/src/java/io/File.java b/sources/net.sf.j2s.java.core/src/java/io/File.java index fe5db3361..5347eda18 100644 --- a/sources/net.sf.j2s.java.core/src/java/io/File.java +++ b/sources/net.sf.j2s.java.core/src/java/io/File.java @@ -1022,13 +1022,14 @@ public void deleteOnExit() { * the directory */ public String[] list() { + if (fs == null) throw new AccessControlException("access denied"); // // SecurityManager security = System.getSecurityManager(); // if (security != null) { // security.checkRead(path); // } -// return fs.list(this); + return fs.list(this); } /** @@ -2003,4 +2004,8 @@ public Path toPath() { return result; } + public long lastModified() { + return this.lastModified; + } + } \ No newline at end of file diff --git a/sources/net.sf.j2s.java.core/src/java/io/FileSystem.java b/sources/net.sf.j2s.java.core/src/java/io/FileSystem.java index 9c659e6cf..b070bdf0c 100644 --- a/sources/net.sf.j2s.java.core/src/java/io/FileSystem.java +++ b/sources/net.sf.j2s.java.core/src/java/io/FileSystem.java @@ -178,12 +178,14 @@ public char getPathSeparator() { // */ // public abstract boolean delete(File f); // -// /** -// * List the elements of the directory denoted by the given abstract -// * pathname. Return an array of strings naming the elements of the -// * directory if successful; otherwise, return null. -// */ -// public abstract String[] list(File f); + /** + * List the elements of the directory denoted by the given abstract + * pathname. Return an array of strings naming the elements of the + * directory if successful; otherwise, return null. + */ + public String[] list(File f) { + return null; + } // // /** // * Create a new directory denoted by the given abstract pathname, diff --git a/sources/net.sf.j2s.java.core/src/java/io/IOException.java b/sources/net.sf.j2s.java.core/src/java/io/IOException.java index cd849fa70..745b579cc 100644 --- a/sources/net.sf.j2s.java.core/src/java/io/IOException.java +++ b/sources/net.sf.j2s.java.core/src/java/io/IOException.java @@ -1,51 +1,101 @@ -/* Copyright 1998, 2004 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.io; - - -/** - * This IO exception is thrown when a program encounters some sort I/O error. - * Details may be specified in the constructor or by one of the subclasses. - * - - */ -public class IOException extends Exception { - - private static final long serialVersionUID = 7818375828146090155L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IOException() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * The detail message for the exception. - */ - public IOException(String detailMessage) { - super(detailMessage); - } - - public IOException(Throwable cause) { - super(cause); - } - -} +/* + * Copyright (c) 1994, 2006, 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 java.io; + +/** + * Signals that an I/O exception of some sort has occurred. This + * class is the general class of exceptions produced by failed or + * interrupted I/O operations. + * + * @author unascribed + * @see java.io.InputStream + * @see java.io.OutputStream + * @since JDK1.0 + */ +public +class IOException extends Exception { + static final long serialVersionUID = 7818375828146090155L; + + /** + * Constructs an {@code IOException} with {@code null} + * as its error detail message. + */ + public IOException() { + super(); + } + + /** + * Constructs an {@code IOException} with the specified detail message. + * + * @param message + * The detail message (which is saved for later retrieval + * by the {@link #getMessage()} method) + */ + public IOException(String message) { + super(message); + } + + /** + * Constructs an {@code IOException} with the specified detail message + * and cause. + * + *

Note that the detail message associated with {@code cause} is + * not automatically incorporated into this exception's detail + * message. + * + * @param message + * The detail message (which is saved for later retrieval + * by the {@link #getMessage()} method) + * + * @param cause + * The cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * + * @since 1.6 + */ + public IOException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs an {@code IOException} with the specified cause and a + * detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of {@code cause}). + * This constructor is useful for IO exceptions that are little more + * than wrappers for other throwables. + * + * @param cause + * The cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * + * @since 1.6 + */ + public IOException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/io/PushbackInputStream.java b/sources/net.sf.j2s.java.core/src/java/io/PushbackInputStream.java index 0ed8cd366..b44848d35 100644 --- a/sources/net.sf.j2s.java.core/src/java/io/PushbackInputStream.java +++ b/sources/net.sf.j2s.java.core/src/java/io/PushbackInputStream.java @@ -1,8 +1,5 @@ /* - * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017 - * for use in SwingJS via transpilation into JavaScript using Java2Script. - * - * Copyright (c) 1994, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1994, 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 @@ -28,8 +25,6 @@ package java.io; -import java.io.IOException; - /** * A PushbackInputStream adds * functionality to another input stream, namely @@ -73,8 +68,6 @@ class PushbackInputStream extends FilterInputStream { /** * Check to make sure that this stream has not been closed - * @throws IOException - * */ private void ensureOpen() throws IOException { if (in == null) @@ -92,7 +85,7 @@ private void ensureOpen() throws IOException { * * @param in the input stream from which bytes will be read. * @param size the size of the pushback buffer. - * @exception IllegalArgumentException if size is <= 0 + * @exception IllegalArgumentException if {@code size <= 0} * @since JDK1.1 */ public PushbackInputStream(InputStream in, int size) { @@ -104,16 +97,6 @@ public PushbackInputStream(InputStream in, int size) { this.pos = size; } -// /** -// * BH: Added to allow full reset of a bundled stream -// */ -// @Override -// public void resetStream() { -// in.resetStream(); -// this.pos = 0; -// } -// - /** * Creates a PushbackInputStream * and saves its argument, the input stream @@ -153,7 +136,7 @@ public int read() throws IOException { if (pos < buf.length) { return buf[pos++] & 0xff; } - return in.read(); + return super.read(); } /** @@ -179,7 +162,6 @@ public int read() throws IOException { * or an I/O error occurs. * @see java.io.InputStream#read(byte[], int, int) */ - @Override public int read(byte[] b, int off, int len) throws IOException { ensureOpen(); if (b == null) { @@ -201,7 +183,7 @@ public int read(byte[] b, int off, int len) throws IOException { len -= avail; } if (len > 0) { - len = in.read(b, off, len); + len = super.read(b, off, len); if (len == -1) { return avail == 0 ? -1 : avail; } @@ -221,7 +203,7 @@ public int read(byte[] b, int off, int len) throws IOException { * buffer for the byte, or this input stream has been closed by * invoking its {@link #close()} method. */ - public void unreadByte(int b) throws IOException { + public void unread(int b) throws IOException { ensureOpen(); if (pos == 0) { throw new IOException("Push back buffer is full"); @@ -253,22 +235,22 @@ public void unread(byte[] b, int off, int len) throws IOException { System.arraycopy(b, off, buf, pos, len); } -// /** -// * Pushes back an array of bytes by copying it to the front of the -// * pushback buffer. After this method returns, the next byte to be read -// * will have the value b[0], the byte after that will have the -// * value b[1], and so forth. -// * -// * @param b the byte array to push back -// * @exception IOException If there is not enough room in the pushback -// * buffer for the specified number of bytes, -// * or this input stream has been closed by -// * invoking its {@link #close()} method. -// * @since JDK1.1 -// */ -// public void unread(byte[] b) throws IOException { -// unread(b, 0, b.length); -// } + /** + * Pushes back an array of bytes by copying it to the front of the + * pushback buffer. After this method returns, the next byte to be read + * will have the value b[0], the byte after that will have the + * value b[1], and so forth. + * + * @param b the byte array to push back + * @exception IOException If there is not enough room in the pushback + * buffer for the specified number of bytes, + * or this input stream has been closed by + * invoking its {@link #close()} method. + * @since JDK1.1 + */ + public void unread(byte[] b) throws IOException { + unread(b, 0, b.length); + } /** * Returns an estimate of the number of bytes that can be read (or @@ -289,11 +271,10 @@ public void unread(byte[] b, int off, int len) throws IOException { * @see java.io.FilterInputStream#in * @see java.io.InputStream#available() */ - @Override public int available() throws IOException { ensureOpen(); int n = buf.length - pos; - int avail = in.available(); + int avail = super.available(); return n > (Integer.MAX_VALUE - avail) ? Integer.MAX_VALUE : n + avail; @@ -321,7 +302,6 @@ public int available() throws IOException { * @see java.io.InputStream#skip(long n) * @since 1.2 */ - @Override public long skip(long n) throws IOException { ensureOpen(); if (n <= 0) { @@ -337,7 +317,7 @@ public long skip(long n) throws IOException { n -= pskip; } if (n > 0) { - pskip += in.skip(n); + pskip += super.skip(n); } return pskip; } @@ -351,7 +331,6 @@ public long skip(long n) throws IOException { * @see java.io.InputStream#mark(int) * @see java.io.InputStream#reset() */ - @Override public boolean markSupported() { return false; } @@ -366,7 +345,6 @@ public boolean markSupported() { * the mark position becomes invalid. * @see java.io.InputStream#reset() */ - @Override public synchronized void mark(int readlimit) { } @@ -382,7 +360,6 @@ public synchronized void mark(int readlimit) { * @see java.io.InputStream#mark(int) * @see java.io.IOException */ - @Override public synchronized void reset() throws IOException { throw new IOException("mark/reset not supported"); } @@ -396,7 +373,6 @@ public synchronized void reset() throws IOException { * * @exception IOException if an I/O error occurs. */ - @Override public synchronized void close() throws IOException { if (in == null) return; diff --git a/sources/net.sf.j2s.java.core/src/java/lang/AssertionError.java b/sources/net.sf.j2s.java.core/src/java/lang/AssertionError.java index a6155a0ab..a560af5b4 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/AssertionError.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/AssertionError.java @@ -1,128 +1,167 @@ -/* - * Copyright 2002, 2004 The Apache Software Foundation or its licensors, as - * applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); you may not - * use this file except in compliance with the License. You may obtain a copy of - * the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT - * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the - * License for the specific language governing permissions and limitations under - * the License. - */ - -package java.lang; - -/** - *

- * Indicates that an assertion has failed. - *

- * - * @since 1.4 - */ -public class AssertionError extends Error { - - private static final long serialVersionUID = -5013299493970297370L; - - /** - *

- * Constructs an instance without a message. - *

- */ - public AssertionError() { - super(); - } - - /** - *

- * Constructs an instance with a message that is the - * {@link String#valueOf(Object)} of the object passed. If the object passed - * is an instanceof {@link Throwable}, then it also becomes the cause of - * this error. - *

- * - * @param detailMessage The value to be converted into the message and - * optionally the cause. - */ - public AssertionError(Object detailMessage) { - super(String.valueOf(detailMessage), - (detailMessage instanceof Throwable ? (Throwable) detailMessage - : null)); - } - - /** - *

- * Constructs an instance with a message that is the - * {@link String#valueOf(boolean)} of the boolean passed. - *

- * - * @param detailMessage The value to be converted into the message. - */ - public AssertionError(boolean detailMessage) { - this(String.valueOf(detailMessage)); - } - - /** - *

- * Constructs an instance with a message that is the - * {@link String#valueOf(char)} of the char passed. - *

- * - * @param detailMessage The value to be converted into the message. - */ - public AssertionError(char detailMessage) { - this(String.valueOf(detailMessage)); - } - - /** - *

- * Constructs an instance with a message that is the - * {@link String#valueOf(int)} of the int passed. - *

- * - * @param detailMessage The value to be converted into the message. - */ - public AssertionError(int detailMessage) { - this(Integer.toString(detailMessage)); - } - - /** - *

- * Constructs an instance with a message that is the - * {@link String#valueOf(long)} of the long passed. - *

- * - * @param detailMessage The value to be converted into the message. - */ - public AssertionError(long detailMessage) { - this(Long.toString(detailMessage)); - } - - /** - *

- * Constructs an instance with a message that is the - * {@link String#valueOf(float)} of the float passed. - *

- * - * @param detailMessage The value to be converted into the message. - */ - public AssertionError(float detailMessage) { - this(Float.toString(detailMessage)); - } - - /** - *

- * Constructs an instance with a message that is the - * {@link String#valueOf(double)} of the double passed. - *

- * - * @param detailMessage The value to be converted into the message. - */ - public AssertionError(double detailMessage) { - this(Double.toString(detailMessage)); - } -} +/* + * Copyright (c) 2000, 2011, 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 java.lang; + +/** + * Thrown to indicate that an assertion has failed. + * + *

The seven one-argument public constructors provided by this + * class ensure that the assertion error returned by the invocation: + *

+ *     new AssertionError(expression)
+ * 
+ * has as its detail message the string conversion of + * expression (as defined in section 15.18.1.1 of + * The Java™ Language Specification), + * regardless of the type of expression. + * + * @since 1.4 + */ +public class AssertionError extends Error { + private static final long serialVersionUID = -5013299493970297370L; + + /** + * Constructs an AssertionError with no detail message. + */ + public AssertionError() { + } + + /** + * This internal constructor does no processing on its string argument, + * even if it is a null reference. The public constructors will + * never call this constructor with a null argument. + */ + private AssertionError(String detailMessage) { + super(detailMessage); + } + + /** + * Constructs an AssertionError with its detail message derived + * from the specified object, which is converted to a string as + * defined in section 15.18.1.1 of + * The Java™ Language Specification. + *

+ * If the specified object is an instance of {@code Throwable}, it + * becomes the cause of the newly constructed assertion error. + * + * @param detailMessage value to be used in constructing detail message + * @see Throwable#getCause() + */ + public AssertionError(Object detailMessage) { + this(String.valueOf(detailMessage)); + if (detailMessage instanceof Throwable) + initCause((Throwable) detailMessage); + } + + /** + * Constructs an AssertionError with its detail message derived + * from the specified boolean, which is converted to + * a string as defined in section 15.18.1.1 of + * The Java™ Language Specification. + * + * @param detailMessage value to be used in constructing detail message + */ + public AssertionError(boolean detailMessage) { + this(String.valueOf(detailMessage)); + } + + /** + * Constructs an AssertionError with its detail message derived + * from the specified char, which is converted to a + * string as defined in section 15.18.1.1 of + * The Java™ Language Specification. + * + * @param detailMessage value to be used in constructing detail message + */ + public AssertionError(char detailMessage) { + this(String.valueOf(detailMessage)); + } + + /** + * Constructs an AssertionError with its detail message derived + * from the specified int, which is converted to a + * string as defined in section 15.18.1.1 of + * The Java™ Language Specification. + * + * @param detailMessage value to be used in constructing detail message + */ + public AssertionError(int detailMessage) { + this(String.valueOf(detailMessage)); + } + + /** + * Constructs an AssertionError with its detail message derived + * from the specified long, which is converted to a + * string as defined in section 15.18.1.1 of + * The Java™ Language Specification. + * + * @param detailMessage value to be used in constructing detail message + */ + public AssertionError(long detailMessage) { + this(String.valueOf(detailMessage)); + } + + /** + * Constructs an AssertionError with its detail message derived + * from the specified float, which is converted to a + * string as defined in section 15.18.1.1 of + * The Java™ Language Specification. + * + * @param detailMessage value to be used in constructing detail message + */ + public AssertionError(float detailMessage) { + this(String.valueOf(detailMessage)); + } + + /** + * Constructs an AssertionError with its detail message derived + * from the specified double, which is converted to a + * string as defined in section 15.18.1.1 of + * The Java™ Language Specification. + * + * @param detailMessage value to be used in constructing detail message + */ + public AssertionError(double detailMessage) { + this(String.valueOf(detailMessage)); + } + + /** + * Constructs a new {@code AssertionError} with the specified + * detail message and cause. + * + *

Note that the detail message associated with + * {@code cause} is not automatically incorporated in + * this error's detail message. + * + * @param message the detail message, may be {@code null} + * @param cause the cause, may be {@code null} + * + * @since 1.7 + */ + public AssertionError(String message, Throwable cause) { + super(message, cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/Class.java b/sources/net.sf.j2s.java.core/src/java/lang/Class.java index c8dfba2f9..17577e824 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/Class.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/Class.java @@ -25,6 +25,7 @@ package java.lang; +import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Constructor; import java.lang.reflect.Field; @@ -34,12 +35,15 @@ import java.lang.reflect.Modifier; //import java.lang.reflect.Type; import java.lang.reflect.TypeVariable; +import java.net.URL; import java.util.Arrays; +import java.util.Enumeration; import java.util.HashMap; import java.util.Map; import javax.xml.bind.annotation.XmlRootElement; +import sun.misc.CompoundEnumeration; import swingjs.JSUtil; //import sun.misc.Unsafe; @@ -748,13 +752,17 @@ ClassLoader getClassLoader0() { * var me = this; * loader.getResourceAsStream$S = function(s) { return me.getResourceAsStream$S(s.indexOf("/") == 0 ? s : "/" + s) }; * loader.getResource$S = function(s) { return me.getResource$S(s.indexOf("/") == 0 ? s : "/" + s) }; - * + * loader.getResources$S = function(s) { return me.getResources$S(s) }; */ { } return loader; } - + + protected CompoundEnumeration> getResources(String name) throws IOException { + // sorry, just not implemented. + return new CompoundEnumeration((Enumeration[]) new Enumeration[] { null, java.util.Collections.emptyEnumeration() }); + } /** * Returns an array of {@code TypeVariable} objects that represent the type * variables declared by the generic declaration represented by this @@ -2871,7 +2879,9 @@ Method get(int i) { void removeByNameAndSignature(Method toRemove) { for (int i = 0; i < length; i++) { Method m = methods[i]; - if (m != null && m.getReturnType() == toRemove.getReturnType() && m.getName() == toRemove.getName() + if (m != null + //&& m.getReturnType() == toRemove.getReturnType() + && m.getName() == toRemove.getName() && arrayContentsEq(m.getParameterTypes(), toRemove.getParameterTypes())) { methods[i] = null; } diff --git a/sources/net.sf.j2s.java.core/src/java/lang/ClassNotFoundException.java b/sources/net.sf.j2s.java.core/src/java/lang/ClassNotFoundException.java index 89e1985d6..c3a0e5cb6 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/ClassNotFoundException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/ClassNotFoundException.java @@ -19,7 +19,7 @@ /** * This exception is thrown when a classloader is unable to find a class. */ -public class ClassNotFoundException extends Exception { +public class ClassNotFoundException extends ReflectiveOperationException { private static final long serialVersionUID = 9176873029745254542L; diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessError.java b/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessError.java index cd0a944c0..ce045cd7f 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessError.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessError.java @@ -1,46 +1,58 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This error is thrown when the VM notices that a an attempt is being made to - * access a field which is not accessable from where it is referenced. - *

- * Note that this can only occur when inconsistant class files are being loaded. - */ -public class IllegalAccessError extends IncompatibleClassChangeError { - - private static final long serialVersionUID = -8988904074992417891L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IllegalAccessError() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IllegalAccessError(String detailMessage) { - super(detailMessage); - } -} +/* + * Copyright (c) 1995, 2008, 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 java.lang; + +/** + * Thrown if an application attempts to access or modify a field, or + * to call a method that it does not have access to. + *

+ * Normally, this error is caught by the compiler; this error can + * only occur at run time if the definition of a class has + * incompatibly changed. + * + * @author unascribed + * @since JDK1.0 + */ +public class IllegalAccessError extends IncompatibleClassChangeError { + private static final long serialVersionUID = -8988904074992417891L; + + /** + * Constructs an IllegalAccessError with no detail message. + */ + public IllegalAccessError() { + super(); + } + + /** + * Constructs an IllegalAccessError with the specified + * detail message. + * + * @param s the detail message. + */ + public IllegalAccessError(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessException.java b/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessException.java index 57b107aad..c7b1df8b8 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IllegalAccessException.java @@ -1,46 +1,78 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This exception is thrown when a program attempts to access a field or method - * which is not accessible from the location where the reference is made. - * - */ -public class IllegalAccessException extends Exception { - - private static final long serialVersionUID = 6616958222490762034L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IllegalAccessException() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IllegalAccessException(String detailMessage) { - super(detailMessage); - } - -} +/* + * Copyright (c) 1995, 2008, 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 java.lang; + +/** + * An IllegalAccessException is thrown when an application tries + * to reflectively create an instance (other than an array), + * set or get a field, or invoke a method, but the currently + * executing method does not have access to the definition of + * the specified class, field, method or constructor. + * + * @author unascribed + * @see Class#newInstance() + * @see java.lang.reflect.Field#set(Object, Object) + * @see java.lang.reflect.Field#setBoolean(Object, boolean) + * @see java.lang.reflect.Field#setByte(Object, byte) + * @see java.lang.reflect.Field#setShort(Object, short) + * @see java.lang.reflect.Field#setChar(Object, char) + * @see java.lang.reflect.Field#setInt(Object, int) + * @see java.lang.reflect.Field#setLong(Object, long) + * @see java.lang.reflect.Field#setFloat(Object, float) + * @see java.lang.reflect.Field#setDouble(Object, double) + * @see java.lang.reflect.Field#get(Object) + * @see java.lang.reflect.Field#getBoolean(Object) + * @see java.lang.reflect.Field#getByte(Object) + * @see java.lang.reflect.Field#getShort(Object) + * @see java.lang.reflect.Field#getChar(Object) + * @see java.lang.reflect.Field#getInt(Object) + * @see java.lang.reflect.Field#getLong(Object) + * @see java.lang.reflect.Field#getFloat(Object) + * @see java.lang.reflect.Field#getDouble(Object) + * @see java.lang.reflect.Method#invoke(Object, Object[]) + * @see java.lang.reflect.Constructor#newInstance(Object[]) + * @since JDK1.0 + */ +public class IllegalAccessException extends ReflectiveOperationException { + private static final long serialVersionUID = 6616958222490762034L; + + /** + * Constructs an IllegalAccessException without a + * detail message. + */ + public IllegalAccessException() { + super(); + } + + /** + * Constructs an IllegalAccessException with a detail message. + * + * @param s the detail message. + */ + public IllegalAccessException(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IllegalArgumentException.java b/sources/net.sf.j2s.java.core/src/java/lang/IllegalArgumentException.java index 094a06af1..c29a9d574 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IllegalArgumentException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IllegalArgumentException.java @@ -1,63 +1,94 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This runtime exception is thrown when a method is invoked with an argument - * which it can not reasonably deal with. - */ -public class IllegalArgumentException extends RuntimeException { - - private static final long serialVersionUID = -5365630128856068164L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IllegalArgumentException() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IllegalArgumentException(String detailMessage) { - super(detailMessage); - } - - /** - *

Constructs a new instance with a message and cause.

- * @param message The message to assign to this exception. - * @param cause The optional cause of this exception; may be null. - * @since 1.5 - */ - public IllegalArgumentException(String message, Throwable cause) { - super(message, cause); - } - - /** - *

Constructs a new instance with a cause.

- * @param cause The optional cause of this exception; may be null. - * @since 1.5 - */ - public IllegalArgumentException(Throwable cause) { - super((cause == null ? null : cause.toString()), cause); - } -} +/* + * Copyright (c) 1994, 2012, 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 java.lang; + +/** + * Thrown to indicate that a method has been passed an illegal or + * inappropriate argument. + * + * @author unascribed + * @since JDK1.0 + */ +public +class IllegalArgumentException extends RuntimeException { + /** + * Constructs an IllegalArgumentException with no + * detail message. + */ + public IllegalArgumentException() { + super(); + } + + /** + * Constructs an IllegalArgumentException with the + * specified detail message. + * + * @param s the detail message. + */ + public IllegalArgumentException(String s) { + super(s); + } + + /** + * Constructs a new exception with the specified detail message and + * cause. + * + *

Note that the detail message associated with cause is + * not automatically incorporated in this exception's detail + * message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link Throwable#getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link Throwable#getCause()} method). (A null value + * is permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.5 + */ + public IllegalArgumentException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified cause and a detail + * message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than + * wrappers for other throwables (for example, {@link + * java.security.PrivilegedActionException}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link Throwable#getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.5 + */ + public IllegalArgumentException(Throwable cause) { + super(cause); + } + + private static final long serialVersionUID = -5365630128856068164L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IllegalMonitorStateException.java b/sources/net.sf.j2s.java.core/src/java/lang/IllegalMonitorStateException.java index c7e95e6de..39850664b 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IllegalMonitorStateException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IllegalMonitorStateException.java @@ -1,45 +1,62 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This runtime exception is thrown when a monitor operation is attempted when - * the monitor is not in the correct state, for example when a thread attempts - * to exit a monitor which it did not own. - */ -public class IllegalMonitorStateException extends RuntimeException { - - private static final long serialVersionUID = 3713306369498869069L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IllegalMonitorStateException() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IllegalMonitorStateException(String detailMessage) { - super(detailMessage); - } -} +/* + * Copyright (c) 1995, 2008, 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 java.lang; + +/** + * Thrown to indicate that a thread has attempted to wait on an + * object's monitor or to notify other threads waiting on an object's + * monitor without owning the specified monitor. + * + * @author unascribed + * @see java.lang.Object#notify() + * @see java.lang.Object#notifyAll() + * @see java.lang.Object#wait() + * @see java.lang.Object#wait(long) + * @see java.lang.Object#wait(long, int) + * @since JDK1.0 + */ +public +class IllegalMonitorStateException extends RuntimeException { + private static final long serialVersionUID = 3713306369498869069L; + + /** + * Constructs an IllegalMonitorStateException with no + * detail message. + */ + public IllegalMonitorStateException() { + super(); + } + + /** + * Constructs an IllegalMonitorStateException with the + * specified detail message. + * + * @param s the detail message. + */ + public IllegalMonitorStateException(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IllegalStateException.java b/sources/net.sf.j2s.java.core/src/java/lang/IllegalStateException.java index ec34bd0a0..9c0c06a60 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IllegalStateException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IllegalStateException.java @@ -1,63 +1,97 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This runtime exception is thrown when an action is attempted at a time when - * the virtual machine is not in the correct state. - */ -public class IllegalStateException extends RuntimeException { - - private static final long serialVersionUID = -1848914673093119416L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IllegalStateException() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IllegalStateException(String detailMessage) { - super(detailMessage); - } - - /** - *

Constructs a new instance with a message and cause.

- * @param message The message to assign to this exception. - * @param cause The optional cause of this exception; may be null. - * @since 1.5 - */ - public IllegalStateException(String message, Throwable cause) { - super(message, cause); - } - - /** - *

Constructs a new instance with a cause.

- * @param cause The optional cause of this exception; may be null. - * @since 1.5 - */ - public IllegalStateException(Throwable cause) { - super((cause == null ? null : cause.toString()), cause); - } -} +/* + * Copyright (c) 1996, 2003, 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 java.lang; + +/** + * Signals that a method has been invoked at an illegal or + * inappropriate time. In other words, the Java environment or + * Java application is not in an appropriate state for the requested + * operation. + * + * @author Jonni Kanerva + * @since JDK1.1 + */ +public +class IllegalStateException extends RuntimeException { + /** + * Constructs an IllegalStateException with no detail message. + * A detail message is a String that describes this particular exception. + */ + public IllegalStateException() { + super(); + } + + /** + * Constructs an IllegalStateException with the specified detail + * message. A detail message is a String that describes this particular + * exception. + * + * @param s the String that contains a detailed message + */ + public IllegalStateException(String s) { + super(s); + } + + /** + * Constructs a new exception with the specified detail message and + * cause. + * + *

Note that the detail message associated with cause is + * not automatically incorporated in this exception's detail + * message. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link Throwable#getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link Throwable#getCause()} method). (A null value + * is permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.5 + */ + public IllegalStateException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Constructs a new exception with the specified cause and a detail + * message of (cause==null ? null : cause.toString()) (which + * typically contains the class and detail message of cause). + * This constructor is useful for exceptions that are little more than + * wrappers for other throwables (for example, {@link + * java.security.PrivilegedActionException}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link Throwable#getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @since 1.5 + */ + public IllegalStateException(Throwable cause) { + super(cause); + } + + static final long serialVersionUID = -1848914673093119416L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IllegalThreadStateException.java b/sources/net.sf.j2s.java.core/src/java/lang/IllegalThreadStateException.java index 3e63d7e34..c59ab5987 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IllegalThreadStateException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IllegalThreadStateException.java @@ -1,44 +1,59 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This runtime exception is thrown when an operation is attempted which is not - * possible given the state that the executing thread is in. - */ -public class IllegalThreadStateException extends IllegalArgumentException { - - private static final long serialVersionUID = -7626246362397460174L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IllegalThreadStateException() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IllegalThreadStateException(String detailMessage) { - super(detailMessage); - } -} +/* + * Copyright (c) 1994, 2008, 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 java.lang; + +/** + * Thrown to indicate that a thread is not in an appropriate state + * for the requested operation. See, for example, the + * suspend and resume methods in class + * Thread. + * + * @author unascribed + * @see java.lang.Thread#resume() + * @see java.lang.Thread#suspend() + * @since JDK1.0 + */ +public class IllegalThreadStateException extends IllegalArgumentException { + private static final long serialVersionUID = -7626246362397460174L; + + /** + * Constructs an IllegalThreadStateException with no + * detail message. + */ + public IllegalThreadStateException() { + super(); + } + + /** + * Constructs an IllegalThreadStateException with the + * specified detail message. + * + * @param s the detail message. + */ + public IllegalThreadStateException(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IncompatibleClassChangeError.java b/sources/net.sf.j2s.java.core/src/java/lang/IncompatibleClassChangeError.java index 8709024d5..edffaee63 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IncompatibleClassChangeError.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IncompatibleClassChangeError.java @@ -1,46 +1,57 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This class is the superclass of all classes which represent errors which - * occur when inconsistant class files are loaded into the same running image. - * - * @see Error - */ -public class IncompatibleClassChangeError extends LinkageError { - - private static final long serialVersionUID = -4914975503642802119L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IncompatibleClassChangeError() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IncompatibleClassChangeError(String detailMessage) { - super(detailMessage); - } -} +/* + * Copyright (c) 1994, 2008, 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 java.lang; + +/** + * Thrown when an incompatible class change has occurred to some class + * definition. The definition of some class, on which the currently + * executing method depends, has since changed. + * + * @author unascribed + * @since JDK1.0 + */ +public +class IncompatibleClassChangeError extends LinkageError { + private static final long serialVersionUID = -4914975503642802119L; + + /** + * Constructs an IncompatibleClassChangeError with no + * detail message. + */ + public IncompatibleClassChangeError () { + super(); + } + + /** + * Constructs an IncompatibleClassChangeError with the + * specified detail message. + * + * @param s the detail message. + */ + public IncompatibleClassChangeError(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/IndexOutOfBoundsException.java b/sources/net.sf.j2s.java.core/src/java/lang/IndexOutOfBoundsException.java index 3b18f8a3f..4dc794848 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/IndexOutOfBoundsException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/IndexOutOfBoundsException.java @@ -1,45 +1,58 @@ -/* Copyright 1998, 2002 The Apache Software Foundation or its licensors, as applicable - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package java.lang; - - -/** - * This runtime exception is thrown when a program attempts to access a value in - * an indexable collection using a value which is outside the possible range of - * indices. - */ -public class IndexOutOfBoundsException extends RuntimeException { - - private static final long serialVersionUID = 234122996006267687L; - - /** - * Constructs a new instance of this class with its walkback filled in. - */ - public IndexOutOfBoundsException() { - super(); - } - - /** - * Constructs a new instance of this class with its walkback and message - * filled in. - * - * @param detailMessage - * String The detail message for the exception. - */ - public IndexOutOfBoundsException(String detailMessage) { - super(detailMessage); - } -} +/* + * Copyright (c) 1995, 2008, 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 java.lang; + +/** + * Thrown to indicate that an index of some sort (such as to an array, to a + * string, or to a vector) is out of range. + *

+ * Applications can subclass this class to indicate similar exceptions. + * + * @author Frank Yellin + * @since JDK1.0 + */ +public +class IndexOutOfBoundsException extends RuntimeException { + private static final long serialVersionUID = 234122996006267687L; + + /** + * Constructs an IndexOutOfBoundsException with no + * detail message. + */ + public IndexOutOfBoundsException() { + super(); + } + + /** + * Constructs an IndexOutOfBoundsException with the + * specified detail message. + * + * @param s the detail message. + */ + public IndexOutOfBoundsException(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/InstantiationException.java b/sources/net.sf.j2s.java.core/src/java/lang/InstantiationException.java index 9eb3f14b9..bd259ee4e 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/InstantiationException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/InstantiationException.java @@ -21,7 +21,7 @@ * which is not accessible from the location where the reference is made. * */ -public class InstantiationException extends Exception { +public class InstantiationException extends ReflectiveOperationException { private static final long serialVersionUID = -8441929162975509110L; /** diff --git a/sources/net.sf.j2s.java.core/src/java/lang/NoSuchFieldException.java b/sources/net.sf.j2s.java.core/src/java/lang/NoSuchFieldException.java index b85e80ad6..e999795ed 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/NoSuchFieldException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/NoSuchFieldException.java @@ -20,7 +20,7 @@ * This exception is thrown when a program attempts to access a field which does * not exist in a class */ -public class NoSuchFieldException extends java.lang.Exception { +public class NoSuchFieldException extends ReflectiveOperationException { private static final long serialVersionUID = -6143714805279938260L; diff --git a/sources/net.sf.j2s.java.core/src/java/lang/NoSuchMethodException.java b/sources/net.sf.j2s.java.core/src/java/lang/NoSuchMethodException.java index e3a4b5c4c..cad64f0a5 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/NoSuchMethodException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/NoSuchMethodException.java @@ -20,7 +20,7 @@ * This exception is thrown when a program attempts to access a method which * does not exist in a class. */ -public class NoSuchMethodException extends java.lang.Exception { +public class NoSuchMethodException extends ReflectiveOperationException { private static final long serialVersionUID = 5034388446362600923L; diff --git a/sources/net.sf.j2s.java.core/src/java/lang/RuntimePermission.java b/sources/net.sf.j2s.java.core/src/java/lang/RuntimePermission.java new file mode 100644 index 000000000..4e74e3805 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/lang/RuntimePermission.java @@ -0,0 +1,384 @@ +/* + * Copyright (c) 1997, 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 java.lang; + +import java.security.BasicPermission; + +/** + * This class is for runtime permissions. A RuntimePermission + * contains a name (also referred to as a "target name") but + * no actions list; you either have the named permission + * or you don't. + * + *

+ * The target name is the name of the runtime permission (see below). The + * naming convention follows the hierarchical property naming convention. + * Also, an asterisk + * may appear at the end of the name, following a ".", or by itself, to + * signify a wildcard match. For example: "loadLibrary.*" and "*" signify a + * wildcard match, while "*loadLibrary" and "a*b" do not. + *

+ * The following table lists all the possible RuntimePermission target names, + * and for each provides a description of what the permission allows + * and a discussion of the risks of granting code the permission. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Permission Target NameWhat the Permission AllowsRisks of Allowing this Permission
createClassLoaderCreation of a class loaderThis is an extremely dangerous permission to grant. + * Malicious applications that can instantiate their own class + * loaders could then load their own rogue classes into the system. + * These newly loaded classes could be placed into any protection + * domain by the class loader, thereby automatically granting the + * classes the permissions for that domain.
getClassLoaderRetrieval of a class loader (e.g., the class loader for the calling + * class)This would grant an attacker permission to get the + * class loader for a particular class. This is dangerous because + * having access to a class's class loader allows the attacker to + * load other classes available to that class loader. The attacker + * would typically otherwise not have access to those classes.
setContextClassLoaderSetting of the context class loader used by a threadThe context class loader is used by system code and extensions + * when they need to lookup resources that might not exist in the system + * class loader. Granting setContextClassLoader permission would allow + * code to change which context class loader is used + * for a particular thread, including system threads.
enableContextClassLoaderOverrideSubclass implementation of the thread context class loader methodsThe context class loader is used by system code and extensions + * when they need to lookup resources that might not exist in the system + * class loader. Granting enableContextClassLoaderOverride permission would allow + * a subclass of Thread to override the methods that are used + * to get or set the context class loader for a particular thread.
closeClassLoaderClosing of a ClassLoaderGranting this permission allows code to close any URLClassLoader + * that it has a reference to.
setSecurityManagerSetting of the security manager (possibly replacing an existing one) + * The security manager is a class that allows + * applications to implement a security policy. Granting the setSecurityManager + * permission would allow code to change which security manager is used by + * installing a different, possibly less restrictive security manager, + * thereby bypassing checks that would have been enforced by the original + * security manager.
createSecurityManagerCreation of a new security managerThis gives code access to protected, sensitive methods that may + * disclose information about other classes or the execution stack.
getenv.{variable name}Reading of the value of the specified environment variableThis would allow code to read the value, or determine the + * existence, of a particular environment variable. This is + * dangerous if the variable contains confidential data.
exitVM.{exit status}Halting of the Java Virtual Machine with the specified exit statusThis allows an attacker to mount a denial-of-service attack + * by automatically forcing the virtual machine to halt. + * Note: The "exitVM.*" permission is automatically granted to all code + * loaded from the application class path, thus enabling applications + * to terminate themselves. Also, the "exitVM" permission is equivalent to + * "exitVM.*".
shutdownHooksRegistration and cancellation of virtual-machine shutdown hooksThis allows an attacker to register a malicious shutdown + * hook that interferes with the clean shutdown of the virtual machine.
setFactorySetting of the socket factory used by ServerSocket or Socket, + * or of the stream handler factory used by URLThis allows code to set the actual implementation + * for the socket, server socket, stream handler, or RMI socket factory. + * An attacker may set a faulty implementation which mangles the data + * stream.
setIOSetting of System.out, System.in, and System.errThis allows changing the value of the standard system streams. + * An attacker may change System.in to monitor and + * steal user input, or may set System.err to a "null" OutputStream, + * which would hide any error messages sent to System.err.
modifyThreadModification of threads, e.g., via calls to Thread + * interrupt, stop, suspend, + * resume, setDaemon, setPriority, + * setName and setUncaughtExceptionHandler + * methodsThis allows an attacker to modify the behaviour of + * any thread in the system.
stopThreadStopping of threads via calls to the Thread stop + * methodThis allows code to stop any thread in the system provided that it is + * already granted permission to access that thread. + * This poses as a threat, because that code may corrupt the system by + * killing existing threads.
modifyThreadGroupmodification of thread groups, e.g., via calls to ThreadGroup + * destroy, getParent, resume, + * setDaemon, setMaxPriority, stop, + * and suspend methodsThis allows an attacker to create thread groups and + * set their run priority.
getProtectionDomainRetrieval of the ProtectionDomain for a classThis allows code to obtain policy information + * for a particular code source. While obtaining policy information + * does not compromise the security of the system, it does give + * attackers additional information, such as local file names for + * example, to better aim an attack.
getFileSystemAttributesRetrieval of file system attributesThis allows code to obtain file system information such as disk usage + * or disk space available to the caller. This is potentially dangerous + * because it discloses information about the system hardware + * configuration and some information about the caller's privilege to + * write files.
readFileDescriptorReading of file descriptorsThis would allow code to read the particular file associated + * with the file descriptor read. This is dangerous if the file + * contains confidential data.
writeFileDescriptorWriting to file descriptorsThis allows code to write to a particular file associated + * with the descriptor. This is dangerous because it may allow + * malicious code to plant viruses or at the very least, fill up + * your entire disk.
loadLibrary.{library name}Dynamic linking of the specified libraryIt is dangerous to allow an applet permission to load native code + * libraries, because the Java security architecture is not designed to and + * does not prevent malicious behavior at the level of native code.
accessClassInPackage.{package name}Access to the specified package via a class loader's + * loadClass method when that class loader calls + * the SecurityManager checkPackageAccess methodThis gives code access to classes in packages + * to which it normally does not have access. Malicious code + * may use these classes to help in its attempt to compromise + * security in the system.
defineClassInPackage.{package name}Definition of classes in the specified package, via a class + * loader's defineClass method when that class loader calls + * the SecurityManager checkPackageDefinition method.This grants code permission to define a class + * in a particular package. This is dangerous because malicious + * code with this permission may define rogue classes in + * trusted packages like java.security or java.lang, + * for example.
accessDeclaredMembersAccess to the declared members of a classThis grants code permission to query a class for its public, + * protected, default (package) access, and private fields and/or + * methods. Although the code would have + * access to the private and protected field and method names, it would not + * have access to the private/protected field data and would not be able + * to invoke any private methods. Nevertheless, malicious code + * may use this information to better aim an attack. + * Additionally, it may invoke any public methods and/or access public fields + * in the class. This could be dangerous if + * the code would normally not be able to invoke those methods and/or + * access the fields because + * it can't cast the object to the class/interface with those methods + * and fields. +
queuePrintJobInitiation of a print job requestThis could print sensitive information to a printer, + * or simply waste paper.
getStackTraceRetrieval of the stack trace information of another thread.This allows retrieval of the stack trace information of + * another thread. This might allow malicious code to monitor the + * execution of threads and discover vulnerabilities in applications.
setDefaultUncaughtExceptionHandlerSetting the default handler to be used when a thread + * terminates abruptly due to an uncaught exceptionThis allows an attacker to register a malicious + * uncaught exception handler that could interfere with termination + * of a thread
preferencesRepresents the permission required to get access to the + * java.util.prefs.Preferences implementations user or system root + * which in turn allows retrieval or update operations within the + * Preferences persistent backing store.) This permission allows the user to read from or write to the + * preferences backing store if the user running the code has + * sufficient OS privileges to read/write to that backing store. + * The actual backing store may reside within a traditional filesystem + * directory or within a registry depending on the platform OS
usePolicyGranting this permission disables the Java Plug-In's default + * security prompting behavior.For more information, refer to Java Plug-In's guides, + * Applet Security Basics and + * usePolicy Permission.
+ * + * @see java.security.BasicPermission + * @see java.security.Permission + * @see java.security.Permissions + * @see java.security.PermissionCollection + * @see java.lang.SecurityManager + * + * + * @author Marianne Mueller + * @author Roland Schemers + */ + +public final class RuntimePermission extends BasicPermission { + + private static final long serialVersionUID = 7399184964622342223L; + + /** + * Creates a new RuntimePermission with the specified name. + * The name is the symbolic name of the RuntimePermission, such as + * "exit", "setFactory", etc. An asterisk + * may appear at the end of the name, following a ".", or by itself, to + * signify a wildcard match. + * + * @param name the name of the RuntimePermission. + * + * @throws NullPointerException if name is null. + * @throws IllegalArgumentException if name is empty. + */ + + public RuntimePermission(String name) + { + super(name); + } + + /** + * Creates a new RuntimePermission object with the specified name. + * The name is the symbolic name of the RuntimePermission, and the + * actions String is currently unused and should be null. + * + * @param name the name of the RuntimePermission. + * @param actions should be null. + * + * @throws NullPointerException if name is null. + * @throws IllegalArgumentException if name is empty. + */ + + public RuntimePermission(String name, String actions) + { + super(name, actions); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/lang/StringCoding.java b/sources/net.sf.j2s.java.core/src/java/lang/StringCoding.java index fdcce0c81..9c0ba4d5f 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/StringCoding.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/StringCoding.java @@ -26,22 +26,22 @@ package java.lang; import java.io.UnsupportedEncodingException; -import java.lang.ref.SoftReference; import java.nio.ByteBuffer; import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; import java.nio.charset.Charset; import java.nio.charset.CharsetDecoder; import java.nio.charset.CharsetEncoder; -import java.nio.charset.CharacterCodingException; import java.nio.charset.CoderResult; import java.nio.charset.CodingErrorAction; import java.nio.charset.IllegalCharsetNameException; import java.nio.charset.UnsupportedCharsetException; import java.util.Arrays; + import sun.misc.MessageUtils; -import sun.nio.cs.HistoricallyNamedCharset; import sun.nio.cs.ArrayDecoder; import sun.nio.cs.ArrayEncoder; +import sun.nio.cs.HistoricallyNamedCharset; /** * Utility class for string encoding and decoding. diff --git a/sources/net.sf.j2s.java.core/src/java/lang/reflect/InvocationTargetException.java b/sources/net.sf.j2s.java.core/src/java/lang/reflect/InvocationTargetException.java index b2ebfd4aa..186ba5af4 100644 --- a/sources/net.sf.j2s.java.core/src/java/lang/reflect/InvocationTargetException.java +++ b/sources/net.sf.j2s.java.core/src/java/lang/reflect/InvocationTargetException.java @@ -23,7 +23,7 @@ * @see java.lang.reflect.Method#invoke * @see java.lang.reflect.Constructor#newInstance */ -public class InvocationTargetException extends Exception { +public class InvocationTargetException extends ReflectiveOperationException { private static final long serialVersionUID = 4085088731926701167L; diff --git a/sources/net.sf.j2s.java.core/src/java/nio/channels/spi/package.html b/sources/net.sf.j2s.java.core/src/java/nio/channels/spi/package.html deleted file mode 100644 index a6f8cbfdc..000000000 --- a/sources/net.sf.j2s.java.core/src/java/nio/channels/spi/package.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -Service-provider classes for the {@link java.nio.channels} package. - -

Only developers who are defining new selector providers or asynchronous -channel providers should need to make direct use of this package.

- -

Unless otherwise noted, passing a null argument to a constructor -or method in any class or interface in this package will cause a {@link -java.lang.NullPointerException NullPointerException} to be thrown. - - -@since 1.4 -@author Mark Reinhold -@author JSR-51 Expert Group - - - diff --git a/sources/net.sf.j2s.java.core/src/java/nio/charset/package.html b/sources/net.sf.j2s.java.core/src/java/nio/charset/package.html deleted file mode 100644 index 69b160b81..000000000 --- a/sources/net.sf.j2s.java.core/src/java/nio/charset/package.html +++ /dev/null @@ -1,88 +0,0 @@ - - - - - - - -Defines charsets, decoders, and encoders, for translating between bytes and -Unicode characters. - -

- - - - - - - - - - - - -

Class name

Description

{@link java.nio.charset.Charset}A named mapping between characters
and bytes
{@link java.nio.charset.CharsetDecoder}Decodes bytes into characters
{@link java.nio.charset.CharsetEncoder}  Encodes characters into bytes
{@link java.nio.charset.CoderResult}  Describes coder results
{@link java.nio.charset.CodingErrorAction}  Describes actions to take when
coding errors are detected
- -

A charset is named mapping between sequences of sixteen-bit Unicode -characters and sequences of bytes, in the sense defined in RFC 2278. A -decoder is an engine which transforms bytes in a specific charset into -characters, and an encoder is an engine which transforms characters into -bytes. Encoders and decoders operate on byte and character buffers. They are -collectively referred to as coders. - -

The {@link java.nio.charset.Charset} class defines methods for creating -coders for a given charset and for retrieving the various names associated with -a charset. It also defines static methods for testing whether a particular -charset is supported, for locating charset instances by name, and for -constructing a map that contains every charset for which support is available -in the current Java virtual machine. - -

Most users will not use these classes directly; instead they will use the -existing charset-related constructors and methods in the {@link -java.lang.String} class, together with the existing {@link -java.io.InputStreamReader} and {@link java.io.OutputStreamWriter} classes, all -of whose implementations have been reworked to make use of the charset -facilities defined in this package. A small number of changes have been made -to the {@link java.io.InputStreamReader} and {@link java.io.OutputStreamWriter} -classes in order to allow explicit charset objects to be specified in the -construction of instances of those classes. - -

Support for new charsets can be made available via the interface defined in -the {@link java.nio.charset.spi.CharsetProvider} class in the {@link -java.nio.charset.spi} package. - -

Unless otherwise noted, passing a null argument to a constructor -or method in any class or interface in this package will cause a {@link -java.lang.NullPointerException NullPointerException} to be thrown. - - -@since 1.4 -@author Mark Reinhold -@author JSR-51 Expert Group - - - diff --git a/sources/net.sf.j2s.java.core/src/java/nio/charset/spi/package.html b/sources/net.sf.j2s.java.core/src/java/nio/charset/spi/package.html deleted file mode 100644 index a7b7ab188..000000000 --- a/sources/net.sf.j2s.java.core/src/java/nio/charset/spi/package.html +++ /dev/null @@ -1,45 +0,0 @@ - - - - - - -Service-provider classes for the {@link java.nio.charset} package. - -

Only developers who are defining new charsets should need to make direct -use of this package.

- -

Unless otherwise noted, passing a null argument to a constructor -or method in any class or interface in this package will cause a {@link -java.lang.NullPointerException NullPointerException} to be thrown. - - -@since 1.4 -@author Mark Reinhold -@author JSR-51 Expert Group - - - diff --git a/sources/net.sf.j2s.java.core/src/java/security/AccessControlContext.java b/sources/net.sf.j2s.java.core/src/java/security/AccessControlContext.java index ccdd6aa84..d7606b995 100644 --- a/sources/net.sf.j2s.java.core/src/java/security/AccessControlContext.java +++ b/sources/net.sf.j2s.java.core/src/java/security/AccessControlContext.java @@ -1,7 +1,958 @@ +/* + * Copyright (c) 1997, 2015, 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 java.security; -public interface AccessControlContext { - - public boolean checkPermission(Object perm); +import java.util.ArrayList; +import java.util.List; +import sun.security.util.Debug; +import sun.security.util.SecurityConstants; + + +/** + * An AccessControlContext is used to make system resource access decisions + * based on the context it encapsulates. + * + *

More specifically, it encapsulates a context and + * has a single method, {@code checkPermission}, + * that is equivalent to the {@code checkPermission} method + * in the AccessController class, with one difference: The AccessControlContext + * {@code checkPermission} method makes access decisions based on the + * context it encapsulates, + * rather than that of the current execution thread. + * + *

Thus, the purpose of AccessControlContext is for those situations where + * a security check that should be made within a given context + * actually needs to be done from within a + * different context (for example, from within a worker thread). + * + *

An AccessControlContext is created by calling the + * {@code AccessController.getContext} method. + * The {@code getContext} method takes a "snapshot" + * of the current calling context, and places + * it in an AccessControlContext object, which it returns. A sample call is + * the following: + * + *

+ *   AccessControlContext acc = AccessController.getContext()
+ * 
+ * + *

+ * Code within a different context can subsequently call the + * {@code checkPermission} method on the + * previously-saved AccessControlContext object. A sample call is the + * following: + * + *

+ *   acc.checkPermission(permission)
+ * 
+ * + * @see AccessController + * + * @author Roland Schemers + */ + +public final class AccessControlContext { + + private ProtectionDomain context[]; + // isPrivileged and isAuthorized are referenced by the VM - do not remove + // or change their names + private boolean isPrivileged; + private boolean isAuthorized = true; +// +// // Note: This field is directly used by the virtual machine +// // native codes. Don't touch it. +// private AccessControlContext privilegedContext; +// +// private DomainCombiner combiner = null; +// +// // limited privilege scope +// private Permission permissions[]; +// private AccessControlContext parent; +// private boolean isWrapped; +// +// // is constrained by limited privilege scope? +// private boolean isLimited; +// private ProtectionDomain limitedContext[]; +// +// private static boolean debugInit = false; +// private static Debug debug = null; +// +// static Debug getDebug() +// { +// if (debugInit) +// return debug; +// else { +// if (Policy.isSet()) { +// debug = Debug.getInstance("access"); +// debugInit = true; +// } +// return debug; +// } +// } +// + /** + * Create an AccessControlContext with the given array of ProtectionDomains. + * Context must not be null. Duplicate domains will be removed from the + * context. + * + * @param context the ProtectionDomains associated with this context. + * The non-duplicate domains are copied from the array. Subsequent + * changes to the array will not affect this AccessControlContext. + * @throws NullPointerException if {@code context} is {@code null} + */ + public AccessControlContext(ProtectionDomain context[]) + { +// if (context.length == 0) { +// this.context = null; +// } else if (context.length == 1) { +// if (context[0] != null) { +// this.context = context.clone(); +// } else { +// this.context = null; +// } +// } else { +// List v = new ArrayList<>(context.length); +// for (int i =0; i< context.length; i++) { +// if ((context[i] != null) && (!v.contains(context[i]))) +// v.add(context[i]); +// } +// if (!v.isEmpty()) { +// this.context = new ProtectionDomain[v.size()]; +// this.context = v.toArray(this.context); +// } +// } + } + + /** + * Create a new {@code AccessControlContext} with the given + * {@code AccessControlContext} and {@code DomainCombiner}. + * This constructor associates the provided + * {@code DomainCombiner} with the provided + * {@code AccessControlContext}. + * + *

+ * + * @param acc the {@code AccessControlContext} associated + * with the provided {@code DomainCombiner}. + * + * @param combiner the {@code DomainCombiner} to be associated + * with the provided {@code AccessControlContext}. + * + * @exception NullPointerException if the provided + * {@code context} is {@code null}. + * + * @exception SecurityException if a security manager is installed and the + * caller does not have the "createAccessControlContext" + * {@link SecurityPermission} + * @since 1.3 + */ + public AccessControlContext(AccessControlContext acc, + DomainCombiner combiner) { + + this(acc, combiner, false); + } + + /** + * package private to allow calls from ProtectionDomain without performing + * the security check for {@linkplain SecurityConstants.CREATE_ACC_PERMISSION} + * permission + */ + AccessControlContext(AccessControlContext acc, + DomainCombiner combiner, + boolean preauthorized) { +// if (!preauthorized) { +// SecurityManager sm = System.getSecurityManager(); +// if (sm != null) { +// sm.checkPermission(SecurityConstants.CREATE_ACC_PERMISSION); +// this.isAuthorized = true; +// } +// } else { +// this.isAuthorized = true; +// } + + this.context = acc.context; +// +// // we do not need to run the combine method on the +// // provided ACC. it was already "combined" when the +// // context was originally retrieved. +// // +// // at this point in time, we simply throw away the old +// // combiner and use the newly provided one. +// this.combiner = combiner; + } + + /** + * package private for AccessController + * + * This "argument wrapper" context will be passed as the actual context + * parameter on an internal doPrivileged() call used in the implementation. + */ + AccessControlContext(ProtectionDomain caller, DomainCombiner combiner, + AccessControlContext parent, AccessControlContext context, + Permission[] perms) + { +// /* +// * Combine the domains from the doPrivileged() context into our +// * wrapper context, if necessary. +// */ +// ProtectionDomain[] callerPDs = null; +// if (caller != null) { +// callerPDs = new ProtectionDomain[] { caller }; +// } +// if (context != null) { +// if (combiner != null) { +// this.context = combiner.combine(callerPDs, context.context); +// } else { +// this.context = combine(callerPDs, context.context); +// } +// } else { +// /* +// * Call combiner even if there is seemingly nothing to combine. +// */ +// if (combiner != null) { +// this.context = combiner.combine(callerPDs, null); +// } else { +// this.context = combine(callerPDs, null); +// } +// } +// this.combiner = combiner; +// +// Permission[] tmp = null; +// if (perms != null) { +// tmp = new Permission[perms.length]; +// for (int i=0; i < perms.length; i++) { +// if (perms[i] == null) { +// throw new NullPointerException("permission can't be null"); +// } +// +// /* +// * An AllPermission argument is equivalent to calling +// * doPrivileged() without any limit permissions. +// */ +// if (perms[i].getClass() == AllPermission.class) { +// parent = null; +// } +// tmp[i] = perms[i]; +// } +// } +// +// /* +// * For a doPrivileged() with limited privilege scope, initialize +// * the relevant fields. +// * +// * The limitedContext field contains the union of all domains which +// * are enclosed by this limited privilege scope. In other words, +// * it contains all of the domains which could potentially be checked +// * if none of the limiting permissions implied a requested permission. +// */ +// if (parent != null) { +// this.limitedContext = combine(parent.context, parent.limitedContext); +// this.isLimited = true; +// this.isWrapped = true; +// this.permissions = tmp; +// this.parent = parent; +// this.privilegedContext = context; // used in checkPermission2() +// } +// this.isAuthorized = true; + } + + + /** + * package private constructor for AccessController.getContext() + */ + + AccessControlContext(ProtectionDomain context[], + boolean isPrivileged) + { + this.context = context; + this.isPrivileged = isPrivileged; + this.isAuthorized = true; + } + + /** + * Constructor for JavaSecurityAccess.doIntersectionPrivilege() + */ + AccessControlContext(ProtectionDomain[] context, + AccessControlContext privilegedContext) + { + this.context = context; + // this.privilegedContext = privilegedContext; + this.isPrivileged = true; + } + +// /** +// * Returns this context's context. +// */ +// ProtectionDomain[] getContext() { +// return context; +// } +// +// /** +// * Returns true if this context is privileged. +// */ +// boolean isPrivileged() +// { +// return isPrivileged; +// } + + /** + * get the assigned combiner from the privileged or inherited context + */ + DomainCombiner getAssignedCombiner() { +// AccessControlContext acc; +// if (isPrivileged) { +// acc = privilegedContext; +// } else { +// acc = AccessController.getInheritedAccessControlContext(); +// } +// if (acc != null) { +// return acc.combiner; +// } + return null; + } + + /** + * Get the {@code DomainCombiner} associated with this + * {@code AccessControlContext}. + * + *

+ * + * @return the {@code DomainCombiner} associated with this + * {@code AccessControlContext}, or {@code null} + * if there is none. + * + * @exception SecurityException if a security manager is installed and + * the caller does not have the "getDomainCombiner" + * {@link SecurityPermission} + * @since 1.3 + */ + public DomainCombiner getDomainCombiner() { + return null; +// SecurityManager sm = System.getSecurityManager(); +// if (sm != null) { +// sm.checkPermission(SecurityConstants.GET_COMBINER_PERMISSION); +// } +// return getCombiner(); + } + +// /** +// * package private for AccessController +// */ +// DomainCombiner getCombiner() { +// return null; +// } +// +// boolean isAuthorized() { +// return true; +// } +// + /** + * Determines whether the access request indicated by the + * specified permission should be allowed or denied, based on + * the security policy currently in effect, and the context in + * this object. The request is allowed only if every ProtectionDomain + * in the context implies the permission. Otherwise the request is + * denied. + * + *

+ * This method quietly returns if the access request + * is permitted, or throws a suitable AccessControlException otherwise. + * + * @param perm the requested permission. + * + * @exception AccessControlException if the specified permission + * is not permitted, based on the current security policy and the + * context encapsulated by this object. + * @exception NullPointerException if the permission to check for is null. + */ + public void checkPermission(Permission perm) + throws AccessControlException + { +// boolean dumpDebug = false; +// +// if (perm == null) { +// throw new NullPointerException("permission can't be null"); +// } +//// if (getDebug() != null) { +// // If "codebase" is not specified, we dump the info by default. +// dumpDebug = !Debug.isOn("codebase="); +// if (!dumpDebug) { +// // If "codebase" is specified, only dump if the specified code +// // value is in the stack. +// for (int i = 0; context != null && i < context.length; i++) { +// if (context[i].getCodeSource() != null && +// context[i].getCodeSource().getLocation() != null && +// Debug.isOn("codebase=" + context[i].getCodeSource().getLocation().toString())) { +// dumpDebug = true; +// break; +// } +// } +// } +// +// dumpDebug &= !Debug.isOn("permission=") || +// Debug.isOn("permission=" + perm.getClass().getCanonicalName()); +// +// if (dumpDebug && Debug.isOn("stack")) { +// Thread.dumpStack(); +// } +// +// if (dumpDebug && Debug.isOn("domain")) { +// if (context == null) { +// debug.println("domain (context is null)"); +// } else { +// for (int i=0; i< context.length; i++) { +// debug.println("domain "+i+" "+context[i]); +// } +// } +// } +// } +// +// /* +// * iterate through the ProtectionDomains in the context. +// * Stop at the first one that doesn't allow the +// * requested permission (throwing an exception). +// * +// */ +// +// /* if ctxt is null, all we had on the stack were system domains, +// or the first domain was a Privileged system domain. This +// is to make the common case for system code very fast */ +// +// if (context == null) { +// checkPermission2(perm); +// return; +// } +// +// for (int i=0; i< context.length; i++) { +// if (context[i] != null && !context[i].implies(perm)) { +// if (dumpDebug) { +// debug.println("access denied " + perm); +// } +// +// if (Debug.isOn("failure") && debug != null) { +// // Want to make sure this is always displayed for failure, +// // but do not want to display again if already displayed +// // above. +// if (!dumpDebug) { +// debug.println("access denied " + perm); +// } +// Thread.dumpStack(); +// final ProtectionDomain pd = context[i]; +// final Debug db = debug; +// AccessController.doPrivileged (new PrivilegedAction() { +// public Void run() { +// db.println("domain that failed "+pd); +// return null; +// } +// }); +// } +// throw new AccessControlException("access denied "+perm, perm); +// } +// } +// +// // allow if all of them allowed access +// if (dumpDebug) { +// debug.println("access allowed "+perm); +// } +// +// checkPermission2(perm); + } + + /* + * Check the domains associated with the limited privilege scope. + */ + private void checkPermission2(Permission perm) { +// if (!isLimited) { +// return; +// } +// +// /* +// * Check the doPrivileged() context parameter, if present. +// */ +// if (privilegedContext != null) { +// privilegedContext.checkPermission2(perm); +// } +// +// /* +// * Ignore the limited permissions and parent fields of a wrapper +// * context since they were already carried down into the unwrapped +// * context. +// */ +// if (isWrapped) { +// return; +// } +// +// /* +// * Try to match any limited privilege scope. +// */ +// if (permissions != null) { +// Class permClass = perm.getClass(); +// for (int i=0; i < permissions.length; i++) { +// Permission limit = permissions[i]; +// if (limit.getClass().equals(permClass) && limit.implies(perm)) { +// return; +// } +// } +// } +// +// /* +// * Check the limited privilege scope up the call stack or the inherited +// * parent thread call stack of this ACC. +// */ +// if (parent != null) { +// /* +// * As an optimization, if the parent context is the inherited call +// * stack context from a parent thread then checking the protection +// * domains of the parent context is redundant since they have +// * already been merged into the child thread's context by +// * optimize(). When parent is set to an inherited context this +// * context was not directly created by a limited scope +// * doPrivileged() and it does not have its own limited permissions. +// */ +// if (permissions == null) { +// parent.checkPermission2(perm); +// } else { +// parent.checkPermission(perm); +// } +// } + } + + /** + * Take the stack-based context (this) and combine it with the + * privileged or inherited context, if need be. Any limited + * privilege scope is flagged regardless of whether the assigned + * context comes from an immediately enclosing limited doPrivileged(). + * The limited privilege scope can indirectly flow from the inherited + * parent thread or an assigned context previously captured by getContext(). + */ + AccessControlContext optimize() { + return this; +// // the assigned (privileged or inherited) context +// AccessControlContext acc; +// DomainCombiner combiner = null; +// AccessControlContext parent = null; +// Permission[] permissions = null; +// +// if (isPrivileged) { +// acc = privilegedContext; +// if (acc != null) { +// /* +// * If the context is from a limited scope doPrivileged() then +// * copy the permissions and parent fields out of the wrapper +// * context that was created to hold them. +// */ +// if (acc.isWrapped) { +// permissions = acc.permissions; +// parent = acc.parent; +// } +// } +// } else { +// acc = AccessController.getInheritedAccessControlContext(); +// if (acc != null) { +// /* +// * If the inherited context is constrained by a limited scope +// * doPrivileged() then set it as our parent so we will process +// * the non-domain-related state. +// */ +// if (acc.isLimited) { +// parent = acc; +// } +// } +// } +// +// // this.context could be null if only system code is on the stack; +// // in that case, ignore the stack context +// boolean skipStack = (context == null); +// +// // acc.context could be null if only system code was involved; +// // in that case, ignore the assigned context +// boolean skipAssigned = (acc == null || acc.context == null); +// ProtectionDomain[] assigned = (skipAssigned) ? null : acc.context; +// ProtectionDomain[] pd; +// +// // if there is no enclosing limited privilege scope on the stack or +// // inherited from a parent thread +// boolean skipLimited = ((acc == null || !acc.isWrapped) && parent == null); +// +// if (acc != null && acc.combiner != null) { +// // let the assigned acc's combiner do its thing +// if (getDebug() != null) { +// debug.println("AccessControlContext invoking the Combiner"); +// } +// +// // No need to clone current and assigned.context +// // combine() will not update them +// combiner = acc.combiner; +// pd = combiner.combine(context, assigned); +// } else { +// if (skipStack) { +// if (skipAssigned) { +// calculateFields(acc, parent, permissions); +// return this; +// } else if (skipLimited) { +// return acc; +// } +// } else if (assigned != null) { +// if (skipLimited) { +// // optimization: if there is a single stack domain and +// // that domain is already in the assigned context; no +// // need to combine +// if (context.length == 1 && context[0] == assigned[0]) { +// return acc; +// } +// } +// } +// +// pd = combine(context, assigned); +// if (skipLimited && !skipAssigned && pd == assigned) { +// return acc; +// } else if (skipAssigned && pd == context) { +// calculateFields(acc, parent, permissions); +// return this; +// } +// } +// +// // Reuse existing ACC +// this.context = pd; +// this.combiner = combiner; +// this.isPrivileged = false; +// +// calculateFields(acc, parent, permissions); +// return this; + } + + +// /* +// * Combine the current (stack) and assigned domains. +// */ +// private static ProtectionDomain[] combine(ProtectionDomain[]current, +// ProtectionDomain[] assigned) { +// +// +// // current could be null if only system code is on the stack; +// // in that case, ignore the stack context +// boolean skipStack = (current == null); +// +// // assigned could be null if only system code was involved; +// // in that case, ignore the assigned context +// boolean skipAssigned = (assigned == null); +// +// int slen = (skipStack) ? 0 : current.length; +// +// // optimization: if there is no assigned context and the stack length +// // is less then or equal to two; there is no reason to compress the +// // stack context, it already is +// if (skipAssigned && slen <= 2) { +// return current; +// } +// +// int n = (skipAssigned) ? 0 : assigned.length; +// +// // now we combine both of them, and create a new context +// ProtectionDomain pd[] = new ProtectionDomain[slen + n]; +// +// // first copy in the assigned context domains, no need to compress +// if (!skipAssigned) { +// System.arraycopy(assigned, 0, pd, 0, n); +// } +// +// // now add the stack context domains, discarding nulls and duplicates +// outer: +// for (int i = 0; i < slen; i++) { +// ProtectionDomain sd = current[i]; +// if (sd != null) { +// for (int j = 0; j < n; j++) { +// if (sd == pd[j]) { +// continue outer; +// } +// } +// pd[n++] = sd; +// } +// } +// +// // if length isn't equal, we need to shorten the array +// if (n != pd.length) { +// // optimization: if we didn't really combine anything +// if (!skipAssigned && n == assigned.length) { +// return assigned; +// } else if (skipAssigned && n == slen) { +// return current; +// } +// ProtectionDomain tmp[] = new ProtectionDomain[n]; +// System.arraycopy(pd, 0, tmp, 0, n); +// pd = tmp; +// } +// +// return pd; +// } +// +// +// /* +// * Calculate the additional domains that could potentially be reached via +// * limited privilege scope. Mark the context as being subject to limited +// * privilege scope unless the reachable domains (if any) are already +// * contained in this domain context (in which case any limited +// * privilege scope checking would be redundant). +// */ +// private void calculateFields(AccessControlContext assigned, +// AccessControlContext parent, Permission[] permissions) +// { +// ProtectionDomain[] parentLimit = null; +// ProtectionDomain[] assignedLimit = null; +// ProtectionDomain[] newLimit; +// +// parentLimit = (parent != null)? parent.limitedContext: null; +// assignedLimit = (assigned != null)? assigned.limitedContext: null; +// newLimit = combine(parentLimit, assignedLimit); +// if (newLimit != null) { +// if (context == null || !containsAllPDs(newLimit, context)) { +// this.limitedContext = newLimit; +// this.permissions = permissions; +// this.parent = parent; +// this.isLimited = true; +// } +// } +// } +// + + /** + * Checks two AccessControlContext objects for equality. + * Checks that obj is + * an AccessControlContext and has the same set of ProtectionDomains + * as this context. + *

+ * @param obj the object we are testing for equality with this object. + * @return true if obj is an AccessControlContext, and has the + * same set of ProtectionDomains as this context, false otherwise. + */ + public boolean equals(Object obj) { + if (obj == this) + return true; + + if (! (obj instanceof AccessControlContext)) + return false; + + AccessControlContext that = (AccessControlContext) obj; + + if (!equalContext(that)) + return false; + + if (!equalLimitedContext(that)) + return false; + + return true; + } + + /* + * Compare for equality based on state that is free of limited + * privilege complications. + */ + private boolean equalContext(AccessControlContext that) { + if (!equalPDs(this.context, that.context)) + return false; + +// if (this.combiner == null && that.combiner != null) +// return false; +// +// if (this.combiner != null && !this.combiner.equals(that.combiner)) +// return false; + + return true; + } + + private boolean equalPDs(ProtectionDomain[] a, ProtectionDomain[] b) { + if (a == null) { + return (b == null); + } + + if (b == null) + return false; +// +// if (!(containsAllPDs(a, b) && containsAllPDs(b, a))) +// return false; + + return true; + } + + /* + * Compare for equality based on state that is captured during a + * call to AccessController.getContext() when a limited privilege + * scope is in effect. + */ + private boolean equalLimitedContext(AccessControlContext that) { + if (that == null) + return false; + return true; +// +// /* +// * If neither instance has limited privilege scope then we're done. +// */ +// if (!this.isLimited && !that.isLimited) +// return true; +// +// /* +// * If only one instance has limited privilege scope then we're done. +// */ +// if (!(this.isLimited && that.isLimited)) +// return false; +// +// /* +// * Wrapped instances should never escape outside the implementation +// * this class and AccessController so this will probably never happen +// * but it only makes any sense to compare if they both have the same +// * isWrapped state. +// */ +// if ((this.isWrapped && !that.isWrapped) || +// (!this.isWrapped && that.isWrapped)) { +// return false; +// } +// +// if (this.permissions == null && that.permissions != null) +// return false; +// +// if (this.permissions != null && that.permissions == null) +// return false; +// +// if (!(this.containsAllLimits(that) && that.containsAllLimits(this))) +// return false; +// +// /* +// * Skip through any wrapped contexts. +// */ +// AccessControlContext thisNextPC = getNextPC(this); +// AccessControlContext thatNextPC = getNextPC(that); +// +// /* +// * The protection domains and combiner of a privilegedContext are +// * not relevant because they have already been included in the context +// * of this instance by optimize() so we only care about any limited +// * privilege state they may have. +// */ +// if (thisNextPC == null && thatNextPC != null && thatNextPC.isLimited) +// return false; +// +// if (thisNextPC != null && !thisNextPC.equalLimitedContext(thatNextPC)) +// return false; +// +// if (this.parent == null && that.parent != null) +// return false; +// +// if (this.parent != null && !this.parent.equals(that.parent)) +// return false; +// +// return true; + } + +// /* +// * Follow the privilegedContext link making our best effort to skip +// * through any wrapper contexts. +// */ +// private static AccessControlContext getNextPC(AccessControlContext acc) { +// while (acc != null && acc.privilegedContext != null) { +// acc = acc.privilegedContext; +// if (!acc.isWrapped) +// return acc; +// } +// return null; +// } +// +// private static boolean containsAllPDs(ProtectionDomain[] thisContext, +// ProtectionDomain[] thatContext) { +// boolean match = false; +// +// // +// // ProtectionDomains within an ACC currently cannot be null +// // and this is enforced by the constructor and the various +// // optimize methods. However, historically this logic made attempts +// // to support the notion of a null PD and therefore this logic continues +// // to support that notion. +// ProtectionDomain thisPd; +// for (int i = 0; i < thisContext.length; i++) { +// match = false; +// if ((thisPd = thisContext[i]) == null) { +// for (int j = 0; (j < thatContext.length) && !match; j++) { +// match = (thatContext[j] == null); +// } +// } else { +// Class thisPdClass = thisPd.getClass(); +// ProtectionDomain thatPd; +// for (int j = 0; (j < thatContext.length) && !match; j++) { +// thatPd = thatContext[j]; +// +// // Class check required to avoid PD exposure (4285406) +// match = (thatPd != null && +// thisPdClass == thatPd.getClass() && thisPd.equals(thatPd)); +// } +// } +// if (!match) return false; +// } +// return match; +// } +// +// private boolean containsAllLimits(AccessControlContext that) { +// boolean match = false; +// Permission thisPerm; +// +// if (this.permissions == null && that.permissions == null) +// return true; +// +// for (int i = 0; i < this.permissions.length; i++) { +// Permission limit = this.permissions[i]; +// Class limitClass = limit.getClass(); +// match = false; +// for (int j = 0; (j < that.permissions.length) && !match; j++) { +// Permission perm = that.permissions[j]; +// match = (limitClass.equals(perm.getClass()) && +// limit.equals(perm)); +// } +// if (!match) return false; +// } +// return match; +// } +// + + /** + * Returns the hash code value for this context. The hash code + * is computed by exclusive or-ing the hash code of all the protection + * domains in the context together. + * + * @return a hash code value for this context. + */ + + public int hashCode() { + int hashCode = 0; + + if (context == null) + return hashCode; + + for (int i =0; i < context.length; i++) { + if (context[i] != null) + hashCode ^= context[i].hashCode(); + } + return hashCode; + } } diff --git a/sources/net.sf.j2s.java.core/src/java/security/AccessControlException.java b/sources/net.sf.j2s.java.core/src/java/security/AccessControlException.java index 20cb86379..a4f2a7803 100644 --- a/sources/net.sf.j2s.java.core/src/java/security/AccessControlException.java +++ b/sources/net.sf.j2s.java.core/src/java/security/AccessControlException.java @@ -1,12 +1,12 @@ /* - * Copyright 1997-2003 Sun Microsystems, Inc. All Rights Reserved. + * Copyright (c) 1997, 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. Sun designates this + * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided - * by Sun in the LICENSE file that accompanied this code. + * 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 @@ -18,9 +18,9 @@ * 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, - * CA 95054 USA or visit www.sun.com if you need additional information or - * have any questions. + * 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 java.security; @@ -40,16 +40,15 @@ * @author Roland Schemers */ -@SuppressWarnings("serial") public class AccessControlException extends SecurityException { -// private static final long serialVersionUID = 5138225684096988535L; + private static final long serialVersionUID = 5138225684096988535L; - // the permission that caused the exeception to be thrown. -// private Permission perm; + // the permission that caused the exception to be thrown. + private Permission perm; /** - * Constructs an AccessControlException with the + * Constructs an {@code AccessControlException} with the * specified, detailed message. * * @param s the detail message. @@ -57,27 +56,27 @@ public class AccessControlException extends SecurityException { public AccessControlException(String s) { super(s); } -// -// /** -// * Constructs an AccessControlException with the -// * specified, detailed message, and the requested permission that caused -// * the exception. -// * -// * @param s the detail message. -// * @param p the permission that caused the exception. -// */ -// public AccessControlException(String s, Permission p) { -// super(s); -// perm = p; -// } -// -// /** -// * Gets the Permission object associated with this exeception, or -// * null if there was no corresponding Permission object. -// * -// * @return the Permission object. -// */ -// public Permission getPermission() { -// return perm; -// } + + /** + * Constructs an {@code AccessControlException} with the + * specified, detailed message, and the requested permission that caused + * the exception. + * + * @param s the detail message. + * @param p the permission that caused the exception. + */ + public AccessControlException(String s, Permission p) { + super(s); + perm = p; + } + + /** + * Gets the Permission object associated with this exception, or + * null if there was no corresponding Permission object. + * + * @return the Permission object. + */ + public Permission getPermission() { + return perm; + } } diff --git a/sources/net.sf.j2s.java.core/src/java/security/AccessController.java b/sources/net.sf.j2s.java.core/src/java/security/AccessController.java index 0854d23b4..7a6036513 100644 --- a/sources/net.sf.j2s.java.core/src/java/security/AccessController.java +++ b/sources/net.sf.j2s.java.core/src/java/security/AccessController.java @@ -1,35 +1,897 @@ +/* + * Copyright (c) 1997, 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 java.security; -public class AccessController implements AccessControlContext { +import sun.security.util.Debug; +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; + +/** + *

The AccessController class is used for access control operations + * and decisions. + * + *

More specifically, the AccessController class is used for + * three purposes: + * + *

    + *
  • to decide whether an access to a critical system + * resource is to be allowed or denied, based on the security policy + * currently in effect, + *
  • to mark code as being "privileged", thus affecting subsequent + * access determinations, and + *
  • to obtain a "snapshot" of the current calling context so + * access-control decisions from a different context can be made with + * respect to the saved context.
+ * + *

The {@link #checkPermission(Permission) checkPermission} method + * determines whether the access request indicated by a specified + * permission should be granted or denied. A sample call appears + * below. In this example, {@code checkPermission} will determine + * whether or not to grant "read" access to the file named "testFile" in + * the "/temp" directory. + * + *

+ *
+ * FilePermission perm = new FilePermission("/temp/testFile", "read");
+ * AccessController.checkPermission(perm);
+ *
+ * 
+ * + *

If a requested access is allowed, + * {@code checkPermission} returns quietly. If denied, an + * AccessControlException is + * thrown. AccessControlException can also be thrown if the requested + * permission is of an incorrect type or contains an invalid value. + * Such information is given whenever possible. + * + * Suppose the current thread traversed m callers, in the order of caller 1 + * to caller 2 to caller m. Then caller m invoked the + * {@code checkPermission} method. + * The {@code checkPermission} method determines whether access + * is granted or denied based on the following algorithm: + * + *

 {@code
+ * for (int i = m; i > 0; i--) {
+ *
+ *     if (caller i's domain does not have the permission)
+ *         throw AccessControlException
+ *
+ *     else if (caller i is marked as privileged) {
+ *         if (a context was specified in the call to doPrivileged)
+ *             context.checkPermission(permission)
+ *         if (limited permissions were specified in the call to doPrivileged) {
+ *             for (each limited permission) {
+ *                 if (the limited permission implies the requested permission)
+ *                     return;
+ *             }
+ *         } else
+ *             return;
+ *     }
+ * }
+ *
+ * // Next, check the context inherited when the thread was created.
+ * // Whenever a new thread is created, the AccessControlContext at
+ * // that time is stored and associated with the new thread, as the
+ * // "inherited" context.
+ *
+ * inheritedContext.checkPermission(permission);
+ * }
+ * + *

A caller can be marked as being "privileged" + * (see {@link #doPrivileged(PrivilegedAction) doPrivileged} and below). + * When making access control decisions, the {@code checkPermission} + * method stops checking if it reaches a caller that + * was marked as "privileged" via a {@code doPrivileged} + * call without a context argument (see below for information about a + * context argument). If that caller's domain has the + * specified permission and at least one limiting permission argument (if any) + * implies the requested permission, no further checking is done and + * {@code checkPermission} + * returns quietly, indicating that the requested access is allowed. + * If that domain does not have the specified permission, an exception + * is thrown, as usual. If the caller's domain had the specified permission + * but it was not implied by any limiting permission arguments given in the call + * to {@code doPrivileged} then the permission checking continues + * until there are no more callers or another {@code doPrivileged} + * call matches the requested permission and returns normally. + * + *

The normal use of the "privileged" feature is as follows. If you + * don't need to return a value from within the "privileged" block, do + * the following: + * + *

 {@code
+ * somemethod() {
+ *     ...normal code here...
+ *     AccessController.doPrivileged(new PrivilegedAction() {
+ *         public Void run() {
+ *             // privileged code goes here, for example:
+ *             System.loadLibrary("awt");
+ *             return null; // nothing to return
+ *         }
+ *     });
+ *     ...normal code here...
+ * }}
+ * + *

+ * PrivilegedAction is an interface with a single method, named + * {@code run}. + * The above example shows creation of an implementation + * of that interface; a concrete implementation of the + * {@code run} method is supplied. + * When the call to {@code doPrivileged} is made, an + * instance of the PrivilegedAction implementation is passed + * to it. The {@code doPrivileged} method calls the + * {@code run} method from the PrivilegedAction + * implementation after enabling privileges, and returns the + * {@code run} method's return value as the + * {@code doPrivileged} return value (which is + * ignored in this example). + * + *

If you need to return a value, you can do something like the following: + * + *

 {@code
+ * somemethod() {
+ *     ...normal code here...
+ *     String user = AccessController.doPrivileged(
+ *         new PrivilegedAction() {
+ *         public String run() {
+ *             return System.getProperty("user.name");
+ *             }
+ *         });
+ *     ...normal code here...
+ * }}
+ * + *

If the action performed in your {@code run} method could + * throw a "checked" exception (those listed in the {@code throws} clause + * of a method), then you need to use the + * {@code PrivilegedExceptionAction} interface instead of the + * {@code PrivilegedAction} interface: + * + *

 {@code
+ * somemethod() throws FileNotFoundException {
+ *     ...normal code here...
+ *     try {
+ *         FileInputStream fis = AccessController.doPrivileged(
+ *         new PrivilegedExceptionAction() {
+ *             public FileInputStream run() throws FileNotFoundException {
+ *                 return new FileInputStream("someFile");
+ *             }
+ *         });
+ *     } catch (PrivilegedActionException e) {
+ *         // e.getException() should be an instance of FileNotFoundException,
+ *         // as only "checked" exceptions will be "wrapped" in a
+ *         // PrivilegedActionException.
+ *         throw (FileNotFoundException) e.getException();
+ *     }
+ *     ...normal code here...
+ *  }}
+ * + *

Be *very* careful in your use of the "privileged" construct, and + * always remember to make the privileged code section as small as possible. + * You can pass {@code Permission} arguments to further limit the + * scope of the "privilege" (see below). + * + * + *

Note that {@code checkPermission} always performs security checks + * within the context of the currently executing thread. + * Sometimes a security check that should be made within a given context + * will actually need to be done from within a + * different context (for example, from within a worker thread). + * The {@link #getContext() getContext} method and + * AccessControlContext class are provided + * for this situation. The {@code getContext} method takes a "snapshot" + * of the current calling context, and places + * it in an AccessControlContext object, which it returns. A sample call is + * the following: + * + *

+ *
+ * AccessControlContext acc = AccessController.getContext()
+ *
+ * 
+ * + *

+ * AccessControlContext itself has a {@code checkPermission} method + * that makes access decisions based on the context it encapsulates, + * rather than that of the current execution thread. + * Code within a different context can thus call that method on the + * previously-saved AccessControlContext object. A sample call is the + * following: + * + *

+ *
+ * acc.checkPermission(permission)
+ *
+ * 
+ * + *

There are also times where you don't know a priori which permissions + * to check the context against. In these cases you can use the + * doPrivileged method that takes a context. You can also limit the scope + * of the privileged code by passing additional {@code Permission} + * parameters. + * + *

 {@code
+ * somemethod() {
+ *     AccessController.doPrivileged(new PrivilegedAction() {
+ *         public Object run() {
+ *             // Code goes here. Any permission checks within this
+ *             // run method will require that the intersection of the
+ *             // caller's protection domain and the snapshot's
+ *             // context have the desired permission. If a requested
+ *             // permission is not implied by the limiting FilePermission
+ *             // argument then checking of the thread continues beyond the
+ *             // caller of doPrivileged.
+ *         }
+ *     }, acc, new FilePermission("/temp/*", read));
+ *     ...normal code here...
+ * }}
+ * 

Passing a limiting {@code Permission} argument of an instance of + * {@code AllPermission} is equivalent to calling the equivalent + * {@code doPrivileged} method without limiting {@code Permission} + * arguments. Passing a zero length array of {@code Permission} disables + * the code privileges so that checking always continues beyond the caller of + * that {@code doPrivileged} method. + * + * @see AccessControlContext + * + * @author Li Gong + * @author Roland Schemers + */ + +public final class AccessController { + + /** + * Don't allow anyone to instantiate an AccessController + */ + private AccessController() { } + + /** + * Performs the specified {@code PrivilegedAction} with privileges + * enabled. The action is performed with all of the permissions + * possessed by the caller's protection domain. + * + *

If the action's {@code run} method throws an (unchecked) + * exception, it will propagate through this method. + * + *

Note that any DomainCombiner associated with the current + * AccessControlContext will be ignored while the action is performed. + * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. + * + * @param action the action to be performed. + * + * @return the value returned by the action's {@code run} method. + * + * @exception NullPointerException if the action is {@code null} + * + * @see #doPrivileged(PrivilegedAction,AccessControlContext) + * @see #doPrivileged(PrivilegedExceptionAction) + * @see #doPrivilegedWithCombiner(PrivilegedAction) + * @see java.security.DomainCombiner + */ + + @CallerSensitive + public static T doPrivileged(PrivilegedAction action) { + return action.run(); + } + + /** + * Performs the specified {@code PrivilegedAction} with privileges + * enabled. The action is performed with all of the permissions + * possessed by the caller's protection domain. + * + *

If the action's {@code run} method throws an (unchecked) + * exception, it will propagate through this method. + * + *

This method preserves the current AccessControlContext's + * DomainCombiner (which may be null) while the action is performed. + * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. + * + * @param action the action to be performed. + * + * @return the value returned by the action's {@code run} method. + * + * @exception NullPointerException if the action is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see java.security.DomainCombiner + * + * @since 1.6 + */ + @CallerSensitive + public static T doPrivilegedWithCombiner(PrivilegedAction action) { + return action.run(); +// AccessControlContext acc = getStackAccessControlContext(); +// if (acc == null) { +// return AccessController.doPrivileged(action); +// } +// DomainCombiner dc = acc.getAssignedCombiner(); +// return AccessController.doPrivileged(action, +// preserveCombiner(dc, Reflection.getCallerClass())); + } + + + /** + * Performs the specified {@code PrivilegedAction} with privileges + * enabled and restricted by the specified {@code AccessControlContext}. + * The action is performed with the intersection of the permissions + * possessed by the caller's protection domain, and those possessed + * by the domains represented by the specified {@code AccessControlContext}. + *

+ * If the action's {@code run} method throws an (unchecked) exception, + * it will propagate through this method. + *

+ * If a security manager is installed and the specified + * {@code AccessControlContext} was not created by system code and the + * caller's {@code ProtectionDomain} has not been granted the + * {@literal "createAccessControlContext"} + * {@link java.security.SecurityPermission}, then the action is performed + * with no permissions. + * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. + * @param action the action to be performed. + * @param context an access control context + * representing the restriction to be applied to the + * caller's domain's privileges before performing + * the specified action. If the context is + * {@code null}, then no additional restriction is applied. + * + * @return the value returned by the action's {@code run} method. + * + * @exception NullPointerException if the action is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) + */ + @CallerSensitive + public static T doPrivileged(PrivilegedAction action, + AccessControlContext context) { + return action.run(); + } + + + /** + * Performs the specified {@code PrivilegedAction} with privileges + * enabled and restricted by the specified + * {@code AccessControlContext} and with a privilege scope limited + * by specified {@code Permission} arguments. + * + * The action is performed with the intersection of the permissions + * possessed by the caller's protection domain, and those possessed + * by the domains represented by the specified + * {@code AccessControlContext}. + *

+ * If the action's {@code run} method throws an (unchecked) exception, + * it will propagate through this method. + *

+ * If a security manager is installed and the specified + * {@code AccessControlContext} was not created by system code and the + * caller's {@code ProtectionDomain} has not been granted the + * {@literal "createAccessControlContext"} + * {@link java.security.SecurityPermission}, then the action is performed + * with no permissions. + * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. + * @param action the action to be performed. + * @param context an access control context + * representing the restriction to be applied to the + * caller's domain's privileges before performing + * the specified action. If the context is + * {@code null}, + * then no additional restriction is applied. + * @param perms the {@code Permission} arguments which limit the + * scope of the caller's privileges. The number of arguments + * is variable. + * + * @return the value returned by the action's {@code run} method. + * + * @throws NullPointerException if action or perms or any element of + * perms is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) + * + * @since 1.8 + */ + @CallerSensitive + public static T doPrivileged(PrivilegedAction action, + AccessControlContext context, Permission... perms) { + return action.run(); +// +// +// AccessControlContext parent = getContext(); +// if (perms == null) { +// throw new NullPointerException("null permissions parameter"); +// } +// Class caller = Reflection.getCallerClass(); +// return AccessController.doPrivileged(action, createWrapper(null, +// caller, parent, context, perms)); + } + + + /** + * Performs the specified {@code PrivilegedAction} with privileges + * enabled and restricted by the specified + * {@code AccessControlContext} and with a privilege scope limited + * by specified {@code Permission} arguments. + * + * The action is performed with the intersection of the permissions + * possessed by the caller's protection domain, and those possessed + * by the domains represented by the specified + * {@code AccessControlContext}. + *

+ * If the action's {@code run} method throws an (unchecked) exception, + * it will propagate through this method. + * + *

This method preserves the current AccessControlContext's + * DomainCombiner (which may be null) while the action is performed. + *

+ * If a security manager is installed and the specified + * {@code AccessControlContext} was not created by system code and the + * caller's {@code ProtectionDomain} has not been granted the + * {@literal "createAccessControlContext"} + * {@link java.security.SecurityPermission}, then the action is performed + * with no permissions. + * + * @param the type of the value returned by the PrivilegedAction's + * {@code run} method. + * @param action the action to be performed. + * @param context an access control context + * representing the restriction to be applied to the + * caller's domain's privileges before performing + * the specified action. If the context is + * {@code null}, + * then no additional restriction is applied. + * @param perms the {@code Permission} arguments which limit the + * scope of the caller's privileges. The number of arguments + * is variable. + * + * @return the value returned by the action's {@code run} method. + * + * @throws NullPointerException if action or perms or any element of + * perms is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) + * @see java.security.DomainCombiner + * + * @since 1.8 + */ + @CallerSensitive + public static T doPrivilegedWithCombiner(PrivilegedAction action, + AccessControlContext context, Permission... perms) { + return action.run(); +// +// AccessControlContext parent = getContext(); +// DomainCombiner dc = parent.getCombiner(); +// if (dc == null && context != null) { +// dc = context.getCombiner(); +// } +// if (perms == null) { +// throw new NullPointerException("null permissions parameter"); +// } +// Class caller = Reflection.getCallerClass(); +// return AccessController.doPrivileged(action, createWrapper(dc, caller, +// parent, context, perms)); + } + + /** + * Performs the specified {@code PrivilegedExceptionAction} with + * privileges enabled. The action is performed with all of the + * permissions possessed by the caller's protection domain. + * + *

If the action's {@code run} method throws an unchecked + * exception, it will propagate through this method. + * + *

Note that any DomainCombiner associated with the current + * AccessControlContext will be ignored while the action is performed. + * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. + * + * @param action the action to be performed + * + * @return the value returned by the action's {@code run} method + * + * @exception PrivilegedActionException if the specified action's + * {@code run} method threw a checked exception + * @exception NullPointerException if the action is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) + * @see #doPrivilegedWithCombiner(PrivilegedExceptionAction) + * @see java.security.DomainCombiner + */ + @CallerSensitive + public static T + doPrivileged(PrivilegedExceptionAction action) + throws PrivilegedActionException { + return justDoIt(action); + } - // a dummy class - public static T doPrivileged(PrivilegedAction action) { - return action.run(); + /** + * Performs the specified {@code PrivilegedExceptionAction} with + * privileges enabled. The action is performed with all of the + * permissions possessed by the caller's protection domain. + * + *

If the action's {@code run} method throws an unchecked + * exception, it will propagate through this method. + * + *

This method preserves the current AccessControlContext's + * DomainCombiner (which may be null) while the action is performed. + * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. + * + * @param action the action to be performed. + * + * @return the value returned by the action's {@code run} method + * + * @exception PrivilegedActionException if the specified action's + * {@code run} method threw a checked exception + * @exception NullPointerException if the action is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedExceptionAction,AccessControlContext) + * @see java.security.DomainCombiner + * + * @since 1.6 + */ + @CallerSensitive + public static T doPrivilegedWithCombiner(PrivilegedExceptionAction action) + throws PrivilegedActionException + { + return justDoIt(action); +// AccessControlContext acc = getStackAccessControlContext(); +// if (acc == null) { +// return AccessController.doPrivileged(action); +// } +// DomainCombiner dc = acc.getAssignedCombiner(); +// return AccessController.doPrivileged(action, +// preserveCombiner(dc, Reflection.getCallerClass())); + } + +// /** +// * preserve the combiner across the doPrivileged call +// */ +// private static AccessControlContext preserveCombiner(DomainCombiner combiner, +// Class caller) +// { +// return createWrapper(combiner, caller, null, null, null); +// } + +// /** +// * Create a wrapper to contain the limited privilege scope data. +// */ +// private static AccessControlContext +// createWrapper(DomainCombiner combiner, Class caller, +// AccessControlContext parent, AccessControlContext context, +// Permission[] perms) +// { +// ProtectionDomain callerPD = getCallerPD(caller); +// // check if caller is authorized to create context +// if (context != null && !context.isAuthorized() && +// System.getSecurityManager() != null && +// !callerPD.impliesCreateAccessControlContext()) +// { +// ProtectionDomain nullPD = new ProtectionDomain(null, null); +// return new AccessControlContext(new ProtectionDomain[] { nullPD }); +// } else { +// return new AccessControlContext(callerPD, combiner, parent, +// context, perms); +// } +// } +// +// private static ProtectionDomain getCallerPD(final Class caller) { +// ProtectionDomain callerPd = doPrivileged +// (new PrivilegedAction() { +// public ProtectionDomain run() { +// return caller.getProtectionDomain(); +// } +// }); +// +// return callerPd; +// } +// + /** + * Performs the specified {@code PrivilegedExceptionAction} with + * privileges enabled and restricted by the specified + * {@code AccessControlContext}. The action is performed with the + * intersection of the permissions possessed by the caller's + * protection domain, and those possessed by the domains represented by the + * specified {@code AccessControlContext}. + *

+ * If the action's {@code run} method throws an unchecked + * exception, it will propagate through this method. + *

+ * If a security manager is installed and the specified + * {@code AccessControlContext} was not created by system code and the + * caller's {@code ProtectionDomain} has not been granted the + * {@literal "createAccessControlContext"} + * {@link java.security.SecurityPermission}, then the action is performed + * with no permissions. + * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. + * @param action the action to be performed + * @param context an access control context + * representing the restriction to be applied to the + * caller's domain's privileges before performing + * the specified action. If the context is + * {@code null}, then no additional restriction is applied. + * + * @return the value returned by the action's {@code run} method + * + * @exception PrivilegedActionException if the specified action's + * {@code run} method threw a checked exception + * @exception NullPointerException if the action is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedAction,AccessControlContext) + */ + @CallerSensitive + public static T + doPrivileged(PrivilegedExceptionAction action, + AccessControlContext context) + throws PrivilegedActionException { + return justDoIt(action); + } + + + /** + * Performs the specified {@code PrivilegedExceptionAction} with privileges + * enabled and restricted by the specified {@code AccessControlContext} and with + * a privilege scope limited by specified {@code Permission} arguments. + * + * The action is performed with the intersection of the permissions possessed by + * the caller's protection domain, and those possessed by the domains + * represented by the specified {@code AccessControlContext}. + *

+ * If the action's {@code run} method throws an (unchecked) exception, it will + * propagate through this method. + *

+ * If a security manager is installed and the specified + * {@code AccessControlContext} was not created by system code and the caller's + * {@code ProtectionDomain} has not been granted the + * {@literal "createAccessControlContext"} + * {@link java.security.SecurityPermission}, then the action is performed with + * no permissions. + * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. + * @param action the action to be performed. + * @param context an access control context representing the restriction + * to be applied to the caller's domain's privileges before + * performing the specified action. If the context is + * {@code null}, then no additional restriction is applied. + * @param perms the {@code Permission} arguments which limit the scope of the + * caller's privileges. The number of arguments is variable. + * + * @return the value returned by the action's {@code run} method. + * + * @throws PrivilegedActionException if the specified action's {@code run} + * method threw a checked exception + * @throws NullPointerException if action or perms or any element of perms + * is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedAction,AccessControlContext) + * + * @since 1.8 + */ + @CallerSensitive + public static T doPrivileged(PrivilegedExceptionAction action, AccessControlContext context, + Permission... perms) throws PrivilegedActionException { + return justDoIt(action); } - public static T doPrivileged(PrivilegedExceptionAction action) throws PrivilegedActionException{ - try { + + /** + * Performs the specified {@code PrivilegedExceptionAction} with + * privileges enabled and restricted by the specified + * {@code AccessControlContext} and with a privilege scope limited by + * specified {@code Permission} arguments. + * + * The action is performed with the intersection of the permissions + * possessed by the caller's protection domain, and those possessed + * by the domains represented by the specified + * {@code AccessControlContext}. + *

+ * If the action's {@code run} method throws an (unchecked) exception, + * it will propagate through this method. + * + *

This method preserves the current AccessControlContext's + * DomainCombiner (which may be null) while the action is performed. + *

+ * If a security manager is installed and the specified + * {@code AccessControlContext} was not created by system code and the + * caller's {@code ProtectionDomain} has not been granted the + * {@literal "createAccessControlContext"} + * {@link java.security.SecurityPermission}, then the action is performed + * with no permissions. + * + * @param the type of the value returned by the + * PrivilegedExceptionAction's {@code run} method. + * @param action the action to be performed. + * @param context an access control context + * representing the restriction to be applied to the + * caller's domain's privileges before performing + * the specified action. If the context is + * {@code null}, + * then no additional restriction is applied. + * @param perms the {@code Permission} arguments which limit the + * scope of the caller's privileges. The number of arguments + * is variable. + * + * @return the value returned by the action's {@code run} method. + * + * @throws PrivilegedActionException if the specified action's + * {@code run} method threw a checked exception + * @throws NullPointerException if action or perms or any element of + * perms is {@code null} + * + * @see #doPrivileged(PrivilegedAction) + * @see #doPrivileged(PrivilegedAction,AccessControlContext) + * @see java.security.DomainCombiner + * + * @since 1.8 + */ + @CallerSensitive + public static T doPrivilegedWithCombiner(PrivilegedExceptionAction action, + AccessControlContext context, + Permission... perms) + throws PrivilegedActionException + { + return justDoIt(action); + } + + @CallerSensitive + private static T justDoIt(PrivilegedAction action) throws PrivilegedActionException { + try { return action.run(); } catch (Exception e) { + throw new PrivilegedActionException(e); } - return null; + } + @CallerSensitive + private static T justDoIt(PrivilegedExceptionAction action) throws PrivilegedActionException { + try { + return action.run(); + } catch (Exception e) { + throw new PrivilegedActionException(e); + } - - public static T doPrivileged(PrivilegedAction action, AccessControlContext context) { - return action.run(); } - public static AccessControlContext getContext() { - return new AccessController(); - } +// /** +// * Returns the AccessControl context. i.e., it gets +// * the protection domains of all the callers on the stack, +// * starting at the first class with a non-null +// * ProtectionDomain. +// * +// * @return the access control context based on the current stack or +// * null if there was only privileged system code. +// */ +// +// private static native AccessControlContext getStackAccessControlContext(); +// +// +// /** +// * Returns the "inherited" AccessControl context. This is the context +// * that existed when the thread was created. Package private so +// * AccessControlContext can use it. +// */ +// +// static native AccessControlContext getInheritedAccessControlContext(); - @Override - public boolean checkPermission(Object perm) { - // no access checking in JavaScript - return true; - } + /** + * This method takes a "snapshot" of the current calling context, which + * includes the current Thread's inherited AccessControlContext and any + * limited privilege scope, and places it in an AccessControlContext object. + * This context may then be checked at a later point, possibly in another thread. + * + * @see AccessControlContext + * + * @return the AccessControlContext based on the current context. + */ + + public static AccessControlContext getContext() + { +// AccessControlContext acc = getStackAccessControlContext(); +// if (acc == null) { +// // all we had was privileged system code. We don't want +// // to return null though, so we construct a real ACC. + return new AccessControlContext(null, true); +// } else { +// return acc.optimize(); +// } + } + + /** + * Determines whether the access request indicated by the + * specified permission should be allowed or denied, based on + * the current AccessControlContext and security policy. + * This method quietly returns if the access request + * is permitted, or throws an AccessControlException otherwise. The + * getPermission method of the AccessControlException returns the + * {@code perm} Permission object instance. + * + * @param perm the requested permission. + * + * @exception AccessControlException if the specified permission + * is not permitted, based on the current security policy. + * @exception NullPointerException if the specified permission + * is {@code null} and is checked based on the + * security policy currently in effect. + */ + public static void checkPermission(Permission perm) + throws AccessControlException + { +// //System.err.println("checkPermission "+perm); +// //Thread.currentThread().dumpStack(); +// +// if (perm == null) { +// throw new NullPointerException("permission can't be null"); +// } +// +// AccessControlContext stack = getStackAccessControlContext(); +// // if context is null, we had privileged system code on the stack. +// if (stack == null) { +// Debug debug = AccessControlContext.getDebug(); +// boolean dumpDebug = false; +// if (debug != null) { +// dumpDebug = !Debug.isOn("codebase="); +// dumpDebug &= !Debug.isOn("permission=") || +// Debug.isOn("permission=" + perm.getClass().getCanonicalName()); +// } +// +// if (dumpDebug && Debug.isOn("stack")) { +// Thread.dumpStack(); +// } +// +// if (dumpDebug && Debug.isOn("domain")) { +// debug.println("domain (context is null)"); +// } +// +// if (dumpDebug) { +// debug.println("access allowed "+perm); +// } +// return; +// } +// +// AccessControlContext acc = stack.optimize(); +// acc.checkPermission(perm); + } } diff --git a/sources/net.sf.j2s.java.core/src/java/security/AlgorithmConstraints.java b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmConstraints.java new file mode 100644 index 000000000..7341603dc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmConstraints.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2010, 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 java.security; + +import java.util.Set; + +/** + * This interface specifies constraints for cryptographic algorithms, + * keys (key sizes), and other algorithm parameters. + *

+ * {@code AlgorithmConstraints} objects are immutable. An implementation + * of this interface should not provide methods that can change the state + * of an instance once it has been created. + *

+ * Note that {@code AlgorithmConstraints} can be used to represent the + * restrictions described by the security properties + * {@code jdk.certpath.disabledAlgorithms} and + * {@code jdk.tls.disabledAlgorithms}, or could be used by a + * concrete {@code PKIXCertPathChecker} to check whether a specified + * certificate in the certification path contains the required algorithm + * constraints. + * + * @see javax.net.ssl.SSLParameters#getAlgorithmConstraints + * @see javax.net.ssl.SSLParameters#setAlgorithmConstraints(AlgorithmConstraints) + * + * @since 1.7 + */ + +public interface AlgorithmConstraints { + + /** + * Determines whether an algorithm is granted permission for the + * specified cryptographic primitives. + * + * @param primitives a set of cryptographic primitives + * @param algorithm the algorithm name + * @param parameters the algorithm parameters, or null if no additional + * parameters + * + * @return true if the algorithm is permitted and can be used for all + * of the specified cryptographic primitives + * + * @throws IllegalArgumentException if primitives or algorithm is null + * or empty + */ + public boolean permits(Set primitives, + String algorithm, AlgorithmParameters parameters); + + /** + * Determines whether a key is granted permission for the specified + * cryptographic primitives. + *

+ * This method is usually used to check key size and key usage. + * + * @param primitives a set of cryptographic primitives + * @param key the key + * + * @return true if the key can be used for all of the specified + * cryptographic primitives + * + * @throws IllegalArgumentException if primitives is null or empty, + * or the key is null + */ + public boolean permits(Set primitives, Key key); + + /** + * Determines whether an algorithm and the corresponding key are granted + * permission for the specified cryptographic primitives. + * + * @param primitives a set of cryptographic primitives + * @param algorithm the algorithm name + * @param key the key + * @param parameters the algorithm parameters, or null if no additional + * parameters + * + * @return true if the key and the algorithm can be used for all of the + * specified cryptographic primitives + * + * @throws IllegalArgumentException if primitives or algorithm is null + * or empty, or the key is null + */ + public boolean permits(Set primitives, + String algorithm, Key key, AlgorithmParameters parameters); + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameterGenerator.java b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameterGenerator.java new file mode 100644 index 000000000..7f9c7cbf4 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameterGenerator.java @@ -0,0 +1,343 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.security.spec.AlgorithmParameterSpec; + +/** + * The {@code AlgorithmParameterGenerator} class is used to generate a + * set of + * parameters to be used with a certain algorithm. Parameter generators + * are constructed using the {@code getInstance} factory methods + * (static methods that return instances of a given class). + * + *

The object that will generate the parameters can be initialized + * in two different ways: in an algorithm-independent manner, or in an + * algorithm-specific manner: + * + *

    + *
  • The algorithm-independent approach uses the fact that all parameter + * generators share the concept of a "size" and a + * source of randomness. The measure of size is universally shared + * by all algorithm parameters, though it is interpreted differently + * for different algorithms. For example, in the case of parameters for + * the DSA algorithm, "size" corresponds to the size + * of the prime modulus (in bits). + * When using this approach, algorithm-specific parameter generation + * values - if any - default to some standard values, unless they can be + * derived from the specified size. + * + *
  • The other approach initializes a parameter generator object + * using algorithm-specific semantics, which are represented by a set of + * algorithm-specific parameter generation values. To generate + * Diffie-Hellman system parameters, for example, the parameter generation + * values usually + * consist of the size of the prime modulus and the size of the + * random exponent, both specified in number of bits. + *
+ * + *

In case the client does not explicitly initialize the + * AlgorithmParameterGenerator + * (via a call to an {@code init} method), each provider must supply (and + * document) a default initialization. For example, the Sun provider uses a + * default modulus prime size of 1024 bits for the generation of DSA + * parameters. + * + *

Every implementation of the Java platform is required to support the + * following standard {@code AlgorithmParameterGenerator} algorithms and + * keysizes in parentheses: + *

    + *
  • {@code DiffieHellman} (1024)
  • + *
  • {@code DSA} (1024)
  • + *
+ * These algorithms are described in the + * AlgorithmParameterGenerator section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + * @author Jan Luehe + * + * + * @see AlgorithmParameters + * @see java.security.spec.AlgorithmParameterSpec + * + * @since 1.2 + */ + +public class AlgorithmParameterGenerator { + + // The provider + private Provider provider; + + // The provider implementation (delegate) + private AlgorithmParameterGeneratorSpi paramGenSpi; + + // The algorithm + private String algorithm; + + /** + * Creates an AlgorithmParameterGenerator object. + * + * @param paramGenSpi the delegate + * @param provider the provider + * @param algorithm the algorithm + */ + protected AlgorithmParameterGenerator + (AlgorithmParameterGeneratorSpi paramGenSpi, Provider provider, + String algorithm) { + this.paramGenSpi = paramGenSpi; + this.provider = provider; + this.algorithm = algorithm; + } + + /** + * Returns the standard name of the algorithm this parameter + * generator is associated with. + * + * @return the string name of the algorithm. + */ + public final String getAlgorithm() { + return this.algorithm; + } + + /** + * Returns an AlgorithmParameterGenerator object for generating + * a set of parameters to be used with the specified algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new AlgorithmParameterGenerator object encapsulating the + * AlgorithmParameterGeneratorSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the algorithm this + * parameter generator is associated with. + * See the AlgorithmParameterGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return the new AlgorithmParameterGenerator object. + * + * @exception NoSuchAlgorithmException if no Provider supports an + * AlgorithmParameterGeneratorSpi implementation for the + * specified algorithm. + * + * @see Provider + */ + public static AlgorithmParameterGenerator getInstance(String algorithm) + throws NoSuchAlgorithmException { + try { + Object[] objs = Security.getImpl(algorithm, + "AlgorithmParameterGenerator", + (String)null); + return new AlgorithmParameterGenerator + ((AlgorithmParameterGeneratorSpi)objs[0], + (Provider)objs[1], + algorithm); + } catch(NoSuchProviderException e) { + throw new NoSuchAlgorithmException(algorithm + " not found"); + } + } + + /** + * Returns an AlgorithmParameterGenerator object for generating + * a set of parameters to be used with the specified algorithm. + * + *

A new AlgorithmParameterGenerator object encapsulating the + * AlgorithmParameterGeneratorSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the algorithm this + * parameter generator is associated with. + * See the AlgorithmParameterGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the string name of the Provider. + * + * @return the new AlgorithmParameterGenerator object. + * + * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + */ + public static AlgorithmParameterGenerator getInstance(String algorithm, + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException + { + if (provider == null || provider.length() == 0) + throw new IllegalArgumentException("missing provider"); + Object[] objs = Security.getImpl(algorithm, + "AlgorithmParameterGenerator", + provider); + return new AlgorithmParameterGenerator + ((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1], + algorithm); + } + + /** + * Returns an AlgorithmParameterGenerator object for generating + * a set of parameters to be used with the specified algorithm. + * + *

A new AlgorithmParameterGenerator object encapsulating the + * AlgorithmParameterGeneratorSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param algorithm the string name of the algorithm this + * parameter generator is associated with. + * See the AlgorithmParameterGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the Provider object. + * + * @return the new AlgorithmParameterGenerator object. + * + * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the specified provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static AlgorithmParameterGenerator getInstance(String algorithm, + Provider provider) + throws NoSuchAlgorithmException + { + if (provider == null) + throw new IllegalArgumentException("missing provider"); + Object[] objs = Security.getImpl(algorithm, + "AlgorithmParameterGenerator", + provider); + return new AlgorithmParameterGenerator + ((AlgorithmParameterGeneratorSpi)objs[0], (Provider)objs[1], + algorithm); + } + + /** + * Returns the provider of this algorithm parameter generator object. + * + * @return the provider of this algorithm parameter generator object + */ + public final Provider getProvider() { + return this.provider; + } + + /** + * Initializes this parameter generator for a certain size. + * To create the parameters, the {@code SecureRandom} + * implementation of the highest-priority installed provider is used as + * the source of randomness. + * (If none of the installed providers supply an implementation of + * {@code SecureRandom}, a system-provided source of randomness is + * used.) + * + * @param size the size (number of bits). + */ + public final void init(int size) { + paramGenSpi.engineInit(size, new SecureRandom()); + } + + /** + * Initializes this parameter generator for a certain size and source + * of randomness. + * + * @param size the size (number of bits). + * @param random the source of randomness. + */ + public final void init(int size, SecureRandom random) { + paramGenSpi.engineInit(size, random); + } + + /** + * Initializes this parameter generator with a set of algorithm-specific + * parameter generation values. + * To generate the parameters, the {@code SecureRandom} + * implementation of the highest-priority installed provider is used as + * the source of randomness. + * (If none of the installed providers supply an implementation of + * {@code SecureRandom}, a system-provided source of randomness is + * used.) + * + * @param genParamSpec the set of algorithm-specific parameter generation values. + * + * @exception InvalidAlgorithmParameterException if the given parameter + * generation values are inappropriate for this parameter generator. + */ + public final void init(AlgorithmParameterSpec genParamSpec) + throws InvalidAlgorithmParameterException { + paramGenSpi.engineInit(genParamSpec, new SecureRandom()); + } + + /** + * Initializes this parameter generator with a set of algorithm-specific + * parameter generation values. + * + * @param genParamSpec the set of algorithm-specific parameter generation values. + * @param random the source of randomness. + * + * @exception InvalidAlgorithmParameterException if the given parameter + * generation values are inappropriate for this parameter generator. + */ + public final void init(AlgorithmParameterSpec genParamSpec, + SecureRandom random) + throws InvalidAlgorithmParameterException { + paramGenSpi.engineInit(genParamSpec, random); + } + + /** + * Generates the parameters. + * + * @return the new AlgorithmParameters object. + */ + public final AlgorithmParameters generateParameters() { + return paramGenSpi.engineGenerateParameters(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameterGeneratorSpi.java b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameterGeneratorSpi.java new file mode 100644 index 000000000..721fb52ac --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameterGeneratorSpi.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.security.spec.AlgorithmParameterSpec; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code AlgorithmParameterGenerator} class, which + * is used to generate a set of parameters to be used with a certain algorithm. + * + *

All the abstract methods in this class must be implemented by each + * cryptographic service provider who wishes to supply the implementation + * of a parameter generator for a particular algorithm. + * + *

In case the client does not explicitly initialize the + * AlgorithmParameterGenerator (via a call to an {@code engineInit} + * method), each provider must supply (and document) a default initialization. + * For example, the Sun provider uses a default modulus prime size of 1024 + * bits for the generation of DSA parameters. + * + * @author Jan Luehe + * + * + * @see AlgorithmParameterGenerator + * @see AlgorithmParameters + * @see java.security.spec.AlgorithmParameterSpec + * + * @since 1.2 + */ + +public abstract class AlgorithmParameterGeneratorSpi { + + /** + * Initializes this parameter generator for a certain size + * and source of randomness. + * + * @param size the size (number of bits). + * @param random the source of randomness. + */ + protected abstract void engineInit(int size, SecureRandom random); + + /** + * Initializes this parameter generator with a set of + * algorithm-specific parameter generation values. + * + * @param genParamSpec the set of algorithm-specific parameter generation values. + * @param random the source of randomness. + * + * @exception InvalidAlgorithmParameterException if the given parameter + * generation values are inappropriate for this parameter generator. + */ + protected abstract void engineInit(AlgorithmParameterSpec genParamSpec, + SecureRandom random) + throws InvalidAlgorithmParameterException; + + /** + * Generates the parameters. + * + * @return the new AlgorithmParameters object. + */ + protected abstract AlgorithmParameters engineGenerateParameters(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameters.java b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameters.java new file mode 100644 index 000000000..b548fcb64 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParameters.java @@ -0,0 +1,399 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.io.*; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidParameterSpecException; + +/** + * This class is used as an opaque representation of cryptographic parameters. + * + *

An {@code AlgorithmParameters} object for managing the parameters + * for a particular algorithm can be obtained by + * calling one of the {@code getInstance} factory methods + * (static methods that return instances of a given class). + * + *

Once an {@code AlgorithmParameters} object is obtained, it must be + * initialized via a call to {@code init}, using an appropriate parameter + * specification or parameter encoding. + * + *

A transparent parameter specification is obtained from an + * {@code AlgorithmParameters} object via a call to + * {@code getParameterSpec}, and a byte encoding of the parameters is + * obtained via a call to {@code getEncoded}. + * + *

Every implementation of the Java platform is required to support the + * following standard {@code AlgorithmParameters} algorithms: + *

    + *
  • {@code AES}
  • + *
  • {@code DES}
  • + *
  • {@code DESede}
  • + *
  • {@code DiffieHellman}
  • + *
  • {@code DSA}
  • + *
+ * These algorithms are described in the + * AlgorithmParameters section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + * @author Jan Luehe + * + * + * @see java.security.spec.AlgorithmParameterSpec + * @see java.security.spec.DSAParameterSpec + * @see KeyPairGenerator + * + * @since 1.2 + */ + +public class AlgorithmParameters { + + // The provider + private Provider provider; + + // The provider implementation (delegate) + private AlgorithmParametersSpi paramSpi; + + // The algorithm + private String algorithm; + + // Has this object been initialized? + private boolean initialized = false; + + /** + * Creates an AlgorithmParameters object. + * + * @param paramSpi the delegate + * @param provider the provider + * @param algorithm the algorithm + */ + protected AlgorithmParameters(AlgorithmParametersSpi paramSpi, + Provider provider, String algorithm) + { + this.paramSpi = paramSpi; + this.provider = provider; + this.algorithm = algorithm; + } + + /** + * Returns the name of the algorithm associated with this parameter object. + * + * @return the algorithm name. + */ + public final String getAlgorithm() { + return this.algorithm; + } + + /** + * Returns a parameter object for the specified algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new AlgorithmParameters object encapsulating the + * AlgorithmParametersSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

The returned parameter object must be initialized via a call to + * {@code init}, using an appropriate parameter specification or + * parameter encoding. + * + * @param algorithm the name of the algorithm requested. + * See the AlgorithmParameters section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return the new parameter object. + * + * @exception NoSuchAlgorithmException if no Provider supports an + * AlgorithmParametersSpi implementation for the + * specified algorithm. + * + * @see Provider + */ + public static AlgorithmParameters getInstance(String algorithm) + throws NoSuchAlgorithmException { + try { + Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", + (String)null); + return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], + (Provider)objs[1], + algorithm); + } catch(NoSuchProviderException e) { + throw new NoSuchAlgorithmException(algorithm + " not found"); + } + } + + /** + * Returns a parameter object for the specified algorithm. + * + *

A new AlgorithmParameters object encapsulating the + * AlgorithmParametersSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

The returned parameter object must be initialized via a call to + * {@code init}, using an appropriate parameter specification or + * parameter encoding. + * + * @param algorithm the name of the algorithm requested. + * See the AlgorithmParameters section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the name of the provider. + * + * @return the new parameter object. + * + * @exception NoSuchAlgorithmException if an AlgorithmParametersSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + */ + public static AlgorithmParameters getInstance(String algorithm, + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException + { + if (provider == null || provider.length() == 0) + throw new IllegalArgumentException("missing provider"); + Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", + provider); + return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], + (Provider)objs[1], + algorithm); + } + + /** + * Returns a parameter object for the specified algorithm. + * + *

A new AlgorithmParameters object encapsulating the + * AlgorithmParametersSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + *

The returned parameter object must be initialized via a call to + * {@code init}, using an appropriate parameter specification or + * parameter encoding. + * + * @param algorithm the name of the algorithm requested. + * See the AlgorithmParameters section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the name of the provider. + * + * @return the new parameter object. + * + * @exception NoSuchAlgorithmException if an AlgorithmParameterGeneratorSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static AlgorithmParameters getInstance(String algorithm, + Provider provider) + throws NoSuchAlgorithmException + { + if (provider == null) + throw new IllegalArgumentException("missing provider"); + Object[] objs = Security.getImpl(algorithm, "AlgorithmParameters", + provider); + return new AlgorithmParameters((AlgorithmParametersSpi)objs[0], + (Provider)objs[1], + algorithm); + } + + /** + * Returns the provider of this parameter object. + * + * @return the provider of this parameter object + */ + public final Provider getProvider() { + return this.provider; + } + + /** + * Initializes this parameter object using the parameters + * specified in {@code paramSpec}. + * + * @param paramSpec the parameter specification. + * + * @exception InvalidParameterSpecException if the given parameter + * specification is inappropriate for the initialization of this parameter + * object, or if this parameter object has already been initialized. + */ + public final void init(AlgorithmParameterSpec paramSpec) + throws InvalidParameterSpecException + { + if (this.initialized) + throw new InvalidParameterSpecException("already initialized"); + paramSpi.engineInit(paramSpec); + this.initialized = true; + } + + /** + * Imports the specified parameters and decodes them according to the + * primary decoding format for parameters. The primary decoding + * format for parameters is ASN.1, if an ASN.1 specification for this type + * of parameters exists. + * + * @param params the encoded parameters. + * + * @exception IOException on decoding errors, or if this parameter object + * has already been initialized. + */ + public final void init(byte[] params) throws IOException { + if (this.initialized) + throw new IOException("already initialized"); + paramSpi.engineInit(params); + this.initialized = true; + } + + /** + * Imports the parameters from {@code params} and decodes them + * according to the specified decoding scheme. + * If {@code format} is null, the + * primary decoding format for parameters is used. The primary decoding + * format is ASN.1, if an ASN.1 specification for these parameters + * exists. + * + * @param params the encoded parameters. + * + * @param format the name of the decoding scheme. + * + * @exception IOException on decoding errors, or if this parameter object + * has already been initialized. + */ + public final void init(byte[] params, String format) throws IOException { + if (this.initialized) + throw new IOException("already initialized"); + paramSpi.engineInit(params, format); + this.initialized = true; + } + + /** + * Returns a (transparent) specification of this parameter object. + * {@code paramSpec} identifies the specification class in which + * the parameters should be returned. It could, for example, be + * {@code DSAParameterSpec.class}, to indicate that the + * parameters should be returned in an instance of the + * {@code DSAParameterSpec} class. + * + * @param the type of the parameter specification to be returrned + * @param paramSpec the specification class in which + * the parameters should be returned. + * + * @return the parameter specification. + * + * @exception InvalidParameterSpecException if the requested parameter + * specification is inappropriate for this parameter object, or if this + * parameter object has not been initialized. + */ + public final + T getParameterSpec(Class paramSpec) + throws InvalidParameterSpecException + { + if (this.initialized == false) { + throw new InvalidParameterSpecException("not initialized"); + } + return paramSpi.engineGetParameterSpec(paramSpec); + } + + /** + * Returns the parameters in their primary encoding format. + * The primary encoding format for parameters is ASN.1, if an ASN.1 + * specification for this type of parameters exists. + * + * @return the parameters encoded using their primary encoding format. + * + * @exception IOException on encoding errors, or if this parameter object + * has not been initialized. + */ + public final byte[] getEncoded() throws IOException + { + if (this.initialized == false) { + throw new IOException("not initialized"); + } + return paramSpi.engineGetEncoded(); + } + + /** + * Returns the parameters encoded in the specified scheme. + * If {@code format} is null, the + * primary encoding format for parameters is used. The primary encoding + * format is ASN.1, if an ASN.1 specification for these parameters + * exists. + * + * @param format the name of the encoding format. + * + * @return the parameters encoded using the specified encoding scheme. + * + * @exception IOException on encoding errors, or if this parameter object + * has not been initialized. + */ + public final byte[] getEncoded(String format) throws IOException + { + if (this.initialized == false) { + throw new IOException("not initialized"); + } + return paramSpi.engineGetEncoded(format); + } + + /** + * Returns a formatted string describing the parameters. + * + * @return a formatted string describing the parameters, or null if this + * parameter object has not been initialized. + */ + public final String toString() { + if (this.initialized == false) { + return null; + } + return paramSpi.engineToString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParametersSpi.java b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParametersSpi.java new file mode 100644 index 000000000..282493b97 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/AlgorithmParametersSpi.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.io.*; +import java.security.spec.AlgorithmParameterSpec; +import java.security.spec.InvalidParameterSpecException; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code AlgorithmParameters} class, which is used to manage + * algorithm parameters. + * + *

All the abstract methods in this class must be implemented by each + * cryptographic service provider who wishes to supply parameter management + * for a particular algorithm. + * + * @author Jan Luehe + * + * + * @see AlgorithmParameters + * @see java.security.spec.AlgorithmParameterSpec + * @see java.security.spec.DSAParameterSpec + * + * @since 1.2 + */ + +public abstract class AlgorithmParametersSpi { + + /** + * Initializes this parameters object using the parameters + * specified in {@code paramSpec}. + * + * @param paramSpec the parameter specification. + * + * @exception InvalidParameterSpecException if the given parameter + * specification is inappropriate for the initialization of this parameter + * object. + */ + protected abstract void engineInit(AlgorithmParameterSpec paramSpec) + throws InvalidParameterSpecException; + + /** + * Imports the specified parameters and decodes them + * according to the primary decoding format for parameters. + * The primary decoding format for parameters is ASN.1, if an ASN.1 + * specification for this type of parameters exists. + * + * @param params the encoded parameters. + * + * @exception IOException on decoding errors + */ + protected abstract void engineInit(byte[] params) + throws IOException; + + /** + * Imports the parameters from {@code params} and + * decodes them according to the specified decoding format. + * If {@code format} is null, the + * primary decoding format for parameters is used. The primary decoding + * format is ASN.1, if an ASN.1 specification for these parameters + * exists. + * + * @param params the encoded parameters. + * + * @param format the name of the decoding format. + * + * @exception IOException on decoding errors + */ + protected abstract void engineInit(byte[] params, String format) + throws IOException; + + /** + * Returns a (transparent) specification of this parameters + * object. + * {@code paramSpec} identifies the specification class in which + * the parameters should be returned. It could, for example, be + * {@code DSAParameterSpec.class}, to indicate that the + * parameters should be returned in an instance of the + * {@code DSAParameterSpec} class. + * + * @param the type of the parameter specification to be returned + * + * @param paramSpec the specification class in which + * the parameters should be returned. + * + * @return the parameter specification. + * + * @exception InvalidParameterSpecException if the requested parameter + * specification is inappropriate for this parameter object. + */ + protected abstract + + T engineGetParameterSpec(Class paramSpec) + throws InvalidParameterSpecException; + + /** + * Returns the parameters in their primary encoding format. + * The primary encoding format for parameters is ASN.1, if an ASN.1 + * specification for this type of parameters exists. + * + * @return the parameters encoded using their primary encoding format. + * + * @exception IOException on encoding errors. + */ + protected abstract byte[] engineGetEncoded() throws IOException; + + /** + * Returns the parameters encoded in the specified format. + * If {@code format} is null, the + * primary encoding format for parameters is used. The primary encoding + * format is ASN.1, if an ASN.1 specification for these parameters + * exists. + * + * @param format the name of the encoding format. + * + * @return the parameters encoded using the specified encoding scheme. + * + * @exception IOException on encoding errors. + */ + protected abstract byte[] engineGetEncoded(String format) + throws IOException; + + /** + * Returns a formatted string describing the parameters. + * + * @return a formatted string describing the parameters. + */ + protected abstract String engineToString(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/AllPermission.java b/sources/net.sf.j2s.java.core/src/java/security/AllPermission.java new file mode 100644 index 000000000..c01b134f0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/AllPermission.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 1998, 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 java.security; + +import java.security.*; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; +import sun.security.util.SecurityConstants; + +/** + * The AllPermission is a permission that implies all other permissions. + *

+ * Note: Granting AllPermission should be done with extreme care, + * as it implies all other permissions. Thus, it grants code the ability + * to run with security + * disabled. Extreme caution should be taken before granting such + * a permission to code. This permission should be used only during testing, + * or in extremely rare cases where an application or applet is + * completely trusted and adding the necessary permissions to the policy + * is prohibitively cumbersome. + * + * @see java.security.Permission + * @see java.security.AccessController + * @see java.security.Permissions + * @see java.security.PermissionCollection + * @see java.lang.SecurityManager + * + * + * @author Roland Schemers + * + * @serial exclude + */ + +public final class AllPermission extends Permission { + + private static final long serialVersionUID = -2916474571451318075L; + + /** + * Creates a new AllPermission object. + */ + public AllPermission() { + super(""); + } + + + /** + * Creates a new AllPermission object. This + * constructor exists for use by the {@code Policy} object + * to instantiate new Permission objects. + * + * @param name ignored + * @param actions ignored. + */ + public AllPermission(String name, String actions) { + this(); + } + + /** + * Checks if the specified permission is "implied" by + * this object. This method always returns true. + * + * @param p the permission to check against. + * + * @return return + */ + public boolean implies(Permission p) { + return true; + } + + /** + * Checks two AllPermission objects for equality. Two AllPermission + * objects are always equal. + * + * @param obj the object we are testing for equality with this object. + * @return true if obj is an AllPermission, false otherwise. + */ + public boolean equals(Object obj) { + return (obj instanceof AllPermission); + } + + /** + * Returns the hash code value for this object. + * + * @return a hash code value for this object. + */ + + public int hashCode() { + return 1; + } + + /** + * Returns the canonical string representation of the actions. + * + * @return the actions. + */ + public String getActions() { + return ""; + } + + /** + * Returns a new PermissionCollection object for storing AllPermission + * objects. + *

+ * + * @return a new PermissionCollection object suitable for + * storing AllPermissions. + */ + public PermissionCollection newPermissionCollection() { + return new AllPermissionCollection(); + } + +} + +/** + * A AllPermissionCollection stores a collection + * of AllPermission permissions. AllPermission objects + * must be stored in a manner that allows them to be inserted in any + * order, but enable the implies function to evaluate the implies + * method in an efficient (and consistent) manner. + * + * @see java.security.Permission + * @see java.security.Permissions + * + * + * @author Roland Schemers + * + * @serial include + */ + +final class AllPermissionCollection + extends PermissionCollection + implements java.io.Serializable +{ + + // use serialVersionUID from JDK 1.2.2 for interoperability + private static final long serialVersionUID = -4023755556366636806L; + + private boolean all_allowed; // true if any all permissions have been added + + /** + * Create an empty AllPermissions object. + * + */ + + public AllPermissionCollection() { + all_allowed = false; + } + + /** + * Adds a permission to the AllPermissions. The key for the hash is + * permission.path. + * + * @param permission the Permission object to add. + * + * @exception IllegalArgumentException - if the permission is not a + * AllPermission + * + * @exception SecurityException - if this AllPermissionCollection object + * has been marked readonly + */ + + public void add(Permission permission) { + if (! (permission instanceof AllPermission)) + throw new IllegalArgumentException("invalid permission: "+ + permission); + if (isReadOnly()) + throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); + + all_allowed = true; // No sync; staleness OK + } + + /** + * Check and see if this set of permissions implies the permissions + * expressed in "permission". + * + * @param permission the Permission object to compare + * + * @return always returns true. + */ + + public boolean implies(Permission permission) { + return all_allowed; // No sync; staleness OK + } + + /** + * Returns an enumeration of all the AllPermission objects in the + * container. + * + * @return an enumeration of all the AllPermission objects. + */ + public Enumeration elements() { + return new Enumeration() { + private boolean hasMore = all_allowed; + + public boolean hasMoreElements() { + return hasMore; + } + + public Permission nextElement() { + hasMore = false; + return SecurityConstants.ALL_PERMISSION; + } + }; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/AuthProvider.java b/sources/net.sf.j2s.java.core/src/java/security/AuthProvider.java new file mode 100644 index 000000000..571a1fe08 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/AuthProvider.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2003, 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 java.security; + +import javax.security.auth.Subject; +import javax.security.auth.login.LoginException; +import javax.security.auth.callback.CallbackHandler; + +/** + * This class defines login and logout methods for a provider. + * + *

While callers may invoke {@code login} directly, + * the provider may also invoke {@code login} on behalf of callers + * if it determines that a login must be performed + * prior to certain operations. + * + * @since 1.5 + */ +public abstract class AuthProvider extends Provider { + + private static final long serialVersionUID = 4197859053084546461L; + + /** + * Constructs a provider with the specified name, version number, + * and information. + * + * @param name the provider name. + * @param version the provider version number. + * @param info a description of the provider and its services. + */ + protected AuthProvider(String name, double version, String info) { + super(name, version, info); + } + + /** + * Log in to this provider. + * + *

The provider relies on a {@code CallbackHandler} + * to obtain authentication information from the caller + * (a PIN, for example). If the caller passes a {@code null} + * handler to this method, the provider uses the handler set in the + * {@code setCallbackHandler} method. + * If no handler was set in that method, the provider queries the + * auth.login.defaultCallbackHandler security property + * for the fully qualified class name of a default handler implementation. + * If the security property is not set, + * the provider is assumed to have alternative means + * for obtaining authentication information. + * + * @param subject the {@code Subject} which may contain + * principals/credentials used for authentication, + * or may be populated with additional principals/credentials + * after successful authentication has completed. + * This parameter may be {@code null}. + * @param handler the {@code CallbackHandler} used by + * this provider to obtain authentication information + * from the caller, which may be {@code null} + * + * @exception LoginException if the login operation fails + * @exception SecurityException if the caller does not pass a + * security check for + * {@code SecurityPermission("authProvider.name")}, + * where {@code name} is the value returned by + * this provider's {@code getName} method + */ + public abstract void login(Subject subject, CallbackHandler handler) + throws LoginException; + + /** + * Log out from this provider. + * + * @exception LoginException if the logout operation fails + * @exception SecurityException if the caller does not pass a + * security check for + * {@code SecurityPermission("authProvider.name")}, + * where {@code name} is the value returned by + * this provider's {@code getName} method + */ + public abstract void logout() throws LoginException; + + /** + * Set a {@code CallbackHandler}. + * + *

The provider uses this handler if one is not passed to the + * {@code login} method. The provider also uses this handler + * if it invokes {@code login} on behalf of callers. + * In either case if a handler is not set via this method, + * the provider queries the + * auth.login.defaultCallbackHandler security property + * for the fully qualified class name of a default handler implementation. + * If the security property is not set, + * the provider is assumed to have alternative means + * for obtaining authentication information. + * + * @param handler a {@code CallbackHandler} for obtaining + * authentication information, which may be {@code null} + * + * @exception SecurityException if the caller does not pass a + * security check for + * {@code SecurityPermission("authProvider.name")}, + * where {@code name} is the value returned by + * this provider's {@code getName} method + */ + public abstract void setCallbackHandler(CallbackHandler handler); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/BasicPermission.java b/sources/net.sf.j2s.java.core/src/java/security/BasicPermission.java new file mode 100644 index 000000000..89cc2f921 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/BasicPermission.java @@ -0,0 +1,554 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.util.Enumeration; +import java.util.Map; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Collections; +import java.io.ObjectStreamField; +import java.io.ObjectOutputStream; +import java.io.ObjectInputStream; +import java.io.IOException; + +/** + * The BasicPermission class extends the Permission class, and + * can be used as the base class for permissions that want to + * follow the same naming convention as BasicPermission. + *

+ * The name for a BasicPermission is the name of the given permission + * (for example, "exit", + * "setFactory", "print.queueJob", etc). The naming + * convention follows the hierarchical property naming convention. + * An asterisk may appear by itself, or if immediately preceded by a "." + * may appear at the end of the name, to signify a wildcard match. + * For example, "*" and "java.*" signify a wildcard match, while "*java", "a*b", + * and "java*" do not. + *

+ * The action string (inherited from Permission) is unused. + * Thus, BasicPermission is commonly used as the base class for + * "named" permissions + * (ones that contain a name but no actions list; you either have the + * named permission or you don't.) + * Subclasses may implement actions on top of BasicPermission, + * if desired. + *

+ * @see java.security.Permission + * @see java.security.Permissions + * @see java.security.PermissionCollection + * @see java.lang.SecurityManager + * + * @author Marianne Mueller + * @author Roland Schemers + */ + +public abstract class BasicPermission extends Permission + implements java.io.Serializable +{ + + private static final long serialVersionUID = 6279438298436773498L; + + // does this permission have a wildcard at the end? + private transient boolean wildcard; + + // the name without the wildcard on the end + private transient String path; + + // is this permission the old-style exitVM permission (pre JDK 1.6)? + private transient boolean exitVM; + + /** + * initialize a BasicPermission object. Common to all constructors. + */ + private void init(String name) { + if (name == null) + throw new NullPointerException("name can't be null"); + + int len = name.length(); + + if (len == 0) { + throw new IllegalArgumentException("name can't be empty"); + } + + char last = name.charAt(len - 1); + + // Is wildcard or ends with ".*"? + if (last == '*' && (len == 1 || name.charAt(len - 2) == '.')) { + wildcard = true; + if (len == 1) { + path = ""; + } else { + path = name.substring(0, len - 1); + } + } else { + if (name.equals("exitVM")) { + wildcard = true; + path = "exitVM."; + exitVM = true; + } else { + path = name; + } + } + } + + /** + * Creates a new BasicPermission with the specified name. + * Name is the symbolic name of the permission, such as + * "setFactory", + * "print.queueJob", or "topLevelWindow", etc. + * + * @param name the name of the BasicPermission. + * + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. + */ + public BasicPermission(String name) { + super(name); + init(name); + } + + + /** + * Creates a new BasicPermission object with the specified name. + * The name is the symbolic name of the BasicPermission, and the + * actions String is currently unused. + * + * @param name the name of the BasicPermission. + * @param actions ignored. + * + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. + */ + public BasicPermission(String name, String actions) { + super(name); + init(name); + } + + /** + * Checks if the specified permission is "implied" by + * this object. + *

+ * More specifically, this method returns true if: + *

    + *
  • p's class is the same as this object's class, and + *
  • p's name equals or (in the case of wildcards) + * is implied by this object's + * name. For example, "a.b.*" implies "a.b.c". + *
+ * + * @param p the permission to check against. + * + * @return true if the passed permission is equal to or + * implied by this permission, false otherwise. + */ + public boolean implies(Permission p) { + if ((p == null) || (p.getClass() != getClass())) + return false; + + BasicPermission that = (BasicPermission) p; + + if (this.wildcard) { + if (that.wildcard) { + // one wildcard can imply another + return that.path.startsWith(path); + } else { + // make sure ap.path is longer so a.b.* doesn't imply a.b + return (that.path.length() > this.path.length()) && + that.path.startsWith(this.path); + } + } else { + if (that.wildcard) { + // a non-wildcard can't imply a wildcard + return false; + } + else { + return this.path.equals(that.path); + } + } + } + + /** + * Checks two BasicPermission objects for equality. + * Checks that obj's class is the same as this object's class + * and has the same name as this object. + *

+ * @param obj the object we are testing for equality with this object. + * @return true if obj's class is the same as this object's class + * and has the same name as this BasicPermission object, false otherwise. + */ + public boolean equals(Object obj) { + if (obj == this) + return true; + + if ((obj == null) || (obj.getClass() != getClass())) + return false; + + BasicPermission bp = (BasicPermission) obj; + + return getName().equals(bp.getName()); + } + + + /** + * Returns the hash code value for this object. + * The hash code used is the hash code of the name, that is, + * {@code getName().hashCode()}, where {@code getName} is + * from the Permission superclass. + * + * @return a hash code value for this object. + */ + public int hashCode() { + return this.getName().hashCode(); + } + + /** + * Returns the canonical string representation of the actions, + * which currently is the empty string "", since there are no actions for + * a BasicPermission. + * + * @return the empty string "". + */ + public String getActions() { + return ""; + } + + /** + * Returns a new PermissionCollection object for storing BasicPermission + * objects. + * + *

BasicPermission objects must be stored in a manner that allows them + * to be inserted in any order, but that also enables the + * PermissionCollection {@code implies} method + * to be implemented in an efficient (and consistent) manner. + * + * @return a new PermissionCollection object suitable for + * storing BasicPermissions. + */ + public PermissionCollection newPermissionCollection() { + return new BasicPermissionCollection(this.getClass()); + } + + /** + * readObject is called to restore the state of the BasicPermission from + * a stream. + */ + private void readObject(ObjectInputStream s) + throws IOException, ClassNotFoundException + { + s.defaultReadObject(); + // init is called to initialize the rest of the values. + init(getName()); + } + + /** + * Returns the canonical name of this BasicPermission. + * All internal invocations of getName should invoke this method, so + * that the pre-JDK 1.6 "exitVM" and current "exitVM.*" permission are + * equivalent in equals/hashCode methods. + * + * @return the canonical name of this BasicPermission. + */ + final String getCanonicalName() { + return exitVM ? "exitVM.*" : getName(); + } +} + +/** + * A BasicPermissionCollection stores a collection + * of BasicPermission permissions. BasicPermission objects + * must be stored in a manner that allows them to be inserted in any + * order, but enable the implies function to evaluate the implies + * method in an efficient (and consistent) manner. + * + * A BasicPermissionCollection handles comparing a permission like "a.b.c.d.e" + * with a Permission such as "a.b.*", or "*". + * + * @see java.security.Permission + * @see java.security.Permissions + * + * + * @author Roland Schemers + * + * @serial include + */ + +final class BasicPermissionCollection + extends PermissionCollection + implements java.io.Serializable +{ + + private static final long serialVersionUID = 739301742472979399L; + + /** + * Key is name, value is permission. All permission objects in + * collection must be of the same type. + * Not serialized; see serialization section at end of class. + */ + private transient Map perms; + + /** + * This is set to {@code true} if this BasicPermissionCollection + * contains a BasicPermission with '*' as its permission name. + * + * @see #serialPersistentFields + */ + private boolean all_allowed; + + /** + * The class to which all BasicPermissions in this + * BasicPermissionCollection belongs. + * + * @see #serialPersistentFields + */ + private Class permClass; + + /** + * Create an empty BasicPermissionCollection object. + * + */ + + public BasicPermissionCollection(Class clazz) { + perms = new HashMap(11); + all_allowed = false; + permClass = clazz; + } + + /** + * Adds a permission to the BasicPermissions. The key for the hash is + * permission.path. + * + * @param permission the Permission object to add. + * + * @exception IllegalArgumentException - if the permission is not a + * BasicPermission, or if + * the permission is not of the + * same Class as the other + * permissions in this collection. + * + * @exception SecurityException - if this BasicPermissionCollection object + * has been marked readonly + */ + public void add(Permission permission) { + if (! (permission instanceof BasicPermission)) + throw new IllegalArgumentException("invalid permission: "+ + permission); + if (isReadOnly()) + throw new SecurityException("attempt to add a Permission to a readonly PermissionCollection"); + + BasicPermission bp = (BasicPermission) permission; + + // make sure we only add new BasicPermissions of the same class + // Also check null for compatibility with deserialized form from + // previous versions. + if (permClass == null) { + // adding first permission + permClass = bp.getClass(); + } else { + if (bp.getClass() != permClass) + throw new IllegalArgumentException("invalid permission: " + + permission); + } + + synchronized (this) { + perms.put(bp.getCanonicalName(), permission); + } + + // No sync on all_allowed; staleness OK + if (!all_allowed) { + if (bp.getCanonicalName().equals("*")) + all_allowed = true; + } + } + + /** + * Check and see if this set of permissions implies the permissions + * expressed in "permission". + * + * @param permission the Permission object to compare + * + * @return true if "permission" is a proper subset of a permission in + * the set, false if not. + */ + public boolean implies(Permission permission) { + if (! (permission instanceof BasicPermission)) + return false; + + BasicPermission bp = (BasicPermission) permission; + + // random subclasses of BasicPermission do not imply each other + if (bp.getClass() != permClass) + return false; + + // short circuit if the "*" Permission was added + if (all_allowed) + return true; + + // strategy: + // Check for full match first. Then work our way up the + // path looking for matches on a.b..* + + String path = bp.getCanonicalName(); + //System.out.println("check "+path); + + Permission x; + + synchronized (this) { + x = perms.get(path); + } + + if (x != null) { + // we have a direct hit! + return x.implies(permission); + } + + // work our way up the tree... + int last, offset; + + offset = path.length()-1; + + while ((last = path.lastIndexOf(".", offset)) != -1) { + + path = path.substring(0, last+1) + "*"; + //System.out.println("check "+path); + + synchronized (this) { + x = perms.get(path); + } + + if (x != null) { + return x.implies(permission); + } + offset = last -1; + } + + // we don't have to check for "*" as it was already checked + // at the top (all_allowed), so we just return false + return false; + } + + /** + * Returns an enumeration of all the BasicPermission objects in the + * container. + * + * @return an enumeration of all the BasicPermission objects. + */ + public Enumeration elements() { + // Convert Iterator of Map values into an Enumeration + synchronized (this) { + return Collections.enumeration(perms.values()); + } + } + + // Need to maintain serialization interoperability with earlier releases, + // which had the serializable field: + // + // @serial the Hashtable is indexed by the BasicPermission name + // + // private Hashtable permissions; + /** + * @serialField permissions java.util.Hashtable + * The BasicPermissions in this BasicPermissionCollection. + * All BasicPermissions in the collection must belong to the same class. + * The Hashtable is indexed by the BasicPermission name; the value + * of the Hashtable entry is the permission. + * @serialField all_allowed boolean + * This is set to {@code true} if this BasicPermissionCollection + * contains a BasicPermission with '*' as its permission name. + * @serialField permClass java.lang.Class + * The class to which all BasicPermissions in this + * BasicPermissionCollection belongs. + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("permissions", Hashtable.class), + new ObjectStreamField("all_allowed", Boolean.TYPE), + new ObjectStreamField("permClass", Class.class), + }; + + /** + * @serialData Default fields. + */ + /* + * Writes the contents of the perms field out as a Hashtable for + * serialization compatibility with earlier releases. all_allowed + * and permClass unchanged. + */ + private void writeObject(ObjectOutputStream out) throws IOException { + // Don't call out.defaultWriteObject() + + // Copy perms into a Hashtable + Hashtable permissions = + new Hashtable<>(perms.size()*2); + + synchronized (this) { + permissions.putAll(perms); + } + + // Write out serializable fields + ObjectOutputStream.PutField pfields = out.putFields(); + pfields.put("all_allowed", all_allowed); + pfields.put("permissions", permissions); + pfields.put("permClass", permClass); + out.writeFields(); + } + + /** + * readObject is called to restore the state of the + * BasicPermissionCollection from a stream. + */ + private void readObject(java.io.ObjectInputStream in) + throws IOException, ClassNotFoundException + { + // Don't call defaultReadObject() + + // Read in serialized fields + ObjectInputStream.GetField gfields = in.readFields(); + + // Get permissions + // writeObject writes a Hashtable for the + // permissions key, so this cast is safe, unless the data is corrupt. + @SuppressWarnings("unchecked") + Hashtable permissions = + (Hashtable)gfields.get("permissions", null); + perms = new HashMap(permissions.size()*2); + perms.putAll(permissions); + + // Get all_allowed + all_allowed = gfields.get("all_allowed", false); + + // Get permClass + permClass = (Class) gfields.get("permClass", null); + + if (permClass == null) { + // set permClass + Enumeration e = permissions.elements(); + if (e.hasMoreElements()) { + Permission p = e.nextElement(); + permClass = p.getClass(); + } + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Certificate.java b/sources/net.sf.j2s.java.core/src/java/security/Certificate.java new file mode 100644 index 000000000..489c6d620 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Certificate.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.io.*; +import java.util.Date; + +/** + *

This is an interface of abstract methods for managing a + * variety of identity certificates. + * An identity certificate is a guarantee by a principal that + * a public key is that of another principal. (A principal represents + * an entity such as an individual user, a group, or a corporation.) + * + *

In particular, this interface is intended to be a common + * abstraction for constructs that have different formats but + * important common uses. For example, different types of + * certificates, such as X.509 certificates and PGP certificates, + * share general certificate functionality (the need to encode and + * decode certificates) and some types of information, such as a + * public key, the principal whose key it is, and the guarantor + * guaranteeing that the public key is that of the specified + * principal. So an implementation of X.509 certificates and an + * implementation of PGP certificates can both utilize the Certificate + * interface, even though their formats and additional types and + * amounts of information stored are different. + * + *

Important: This interface is useful for cataloging and + * grouping objects sharing certain common uses. It does not have any + * semantics of its own. In particular, a Certificate object does not + * make any statement as to the validity of the binding. It is + * the duty of the application implementing this interface to verify + * the certificate and satisfy itself of its validity. + * + * @author Benjamin Renaud + * @deprecated A new certificate handling package is created in the Java platform. + * This Certificate interface is entirely deprecated and + * is here to allow for a smooth transition to the new + * package. + * @see java.security.cert.Certificate + */ +@Deprecated +public interface Certificate { + + /** + * Returns the guarantor of the certificate, that is, the principal + * guaranteeing that the public key associated with this certificate + * is that of the principal associated with this certificate. For X.509 + * certificates, the guarantor will typically be a Certificate Authority + * (such as the United States Postal Service or Verisign, Inc.). + * + * @return the guarantor which guaranteed the principal-key + * binding. + */ + public abstract Principal getGuarantor(); + + /** + * Returns the principal of the principal-key pair being guaranteed by + * the guarantor. + * + * @return the principal to which this certificate is bound. + */ + public abstract Principal getPrincipal(); + + /** + * Returns the key of the principal-key pair being guaranteed by + * the guarantor. + * + * @return the public key that this certificate certifies belongs + * to a particular principal. + */ + public abstract PublicKey getPublicKey(); + + /** + * Encodes the certificate to an output stream in a format that can + * be decoded by the {@code decode} method. + * + * @param stream the output stream to which to encode the + * certificate. + * + * @exception KeyException if the certificate is not + * properly initialized, or data is missing, etc. + * + * @exception IOException if a stream exception occurs while + * trying to output the encoded certificate to the output stream. + * + * @see #decode + * @see #getFormat + */ + public abstract void encode(OutputStream stream) + throws KeyException, IOException; + + /** + * Decodes a certificate from an input stream. The format should be + * that returned by {@code getFormat} and produced by + * {@code encode}. + * + * @param stream the input stream from which to fetch the data + * being decoded. + * + * @exception KeyException if the certificate is not properly initialized, + * or data is missing, etc. + * + * @exception IOException if an exception occurs while trying to input + * the encoded certificate from the input stream. + * + * @see #encode + * @see #getFormat + */ + public abstract void decode(InputStream stream) + throws KeyException, IOException; + + + /** + * Returns the name of the coding format. This is used as a hint to find + * an appropriate parser. It could be "X.509", "PGP", etc. This is + * the format produced and understood by the {@code encode} + * and {@code decode} methods. + * + * @return the name of the coding format. + */ + public abstract String getFormat(); + + /** + * Returns a string that represents the contents of the certificate. + * + * @param detailed whether or not to give detailed information + * about the certificate + * + * @return a string representing the contents of the certificate + */ + public String toString(boolean detailed); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/CodeSigner.java b/sources/net.sf.j2s.java.core/src/java/security/CodeSigner.java new file mode 100644 index 000000000..37c12b153 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/CodeSigner.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2003, 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 java.security; + +import java.io.*; +import java.security.cert.CertPath; + +/** + * This class encapsulates information about a code signer. + * It is immutable. + * + * @since 1.5 + * @author Vincent Ryan + */ + +public final class CodeSigner implements Serializable { + + private static final long serialVersionUID = 6819288105193937581L; + + /** + * The signer's certificate path. + * + * @serial + */ + private CertPath signerCertPath; + + /* + * The signature timestamp. + * + * @serial + */ + private Timestamp timestamp; + + /* + * Hash code for this code signer. + */ + private transient int myhash = -1; + + /** + * Constructs a CodeSigner object. + * + * @param signerCertPath The signer's certificate path. + * It must not be {@code null}. + * @param timestamp A signature timestamp. + * If {@code null} then no timestamp was generated + * for the signature. + * @throws NullPointerException if {@code signerCertPath} is + * {@code null}. + */ + public CodeSigner(CertPath signerCertPath, Timestamp timestamp) { + if (signerCertPath == null) { + throw new NullPointerException(); + } + this.signerCertPath = signerCertPath; + this.timestamp = timestamp; + } + + /** + * Returns the signer's certificate path. + * + * @return A certificate path. + */ + public CertPath getSignerCertPath() { + return signerCertPath; + } + + /** + * Returns the signature timestamp. + * + * @return The timestamp or {@code null} if none is present. + */ + public Timestamp getTimestamp() { + return timestamp; + } + + /** + * Returns the hash code value for this code signer. + * The hash code is generated using the signer's certificate path and the + * timestamp, if present. + * + * @return a hash code value for this code signer. + */ + public int hashCode() { + if (myhash == -1) { + if (timestamp == null) { + myhash = signerCertPath.hashCode(); + } else { + myhash = signerCertPath.hashCode() + timestamp.hashCode(); + } + } + return myhash; + } + + /** + * Tests for equality between the specified object and this + * code signer. Two code signers are considered equal if their + * signer certificate paths are equal and if their timestamps are equal, + * if present in both. + * + * @param obj the object to test for equality with this object. + * + * @return true if the objects are considered equal, false otherwise. + */ + public boolean equals(Object obj) { + if (obj == null || (!(obj instanceof CodeSigner))) { + return false; + } + CodeSigner that = (CodeSigner)obj; + + if (this == that) { + return true; + } + Timestamp thatTimestamp = that.getTimestamp(); + if (timestamp == null) { + if (thatTimestamp != null) { + return false; + } + } else { + if (thatTimestamp == null || + (! timestamp.equals(thatTimestamp))) { + return false; + } + } + return signerCertPath.equals(that.getSignerCertPath()); + } + + /** + * Returns a string describing this code signer. + * + * @return A string comprising the signer's certificate and a timestamp, + * if present. + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("("); + sb.append("Signer: " + signerCertPath.getCertificates().get(0)); + if (timestamp != null) { + sb.append("timestamp: " + timestamp); + } + sb.append(")"); + return sb.toString(); + } + + // Explicitly reset hash code value to -1 + private void readObject(ObjectInputStream ois) + throws IOException, ClassNotFoundException { + ois.defaultReadObject(); + myhash = -1; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/CodeSource.java b/sources/net.sf.j2s.java.core/src/java/security/CodeSource.java new file mode 100644 index 000000000..62a5959ec --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/CodeSource.java @@ -0,0 +1,645 @@ +/* + * Copyright (c) 1997, 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 java.security; + + +import java.net.URL; +import java.net.SocketPermission; +import java.util.ArrayList; +import java.util.List; +import java.util.Hashtable; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.security.cert.*; + +/** + * + *

This class extends the concept of a codebase to + * encapsulate not only the location (URL) but also the certificate chains + * that were used to verify signed code originating from that location. + * + * @author Li Gong + * @author Roland Schemers + */ + +public class CodeSource implements java.io.Serializable { + + private static final long serialVersionUID = 4977541819976013951L; + + /** + * The code location. + * + * @serial + */ + private URL location; + + /* + * The code signers. + */ + private transient CodeSigner[] signers = null; + + /* + * The code signers. Certificate chains are concatenated. + */ + private transient java.security.cert.Certificate certs[] = null; + + // cached SocketPermission used for matchLocation + private transient SocketPermission sp; + + // for generating cert paths + private transient CertificateFactory factory = null; + + /** + * Constructs a CodeSource and associates it with the specified + * location and set of certificates. + * + * @param url the location (URL). + * + * @param certs the certificate(s). It may be null. The contents of the + * array are copied to protect against subsequent modification. + */ + public CodeSource(URL url, java.security.cert.Certificate certs[]) { + this.location = url; + + // Copy the supplied certs + if (certs != null) { + this.certs = certs.clone(); + } + } + + /** + * Constructs a CodeSource and associates it with the specified + * location and set of code signers. + * + * @param url the location (URL). + * @param signers the code signers. It may be null. The contents of the + * array are copied to protect against subsequent modification. + * + * @since 1.5 + */ + public CodeSource(URL url, CodeSigner[] signers) { + this.location = url; + + // Copy the supplied signers + if (signers != null) { + this.signers = signers.clone(); + } + } + + /** + * Returns the hash code value for this object. + * + * @return a hash code value for this object. + */ + @Override + public int hashCode() { + if (location != null) + return location.hashCode(); + else + return 0; + } + + /** + * Tests for equality between the specified object and this + * object. Two CodeSource objects are considered equal if their + * locations are of identical value and if their signer certificate + * chains are of identical value. It is not required that + * the certificate chains be in the same order. + * + * @param obj the object to test for equality with this object. + * + * @return true if the objects are considered equal, false otherwise. + */ + @Override + public boolean equals(Object obj) { + if (obj == this) + return true; + + // objects types must be equal + if (!(obj instanceof CodeSource)) + return false; + + CodeSource cs = (CodeSource) obj; + + // URLs must match + if (location == null) { + // if location is null, then cs.location must be null as well + if (cs.location != null) return false; + } else { + // if location is not null, then it must equal cs.location + if (!location.equals(cs.location)) return false; + } + + // certs must match + return matchCerts(cs, true); + } + + /** + * Returns the location associated with this CodeSource. + * + * @return the location (URL). + */ + public final URL getLocation() { + /* since URL is practically immutable, returning itself is not + a security problem */ + return this.location; + } + + /** + * Returns the certificates associated with this CodeSource. + *

+ * If this CodeSource object was created using the + * {@link #CodeSource(URL url, CodeSigner[] signers)} + * constructor then its certificate chains are extracted and used to + * create an array of Certificate objects. Each signer certificate is + * followed by its supporting certificate chain (which may be empty). + * Each signer certificate and its supporting certificate chain is ordered + * bottom-to-top (i.e., with the signer certificate first and the (root) + * certificate authority last). + * + * @return A copy of the certificates array, or null if there is none. + */ + public final java.security.cert.Certificate[] getCertificates() { + if (certs != null) { + return certs.clone(); + + } else if (signers != null) { + // Convert the code signers to certs + ArrayList certChains = + new ArrayList<>(); + for (int i = 0; i < signers.length; i++) { + certChains.addAll( + signers[i].getSignerCertPath().getCertificates()); + } + certs = certChains.toArray( + new java.security.cert.Certificate[certChains.size()]); + return certs.clone(); + + } else { + return null; + } + } + + /** + * Returns the code signers associated with this CodeSource. + *

+ * If this CodeSource object was created using the + * {@link #CodeSource(URL url, java.security.cert.Certificate[] certs)} + * constructor then its certificate chains are extracted and used to + * create an array of CodeSigner objects. Note that only X.509 certificates + * are examined - all other certificate types are ignored. + * + * @return A copy of the code signer array, or null if there is none. + * + * @since 1.5 + */ + public final CodeSigner[] getCodeSigners() { + if (signers != null) { + return signers.clone(); + + } else if (certs != null) { + // Convert the certs to code signers + signers = convertCertArrayToSignerArray(certs); + return signers.clone(); + + } else { + return null; + } + } + + /** + * Returns true if this CodeSource object "implies" the specified CodeSource. + *

+ * More specifically, this method makes the following checks. + * If any fail, it returns false. If they all succeed, it returns true. + *

    + *
  • codesource must not be null. + *
  • If this object's certificates are not null, then all + * of this object's certificates must be present in codesource's + * certificates. + *
  • If this object's location (getLocation()) is not null, then the + * following checks are made against this object's location and + * codesource's: + *
      + *
    • codesource's location must not be null. + * + *
    • If this object's location + * equals codesource's location, then return true. + * + *
    • This object's protocol (getLocation().getProtocol()) must be + * equal to codesource's protocol, ignoring case. + * + *
    • If this object's host (getLocation().getHost()) is not null, + * then the SocketPermission + * constructed with this object's host must imply the + * SocketPermission constructed with codesource's host. + * + *
    • If this object's port (getLocation().getPort()) is not + * equal to -1 (that is, if a port is specified), it must equal + * codesource's port or default port + * (codesource.getLocation().getDefaultPort()). + * + *
    • If this object's file (getLocation().getFile()) doesn't equal + * codesource's file, then the following checks are made: + * If this object's file ends with "/-", + * then codesource's file must start with this object's + * file (exclusive the trailing "-"). + * If this object's file ends with a "/*", + * then codesource's file must start with this object's + * file and must not have any further "/" separators. + * If this object's file doesn't end with a "/", + * then codesource's file must match this object's + * file with a '/' appended. + * + *
    • If this object's reference (getLocation().getRef()) is + * not null, it must equal codesource's reference. + * + *
    + *
+ *

+ * For example, the codesource objects with the following locations + * and null certificates all imply + * the codesource with the location "http://java.sun.com/classes/foo.jar" + * and null certificates: + *

+     *     http:
+     *     http://*.sun.com/classes/*
+     *     http://java.sun.com/classes/-
+     *     http://java.sun.com/classes/foo.jar
+     * 
+ * + * Note that if this CodeSource has a null location and a null + * certificate chain, then it implies every other CodeSource. + * + * @param codesource CodeSource to compare against. + * + * @return true if the specified codesource is implied by this codesource, + * false if not. + */ + + public boolean implies(CodeSource codesource) + { + if (codesource == null) + return false; + + return matchCerts(codesource, false) && matchLocation(codesource); + } + + /** + * Returns true if all the certs in this + * CodeSource are also in that. + * + * @param that the CodeSource to check against. + * @param strict If true then a strict equality match is performed. + * Otherwise a subset match is performed. + */ + private boolean matchCerts(CodeSource that, boolean strict) + { + boolean match; + + // match any key + if (certs == null && signers == null) { + if (strict) { + return (that.certs == null && that.signers == null); + } else { + return true; + } + // both have signers + } else if (signers != null && that.signers != null) { + if (strict && signers.length != that.signers.length) { + return false; + } + for (int i = 0; i < signers.length; i++) { + match = false; + for (int j = 0; j < that.signers.length; j++) { + if (signers[i].equals(that.signers[j])) { + match = true; + break; + } + } + if (!match) return false; + } + return true; + + // both have certs + } else if (certs != null && that.certs != null) { + if (strict && certs.length != that.certs.length) { + return false; + } + for (int i = 0; i < certs.length; i++) { + match = false; + for (int j = 0; j < that.certs.length; j++) { + if (certs[i].equals(that.certs[j])) { + match = true; + break; + } + } + if (!match) return false; + } + return true; + } + + return false; + } + + + /** + * Returns true if two CodeSource's have the "same" location. + * + * @param that CodeSource to compare against + */ + private boolean matchLocation(CodeSource that) { + if (location == null) + return true; + + if ((that == null) || (that.location == null)) + return false; + + if (location.equals(that.location)) + return true; + + if (!location.getProtocol().equalsIgnoreCase(that.location.getProtocol())) + return false; + + int thisPort = location.getPort(); + if (thisPort != -1) { + int thatPort = that.location.getPort(); + int port = thatPort != -1 ? thatPort + : that.location.getDefaultPort(); + if (thisPort != port) + return false; + } + + if (location.getFile().endsWith("/-")) { + // Matches the directory and (recursively) all files + // and subdirectories contained in that directory. + // For example, "/a/b/-" implies anything that starts with + // "/a/b/" + String thisPath = location.getFile().substring(0, + location.getFile().length()-1); + if (!that.location.getFile().startsWith(thisPath)) + return false; + } else if (location.getFile().endsWith("/*")) { + // Matches the directory and all the files contained in that + // directory. + // For example, "/a/b/*" implies anything that starts with + // "/a/b/" but has no further slashes + int last = that.location.getFile().lastIndexOf('/'); + if (last == -1) + return false; + String thisPath = location.getFile().substring(0, + location.getFile().length()-1); + String thatPath = that.location.getFile().substring(0, last+1); + if (!thatPath.equals(thisPath)) + return false; + } else { + // Exact matches only. + // For example, "/a/b" and "/a/b/" both imply "/a/b/" + if ((!that.location.getFile().equals(location.getFile())) + && (!that.location.getFile().equals(location.getFile()+"/"))) { + return false; + } + } + + if (location.getRef() != null + && !location.getRef().equals(that.location.getRef())) { + return false; + } + + String thisHost = location.getHost(); + String thatHost = that.location.getHost(); + if (thisHost != null) { + if (("".equals(thisHost) || "localhost".equals(thisHost)) && + ("".equals(thatHost) || "localhost".equals(thatHost))) { + // ok + } else if (!thisHost.equals(thatHost)) { + if (thatHost == null) { + return false; + } + if (this.sp == null) { + this.sp = new SocketPermission(thisHost, "resolve"); + } + if (that.sp == null) { + that.sp = new SocketPermission(thatHost, "resolve"); + } + if (!this.sp.implies(that.sp)) { + return false; + } + } + } + // everything matches + return true; + } + + /** + * Returns a string describing this CodeSource, telling its + * URL and certificates. + * + * @return information about this CodeSource. + */ + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("("); + sb.append(this.location); + + if (this.certs != null && this.certs.length > 0) { + for (int i = 0; i < this.certs.length; i++) { + sb.append( " " + this.certs[i]); + } + + } else if (this.signers != null && this.signers.length > 0) { + for (int i = 0; i < this.signers.length; i++) { + sb.append( " " + this.signers[i]); + } + } else { + sb.append(" "); + } + sb.append(")"); + return sb.toString(); + } + + /** + * Writes this object out to a stream (i.e., serializes it). + * + * @serialData An initial {@code URL} is followed by an + * {@code int} indicating the number of certificates to follow + * (a value of "zero" denotes that there are no certificates associated + * with this object). + * Each certificate is written out starting with a {@code String} + * denoting the certificate type, followed by an + * {@code int} specifying the length of the certificate encoding, + * followed by the certificate encoding itself which is written out as an + * array of bytes. Finally, if any code signers are present then the array + * of code signers is serialized and written out too. + */ + private void writeObject(java.io.ObjectOutputStream oos) + throws IOException + { + oos.defaultWriteObject(); // location + + // Serialize the array of certs + if (certs == null || certs.length == 0) { + oos.writeInt(0); + } else { + // write out the total number of certs + oos.writeInt(certs.length); + // write out each cert, including its type + for (int i = 0; i < certs.length; i++) { + java.security.cert.Certificate cert = certs[i]; + try { + oos.writeUTF(cert.getType()); + byte[] encoded = cert.getEncoded(); + oos.writeInt(encoded.length); + oos.write(encoded); + } catch (CertificateEncodingException cee) { + throw new IOException(cee.getMessage()); + } + } + } + + // Serialize the array of code signers (if any) + if (signers != null && signers.length > 0) { + oos.writeObject(signers); + } + } + + /** + * Restores this object from a stream (i.e., deserializes it). + */ + private void readObject(java.io.ObjectInputStream ois) + throws IOException, ClassNotFoundException + { + CertificateFactory cf; + Hashtable cfs = null; + + ois.defaultReadObject(); // location + + // process any new-style certs in the stream (if present) + int size = ois.readInt(); + if (size > 0) { + // we know of 3 different cert types: X.509, PGP, SDSI, which + // could all be present in the stream at the same time + cfs = new Hashtable(3); + this.certs = new java.security.cert.Certificate[size]; + } + + for (int i = 0; i < size; i++) { + // read the certificate type, and instantiate a certificate + // factory of that type (reuse existing factory if possible) + String certType = ois.readUTF(); + if (cfs.containsKey(certType)) { + // reuse certificate factory + cf = cfs.get(certType); + } else { + // create new certificate factory + try { + cf = CertificateFactory.getInstance(certType); + } catch (CertificateException ce) { + throw new ClassNotFoundException + ("Certificate factory for " + certType + " not found"); + } + // store the certificate factory so we can reuse it later + cfs.put(certType, cf); + } + // parse the certificate + byte[] encoded = null; + try { + encoded = new byte[ois.readInt()]; + } catch (OutOfMemoryError oome) { + throw new IOException("Certificate too big"); + } + ois.readFully(encoded); + ByteArrayInputStream bais = new ByteArrayInputStream(encoded); + try { + this.certs[i] = cf.generateCertificate(bais); + } catch (CertificateException ce) { + throw new IOException(ce.getMessage()); + } + bais.close(); + } + + // Deserialize array of code signers (if any) + try { + this.signers = ((CodeSigner[])ois.readObject()).clone(); + } catch (IOException ioe) { + // no signers present + } + } + + /* + * Convert an array of certificates to an array of code signers. + * The array of certificates is a concatenation of certificate chains + * where the initial certificate in each chain is the end-entity cert. + * + * @return An array of code signers or null if none are generated. + */ + private CodeSigner[] convertCertArrayToSignerArray( + java.security.cert.Certificate[] certs) { + + if (certs == null) { + return null; + } + + try { + // Initialize certificate factory + if (factory == null) { + factory = CertificateFactory.getInstance("X.509"); + } + + // Iterate through all the certificates + int i = 0; + List signers = new ArrayList<>(); + while (i < certs.length) { + List certChain = + new ArrayList<>(); + certChain.add(certs[i++]); // first cert is an end-entity cert + int j = i; + + // Extract chain of certificates + // (loop while certs are not end-entity certs) + while (j < certs.length && + certs[j] instanceof X509Certificate && + ((X509Certificate)certs[j]).getBasicConstraints() != -1) { + certChain.add(certs[j]); + j++; + } + i = j; + CertPath certPath = factory.generateCertPath(certChain); + signers.add(new CodeSigner(certPath, null)); + } + + if (signers.isEmpty()) { + return null; + } else { + return signers.toArray(new CodeSigner[signers.size()]); + } + + } catch (CertificateException e) { + return null; //TODO - may be better to throw an ex. here + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/CryptoPrimitive.java b/sources/net.sf.j2s.java.core/src/java/security/CryptoPrimitive.java new file mode 100644 index 000000000..158643b95 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/CryptoPrimitive.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2010, 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 java.security; + +/** + * An enumeration of cryptographic primitives. + * + * @since 1.7 + */ +public enum CryptoPrimitive { + /** + * Hash function + */ + MESSAGE_DIGEST, + + /** + * Cryptographic random number generator + */ + SECURE_RANDOM, + + /** + * Symmetric primitive: block cipher + */ + BLOCK_CIPHER, + + /** + * Symmetric primitive: stream cipher + */ + STREAM_CIPHER, + + /** + * Symmetric primitive: message authentication code + */ + MAC, + + /** + * Symmetric primitive: key wrap + */ + KEY_WRAP, + + /** + * Asymmetric primitive: public key encryption + */ + PUBLIC_KEY_ENCRYPTION, + + /** + * Asymmetric primitive: signature scheme + */ + SIGNATURE, + + /** + * Asymmetric primitive: key encapsulation mechanism + */ + KEY_ENCAPSULATION, + + /** + * Asymmetric primitive: key agreement and key distribution + */ + KEY_AGREEMENT +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/DigestException.java b/sources/net.sf.j2s.java.core/src/java/security/DigestException.java new file mode 100644 index 000000000..2327c9828 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/DigestException.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * This is the generic Message Digest exception. + * + * @author Benjamin Renaud + */ +public class DigestException extends GeneralSecurityException { + + private static final long serialVersionUID = 5821450303093652515L; + + /** + * Constructs a DigestException with no detail message. (A + * detail message is a String that describes this particular + * exception.) + */ + public DigestException() { + super(); + } + + /** + * Constructs a DigestException with the specified detail + * message. (A detail message is a String that describes this + * particular exception.) + * + * @param msg the detail message. + */ + public DigestException(String msg) { + super(msg); + } + + /** + * Creates a {@code DigestException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public DigestException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code DigestException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public DigestException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/DigestInputStream.java b/sources/net.sf.j2s.java.core/src/java/security/DigestInputStream.java new file mode 100644 index 000000000..a1bf55ac9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/DigestInputStream.java @@ -0,0 +1,188 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.io.IOException; +import java.io.EOFException; +import java.io.InputStream; +import java.io.FilterInputStream; +import java.io.PrintStream; +import java.io.ByteArrayInputStream; + +/** + * A transparent stream that updates the associated message digest using + * the bits going through the stream. + * + *

To complete the message digest computation, call one of the + * {@code digest} methods on the associated message + * digest after your calls to one of this digest input stream's + * {@link #read() read} methods. + * + *

It is possible to turn this stream on or off (see + * {@link #on(boolean) on}). When it is on, a call to one of the + * {@code read} methods + * results in an update on the message digest. But when it is off, + * the message digest is not updated. The default is for the stream + * to be on. + * + *

Note that digest objects can compute only one digest (see + * {@link MessageDigest}), + * so that in order to compute intermediate digests, a caller should + * retain a handle onto the digest object, and clone it for each + * digest to be computed, leaving the orginal digest untouched. + * + * @see MessageDigest + * + * @see DigestOutputStream + * + * @author Benjamin Renaud + */ + +public class DigestInputStream extends FilterInputStream { + + /* NOTE: This should be made a generic UpdaterInputStream */ + + /* Are we on or off? */ + private boolean on = true; + + /** + * The message digest associated with this stream. + */ + protected MessageDigest digest; + + /** + * Creates a digest input stream, using the specified input stream + * and message digest. + * + * @param stream the input stream. + * + * @param digest the message digest to associate with this stream. + */ + public DigestInputStream(InputStream stream, MessageDigest digest) { + super(stream); + setMessageDigest(digest); + } + + /** + * Returns the message digest associated with this stream. + * + * @return the message digest associated with this stream. + * @see #setMessageDigest(java.security.MessageDigest) + */ + public MessageDigest getMessageDigest() { + return digest; + } + + /** + * Associates the specified message digest with this stream. + * + * @param digest the message digest to be associated with this stream. + * @see #getMessageDigest() + */ + public void setMessageDigest(MessageDigest digest) { + this.digest = digest; + } + + /** + * Reads a byte, and updates the message digest (if the digest + * function is on). That is, this method reads a byte from the + * input stream, blocking until the byte is actually read. If the + * digest function is on (see {@link #on(boolean) on}), this method + * will then call {@code update} on the message digest associated + * with this stream, passing it the byte read. + * + * @return the byte read. + * + * @exception IOException if an I/O error occurs. + * + * @see MessageDigest#update(byte) + */ + public int read() throws IOException { + int ch = in.read(); + if (on && ch != -1) { + digest.update((byte)ch); + } + return ch; + } + + /** + * Reads into a byte array, and updates the message digest (if the + * digest function is on). That is, this method reads up to + * {@code len} bytes from the input stream into the array + * {@code b}, starting at offset {@code off}. This method + * blocks until the data is actually + * read. If the digest function is on (see + * {@link #on(boolean) on}), this method will then call {@code update} + * on the message digest associated with this stream, passing it + * the data. + * + * @param b the array into which the data is read. + * + * @param off the starting offset into {@code b} of where the + * data should be placed. + * + * @param len the maximum number of bytes to be read from the input + * stream into b, starting at offset {@code off}. + * + * @return the actual number of bytes read. This is less than + * {@code len} if the end of the stream is reached prior to + * reading {@code len} bytes. -1 is returned if no bytes were + * read because the end of the stream had already been reached when + * the call was made. + * + * @exception IOException if an I/O error occurs. + * + * @see MessageDigest#update(byte[], int, int) + */ + public int read(byte[] b, int off, int len) throws IOException { + int result = in.read(b, off, len); + if (on && result != -1) { + digest.update(b, off, result); + } + return result; + } + + /** + * Turns the digest function on or off. The default is on. When + * it is on, a call to one of the {@code read} methods results in an + * update on the message digest. But when it is off, the message + * digest is not updated. + * + * @param on true to turn the digest function on, false to turn + * it off. + */ + public void on(boolean on) { + this.on = on; + } + + /** + * Prints a string representation of this digest input stream and + * its associated message digest object. + */ + public String toString() { + return "[Digest Input Stream] " + digest.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/DigestOutputStream.java b/sources/net.sf.j2s.java.core/src/java/security/DigestOutputStream.java new file mode 100644 index 000000000..51db133a5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/DigestOutputStream.java @@ -0,0 +1,171 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.io.IOException; +import java.io.EOFException; +import java.io.OutputStream; +import java.io.FilterOutputStream; +import java.io.PrintStream; +import java.io.ByteArrayOutputStream; + +/** + * A transparent stream that updates the associated message digest using + * the bits going through the stream. + * + *

To complete the message digest computation, call one of the + * {@code digest} methods on the associated message + * digest after your calls to one of this digest output stream's + * {@link #write(int) write} methods. + * + *

It is possible to turn this stream on or off (see + * {@link #on(boolean) on}). When it is on, a call to one of the + * {@code write} methods results in + * an update on the message digest. But when it is off, the message + * digest is not updated. The default is for the stream to be on. + * + * @see MessageDigest + * @see DigestInputStream + * + * @author Benjamin Renaud + */ +public class DigestOutputStream extends FilterOutputStream { + + private boolean on = true; + + /** + * The message digest associated with this stream. + */ + protected MessageDigest digest; + + /** + * Creates a digest output stream, using the specified output stream + * and message digest. + * + * @param stream the output stream. + * + * @param digest the message digest to associate with this stream. + */ + public DigestOutputStream(OutputStream stream, MessageDigest digest) { + super(stream); + setMessageDigest(digest); + } + + /** + * Returns the message digest associated with this stream. + * + * @return the message digest associated with this stream. + * @see #setMessageDigest(java.security.MessageDigest) + */ + public MessageDigest getMessageDigest() { + return digest; + } + + /** + * Associates the specified message digest with this stream. + * + * @param digest the message digest to be associated with this stream. + * @see #getMessageDigest() + */ + public void setMessageDigest(MessageDigest digest) { + this.digest = digest; + } + + /** + * Updates the message digest (if the digest function is on) using + * the specified byte, and in any case writes the byte + * to the output stream. That is, if the digest function is on + * (see {@link #on(boolean) on}), this method calls + * {@code update} on the message digest associated with this + * stream, passing it the byte {@code b}. This method then + * writes the byte to the output stream, blocking until the byte + * is actually written. + * + * @param b the byte to be used for updating and writing to the + * output stream. + * + * @exception IOException if an I/O error occurs. + * + * @see MessageDigest#update(byte) + */ + public void write(int b) throws IOException { + out.write(b); + if (on) { + digest.update((byte)b); + } + } + + /** + * Updates the message digest (if the digest function is on) using + * the specified subarray, and in any case writes the subarray to + * the output stream. That is, if the digest function is on (see + * {@link #on(boolean) on}), this method calls {@code update} + * on the message digest associated with this stream, passing it + * the subarray specifications. This method then writes the subarray + * bytes to the output stream, blocking until the bytes are actually + * written. + * + * @param b the array containing the subarray to be used for updating + * and writing to the output stream. + * + * @param off the offset into {@code b} of the first byte to + * be updated and written. + * + * @param len the number of bytes of data to be updated and written + * from {@code b}, starting at offset {@code off}. + * + * @exception IOException if an I/O error occurs. + * + * @see MessageDigest#update(byte[], int, int) + */ + public void write(byte[] b, int off, int len) throws IOException { + out.write(b, off, len); + if (on) { + digest.update(b, off, len); + } + } + + /** + * Turns the digest function on or off. The default is on. When + * it is on, a call to one of the {@code write} methods results in an + * update on the message digest. But when it is off, the message + * digest is not updated. + * + * @param on true to turn the digest function on, false to turn it + * off. + */ + public void on(boolean on) { + this.on = on; + } + + /** + * Prints a string representation of this digest output stream and + * its associated message digest object. + */ + public String toString() { + return "[Digest Output Stream] " + digest.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/DomainCombiner.java b/sources/net.sf.j2s.java.core/src/java/security/DomainCombiner.java new file mode 100644 index 000000000..7aadc7e7b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/DomainCombiner.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1999, 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 java.security; + +/** + * A {@code DomainCombiner} provides a means to dynamically + * update the ProtectionDomains associated with the current + * {@code AccessControlContext}. + * + *

A {@code DomainCombiner} is passed as a parameter to the + * appropriate constructor for {@code AccessControlContext}. + * The newly constructed context is then passed to the + * {@code AccessController.doPrivileged(..., context)} method + * to bind the provided context (and associated {@code DomainCombiner}) + * with the current execution Thread. Subsequent calls to + * {@code AccessController.getContext} or + * {@code AccessController.checkPermission} + * cause the {@code DomainCombiner.combine} to get invoked. + * + *

The combine method takes two arguments. The first argument represents + * an array of ProtectionDomains from the current execution Thread, + * since the most recent call to {@code AccessController.doPrivileged}. + * If no call to doPrivileged was made, then the first argument will contain + * all the ProtectionDomains from the current execution Thread. + * The second argument represents an array of inherited ProtectionDomains, + * which may be {@code null}. ProtectionDomains may be inherited + * from a parent Thread, or from a privileged context. If no call to + * doPrivileged was made, then the second argument will contain the + * ProtectionDomains inherited from the parent Thread. If one or more calls + * to doPrivileged were made, and the most recent call was to + * doPrivileged(action, context), then the second argument will contain the + * ProtectionDomains from the privileged context. If the most recent call + * was to doPrivileged(action), then there is no privileged context, + * and the second argument will be {@code null}. + * + *

The {@code combine} method investigates the two input arrays + * of ProtectionDomains and returns a single array containing the updated + * ProtectionDomains. In the simplest case, the {@code combine} + * method merges the two stacks into one. In more complex cases, + * the {@code combine} method returns a modified + * stack of ProtectionDomains. The modification may have added new + * ProtectionDomains, removed certain ProtectionDomains, or simply + * updated existing ProtectionDomains. Re-ordering and other optimizations + * to the ProtectionDomains are also permitted. Typically the + * {@code combine} method bases its updates on the information + * encapsulated in the {@code DomainCombiner}. + * + *

After the {@code AccessController.getContext} method + * receives the combined stack of ProtectionDomains back from + * the {@code DomainCombiner}, it returns a new + * AccessControlContext that has both the combined ProtectionDomains + * as well as the {@code DomainCombiner}. + * + * @see AccessController + * @see AccessControlContext + * @since 1.3 + */ +public interface DomainCombiner { + + /** + * Modify or update the provided ProtectionDomains. + * ProtectionDomains may be added to or removed from the given + * ProtectionDomains. The ProtectionDomains may be re-ordered. + * Individual ProtectionDomains may be modified (with a new + * set of Permissions, for example). + * + *

+ * + * @param currentDomains the ProtectionDomains associated with the + * current execution Thread, up to the most recent + * privileged {@code ProtectionDomain}. + * The ProtectionDomains are are listed in order of execution, + * with the most recently executing {@code ProtectionDomain} + * residing at the beginning of the array. This parameter may + * be {@code null} if the current execution Thread + * has no associated ProtectionDomains.

+ * + * @param assignedDomains an array of inherited ProtectionDomains. + * ProtectionDomains may be inherited from a parent Thread, + * or from a privileged {@code AccessControlContext}. + * This parameter may be {@code null} + * if there are no inherited ProtectionDomains. + * + * @return a new array consisting of the updated ProtectionDomains, + * or {@code null}. + */ + ProtectionDomain[] combine(ProtectionDomain[] currentDomains, + ProtectionDomain[] assignedDomains); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/DomainLoadStoreParameter.java b/sources/net.sf.j2s.java.core/src/java/security/DomainLoadStoreParameter.java new file mode 100644 index 000000000..bc9697597 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/DomainLoadStoreParameter.java @@ -0,0 +1,171 @@ +/* + * 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 java.security; + +import java.net.URI; +import java.util.*; +import static java.security.KeyStore.*; + +/** + * Configuration data that specifies the keystores in a keystore domain. + * A keystore domain is a collection of keystores that are presented as a + * single logical keystore. The configuration data is used during + * {@code KeyStore} + * {@link KeyStore#load(KeyStore.LoadStoreParameter) load} and + * {@link KeyStore#store(KeyStore.LoadStoreParameter) store} operations. + *

+ * The following syntax is supported for configuration data: + *

{@code
+ *     domain  [ ...] {
+ *         keystore  [ ...] ;
+ *         ...
+ *     };
+ *     ...
+ * }
+ * where {@code domainName} and {@code keystoreName} are identifiers + * and {@code property} is a key/value pairing. The key and value are + * separated by an 'equals' symbol and the value is enclosed in double + * quotes. A property value may be either a printable string or a binary + * string of colon-separated pairs of hexadecimal digits. Multi-valued + * properties are represented as a comma-separated list of values, + * enclosed in square brackets. + * See {@link Arrays#toString(java.lang.Object[])}. + *

+ * To ensure that keystore entries are uniquely identified, each + * entry's alias is prefixed by its {@code keystoreName} followed + * by the entry name separator and each {@code keystoreName} must be + * unique within its domain. Entry name prefixes are omitted when + * storing a keystore. + *

+ * Properties are context-sensitive: properties that apply to + * all the keystores in a domain are located in the domain clause, + * and properties that apply only to a specific keystore are located + * in that keystore's clause. + * Unless otherwise specified, a property in a keystore clause overrides + * a property of the same name in the domain clause. All property names + * are case-insensitive. The following properties are supported: + *

+ *
{@code keystoreType=""}
+ *
The keystore type.
+ *
{@code keystoreURI=""}
+ *
The keystore location.
+ *
{@code keystoreProviderName=""}
+ *
The name of the keystore's JCE provider.
+ *
{@code keystorePasswordEnv=""}
+ *
The environment variable that stores a keystore password. + * Alternatively, passwords may be supplied to the constructor + * method in a {@code Map}.
+ *
{@code entryNameSeparator=""}
+ *
The separator between a keystore name prefix and an entry name. + * When specified, it applies to all the entries in a domain. + * Its default value is a space.
+ *
+ *

+ * For example, configuration data for a simple keystore domain + * comprising three keystores is shown below: + *

+ *
+ * domain app1 {
+ *     keystore app1-truststore
+ *         keystoreURI="file:///app1/etc/truststore.jks";
+ *
+ *     keystore system-truststore
+ *         keystoreURI="${java.home}/lib/security/cacerts";
+ *
+ *     keystore app1-keystore
+ *         keystoreType="PKCS12"
+ *         keystoreURI="file:///app1/etc/keystore.p12";
+ * };
+ *
+ * 
+ * @since 1.8 + */ +public final class DomainLoadStoreParameter implements LoadStoreParameter { + + private final URI configuration; + private final Map protectionParams; + + /** + * Constructs a DomainLoadStoreParameter for a keystore domain with + * the parameters used to protect keystore data. + * + * @param configuration identifier for the domain configuration data. + * The name of the target domain should be specified in the + * {@code java.net.URI} fragment component when it is necessary + * to distinguish between several domain configurations at the + * same location. + * + * @param protectionParams the map from keystore name to the parameter + * used to protect keystore data. + * A {@code java.util.Collections.EMPTY_MAP} should be used + * when protection parameters are not required or when they have + * been specified by properties in the domain configuration data. + * It is cloned to prevent subsequent modification. + * + * @exception NullPointerException if {@code configuration} or + * {@code protectionParams} is {@code null} + */ + public DomainLoadStoreParameter(URI configuration, + Map protectionParams) { + if (configuration == null || protectionParams == null) { + throw new NullPointerException("invalid null input"); + } + this.configuration = configuration; + this.protectionParams = + Collections.unmodifiableMap(new HashMap<>(protectionParams)); + } + + /** + * Gets the identifier for the domain configuration data. + * + * @return the identifier for the configuration data + */ + public URI getConfiguration() { + return configuration; + } + + /** + * Gets the keystore protection parameters for keystores in this + * domain. + * + * @return an unmodifiable map of keystore names to protection + * parameters + */ + public Map getProtectionParams() { + return protectionParams; + } + + /** + * Gets the keystore protection parameters for this domain. + * Keystore domains do not support a protection parameter. + * + * @return always returns {@code null} + */ + @Override + public KeyStore.ProtectionParameter getProtectionParameter() { + return null; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/GeneralSecurityException.java b/sources/net.sf.j2s.java.core/src/java/security/GeneralSecurityException.java new file mode 100644 index 000000000..dc9ea06ec --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/GeneralSecurityException.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1997, 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 java.security; + +/** + * The {@code GeneralSecurityException} class is a generic + * security exception class that provides type safety for all the + * security-related exception classes that extend from it. + * + * @author Jan Luehe + */ + +public class GeneralSecurityException extends Exception { + + private static final long serialVersionUID = 894798122053539237L; + + /** + * Constructs a GeneralSecurityException with no detail message. + */ + public GeneralSecurityException() { + super(); + } + + /** + * Constructs a GeneralSecurityException with the specified detail + * message. + * A detail message is a String that describes this particular + * exception. + * + * @param msg the detail message. + */ + public GeneralSecurityException(String msg) { + super(msg); + } + + /** + * Creates a {@code GeneralSecurityException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public GeneralSecurityException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code GeneralSecurityException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public GeneralSecurityException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Guard.java b/sources/net.sf.j2s.java.core/src/java/security/Guard.java new file mode 100644 index 000000000..abafb5886 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Guard.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1997, 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 java.security; + +/** + *

This interface represents a guard, which is an object that is used + * to protect access to another object. + * + *

This interface contains a single method, {@code checkGuard}, + * with a single {@code object} argument. {@code checkGuard} is + * invoked (by the GuardedObject {@code getObject} method) + * to determine whether or not to allow access to the object. + * + * @see GuardedObject + * + * @author Roland Schemers + * @author Li Gong + */ + +public interface Guard { + + /** + * Determines whether or not to allow access to the guarded object + * {@code object}. Returns silently if access is allowed. + * Otherwise, throws a SecurityException. + * + * @param object the object being protected by the guard. + * + * @exception SecurityException if access is denied. + * + */ + void checkGuard(Object object) throws SecurityException; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/GuardedObject.java b/sources/net.sf.j2s.java.core/src/java/security/GuardedObject.java new file mode 100644 index 000000000..a275ddf04 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/GuardedObject.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1997, 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 java.security; + +/** + * A GuardedObject is an object that is used to protect access to + * another object. + * + *

A GuardedObject encapsulates a target object and a Guard object, + * such that access to the target object is possible + * only if the Guard object allows it. + * Once an object is encapsulated by a GuardedObject, + * access to that object is controlled by the {@code getObject} + * method, which invokes the + * {@code checkGuard} method on the Guard object that is + * guarding access. If access is not allowed, + * an exception is thrown. + * + * @see Guard + * @see Permission + * + * @author Roland Schemers + * @author Li Gong + */ + +public class GuardedObject implements java.io.Serializable { + + private static final long serialVersionUID = -5240450096227834308L; + + private Object object; // the object we are guarding + private Guard guard; // the guard + + /** + * Constructs a GuardedObject using the specified object and guard. + * If the Guard object is null, then no restrictions will + * be placed on who can access the object. + * + * @param object the object to be guarded. + * + * @param guard the Guard object that guards access to the object. + */ + + public GuardedObject(Object object, Guard guard) + { + this.guard = guard; + this.object = object; + } + + /** + * Retrieves the guarded object, or throws an exception if access + * to the guarded object is denied by the guard. + * + * @return the guarded object. + * + * @exception SecurityException if access to the guarded object is + * denied. + */ + public Object getObject() + throws SecurityException + { + if (guard != null) + guard.checkGuard(object); + + return object; + } + + /** + * Writes this object out to a stream (i.e., serializes it). + * We check the guard if there is one. + */ + private void writeObject(java.io.ObjectOutputStream oos) + throws java.io.IOException + { + if (guard != null) + guard.checkGuard(object); + + oos.defaultWriteObject(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Identity.java b/sources/net.sf.j2s.java.core/src/java/security/Identity.java new file mode 100644 index 000000000..6a5e87e20 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Identity.java @@ -0,0 +1,495 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.io.Serializable; +import java.util.*; + +/** + *

This class represents identities: real-world objects such as people, + * companies or organizations whose identities can be authenticated using + * their public keys. Identities may also be more abstract (or concrete) + * constructs, such as daemon threads or smart cards. + * + *

All Identity objects have a name and a public key. Names are + * immutable. Identities may also be scoped. That is, if an Identity is + * specified to have a particular scope, then the name and public + * key of the Identity are unique within that scope. + * + *

An Identity also has a set of certificates (all certifying its own + * public key). The Principal names specified in these certificates need + * not be the same, only the key. + * + *

An Identity can be subclassed, to include postal and email addresses, + * telephone numbers, images of faces and logos, and so on. + * + * @see IdentityScope + * @see Signer + * @see Principal + * + * @author Benjamin Renaud + * @deprecated This class is no longer used. Its functionality has been + * replaced by {@code java.security.KeyStore}, the + * {@code java.security.cert} package, and + * {@code java.security.Principal}. + */ +@Deprecated +public abstract class Identity implements Principal, Serializable { + + /** use serialVersionUID from JDK 1.1.x for interoperability */ + private static final long serialVersionUID = 3609922007826600659L; + + /** + * The name for this identity. + * + * @serial + */ + private String name; + + /** + * The public key for this identity. + * + * @serial + */ + private PublicKey publicKey; + + /** + * Generic, descriptive information about the identity. + * + * @serial + */ + String info = "No further information available."; + + /** + * The scope of the identity. + * + * @serial + */ + IdentityScope scope; + + /** + * The certificates for this identity. + * + * @serial + */ + Vector certificates; + + /** + * Constructor for serialization only. + */ + protected Identity() { + this("restoring..."); + } + + /** + * Constructs an identity with the specified name and scope. + * + * @param name the identity name. + * @param scope the scope of the identity. + * + * @exception KeyManagementException if there is already an identity + * with the same name in the scope. + */ + public Identity(String name, IdentityScope scope) throws + KeyManagementException { + this(name); + if (scope != null) { + scope.addIdentity(this); + } + this.scope = scope; + } + + /** + * Constructs an identity with the specified name and no scope. + * + * @param name the identity name. + */ + public Identity(String name) { + this.name = name; + } + + /** + * Returns this identity's name. + * + * @return the name of this identity. + */ + public final String getName() { + return name; + } + + /** + * Returns this identity's scope. + * + * @return the scope of this identity. + */ + public final IdentityScope getScope() { + return scope; + } + + /** + * Returns this identity's public key. + * + * @return the public key for this identity. + * + * @see #setPublicKey + */ + public PublicKey getPublicKey() { + return publicKey; + } + + /** + * Sets this identity's public key. The old key and all of this + * identity's certificates are removed by this operation. + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "setIdentityPublicKey"} + * as its argument to see if it's ok to set the public key. + * + * @param key the public key for this identity. + * + * @exception KeyManagementException if another identity in the + * identity's scope has the same public key, or if another exception occurs. + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * setting the public key. + * + * @see #getPublicKey + * @see SecurityManager#checkSecurityAccess + */ + /* Should we throw an exception if this is already set? */ + public void setPublicKey(PublicKey key) throws KeyManagementException { + + check("setIdentityPublicKey"); + this.publicKey = key; + certificates = new Vector(); + } + + /** + * Specifies a general information string for this identity. + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "setIdentityInfo"} + * as its argument to see if it's ok to specify the information string. + * + * @param info the information string. + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * setting the information string. + * + * @see #getInfo + * @see SecurityManager#checkSecurityAccess + */ + public void setInfo(String info) { + check("setIdentityInfo"); + this.info = info; + } + + /** + * Returns general information previously specified for this identity. + * + * @return general information about this identity. + * + * @see #setInfo + */ + public String getInfo() { + return info; + } + + /** + * Adds a certificate for this identity. If the identity has a public + * key, the public key in the certificate must be the same, and if + * the identity does not have a public key, the identity's + * public key is set to be that specified in the certificate. + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "addIdentityCertificate"} + * as its argument to see if it's ok to add a certificate. + * + * @param certificate the certificate to be added. + * + * @exception KeyManagementException if the certificate is not valid, + * if the public key in the certificate being added conflicts with + * this identity's public key, or if another exception occurs. + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * adding a certificate. + * + * @see SecurityManager#checkSecurityAccess + */ + public void addCertificate(Certificate certificate) + throws KeyManagementException { + + check("addIdentityCertificate"); + + if (certificates == null) { + certificates = new Vector(); + } + if (publicKey != null) { + if (!keyEquals(publicKey, certificate.getPublicKey())) { + throw new KeyManagementException( + "public key different from cert public key"); + } + } else { + publicKey = certificate.getPublicKey(); + } + certificates.addElement(certificate); + } + + private boolean keyEquals(Key aKey, Key anotherKey) { + String aKeyFormat = aKey.getFormat(); + String anotherKeyFormat = anotherKey.getFormat(); + if ((aKeyFormat == null) ^ (anotherKeyFormat == null)) + return false; + if (aKeyFormat != null && anotherKeyFormat != null) + if (!aKeyFormat.equalsIgnoreCase(anotherKeyFormat)) + return false; + return java.util.Arrays.equals(aKey.getEncoded(), + anotherKey.getEncoded()); + } + + + /** + * Removes a certificate from this identity. + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "removeIdentityCertificate"} + * as its argument to see if it's ok to remove a certificate. + * + * @param certificate the certificate to be removed. + * + * @exception KeyManagementException if the certificate is + * missing, or if another exception occurs. + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * removing a certificate. + * + * @see SecurityManager#checkSecurityAccess + */ + public void removeCertificate(Certificate certificate) + throws KeyManagementException { + check("removeIdentityCertificate"); + if (certificates != null) { + certificates.removeElement(certificate); + } + } + + /** + * Returns a copy of all the certificates for this identity. + * + * @return a copy of all the certificates for this identity. + */ + public Certificate[] certificates() { + if (certificates == null) { + return new Certificate[0]; + } + int len = certificates.size(); + Certificate[] certs = new Certificate[len]; + certificates.copyInto(certs); + return certs; + } + + /** + * Tests for equality between the specified object and this identity. + * This first tests to see if the entities actually refer to the same + * object, in which case it returns true. Next, it checks to see if + * the entities have the same name and the same scope. If they do, + * the method returns true. Otherwise, it calls + * {@link #identityEquals(Identity) identityEquals}, which subclasses should + * override. + * + * @param identity the object to test for equality with this identity. + * + * @return true if the objects are considered equal, false otherwise. + * + * @see #identityEquals + */ + public final boolean equals(Object identity) { + + if (identity == this) { + return true; + } + + if (identity instanceof Identity) { + Identity i = (Identity)identity; + if (this.fullName().equals(i.fullName())) { + return true; + } else { + return identityEquals(i); + } + } + return false; + } + + /** + * Tests for equality between the specified identity and this identity. + * This method should be overriden by subclasses to test for equality. + * The default behavior is to return true if the names and public keys + * are equal. + * + * @param identity the identity to test for equality with this identity. + * + * @return true if the identities are considered equal, false + * otherwise. + * + * @see #equals + */ + protected boolean identityEquals(Identity identity) { + if (!name.equalsIgnoreCase(identity.name)) + return false; + + if ((publicKey == null) ^ (identity.publicKey == null)) + return false; + + if (publicKey != null && identity.publicKey != null) + if (!publicKey.equals(identity.publicKey)) + return false; + + return true; + + } + + /** + * Returns a parsable name for identity: identityName.scopeName + */ + String fullName() { + String parsable = name; + if (scope != null) { + parsable += "." + scope.getName(); + } + return parsable; + } + + /** + * Returns a short string describing this identity, telling its + * name and its scope (if any). + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "printIdentity"} + * as its argument to see if it's ok to return the string. + * + * @return information about this identity, such as its name and the + * name of its scope (if any). + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * returning a string describing this identity. + * + * @see SecurityManager#checkSecurityAccess + */ + public String toString() { + check("printIdentity"); + String printable = name; + if (scope != null) { + printable += "[" + scope.getName() + "]"; + } + return printable; + } + + /** + * Returns a string representation of this identity, with + * optionally more details than that provided by the + * {@code toString} method without any arguments. + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "printIdentity"} + * as its argument to see if it's ok to return the string. + * + * @param detailed whether or not to provide detailed information. + * + * @return information about this identity. If {@code detailed} + * is true, then this method returns more information than that + * provided by the {@code toString} method without any arguments. + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * returning a string describing this identity. + * + * @see #toString + * @see SecurityManager#checkSecurityAccess + */ + public String toString(boolean detailed) { + String out = toString(); + if (detailed) { + out += "\n"; + out += printKeys(); + out += "\n" + printCertificates(); + if (info != null) { + out += "\n\t" + info; + } else { + out += "\n\tno additional information available."; + } + } + return out; + } + + String printKeys() { + String key = ""; + if (publicKey != null) { + key = "\tpublic key initialized"; + } else { + key = "\tno public key"; + } + return key; + } + + String printCertificates() { + String out = ""; + if (certificates == null) { + return "\tno certificates"; + } else { + out += "\tcertificates: \n"; + + int i = 1; + for (Certificate cert : certificates) { + out += "\tcertificate " + i++ + + "\tfor : " + cert.getPrincipal() + "\n"; + out += "\t\t\tfrom : " + + cert.getGuarantor() + "\n"; + } + } + return out; + } + + /** + * Returns a hashcode for this identity. + * + * @return a hashcode for this identity. + */ + public int hashCode() { + return name.hashCode(); + } + + private static void check(String directive) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkSecurityAccess(directive); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/IdentityScope.java b/sources/net.sf.j2s.java.core/src/java/security/IdentityScope.java new file mode 100644 index 000000000..64c4a6343 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/IdentityScope.java @@ -0,0 +1,257 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.io.Serializable; +import java.util.Enumeration; +import java.util.Properties; + +/** + *

This class represents a scope for identities. It is an Identity + * itself, and therefore has a name and can have a scope. It can also + * optionally have a public key and associated certificates. + * + *

An IdentityScope can contain Identity objects of all kinds, including + * Signers. All types of Identity objects can be retrieved, added, and + * removed using the same methods. Note that it is possible, and in fact + * expected, that different types of identity scopes will + * apply different policies for their various operations on the + * various types of Identities. + * + *

There is a one-to-one mapping between keys and identities, and + * there can only be one copy of one key per scope. For example, suppose + * Acme Software, Inc is a software publisher known to a user. + * Suppose it is an Identity, that is, it has a public key, and a set of + * associated certificates. It is named in the scope using the name + * "Acme Software". No other named Identity in the scope has the same + * public key. Of course, none has the same name as well. + * + * @see Identity + * @see Signer + * @see Principal + * @see Key + * + * @author Benjamin Renaud + * + * @deprecated This class is no longer used. Its functionality has been + * replaced by {@code java.security.KeyStore}, the + * {@code java.security.cert} package, and + * {@code java.security.Principal}. + */ +@Deprecated +public abstract +class IdentityScope extends Identity { + + private static final long serialVersionUID = -2337346281189773310L; + + /* The system's scope */ + private static IdentityScope scope; + + // initialize the system scope + private static void initializeSystemScope() { + + String classname = AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return Security.getProperty("system.scope"); + } + }); + + if (classname == null) { + return; + + } else { + + try { + Class.forName(classname); + } catch (ClassNotFoundException e) { + //Security.error("unable to establish a system scope from " + + // classname); + e.printStackTrace(); + } + } + } + + /** + * This constructor is used for serialization only and should not + * be used by subclasses. + */ + protected IdentityScope() { + this("restoring..."); + } + + /** + * Constructs a new identity scope with the specified name. + * + * @param name the scope name. + */ + public IdentityScope(String name) { + super(name); + } + + /** + * Constructs a new identity scope with the specified name and scope. + * + * @param name the scope name. + * @param scope the scope for the new identity scope. + * + * @exception KeyManagementException if there is already an identity + * with the same name in the scope. + */ + public IdentityScope(String name, IdentityScope scope) + throws KeyManagementException { + super(name, scope); + } + + /** + * Returns the system's identity scope. + * + * @return the system's identity scope, or {@code null} if none has been + * set. + * + * @see #setSystemScope + */ + public static IdentityScope getSystemScope() { + if (scope == null) { + initializeSystemScope(); + } + return scope; + } + + + /** + * Sets the system's identity scope. + * + *

First, if there is a security manager, its + * {@code checkSecurityAccess} + * method is called with {@code "setSystemScope"} + * as its argument to see if it's ok to set the identity scope. + * + * @param scope the scope to set. + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * setting the identity scope. + * + * @see #getSystemScope + * @see SecurityManager#checkSecurityAccess + */ + protected static void setSystemScope(IdentityScope scope) { + check("setSystemScope"); + IdentityScope.scope = scope; + } + + /** + * Returns the number of identities within this identity scope. + * + * @return the number of identities within this identity scope. + */ + public abstract int size(); + + /** + * Returns the identity in this scope with the specified name (if any). + * + * @param name the name of the identity to be retrieved. + * + * @return the identity named {@code name}, or null if there are + * no identities named {@code name} in this scope. + */ + public abstract Identity getIdentity(String name); + + /** + * Retrieves the identity whose name is the same as that of the + * specified principal. (Note: Identity implements Principal.) + * + * @param principal the principal corresponding to the identity + * to be retrieved. + * + * @return the identity whose name is the same as that of the + * principal, or null if there are no identities of the same name + * in this scope. + */ + public Identity getIdentity(Principal principal) { + return getIdentity(principal.getName()); + } + + /** + * Retrieves the identity with the specified public key. + * + * @param key the public key for the identity to be returned. + * + * @return the identity with the given key, or null if there are + * no identities in this scope with that key. + */ + public abstract Identity getIdentity(PublicKey key); + + /** + * Adds an identity to this identity scope. + * + * @param identity the identity to be added. + * + * @exception KeyManagementException if the identity is not + * valid, a name conflict occurs, another identity has the same + * public key as the identity being added, or another exception + * occurs. */ + public abstract void addIdentity(Identity identity) + throws KeyManagementException; + + /** + * Removes an identity from this identity scope. + * + * @param identity the identity to be removed. + * + * @exception KeyManagementException if the identity is missing, + * or another exception occurs. + */ + public abstract void removeIdentity(Identity identity) + throws KeyManagementException; + + /** + * Returns an enumeration of all identities in this identity scope. + * + * @return an enumeration of all identities in this identity scope. + */ + public abstract Enumeration identities(); + + /** + * Returns a string representation of this identity scope, including + * its name, its scope name, and the number of identities in this + * identity scope. + * + * @return a string representation of this identity scope. + */ + public String toString() { + return super.toString() + "[" + size() + "]"; + } + + private static void check(String directive) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkSecurityAccess(directive); + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/InvalidAlgorithmParameterException.java b/sources/net.sf.j2s.java.core/src/java/security/InvalidAlgorithmParameterException.java new file mode 100644 index 000000000..559a8beed --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/InvalidAlgorithmParameterException.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 1997, 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 java.security; + +/** + * This is the exception for invalid or inappropriate algorithm parameters. + * + * @author Jan Luehe + * + * + * @see AlgorithmParameters + * @see java.security.spec.AlgorithmParameterSpec + * + * @since 1.2 + */ + +public class InvalidAlgorithmParameterException +extends GeneralSecurityException { + + private static final long serialVersionUID = 2864672297499471472L; + + /** + * Constructs an InvalidAlgorithmParameterException with no detail + * message. + * A detail message is a String that describes this particular + * exception. + */ + public InvalidAlgorithmParameterException() { + super(); + } + + /** + * Constructs an InvalidAlgorithmParameterException with the specified + * detail message. + * A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public InvalidAlgorithmParameterException(String msg) { + super(msg); + } + + /** + * Creates a {@code InvalidAlgorithmParameterException} with the + * specified detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public InvalidAlgorithmParameterException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code InvalidAlgorithmParameterException} with the + * specified cause and a detail message of + * {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public InvalidAlgorithmParameterException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/InvalidKeyException.java b/sources/net.sf.j2s.java.core/src/java/security/InvalidKeyException.java new file mode 100644 index 000000000..35fc64c3d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/InvalidKeyException.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * This is the exception for invalid Keys (invalid encoding, wrong + * length, uninitialized, etc). + * + * @author Benjamin Renaud + */ + +public class InvalidKeyException extends KeyException { + + private static final long serialVersionUID = 5698479920593359816L; + + /** + * Constructs an InvalidKeyException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public InvalidKeyException() { + super(); + } + + /** + * Constructs an InvalidKeyException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public InvalidKeyException(String msg) { + super(msg); + } + + /** + * Creates a {@code InvalidKeyException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public InvalidKeyException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code InvalidKeyException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public InvalidKeyException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/InvalidParameterException.java b/sources/net.sf.j2s.java.core/src/java/security/InvalidParameterException.java new file mode 100644 index 000000000..a095f90de --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/InvalidParameterException.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1996, 2003, 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 java.security; + +/** + * This exception, designed for use by the JCA/JCE engine classes, + * is thrown when an invalid parameter is passed + * to a method. + * + * @author Benjamin Renaud + */ + +public class InvalidParameterException extends IllegalArgumentException { + + private static final long serialVersionUID = -857968536935667808L; + + /** + * Constructs an InvalidParameterException with no detail message. + * A detail message is a String that describes this particular + * exception. + */ + public InvalidParameterException() { + super(); + } + + /** + * Constructs an InvalidParameterException with the specified + * detail message. A detail message is a String that describes + * this particular exception. + * + * @param msg the detail message. + */ + public InvalidParameterException(String msg) { + super(msg); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Key.java b/sources/net.sf.j2s.java.core/src/java/security/Key.java new file mode 100644 index 000000000..c0c63d7c7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Key.java @@ -0,0 +1,152 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * The Key interface is the top-level interface for all keys. It + * defines the functionality shared by all key objects. All keys + * have three characteristics: + * + *

    + * + *
  • An Algorithm + * + *

    This is the key algorithm for that key. The key algorithm is usually + * an encryption or asymmetric operation algorithm (such as DSA or + * RSA), which will work with those algorithms and with related + * algorithms (such as MD5 with RSA, SHA-1 with RSA, Raw DSA, etc.) + * The name of the algorithm of a key is obtained using the + * {@link #getAlgorithm() getAlgorithm} method. + * + *

  • An Encoded Form + * + *

    This is an external encoded form for the key used when a standard + * representation of the key is needed outside the Java Virtual Machine, + * as when transmitting the key to some other party. The key + * is encoded according to a standard format (such as + * X.509 {@code SubjectPublicKeyInfo} or PKCS#8), and + * is returned using the {@link #getEncoded() getEncoded} method. + * Note: The syntax of the ASN.1 type {@code SubjectPublicKeyInfo} + * is defined as follows: + * + *

    + * SubjectPublicKeyInfo ::= SEQUENCE {
    + *   algorithm AlgorithmIdentifier,
    + *   subjectPublicKey BIT STRING }
    + *
    + * AlgorithmIdentifier ::= SEQUENCE {
    + *   algorithm OBJECT IDENTIFIER,
    + *   parameters ANY DEFINED BY algorithm OPTIONAL }
    + * 
    + * + * For more information, see + * RFC 3280: + * Internet X.509 Public Key Infrastructure Certificate and CRL Profile. + * + *
  • A Format + * + *

    This is the name of the format of the encoded key. It is returned + * by the {@link #getFormat() getFormat} method. + * + *

+ * + * Keys are generally obtained through key generators, certificates, + * or various Identity classes used to manage keys. + * Keys may also be obtained from key specifications (transparent + * representations of the underlying key material) through the use of a key + * factory (see {@link KeyFactory}). + * + *

A Key should use KeyRep as its serialized representation. + * Note that a serialized Key may contain sensitive information + * which should not be exposed in untrusted environments. See the + * + * Security Appendix + * of the Serialization Specification for more information. + * + * @see PublicKey + * @see PrivateKey + * @see KeyPair + * @see KeyPairGenerator + * @see KeyFactory + * @see KeyRep + * @see java.security.spec.KeySpec + * @see Identity + * @see Signer + * + * @author Benjamin Renaud + */ + +public interface Key extends java.io.Serializable { + + // Declare serialVersionUID to be compatible with JDK1.1 + + /** + * The class fingerprint that is set to indicate + * serialization compatibility with a previous + * version of the class. + */ + static final long serialVersionUID = 6603384152749567654L; + + /** + * Returns the standard algorithm name for this key. For + * example, "DSA" would indicate that this key is a DSA key. + * See Appendix A in the + * Java Cryptography Architecture API Specification & Reference + * for information about standard algorithm names. + * + * @return the name of the algorithm associated with this key. + */ + public String getAlgorithm(); + + /** + * Returns the name of the primary encoding format of this key, + * or null if this key does not support encoding. + * The primary encoding format is + * named in terms of the appropriate ASN.1 data format, if an + * ASN.1 specification for this key exists. + * For example, the name of the ASN.1 data format for public + * keys is SubjectPublicKeyInfo, as + * defined by the X.509 standard; in this case, the returned format is + * {@code "X.509"}. Similarly, + * the name of the ASN.1 data format for private keys is + * PrivateKeyInfo, + * as defined by the PKCS #8 standard; in this case, the returned format is + * {@code "PKCS#8"}. + * + * @return the primary encoding format of the key. + */ + public String getFormat(); + + /** + * Returns the key in its primary encoding format, or null + * if this key does not support encoding. + * + * @return the encoded key, or null if the key does not support + * encoding. + */ + public byte[] getEncoded(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyException.java b/sources/net.sf.j2s.java.core/src/java/security/KeyException.java new file mode 100644 index 000000000..59cdd6f3a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyException.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * This is the basic key exception. + * + * @see Key + * @see InvalidKeyException + * @see KeyManagementException + * + * @author Benjamin Renaud + */ + +public class KeyException extends GeneralSecurityException { + + private static final long serialVersionUID = -7483676942812432108L; + + /** + * Constructs a KeyException with no detail message. A detail + * message is a String that describes this particular exception. + */ + public KeyException() { + super(); + } + + /** + * Constructs a KeyException with the specified detail message. + * A detail message is a String that describes this particular + * exception. + * + * @param msg the detail message. + */ + public KeyException(String msg) { + super(msg); + } + + /** + * Creates a {@code KeyException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public KeyException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code KeyException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public KeyException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyFactory.java b/sources/net.sf.j2s.java.core/src/java/security/KeyFactory.java new file mode 100644 index 000000000..8e761ff41 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyFactory.java @@ -0,0 +1,476 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.util.*; + +import java.security.Provider.Service; +import java.security.spec.KeySpec; +import java.security.spec.InvalidKeySpecException; + +import sun.security.util.Debug; +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; + +/** + * Key factories are used to convert keys (opaque + * cryptographic keys of type {@code Key}) into key specifications + * (transparent representations of the underlying key material), and vice + * versa. + * + *

Key factories are bi-directional. That is, they allow you to build an + * opaque key object from a given key specification (key material), or to + * retrieve the underlying key material of a key object in a suitable format. + * + *

Multiple compatible key specifications may exist for the same key. + * For example, a DSA public key may be specified using + * {@code DSAPublicKeySpec} or + * {@code X509EncodedKeySpec}. A key factory can be used to translate + * between compatible key specifications. + * + *

The following is an example of how to use a key factory in order to + * instantiate a DSA public key from its encoding. + * Assume Alice has received a digital signature from Bob. + * Bob also sent her his public key (in encoded format) to verify + * his signature. Alice then performs the following actions: + * + *

+ * X509EncodedKeySpec bobPubKeySpec = new X509EncodedKeySpec(bobEncodedPubKey);
+ * KeyFactory keyFactory = KeyFactory.getInstance("DSA");
+ * PublicKey bobPubKey = keyFactory.generatePublic(bobPubKeySpec);
+ * Signature sig = Signature.getInstance("DSA");
+ * sig.initVerify(bobPubKey);
+ * sig.update(data);
+ * sig.verify(signature);
+ * 
+ * + *

Every implementation of the Java platform is required to support the + * following standard {@code KeyFactory} algorithms: + *

    + *
  • {@code DiffieHellman}
  • + *
  • {@code DSA}
  • + *
  • {@code RSA}
  • + *
+ * These algorithms are described in the + * KeyFactory section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + * @author Jan Luehe + * + * @see Key + * @see PublicKey + * @see PrivateKey + * @see java.security.spec.KeySpec + * @see java.security.spec.DSAPublicKeySpec + * @see java.security.spec.X509EncodedKeySpec + * + * @since 1.2 + */ + +public class KeyFactory { + + private static final Debug debug = + Debug.getInstance("jca", "KeyFactory"); + + // The algorithm associated with this key factory + private final String algorithm; + + // The provider + private Provider provider; + + // The provider implementation (delegate) + private volatile KeyFactorySpi spi; + + // lock for mutex during provider selection + private final Object lock = new Object(); + + // remaining services to try in provider selection + // null once provider is selected + private Iterator serviceIterator; + + /** + * Creates a KeyFactory object. + * + * @param keyFacSpi the delegate + * @param provider the provider + * @param algorithm the name of the algorithm + * to associate with this {@code KeyFactory} + */ + protected KeyFactory(KeyFactorySpi keyFacSpi, Provider provider, + String algorithm) { + this.spi = keyFacSpi; + this.provider = provider; + this.algorithm = algorithm; + } + + private KeyFactory(String algorithm) throws NoSuchAlgorithmException { + this.algorithm = algorithm; + List list = GetInstance.getServices("KeyFactory", algorithm); + serviceIterator = list.iterator(); + // fetch and instantiate initial spi + if (nextSpi(null) == null) { + throw new NoSuchAlgorithmException + (algorithm + " KeyFactory not available"); + } + } + + /** + * Returns a KeyFactory object that converts + * public/private keys of the specified algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new KeyFactory object encapsulating the + * KeyFactorySpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the requested key algorithm. + * See the KeyFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return the new KeyFactory object. + * + * @exception NoSuchAlgorithmException if no Provider supports a + * KeyFactorySpi implementation for the + * specified algorithm. + * + * @see Provider + */ + public static KeyFactory getInstance(String algorithm) + throws NoSuchAlgorithmException { + return new KeyFactory(algorithm); + } + + /** + * Returns a KeyFactory object that converts + * public/private keys of the specified algorithm. + * + *

A new KeyFactory object encapsulating the + * KeyFactorySpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the requested key algorithm. + * See the KeyFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the name of the provider. + * + * @return the new KeyFactory object. + * + * @exception NoSuchAlgorithmException if a KeyFactorySpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + */ + public static KeyFactory getInstance(String algorithm, String provider) + throws NoSuchAlgorithmException, NoSuchProviderException { + Instance instance = GetInstance.getInstance("KeyFactory", + KeyFactorySpi.class, algorithm, provider); + return new KeyFactory((KeyFactorySpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns a KeyFactory object that converts + * public/private keys of the specified algorithm. + * + *

A new KeyFactory object encapsulating the + * KeyFactorySpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param algorithm the name of the requested key algorithm. + * See the KeyFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the provider. + * + * @return the new KeyFactory object. + * + * @exception NoSuchAlgorithmException if a KeyFactorySpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the specified provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static KeyFactory getInstance(String algorithm, Provider provider) + throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("KeyFactory", + KeyFactorySpi.class, algorithm, provider); + return new KeyFactory((KeyFactorySpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns the provider of this key factory object. + * + * @return the provider of this key factory object + */ + public final Provider getProvider() { + synchronized (lock) { + // disable further failover after this call + serviceIterator = null; + return provider; + } + } + + /** + * Gets the name of the algorithm + * associated with this {@code KeyFactory}. + * + * @return the name of the algorithm associated with this + * {@code KeyFactory} + */ + public final String getAlgorithm() { + return this.algorithm; + } + + /** + * Update the active KeyFactorySpi of this class and return the next + * implementation for failover. If no more implemenations are + * available, this method returns null. However, the active spi of + * this class is never set to null. + */ + private KeyFactorySpi nextSpi(KeyFactorySpi oldSpi) { + synchronized (lock) { + // somebody else did a failover concurrently + // try that spi now + if ((oldSpi != null) && (oldSpi != spi)) { + return spi; + } + if (serviceIterator == null) { + return null; + } + while (serviceIterator.hasNext()) { + Service s = serviceIterator.next(); + try { + Object obj = s.newInstance(null); + if (obj instanceof KeyFactorySpi == false) { + continue; + } + KeyFactorySpi spi = (KeyFactorySpi)obj; + provider = s.getProvider(); + this.spi = spi; + return spi; + } catch (NoSuchAlgorithmException e) { + // ignore + } + } + serviceIterator = null; + return null; + } + } + + /** + * Generates a public key object from the provided key specification + * (key material). + * + * @param keySpec the specification (key material) of the public key. + * + * @return the public key. + * + * @exception InvalidKeySpecException if the given key specification + * is inappropriate for this key factory to produce a public key. + */ + public final PublicKey generatePublic(KeySpec keySpec) + throws InvalidKeySpecException { + if (serviceIterator == null) { + return spi.engineGeneratePublic(keySpec); + } + Exception failure = null; + KeyFactorySpi mySpi = spi; + do { + try { + return mySpi.engineGeneratePublic(keySpec); + } catch (Exception e) { + if (failure == null) { + failure = e; + } + mySpi = nextSpi(mySpi); + } + } while (mySpi != null); + if (failure instanceof RuntimeException) { + throw (RuntimeException)failure; + } + if (failure instanceof InvalidKeySpecException) { + throw (InvalidKeySpecException)failure; + } + throw new InvalidKeySpecException + ("Could not generate public key", failure); + } + + /** + * Generates a private key object from the provided key specification + * (key material). + * + * @param keySpec the specification (key material) of the private key. + * + * @return the private key. + * + * @exception InvalidKeySpecException if the given key specification + * is inappropriate for this key factory to produce a private key. + */ + public final PrivateKey generatePrivate(KeySpec keySpec) + throws InvalidKeySpecException { + if (serviceIterator == null) { + return spi.engineGeneratePrivate(keySpec); + } + Exception failure = null; + KeyFactorySpi mySpi = spi; + do { + try { + return mySpi.engineGeneratePrivate(keySpec); + } catch (Exception e) { + if (failure == null) { + failure = e; + } + mySpi = nextSpi(mySpi); + } + } while (mySpi != null); + if (failure instanceof RuntimeException) { + throw (RuntimeException)failure; + } + if (failure instanceof InvalidKeySpecException) { + throw (InvalidKeySpecException)failure; + } + throw new InvalidKeySpecException + ("Could not generate private key", failure); + } + + /** + * Returns a specification (key material) of the given key object. + * {@code keySpec} identifies the specification class in which + * the key material should be returned. It could, for example, be + * {@code DSAPublicKeySpec.class}, to indicate that the + * key material should be returned in an instance of the + * {@code DSAPublicKeySpec} class. + * + * @param the type of the key specification to be returned + * + * @param key the key. + * + * @param keySpec the specification class in which + * the key material should be returned. + * + * @return the underlying key specification (key material) in an instance + * of the requested specification class. + * + * @exception InvalidKeySpecException if the requested key specification is + * inappropriate for the given key, or the given key cannot be processed + * (e.g., the given key has an unrecognized algorithm or format). + */ + public final T getKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException { + if (serviceIterator == null) { + return spi.engineGetKeySpec(key, keySpec); + } + Exception failure = null; + KeyFactorySpi mySpi = spi; + do { + try { + return mySpi.engineGetKeySpec(key, keySpec); + } catch (Exception e) { + if (failure == null) { + failure = e; + } + mySpi = nextSpi(mySpi); + } + } while (mySpi != null); + if (failure instanceof RuntimeException) { + throw (RuntimeException)failure; + } + if (failure instanceof InvalidKeySpecException) { + throw (InvalidKeySpecException)failure; + } + throw new InvalidKeySpecException + ("Could not get key spec", failure); + } + + /** + * Translates a key object, whose provider may be unknown or potentially + * untrusted, into a corresponding key object of this key factory. + * + * @param key the key whose provider is unknown or untrusted. + * + * @return the translated key. + * + * @exception InvalidKeyException if the given key cannot be processed + * by this key factory. + */ + public final Key translateKey(Key key) throws InvalidKeyException { + if (serviceIterator == null) { + return spi.engineTranslateKey(key); + } + Exception failure = null; + KeyFactorySpi mySpi = spi; + do { + try { + return mySpi.engineTranslateKey(key); + } catch (Exception e) { + if (failure == null) { + failure = e; + } + mySpi = nextSpi(mySpi); + } + } while (mySpi != null); + if (failure instanceof RuntimeException) { + throw (RuntimeException)failure; + } + if (failure instanceof InvalidKeyException) { + throw (InvalidKeyException)failure; + } + throw new InvalidKeyException + ("Could not translate key", failure); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyFactorySpi.java b/sources/net.sf.j2s.java.core/src/java/security/KeyFactorySpi.java new file mode 100644 index 000000000..5ee7f4589 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyFactorySpi.java @@ -0,0 +1,142 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.security.spec.KeySpec; +import java.security.spec.InvalidKeySpecException; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code KeyFactory} class. + * All the abstract methods in this class must be implemented by each + * cryptographic service provider who wishes to supply the implementation + * of a key factory for a particular algorithm. + * + *

Key factories are used to convert keys (opaque + * cryptographic keys of type {@code Key}) into key specifications + * (transparent representations of the underlying key material), and vice + * versa. + * + *

Key factories are bi-directional. That is, they allow you to build an + * opaque key object from a given key specification (key material), or to + * retrieve the underlying key material of a key object in a suitable format. + * + *

Multiple compatible key specifications may exist for the same key. + * For example, a DSA public key may be specified using + * {@code DSAPublicKeySpec} or + * {@code X509EncodedKeySpec}. A key factory can be used to translate + * between compatible key specifications. + * + *

A provider should document all the key specifications supported by its + * key factory. + * + * @author Jan Luehe + * + * + * @see KeyFactory + * @see Key + * @see PublicKey + * @see PrivateKey + * @see java.security.spec.KeySpec + * @see java.security.spec.DSAPublicKeySpec + * @see java.security.spec.X509EncodedKeySpec + * + * @since 1.2 + */ + +public abstract class KeyFactorySpi { + + /** + * Generates a public key object from the provided key + * specification (key material). + * + * @param keySpec the specification (key material) of the public key. + * + * @return the public key. + * + * @exception InvalidKeySpecException if the given key specification + * is inappropriate for this key factory to produce a public key. + */ + protected abstract PublicKey engineGeneratePublic(KeySpec keySpec) + throws InvalidKeySpecException; + + /** + * Generates a private key object from the provided key + * specification (key material). + * + * @param keySpec the specification (key material) of the private key. + * + * @return the private key. + * + * @exception InvalidKeySpecException if the given key specification + * is inappropriate for this key factory to produce a private key. + */ + protected abstract PrivateKey engineGeneratePrivate(KeySpec keySpec) + throws InvalidKeySpecException; + + /** + * Returns a specification (key material) of the given key + * object. + * {@code keySpec} identifies the specification class in which + * the key material should be returned. It could, for example, be + * {@code DSAPublicKeySpec.class}, to indicate that the + * key material should be returned in an instance of the + * {@code DSAPublicKeySpec} class. + * + * @param the type of the key specification to be returned + * + * @param key the key. + * + * @param keySpec the specification class in which + * the key material should be returned. + * + * @return the underlying key specification (key material) in an instance + * of the requested specification class. + + * @exception InvalidKeySpecException if the requested key specification is + * inappropriate for the given key, or the given key cannot be dealt with + * (e.g., the given key has an unrecognized format). + */ + protected abstract + T engineGetKeySpec(Key key, Class keySpec) + throws InvalidKeySpecException; + + /** + * Translates a key object, whose provider may be unknown or + * potentially untrusted, into a corresponding key object of this key + * factory. + * + * @param key the key whose provider is unknown or untrusted. + * + * @return the translated key. + * + * @exception InvalidKeyException if the given key cannot be processed + * by this key factory. + */ + protected abstract Key engineTranslateKey(Key key) + throws InvalidKeyException; + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyManagementException.java b/sources/net.sf.j2s.java.core/src/java/security/KeyManagementException.java new file mode 100644 index 000000000..be212b9fd --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyManagementException.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * This is the general key management exception for all operations + * dealing with key management. Examples of subclasses of + * KeyManagementException that developers might create for + * giving more detailed information could include: + * + *

    + *
  • KeyIDConflictException + *
  • KeyAuthorizationFailureException + *
  • ExpiredKeyException + *
+ * + * @author Benjamin Renaud + * + * @see Key + * @see KeyException + */ + +public class KeyManagementException extends KeyException { + + private static final long serialVersionUID = 947674216157062695L; + + /** + * Constructs a KeyManagementException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public KeyManagementException() { + super(); + } + + /** + * Constructs a KeyManagementException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public KeyManagementException(String msg) { + super(msg); + } + + /** + * Creates a {@code KeyManagementException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public KeyManagementException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code KeyManagementException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public KeyManagementException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyPair.java b/sources/net.sf.j2s.java.core/src/java/security/KeyPair.java new file mode 100644 index 000000000..6147a16aa --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyPair.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.util.*; + +/** + * This class is a simple holder for a key pair (a public key and a + * private key). It does not enforce any security, and, when initialized, + * should be treated like a PrivateKey. + * + * @see PublicKey + * @see PrivateKey + * + * @author Benjamin Renaud + */ + +public final class KeyPair implements java.io.Serializable { + + private static final long serialVersionUID = -7565189502268009837L; + + private PrivateKey privateKey; + private PublicKey publicKey; + + /** + * Constructs a key pair from the given public key and private key. + * + *

Note that this constructor only stores references to the public + * and private key components in the generated key pair. This is safe, + * because {@code Key} objects are immutable. + * + * @param publicKey the public key. + * + * @param privateKey the private key. + */ + public KeyPair(PublicKey publicKey, PrivateKey privateKey) { + this.publicKey = publicKey; + this.privateKey = privateKey; + } + + /** + * Returns a reference to the public key component of this key pair. + * + * @return a reference to the public key. + */ + public PublicKey getPublic() { + return publicKey; + } + + /** + * Returns a reference to the private key component of this key pair. + * + * @return a reference to the private key. + */ + public PrivateKey getPrivate() { + return privateKey; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyPairGenerator.java b/sources/net.sf.j2s.java.core/src/java/security/KeyPairGenerator.java new file mode 100644 index 000000000..205676889 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyPairGenerator.java @@ -0,0 +1,715 @@ +/* + * Copyright (c) 1997, 2014, 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 java.security; + +import java.util.*; + +import java.security.spec.AlgorithmParameterSpec; + +import java.security.Provider.Service; + +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; +import sun.security.util.Debug; + +/** + * The KeyPairGenerator class is used to generate pairs of + * public and private keys. Key pair generators are constructed using the + * {@code getInstance} factory methods (static methods that + * return instances of a given class). + * + *

A Key pair generator for a particular algorithm creates a public/private + * key pair that can be used with this algorithm. It also associates + * algorithm-specific parameters with each of the generated keys. + * + *

There are two ways to generate a key pair: in an algorithm-independent + * manner, and in an algorithm-specific manner. + * The only difference between the two is the initialization of the object: + * + *

    + *
  • Algorithm-Independent Initialization + *

    All key pair generators share the concepts of a keysize and a + * source of randomness. The keysize is interpreted differently for different + * algorithms (e.g., in the case of the DSA algorithm, the keysize + * corresponds to the length of the modulus). + * There is an + * {@link #initialize(int, java.security.SecureRandom) initialize} + * method in this KeyPairGenerator class that takes these two universally + * shared types of arguments. There is also one that takes just a + * {@code keysize} argument, and uses the {@code SecureRandom} + * implementation of the highest-priority installed provider as the source + * of randomness. (If none of the installed providers supply an implementation + * of {@code SecureRandom}, a system-provided source of randomness is + * used.) + * + *

    Since no other parameters are specified when you call the above + * algorithm-independent {@code initialize} methods, it is up to the + * provider what to do about the algorithm-specific parameters (if any) to be + * associated with each of the keys. + * + *

    If the algorithm is the DSA algorithm, and the keysize (modulus + * size) is 512, 768, or 1024, then the Sun provider uses a set of + * precomputed values for the {@code p}, {@code q}, and + * {@code g} parameters. If the modulus size is not one of the above + * values, the Sun provider creates a new set of parameters. Other + * providers might have precomputed parameter sets for more than just the + * three modulus sizes mentioned above. Still others might not have a list of + * precomputed parameters at all and instead always create new parameter sets. + * + *

  • Algorithm-Specific Initialization + *

    For situations where a set of algorithm-specific parameters already + * exists (e.g., so-called community parameters in DSA), there are two + * {@link #initialize(java.security.spec.AlgorithmParameterSpec) + * initialize} methods that have an {@code AlgorithmParameterSpec} + * argument. One also has a {@code SecureRandom} argument, while the + * the other uses the {@code SecureRandom} + * implementation of the highest-priority installed provider as the source + * of randomness. (If none of the installed providers supply an implementation + * of {@code SecureRandom}, a system-provided source of randomness is + * used.) + *

+ * + *

In case the client does not explicitly initialize the KeyPairGenerator + * (via a call to an {@code initialize} method), each provider must + * supply (and document) a default initialization. + * For example, the Sun provider uses a default modulus size (keysize) + * of 1024 bits. + * + *

Note that this class is abstract and extends from + * {@code KeyPairGeneratorSpi} for historical reasons. + * Application developers should only take notice of the methods defined in + * this {@code KeyPairGenerator} class; all the methods in + * the superclass are intended for cryptographic service providers who wish to + * supply their own implementations of key pair generators. + * + *

Every implementation of the Java platform is required to support the + * following standard {@code KeyPairGenerator} algorithms and keysizes in + * parentheses: + *

    + *
  • {@code DiffieHellman} (1024)
  • + *
  • {@code DSA} (1024)
  • + *
  • {@code RSA} (1024, 2048)
  • + *
+ * These algorithms are described in the + * KeyPairGenerator section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + * @author Benjamin Renaud + * + * @see java.security.spec.AlgorithmParameterSpec + */ + +public abstract class KeyPairGenerator extends KeyPairGeneratorSpi { + + private static final Debug pdebug = + Debug.getInstance("provider", "Provider"); + private static final boolean skipDebug = + Debug.isOn("engine=") && !Debug.isOn("keypairgenerator"); + + private final String algorithm; + + // The provider + Provider provider; + + /** + * Creates a KeyPairGenerator object for the specified algorithm. + * + * @param algorithm the standard string name of the algorithm. + * See the KeyPairGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + */ + protected KeyPairGenerator(String algorithm) { + this.algorithm = algorithm; + } + + /** + * Returns the standard name of the algorithm for this key pair generator. + * See the KeyPairGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return the standard string name of the algorithm. + */ + public String getAlgorithm() { + return this.algorithm; + } + + private static KeyPairGenerator getInstance(Instance instance, + String algorithm) { + KeyPairGenerator kpg; + if (instance.impl instanceof KeyPairGenerator) { + kpg = (KeyPairGenerator)instance.impl; + } else { + KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)instance.impl; + kpg = new Delegate(spi, algorithm); + } + kpg.provider = instance.provider; + + if (!skipDebug && pdebug != null) { + pdebug.println("KeyPairGenerator." + algorithm + + " algorithm from: " + kpg.provider.getName()); + } + + return kpg; + } + + /** + * Returns a KeyPairGenerator object that generates public/private + * key pairs for the specified algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new KeyPairGenerator object encapsulating the + * KeyPairGeneratorSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the standard string name of the algorithm. + * See the KeyPairGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return the new KeyPairGenerator object. + * + * @exception NoSuchAlgorithmException if no Provider supports a + * KeyPairGeneratorSpi implementation for the + * specified algorithm. + * + * @see Provider + */ + public static KeyPairGenerator getInstance(String algorithm) + throws NoSuchAlgorithmException { + List list = + GetInstance.getServices("KeyPairGenerator", algorithm); + Iterator t = list.iterator(); + if (t.hasNext() == false) { + throw new NoSuchAlgorithmException + (algorithm + " KeyPairGenerator not available"); + } + // find a working Spi or KeyPairGenerator subclass + NoSuchAlgorithmException failure = null; + do { + Service s = t.next(); + try { + Instance instance = + GetInstance.getInstance(s, KeyPairGeneratorSpi.class); + if (instance.impl instanceof KeyPairGenerator) { + return getInstance(instance, algorithm); + } else { + return new Delegate(instance, t, algorithm); + } + } catch (NoSuchAlgorithmException e) { + if (failure == null) { + failure = e; + } + } + } while (t.hasNext()); + throw failure; + } + + /** + * Returns a KeyPairGenerator object that generates public/private + * key pairs for the specified algorithm. + * + *

A new KeyPairGenerator object encapsulating the + * KeyPairGeneratorSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the standard string name of the algorithm. + * See the KeyPairGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the string name of the provider. + * + * @return the new KeyPairGenerator object. + * + * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + */ + public static KeyPairGenerator getInstance(String algorithm, + String provider) + throws NoSuchAlgorithmException, NoSuchProviderException { + Instance instance = GetInstance.getInstance("KeyPairGenerator", + KeyPairGeneratorSpi.class, algorithm, provider); + return getInstance(instance, algorithm); + } + + /** + * Returns a KeyPairGenerator object that generates public/private + * key pairs for the specified algorithm. + * + *

A new KeyPairGenerator object encapsulating the + * KeyPairGeneratorSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param algorithm the standard string name of the algorithm. + * See the KeyPairGenerator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the provider. + * + * @return the new KeyPairGenerator object. + * + * @exception NoSuchAlgorithmException if a KeyPairGeneratorSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the specified provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static KeyPairGenerator getInstance(String algorithm, + Provider provider) throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("KeyPairGenerator", + KeyPairGeneratorSpi.class, algorithm, provider); + return getInstance(instance, algorithm); + } + + /** + * Returns the provider of this key pair generator object. + * + * @return the provider of this key pair generator object + */ + public final Provider getProvider() { + disableFailover(); + return this.provider; + } + + void disableFailover() { + // empty, overridden in Delegate + } + + /** + * Initializes the key pair generator for a certain keysize using + * a default parameter set and the {@code SecureRandom} + * implementation of the highest-priority installed provider as the source + * of randomness. + * (If none of the installed providers supply an implementation of + * {@code SecureRandom}, a system-provided source of randomness is + * used.) + * + * @param keysize the keysize. This is an + * algorithm-specific metric, such as modulus length, specified in + * number of bits. + * + * @exception InvalidParameterException if the {@code keysize} is not + * supported by this KeyPairGenerator object. + */ + public void initialize(int keysize) { + initialize(keysize, JCAUtil.getSecureRandom()); + } + + /** + * Initializes the key pair generator for a certain keysize with + * the given source of randomness (and a default parameter set). + * + * @param keysize the keysize. This is an + * algorithm-specific metric, such as modulus length, specified in + * number of bits. + * @param random the source of randomness. + * + * @exception InvalidParameterException if the {@code keysize} is not + * supported by this KeyPairGenerator object. + * + * @since 1.2 + */ + public void initialize(int keysize, SecureRandom random) { + // This does nothing, because either + // 1. the implementation object returned by getInstance() is an + // instance of KeyPairGenerator which has its own + // initialize(keysize, random) method, so the application would + // be calling that method directly, or + // 2. the implementation returned by getInstance() is an instance + // of Delegate, in which case initialize(keysize, random) is + // overridden to call the corresponding SPI method. + // (This is a special case, because the API and SPI method have the + // same name.) + } + + /** + * Initializes the key pair generator using the specified parameter + * set and the {@code SecureRandom} + * implementation of the highest-priority installed provider as the source + * of randomness. + * (If none of the installed providers supply an implementation of + * {@code SecureRandom}, a system-provided source of randomness is + * used.). + * + *

This concrete method has been added to this previously-defined + * abstract class. + * This method calls the KeyPairGeneratorSpi + * {@link KeyPairGeneratorSpi#initialize( + * java.security.spec.AlgorithmParameterSpec, + * java.security.SecureRandom) initialize} method, + * passing it {@code params} and a source of randomness (obtained + * from the highest-priority installed provider or system-provided if none + * of the installed providers supply one). + * That {@code initialize} method always throws an + * UnsupportedOperationException if it is not overridden by the provider. + * + * @param params the parameter set used to generate the keys. + * + * @exception InvalidAlgorithmParameterException if the given parameters + * are inappropriate for this key pair generator. + * + * @since 1.2 + */ + public void initialize(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + initialize(params, JCAUtil.getSecureRandom()); + } + + /** + * Initializes the key pair generator with the given parameter + * set and source of randomness. + * + *

This concrete method has been added to this previously-defined + * abstract class. + * This method calls the KeyPairGeneratorSpi {@link + * KeyPairGeneratorSpi#initialize( + * java.security.spec.AlgorithmParameterSpec, + * java.security.SecureRandom) initialize} method, + * passing it {@code params} and {@code random}. + * That {@code initialize} + * method always throws an + * UnsupportedOperationException if it is not overridden by the provider. + * + * @param params the parameter set used to generate the keys. + * @param random the source of randomness. + * + * @exception InvalidAlgorithmParameterException if the given parameters + * are inappropriate for this key pair generator. + * + * @since 1.2 + */ + public void initialize(AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException + { + // This does nothing, because either + // 1. the implementation object returned by getInstance() is an + // instance of KeyPairGenerator which has its own + // initialize(params, random) method, so the application would + // be calling that method directly, or + // 2. the implementation returned by getInstance() is an instance + // of Delegate, in which case initialize(params, random) is + // overridden to call the corresponding SPI method. + // (This is a special case, because the API and SPI method have the + // same name.) + } + + /** + * Generates a key pair. + * + *

If this KeyPairGenerator has not been initialized explicitly, + * provider-specific defaults will be used for the size and other + * (algorithm-specific) values of the generated keys. + * + *

This will generate a new key pair every time it is called. + * + *

This method is functionally equivalent to + * {@link #generateKeyPair() generateKeyPair}. + * + * @return the generated key pair + * + * @since 1.2 + */ + public final KeyPair genKeyPair() { + return generateKeyPair(); + } + + /** + * Generates a key pair. + * + *

If this KeyPairGenerator has not been initialized explicitly, + * provider-specific defaults will be used for the size and other + * (algorithm-specific) values of the generated keys. + * + *

This will generate a new key pair every time it is called. + * + *

This method is functionally equivalent to + * {@link #genKeyPair() genKeyPair}. + * + * @return the generated key pair + */ + public KeyPair generateKeyPair() { + // This does nothing (except returning null), because either: + // + // 1. the implementation object returned by getInstance() is an + // instance of KeyPairGenerator which has its own implementation + // of generateKeyPair (overriding this one), so the application + // would be calling that method directly, or + // + // 2. the implementation returned by getInstance() is an instance + // of Delegate, in which case generateKeyPair is + // overridden to invoke the corresponding SPI method. + // + // (This is a special case, because in JDK 1.1.x the generateKeyPair + // method was used both as an API and a SPI method.) + return null; + } + + + /* + * The following class allows providers to extend from KeyPairGeneratorSpi + * rather than from KeyPairGenerator. It represents a KeyPairGenerator + * with an encapsulated, provider-supplied SPI object (of type + * KeyPairGeneratorSpi). + * If the provider implementation is an instance of KeyPairGeneratorSpi, + * the getInstance() methods above return an instance of this class, with + * the SPI object encapsulated. + * + * Note: All SPI methods from the original KeyPairGenerator class have been + * moved up the hierarchy into a new class (KeyPairGeneratorSpi), which has + * been interposed in the hierarchy between the API (KeyPairGenerator) + * and its original parent (Object). + */ + + // + // error failover notes: + // + // . we failover if the implementation throws an error during init + // by retrying the init on other providers + // + // . we also failover if the init succeeded but the subsequent call + // to generateKeyPair() fails. In order for this to work, we need + // to remember the parameters to the last successful call to init + // and initialize() the next spi using them. + // + // . although not specified, KeyPairGenerators could be thread safe, + // so we make sure we do not interfere with that + // + // . failover is not available, if: + // . getInstance(algorithm, provider) was used + // . a provider extends KeyPairGenerator rather than + // KeyPairGeneratorSpi (JDK 1.1 style) + // . once getProvider() is called + // + + private static final class Delegate extends KeyPairGenerator { + + // The provider implementation (delegate) + private volatile KeyPairGeneratorSpi spi; + + private final Object lock = new Object(); + + private Iterator serviceIterator; + + private final static int I_NONE = 1; + private final static int I_SIZE = 2; + private final static int I_PARAMS = 3; + + private int initType; + private int initKeySize; + private AlgorithmParameterSpec initParams; + private SecureRandom initRandom; + + // constructor + Delegate(KeyPairGeneratorSpi spi, String algorithm) { + super(algorithm); + this.spi = spi; + } + + Delegate(Instance instance, Iterator serviceIterator, + String algorithm) { + super(algorithm); + spi = (KeyPairGeneratorSpi)instance.impl; + provider = instance.provider; + this.serviceIterator = serviceIterator; + initType = I_NONE; + + if (!skipDebug && pdebug != null) { + pdebug.println("KeyPairGenerator." + algorithm + + " algorithm from: " + provider.getName()); + } + } + + /** + * Update the active spi of this class and return the next + * implementation for failover. If no more implemenations are + * available, this method returns null. However, the active spi of + * this class is never set to null. + */ + private KeyPairGeneratorSpi nextSpi(KeyPairGeneratorSpi oldSpi, + boolean reinit) { + synchronized (lock) { + // somebody else did a failover concurrently + // try that spi now + if ((oldSpi != null) && (oldSpi != spi)) { + return spi; + } + if (serviceIterator == null) { + return null; + } + while (serviceIterator.hasNext()) { + Service s = serviceIterator.next(); + try { + Object inst = s.newInstance(null); + // ignore non-spis + if (inst instanceof KeyPairGeneratorSpi == false) { + continue; + } + if (inst instanceof KeyPairGenerator) { + continue; + } + KeyPairGeneratorSpi spi = (KeyPairGeneratorSpi)inst; + if (reinit) { + if (initType == I_SIZE) { + spi.initialize(initKeySize, initRandom); + } else if (initType == I_PARAMS) { + spi.initialize(initParams, initRandom); + } else if (initType != I_NONE) { + throw new AssertionError + ("KeyPairGenerator initType: " + initType); + } + } + provider = s.getProvider(); + this.spi = spi; + return spi; + } catch (Exception e) { + // ignore + } + } + disableFailover(); + return null; + } + } + + void disableFailover() { + serviceIterator = null; + initType = 0; + initParams = null; + initRandom = null; + } + + // engine method + public void initialize(int keysize, SecureRandom random) { + if (serviceIterator == null) { + spi.initialize(keysize, random); + return; + } + RuntimeException failure = null; + KeyPairGeneratorSpi mySpi = spi; + do { + try { + mySpi.initialize(keysize, random); + initType = I_SIZE; + initKeySize = keysize; + initParams = null; + initRandom = random; + return; + } catch (RuntimeException e) { + if (failure == null) { + failure = e; + } + mySpi = nextSpi(mySpi, false); + } + } while (mySpi != null); + throw failure; + } + + // engine method + public void initialize(AlgorithmParameterSpec params, + SecureRandom random) throws InvalidAlgorithmParameterException { + if (serviceIterator == null) { + spi.initialize(params, random); + return; + } + Exception failure = null; + KeyPairGeneratorSpi mySpi = spi; + do { + try { + mySpi.initialize(params, random); + initType = I_PARAMS; + initKeySize = 0; + initParams = params; + initRandom = random; + return; + } catch (Exception e) { + if (failure == null) { + failure = e; + } + mySpi = nextSpi(mySpi, false); + } + } while (mySpi != null); + if (failure instanceof RuntimeException) { + throw (RuntimeException)failure; + } + // must be an InvalidAlgorithmParameterException + throw (InvalidAlgorithmParameterException)failure; + } + + // engine method + public KeyPair generateKeyPair() { + if (serviceIterator == null) { + return spi.generateKeyPair(); + } + RuntimeException failure = null; + KeyPairGeneratorSpi mySpi = spi; + do { + try { + return mySpi.generateKeyPair(); + } catch (RuntimeException e) { + if (failure == null) { + failure = e; + } + mySpi = nextSpi(mySpi, true); + } + } while (mySpi != null); + throw failure; + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyPairGeneratorSpi.java b/sources/net.sf.j2s.java.core/src/java/security/KeyPairGeneratorSpi.java new file mode 100644 index 000000000..dfe8c0421 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyPairGeneratorSpi.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.security.spec.AlgorithmParameterSpec; + +/** + *

This class defines the Service Provider Interface (SPI) + * for the {@code KeyPairGenerator} class, which is used to generate + * pairs of public and private keys. + * + *

All the abstract methods in this class must be implemented by each + * cryptographic service provider who wishes to supply the implementation + * of a key pair generator for a particular algorithm. + * + *

In case the client does not explicitly initialize the KeyPairGenerator + * (via a call to an {@code initialize} method), each provider must + * supply (and document) a default initialization. + * For example, the Sun provider uses a default modulus size (keysize) + * of 1024 bits. + * + * @author Benjamin Renaud + * + * + * @see KeyPairGenerator + * @see java.security.spec.AlgorithmParameterSpec + */ + +public abstract class KeyPairGeneratorSpi { + + /** + * Initializes the key pair generator for a certain keysize, using + * the default parameter set. + * + * @param keysize the keysize. This is an + * algorithm-specific metric, such as modulus length, specified in + * number of bits. + * + * @param random the source of randomness for this generator. + * + * @exception InvalidParameterException if the {@code keysize} is not + * supported by this KeyPairGeneratorSpi object. + */ + public abstract void initialize(int keysize, SecureRandom random); + + /** + * Initializes the key pair generator using the specified parameter + * set and user-provided source of randomness. + * + *

This concrete method has been added to this previously-defined + * abstract class. (For backwards compatibility, it cannot be abstract.) + * It may be overridden by a provider to initialize the key pair + * generator. Such an override + * is expected to throw an InvalidAlgorithmParameterException if + * a parameter is inappropriate for this key pair generator. + * If this method is not overridden, it always throws an + * UnsupportedOperationException. + * + * @param params the parameter set used to generate the keys. + * + * @param random the source of randomness for this generator. + * + * @exception InvalidAlgorithmParameterException if the given parameters + * are inappropriate for this key pair generator. + * + * @since 1.2 + */ + public void initialize(AlgorithmParameterSpec params, + SecureRandom random) + throws InvalidAlgorithmParameterException { + throw new UnsupportedOperationException(); + } + + /** + * Generates a key pair. Unless an initialization method is called + * using a KeyPairGenerator interface, algorithm-specific defaults + * will be used. This will generate a new key pair every time it + * is called. + * + * @return the newly generated {@code KeyPair} + */ + public abstract KeyPair generateKeyPair(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyRep.java b/sources/net.sf.j2s.java.core/src/java/security/KeyRep.java new file mode 100644 index 000000000..0b1412c15 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyRep.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2003, 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 java.security; + +import java.io.*; +import java.util.Locale; + +import java.security.spec.PKCS8EncodedKeySpec; +import java.security.spec.X509EncodedKeySpec; +import java.security.spec.InvalidKeySpecException; + +import javax.crypto.SecretKeyFactory; +import javax.crypto.spec.SecretKeySpec; + +/** + * Standardized representation for serialized Key objects. + * + *

+ * + * Note that a serialized Key may contain sensitive information + * which should not be exposed in untrusted environments. See the + * + * Security Appendix + * of the Serialization Specification for more information. + * + * @see Key + * @see KeyFactory + * @see javax.crypto.spec.SecretKeySpec + * @see java.security.spec.X509EncodedKeySpec + * @see java.security.spec.PKCS8EncodedKeySpec + * + * @since 1.5 + */ + +public class KeyRep implements Serializable { + + private static final long serialVersionUID = -4757683898830641853L; + + /** + * Key type. + * + * @since 1.5 + */ + public static enum Type { + + /** Type for secret keys. */ + SECRET, + + /** Type for public keys. */ + PUBLIC, + + /** Type for private keys. */ + PRIVATE, + + } + + private static final String PKCS8 = "PKCS#8"; + private static final String X509 = "X.509"; + private static final String RAW = "RAW"; + + /** + * Either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE + * + * @serial + */ + private Type type; + + /** + * The Key algorithm + * + * @serial + */ + private String algorithm; + + /** + * The Key encoding format + * + * @serial + */ + private String format; + + /** + * The encoded Key bytes + * + * @serial + */ + private byte[] encoded; + + /** + * Construct the alternate Key class. + * + *

+ * + * @param type either one of Type.SECRET, Type.PUBLIC, or Type.PRIVATE + * @param algorithm the algorithm returned from + * {@code Key.getAlgorithm()} + * @param format the encoding format returned from + * {@code Key.getFormat()} + * @param encoded the encoded bytes returned from + * {@code Key.getEncoded()} + * + * @exception NullPointerException + * if type is {@code null}, + * if algorithm is {@code null}, + * if format is {@code null}, + * or if encoded is {@code null} + */ + public KeyRep(Type type, String algorithm, + String format, byte[] encoded) { + + if (type == null || algorithm == null || + format == null || encoded == null) { + throw new NullPointerException("invalid null input(s)"); + } + + this.type = type; + this.algorithm = algorithm; + this.format = format.toUpperCase(Locale.ENGLISH); + this.encoded = encoded.clone(); + } + + /** + * Resolve the Key object. + * + *

This method supports three Type/format combinations: + *

    + *
  • Type.SECRET/"RAW" - returns a SecretKeySpec object + * constructed using encoded key bytes and algorithm + *
  • Type.PUBLIC/"X.509" - gets a KeyFactory instance for + * the key algorithm, constructs an X509EncodedKeySpec with the + * encoded key bytes, and generates a public key from the spec + *
  • Type.PRIVATE/"PKCS#8" - gets a KeyFactory instance for + * the key algorithm, constructs a PKCS8EncodedKeySpec with the + * encoded key bytes, and generates a private key from the spec + *
+ * + *

+ * + * @return the resolved Key object + * + * @exception ObjectStreamException if the Type/format + * combination is unrecognized, if the algorithm, key format, or + * encoded key bytes are unrecognized/invalid, of if the + * resolution of the key fails for any reason + */ + protected Object readResolve() throws ObjectStreamException { + try { + if (type == Type.SECRET && RAW.equals(format)) { + return new SecretKeySpec(encoded, algorithm); + } else if (type == Type.PUBLIC && X509.equals(format)) { + KeyFactory f = KeyFactory.getInstance(algorithm); + return f.generatePublic(new X509EncodedKeySpec(encoded)); + } else if (type == Type.PRIVATE && PKCS8.equals(format)) { + KeyFactory f = KeyFactory.getInstance(algorithm); + return f.generatePrivate(new PKCS8EncodedKeySpec(encoded)); + } else { + throw new NotSerializableException + ("unrecognized type/format combination: " + + type + "/" + format); + } + } catch (NotSerializableException nse) { + throw nse; + } catch (Exception e) { + NotSerializableException nse = new NotSerializableException + ("java.security.Key: " + + "[" + type + "] " + + "[" + algorithm + "] " + + "[" + format + "]"); + nse.initCause(e); + throw nse; + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyStore.java b/sources/net.sf.j2s.java.core/src/java/security/KeyStore.java new file mode 100644 index 000000000..4278369e8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyStore.java @@ -0,0 +1,2001 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.io.*; +import java.net.URI; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; +import java.security.cert.CertificateException; +import java.security.spec.AlgorithmParameterSpec; +import java.util.*; +import javax.crypto.SecretKey; + +import javax.security.auth.DestroyFailedException; +import javax.security.auth.callback.*; + +import sun.security.util.Debug; + +/** + * This class represents a storage facility for cryptographic + * keys and certificates. + * + *

A {@code KeyStore} manages different types of entries. + * Each type of entry implements the {@code KeyStore.Entry} interface. + * Three basic {@code KeyStore.Entry} implementations are provided: + * + *

    + *
  • KeyStore.PrivateKeyEntry + *

    This type of entry holds a cryptographic {@code PrivateKey}, + * which is optionally stored in a protected format to prevent + * unauthorized access. It is also accompanied by a certificate chain + * for the corresponding public key. + * + *

    Private keys and certificate chains are used by a given entity for + * self-authentication. Applications for this authentication include software + * distribution organizations which sign JAR files as part of releasing + * and/or licensing software. + * + *

  • KeyStore.SecretKeyEntry + *

    This type of entry holds a cryptographic {@code SecretKey}, + * which is optionally stored in a protected format to prevent + * unauthorized access. + * + *

  • KeyStore.TrustedCertificateEntry + *

    This type of entry contains a single public key {@code Certificate} + * belonging to another party. It is called a trusted certificate + * because the keystore owner trusts that the public key in the certificate + * indeed belongs to the identity identified by the subject (owner) + * of the certificate. + * + *

    This type of entry can be used to authenticate other parties. + *

+ * + *

Each entry in a keystore is identified by an "alias" string. In the + * case of private keys and their associated certificate chains, these strings + * distinguish among the different ways in which the entity may authenticate + * itself. For example, the entity may authenticate itself using different + * certificate authorities, or using different public key algorithms. + * + *

Whether aliases are case sensitive is implementation dependent. In order + * to avoid problems, it is recommended not to use aliases in a KeyStore that + * only differ in case. + * + *

Whether keystores are persistent, and the mechanisms used by the + * keystore if it is persistent, are not specified here. This allows + * use of a variety of techniques for protecting sensitive (e.g., private or + * secret) keys. Smart cards or other integrated cryptographic engines + * (SafeKeyper) are one option, and simpler mechanisms such as files may also + * be used (in a variety of formats). + * + *

Typical ways to request a KeyStore object include + * relying on the default type and providing a specific keystore type. + * + *

    + *
  • To rely on the default type: + *
    + *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
    + * 
    + * The system will return a keystore implementation for the default type. + * + *
  • To provide a specific keystore type: + *
    + *      KeyStore ks = KeyStore.getInstance("JKS");
    + * 
    + * The system will return the most preferred implementation of the + * specified keystore type available in the environment.

    + *

+ * + *

Before a keystore can be accessed, it must be + * {@link #load(java.io.InputStream, char[]) loaded}. + *

+ *    KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
+ *
+ *    // get user password and file input stream
+ *    char[] password = getPassword();
+ *
+ *    try (FileInputStream fis = new FileInputStream("keyStoreName")) {
+ *        ks.load(fis, password);
+ *    }
+ * 
+ * + * To create an empty keystore using the above {@code load} method, + * pass {@code null} as the {@code InputStream} argument. + * + *

Once the keystore has been loaded, it is possible + * to read existing entries from the keystore, or to write new entries + * into the keystore: + *

+ *    KeyStore.ProtectionParameter protParam =
+ *        new KeyStore.PasswordProtection(password);
+ *
+ *    // get my private key
+ *    KeyStore.PrivateKeyEntry pkEntry = (KeyStore.PrivateKeyEntry)
+ *        ks.getEntry("privateKeyAlias", protParam);
+ *    PrivateKey myPrivateKey = pkEntry.getPrivateKey();
+ *
+ *    // save my secret key
+ *    javax.crypto.SecretKey mySecretKey;
+ *    KeyStore.SecretKeyEntry skEntry =
+ *        new KeyStore.SecretKeyEntry(mySecretKey);
+ *    ks.setEntry("secretKeyAlias", skEntry, protParam);
+ *
+ *    // store away the keystore
+ *    try (FileOutputStream fos = new FileOutputStream("newKeyStoreName")) {
+ *        ks.store(fos, password);
+ *    }
+ * 
+ * + * Note that although the same password may be used to + * load the keystore, to protect the private key entry, + * to protect the secret key entry, and to store the keystore + * (as is shown in the sample code above), + * different passwords or other protection parameters + * may also be used. + * + *

Every implementation of the Java platform is required to support + * the following standard {@code KeyStore} type: + *

    + *
  • {@code PKCS12}
  • + *
+ * This type is described in the + * KeyStore section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other types are supported. + * + * @author Jan Luehe + * + * @see java.security.PrivateKey + * @see javax.crypto.SecretKey + * @see java.security.cert.Certificate + * + * @since 1.2 + */ + +public class KeyStore { + + private static final Debug pdebug = + Debug.getInstance("provider", "Provider"); + private static final boolean skipDebug = + Debug.isOn("engine=") && !Debug.isOn("keystore"); + + /* + * Constant to lookup in the Security properties file to determine + * the default keystore type. + * In the Security properties file, the default keystore type is given as: + *
+     * keystore.type=jks
+     * 
+ */ + private static final String KEYSTORE_TYPE = "keystore.type"; + + // The keystore type + private String type; + + // The provider + private Provider provider; + + // The provider implementation + private KeyStoreSpi keyStoreSpi; + + // Has this keystore been initialized (loaded)? + private boolean initialized = false; + + /** + * A marker interface for {@code KeyStore} + * {@link #load(KeyStore.LoadStoreParameter) load} + * and + * {@link #store(KeyStore.LoadStoreParameter) store} + * parameters. + * + * @since 1.5 + */ + public static interface LoadStoreParameter { + /** + * Gets the parameter used to protect keystore data. + * + * @return the parameter used to protect keystore data, or null + */ + public ProtectionParameter getProtectionParameter(); + } + + /** + * A marker interface for keystore protection parameters. + * + *

The information stored in a {@code ProtectionParameter} + * object protects the contents of a keystore. + * For example, protection parameters may be used to check + * the integrity of keystore data, or to protect the + * confidentiality of sensitive keystore data + * (such as a {@code PrivateKey}). + * + * @since 1.5 + */ + public static interface ProtectionParameter { } + + /** + * A password-based implementation of {@code ProtectionParameter}. + * + * @since 1.5 + */ + public static class PasswordProtection implements + ProtectionParameter, javax.security.auth.Destroyable { + + private final char[] password; + private final String protectionAlgorithm; + private final AlgorithmParameterSpec protectionParameters; + private volatile boolean destroyed = false; + + /** + * Creates a password parameter. + * + *

The specified {@code password} is cloned before it is stored + * in the new {@code PasswordProtection} object. + * + * @param password the password, which may be {@code null} + */ + public PasswordProtection(char[] password) { + this.password = (password == null) ? null : password.clone(); + this.protectionAlgorithm = null; + this.protectionParameters = null; + } + + /** + * Creates a password parameter and specifies the protection algorithm + * and associated parameters to use when encrypting a keystore entry. + *

+ * The specified {@code password} is cloned before it is stored in the + * new {@code PasswordProtection} object. + * + * @param password the password, which may be {@code null} + * @param protectionAlgorithm the encryption algorithm name, for + * example, {@code PBEWithHmacSHA256AndAES_256}. + * See the Cipher section in the + * Java Cryptography Architecture Standard Algorithm Name + * Documentation + * for information about standard encryption algorithm names. + * @param protectionParameters the encryption algorithm parameter + * specification, which may be {@code null} + * @exception NullPointerException if {@code protectionAlgorithm} is + * {@code null} + * + * @since 1.8 + */ + public PasswordProtection(char[] password, String protectionAlgorithm, + AlgorithmParameterSpec protectionParameters) { + if (protectionAlgorithm == null) { + throw new NullPointerException("invalid null input"); + } + this.password = (password == null) ? null : password.clone(); + this.protectionAlgorithm = protectionAlgorithm; + this.protectionParameters = protectionParameters; + } + + /** + * Gets the name of the protection algorithm. + * If none was set then the keystore provider will use its default + * protection algorithm. The name of the default protection algorithm + * for a given keystore type is set using the + * {@code 'keystore..keyProtectionAlgorithm'} security property. + * For example, the + * {@code keystore.PKCS12.keyProtectionAlgorithm} property stores the + * name of the default key protection algorithm used for PKCS12 + * keystores. If the security property is not set, an + * implementation-specific algorithm will be used. + * + * @return the algorithm name, or {@code null} if none was set + * + * @since 1.8 + */ + public String getProtectionAlgorithm() { + return protectionAlgorithm; + } + + /** + * Gets the parameters supplied for the protection algorithm. + * + * @return the algorithm parameter specification, or {@code null}, + * if none was set + * + * @since 1.8 + */ + public AlgorithmParameterSpec getProtectionParameters() { + return protectionParameters; + } + + /** + * Gets the password. + * + *

Note that this method returns a reference to the password. + * If a clone of the array is created it is the caller's + * responsibility to zero out the password information + * after it is no longer needed. + * + * @see #destroy() + * @return the password, which may be {@code null} + * @exception IllegalStateException if the password has + * been cleared (destroyed) + */ + public synchronized char[] getPassword() { + if (destroyed) { + throw new IllegalStateException("password has been cleared"); + } + return password; + } + + /** + * Clears the password. + * + * @exception DestroyFailedException if this method was unable + * to clear the password + */ + public synchronized void destroy() throws DestroyFailedException { + destroyed = true; + if (password != null) { + Arrays.fill(password, ' '); + } + } + + /** + * Determines if password has been cleared. + * + * @return true if the password has been cleared, false otherwise + */ + public synchronized boolean isDestroyed() { + return destroyed; + } + } + + /** + * A ProtectionParameter encapsulating a CallbackHandler. + * + * @since 1.5 + */ + public static class CallbackHandlerProtection + implements ProtectionParameter { + + private final CallbackHandler handler; + + /** + * Constructs a new CallbackHandlerProtection from a + * CallbackHandler. + * + * @param handler the CallbackHandler + * @exception NullPointerException if handler is null + */ + public CallbackHandlerProtection(CallbackHandler handler) { + if (handler == null) { + throw new NullPointerException("handler must not be null"); + } + this.handler = handler; + } + + /** + * Returns the CallbackHandler. + * + * @return the CallbackHandler. + */ + public CallbackHandler getCallbackHandler() { + return handler; + } + + } + + /** + * A marker interface for {@code KeyStore} entry types. + * + * @since 1.5 + */ + public static interface Entry { + + /** + * Retrieves the attributes associated with an entry. + *

+ * The default implementation returns an empty {@code Set}. + * + * @return an unmodifiable {@code Set} of attributes, possibly empty + * + * @since 1.8 + */ + public default Set getAttributes() { + return Collections.emptySet(); + } + + /** + * An attribute associated with a keystore entry. + * It comprises a name and one or more values. + * + * @since 1.8 + */ + public interface Attribute { + /** + * Returns the attribute's name. + * + * @return the attribute name + */ + public String getName(); + + /** + * Returns the attribute's value. + * Multi-valued attributes encode their values as a single string. + * + * @return the attribute value + */ + public String getValue(); + } + } + + /** + * A {@code KeyStore} entry that holds a {@code PrivateKey} + * and corresponding certificate chain. + * + * @since 1.5 + */ + public static final class PrivateKeyEntry implements Entry { + + private final PrivateKey privKey; + private final Certificate[] chain; + private final Set attributes; + + /** + * Constructs a {@code PrivateKeyEntry} with a + * {@code PrivateKey} and corresponding certificate chain. + * + *

The specified {@code chain} is cloned before it is stored + * in the new {@code PrivateKeyEntry} object. + * + * @param privateKey the {@code PrivateKey} + * @param chain an array of {@code Certificate}s + * representing the certificate chain. + * The chain must be ordered and contain a + * {@code Certificate} at index 0 + * corresponding to the private key. + * + * @exception NullPointerException if + * {@code privateKey} or {@code chain} + * is {@code null} + * @exception IllegalArgumentException if the specified chain has a + * length of 0, if the specified chain does not contain + * {@code Certificate}s of the same type, + * or if the {@code PrivateKey} algorithm + * does not match the algorithm of the {@code PublicKey} + * in the end entity {@code Certificate} (at index 0) + */ + public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain) { + this(privateKey, chain, Collections.emptySet()); + } + + /** + * Constructs a {@code PrivateKeyEntry} with a {@code PrivateKey} and + * corresponding certificate chain and associated entry attributes. + * + *

The specified {@code chain} and {@code attributes} are cloned + * before they are stored in the new {@code PrivateKeyEntry} object. + * + * @param privateKey the {@code PrivateKey} + * @param chain an array of {@code Certificate}s + * representing the certificate chain. + * The chain must be ordered and contain a + * {@code Certificate} at index 0 + * corresponding to the private key. + * @param attributes the attributes + * + * @exception NullPointerException if {@code privateKey}, {@code chain} + * or {@code attributes} is {@code null} + * @exception IllegalArgumentException if the specified chain has a + * length of 0, if the specified chain does not contain + * {@code Certificate}s of the same type, + * or if the {@code PrivateKey} algorithm + * does not match the algorithm of the {@code PublicKey} + * in the end entity {@code Certificate} (at index 0) + * + * @since 1.8 + */ + public PrivateKeyEntry(PrivateKey privateKey, Certificate[] chain, + Set attributes) { + + if (privateKey == null || chain == null || attributes == null) { + throw new NullPointerException("invalid null input"); + } + if (chain.length == 0) { + throw new IllegalArgumentException + ("invalid zero-length input chain"); + } + + Certificate[] clonedChain = chain.clone(); + String certType = clonedChain[0].getType(); + for (int i = 1; i < clonedChain.length; i++) { + if (!certType.equals(clonedChain[i].getType())) { + throw new IllegalArgumentException + ("chain does not contain certificates " + + "of the same type"); + } + } + if (!privateKey.getAlgorithm().equals + (clonedChain[0].getPublicKey().getAlgorithm())) { + throw new IllegalArgumentException + ("private key algorithm does not match " + + "algorithm of public key in end entity " + + "certificate (at index 0)"); + } + this.privKey = privateKey; + + if (clonedChain[0] instanceof X509Certificate && + !(clonedChain instanceof X509Certificate[])) { + + this.chain = new X509Certificate[clonedChain.length]; + System.arraycopy(clonedChain, 0, + this.chain, 0, clonedChain.length); + } else { + this.chain = clonedChain; + } + + this.attributes = + Collections.unmodifiableSet(new HashSet<>(attributes)); + } + + /** + * Gets the {@code PrivateKey} from this entry. + * + * @return the {@code PrivateKey} from this entry + */ + public PrivateKey getPrivateKey() { + return privKey; + } + + /** + * Gets the {@code Certificate} chain from this entry. + * + *

The stored chain is cloned before being returned. + * + * @return an array of {@code Certificate}s corresponding + * to the certificate chain for the public key. + * If the certificates are of type X.509, + * the runtime type of the returned array is + * {@code X509Certificate[]}. + */ + public Certificate[] getCertificateChain() { + return chain.clone(); + } + + /** + * Gets the end entity {@code Certificate} + * from the certificate chain in this entry. + * + * @return the end entity {@code Certificate} (at index 0) + * from the certificate chain in this entry. + * If the certificate is of type X.509, + * the runtime type of the returned certificate is + * {@code X509Certificate}. + */ + public Certificate getCertificate() { + return chain[0]; + } + + /** + * Retrieves the attributes associated with an entry. + *

+ * + * @return an unmodifiable {@code Set} of attributes, possibly empty + * + * @since 1.8 + */ + @Override + public Set getAttributes() { + return attributes; + } + + /** + * Returns a string representation of this PrivateKeyEntry. + * @return a string representation of this PrivateKeyEntry. + */ + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Private key entry and certificate chain with " + + chain.length + " elements:\r\n"); + for (Certificate cert : chain) { + sb.append(cert); + sb.append("\r\n"); + } + return sb.toString(); + } + + } + + /** + * A {@code KeyStore} entry that holds a {@code SecretKey}. + * + * @since 1.5 + */ + public static final class SecretKeyEntry implements Entry { + + private final SecretKey sKey; + private final Set attributes; + + /** + * Constructs a {@code SecretKeyEntry} with a + * {@code SecretKey}. + * + * @param secretKey the {@code SecretKey} + * + * @exception NullPointerException if {@code secretKey} + * is {@code null} + */ + public SecretKeyEntry(SecretKey secretKey) { + if (secretKey == null) { + throw new NullPointerException("invalid null input"); + } + this.sKey = secretKey; + this.attributes = Collections.emptySet(); + } + + /** + * Constructs a {@code SecretKeyEntry} with a {@code SecretKey} and + * associated entry attributes. + * + *

The specified {@code attributes} is cloned before it is stored + * in the new {@code SecretKeyEntry} object. + * + * @param secretKey the {@code SecretKey} + * @param attributes the attributes + * + * @exception NullPointerException if {@code secretKey} or + * {@code attributes} is {@code null} + * + * @since 1.8 + */ + public SecretKeyEntry(SecretKey secretKey, Set attributes) { + + if (secretKey == null || attributes == null) { + throw new NullPointerException("invalid null input"); + } + this.sKey = secretKey; + this.attributes = + Collections.unmodifiableSet(new HashSet<>(attributes)); + } + + /** + * Gets the {@code SecretKey} from this entry. + * + * @return the {@code SecretKey} from this entry + */ + public SecretKey getSecretKey() { + return sKey; + } + + /** + * Retrieves the attributes associated with an entry. + *

+ * + * @return an unmodifiable {@code Set} of attributes, possibly empty + * + * @since 1.8 + */ + @Override + public Set getAttributes() { + return attributes; + } + + /** + * Returns a string representation of this SecretKeyEntry. + * @return a string representation of this SecretKeyEntry. + */ + public String toString() { + return "Secret key entry with algorithm " + sKey.getAlgorithm(); + } + } + + /** + * A {@code KeyStore} entry that holds a trusted + * {@code Certificate}. + * + * @since 1.5 + */ + public static final class TrustedCertificateEntry implements Entry { + + private final Certificate cert; + private final Set attributes; + + /** + * Constructs a {@code TrustedCertificateEntry} with a + * trusted {@code Certificate}. + * + * @param trustedCert the trusted {@code Certificate} + * + * @exception NullPointerException if + * {@code trustedCert} is {@code null} + */ + public TrustedCertificateEntry(Certificate trustedCert) { + if (trustedCert == null) { + throw new NullPointerException("invalid null input"); + } + this.cert = trustedCert; + this.attributes = Collections.emptySet(); + } + + /** + * Constructs a {@code TrustedCertificateEntry} with a + * trusted {@code Certificate} and associated entry attributes. + * + *

The specified {@code attributes} is cloned before it is stored + * in the new {@code TrustedCertificateEntry} object. + * + * @param trustedCert the trusted {@code Certificate} + * @param attributes the attributes + * + * @exception NullPointerException if {@code trustedCert} or + * {@code attributes} is {@code null} + * + * @since 1.8 + */ + public TrustedCertificateEntry(Certificate trustedCert, + Set attributes) { + if (trustedCert == null || attributes == null) { + throw new NullPointerException("invalid null input"); + } + this.cert = trustedCert; + this.attributes = + Collections.unmodifiableSet(new HashSet<>(attributes)); + } + + /** + * Gets the trusted {@code Certficate} from this entry. + * + * @return the trusted {@code Certificate} from this entry + */ + public Certificate getTrustedCertificate() { + return cert; + } + + /** + * Retrieves the attributes associated with an entry. + *

+ * + * @return an unmodifiable {@code Set} of attributes, possibly empty + * + * @since 1.8 + */ + @Override + public Set getAttributes() { + return attributes; + } + + /** + * Returns a string representation of this TrustedCertificateEntry. + * @return a string representation of this TrustedCertificateEntry. + */ + public String toString() { + return "Trusted certificate entry:\r\n" + cert.toString(); + } + } + + /** + * Creates a KeyStore object of the given type, and encapsulates the given + * provider implementation (SPI object) in it. + * + * @param keyStoreSpi the provider implementation. + * @param provider the provider. + * @param type the keystore type. + */ + protected KeyStore(KeyStoreSpi keyStoreSpi, Provider provider, String type) + { + this.keyStoreSpi = keyStoreSpi; + this.provider = provider; + this.type = type; + + if (!skipDebug && pdebug != null) { + pdebug.println("KeyStore." + type.toUpperCase() + " type from: " + + this.provider.getName()); + } + } + + /** + * Returns a keystore object of the specified type. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new KeyStore object encapsulating the + * KeyStoreSpi implementation from the first + * Provider that supports the specified type is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param type the type of keystore. + * See the KeyStore section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard keystore types. + * + * @return a keystore object of the specified type. + * + * @exception KeyStoreException if no Provider supports a + * KeyStoreSpi implementation for the + * specified type. + * + * @see Provider + */ + public static KeyStore getInstance(String type) + throws KeyStoreException + { + try { + Object[] objs = Security.getImpl(type, "KeyStore", (String)null); + return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type); + } catch (NoSuchAlgorithmException nsae) { + throw new KeyStoreException(type + " not found", nsae); + } catch (NoSuchProviderException nspe) { + throw new KeyStoreException(type + " not found", nspe); + } + } + + /** + * Returns a keystore object of the specified type. + * + *

A new KeyStore object encapsulating the + * KeyStoreSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param type the type of keystore. + * See the KeyStore section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard keystore types. + * + * @param provider the name of the provider. + * + * @return a keystore object of the specified type. + * + * @exception KeyStoreException if a KeyStoreSpi + * implementation for the specified type is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + */ + public static KeyStore getInstance(String type, String provider) + throws KeyStoreException, NoSuchProviderException + { + if (provider == null || provider.length() == 0) + throw new IllegalArgumentException("missing provider"); + try { + Object[] objs = Security.getImpl(type, "KeyStore", provider); + return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type); + } catch (NoSuchAlgorithmException nsae) { + throw new KeyStoreException(type + " not found", nsae); + } + } + + /** + * Returns a keystore object of the specified type. + * + *

A new KeyStore object encapsulating the + * KeyStoreSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param type the type of keystore. + * See the KeyStore section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard keystore types. + * + * @param provider the provider. + * + * @return a keystore object of the specified type. + * + * @exception KeyStoreException if KeyStoreSpi + * implementation for the specified type is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the specified provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static KeyStore getInstance(String type, Provider provider) + throws KeyStoreException + { + if (provider == null) + throw new IllegalArgumentException("missing provider"); + try { + Object[] objs = Security.getImpl(type, "KeyStore", provider); + return new KeyStore((KeyStoreSpi)objs[0], (Provider)objs[1], type); + } catch (NoSuchAlgorithmException nsae) { + throw new KeyStoreException(type + " not found", nsae); + } + } + + /** + * Returns the default keystore type as specified by the + * {@code keystore.type} security property, or the string + * {@literal "jks"} (acronym for {@literal "Java keystore"}) + * if no such property exists. + * + *

The default keystore type can be used by applications that do not + * want to use a hard-coded keystore type when calling one of the + * {@code getInstance} methods, and want to provide a default keystore + * type in case a user does not specify its own. + * + *

The default keystore type can be changed by setting the value of the + * {@code keystore.type} security property to the desired keystore type. + * + * @return the default keystore type as specified by the + * {@code keystore.type} security property, or the string {@literal "jks"} + * if no such property exists. + * @see java.security.Security security properties + */ + public final static String getDefaultType() { + String kstype; + kstype = AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return Security.getProperty(KEYSTORE_TYPE); + } + }); + if (kstype == null) { + kstype = "jks"; + } + return kstype; + } + + /** + * Returns the provider of this keystore. + * + * @return the provider of this keystore. + */ + public final Provider getProvider() + { + return this.provider; + } + + /** + * Returns the type of this keystore. + * + * @return the type of this keystore. + */ + public final String getType() + { + return this.type; + } + + /** + * Returns the key associated with the given alias, using the given + * password to recover it. The key must have been associated with + * the alias by a call to {@code setKeyEntry}, + * or by a call to {@code setEntry} with a + * {@code PrivateKeyEntry} or {@code SecretKeyEntry}. + * + * @param alias the alias name + * @param password the password for recovering the key + * + * @return the requested key, or null if the given alias does not exist + * or does not identify a key-related entry. + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + * @exception NoSuchAlgorithmException if the algorithm for recovering the + * key cannot be found + * @exception UnrecoverableKeyException if the key cannot be recovered + * (e.g., the given password is wrong). + */ + public final Key getKey(String alias, char[] password) + throws KeyStoreException, NoSuchAlgorithmException, + UnrecoverableKeyException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineGetKey(alias, password); + } + + /** + * Returns the certificate chain associated with the given alias. + * The certificate chain must have been associated with the alias + * by a call to {@code setKeyEntry}, + * or by a call to {@code setEntry} with a + * {@code PrivateKeyEntry}. + * + * @param alias the alias name + * + * @return the certificate chain (ordered with the user's certificate first + * followed by zero or more certificate authorities), or null if the given alias + * does not exist or does not contain a certificate chain + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final Certificate[] getCertificateChain(String alias) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineGetCertificateChain(alias); + } + + /** + * Returns the certificate associated with the given alias. + * + *

If the given alias name identifies an entry + * created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}, + * then the trusted certificate contained in that entry is returned. + * + *

If the given alias name identifies an entry + * created by a call to {@code setKeyEntry}, + * or created by a call to {@code setEntry} with a + * {@code PrivateKeyEntry}, + * then the first element of the certificate chain in that entry + * is returned. + * + * @param alias the alias name + * + * @return the certificate, or null if the given alias does not exist or + * does not contain a certificate. + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final Certificate getCertificate(String alias) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineGetCertificate(alias); + } + + /** + * Returns the creation date of the entry identified by the given alias. + * + * @param alias the alias name + * + * @return the creation date of this entry, or null if the given alias does + * not exist + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final Date getCreationDate(String alias) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineGetCreationDate(alias); + } + + /** + * Assigns the given key to the given alias, protecting it with the given + * password. + * + *

If the given key is of type {@code java.security.PrivateKey}, + * it must be accompanied by a certificate chain certifying the + * corresponding public key. + * + *

If the given alias already exists, the keystore information + * associated with it is overridden by the given key (and possibly + * certificate chain). + * + * @param alias the alias name + * @param key the key to be associated with the alias + * @param password the password to protect the key + * @param chain the certificate chain for the corresponding public + * key (only required if the given key is of type + * {@code java.security.PrivateKey}). + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded), the given key cannot be protected, or this operation fails + * for some other reason + */ + public final void setKeyEntry(String alias, Key key, char[] password, + Certificate[] chain) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + if ((key instanceof PrivateKey) && + (chain == null || chain.length == 0)) { + throw new IllegalArgumentException("Private key must be " + + "accompanied by certificate " + + "chain"); + } + keyStoreSpi.engineSetKeyEntry(alias, key, password, chain); + } + + /** + * Assigns the given key (that has already been protected) to the given + * alias. + * + *

If the protected key is of type + * {@code java.security.PrivateKey}, it must be accompanied by a + * certificate chain certifying the corresponding public key. If the + * underlying keystore implementation is of type {@code jks}, + * {@code key} must be encoded as an + * {@code EncryptedPrivateKeyInfo} as defined in the PKCS #8 standard. + * + *

If the given alias already exists, the keystore information + * associated with it is overridden by the given key (and possibly + * certificate chain). + * + * @param alias the alias name + * @param key the key (in protected format) to be associated with the alias + * @param chain the certificate chain for the corresponding public + * key (only useful if the protected key is of type + * {@code java.security.PrivateKey}). + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded), or if this operation fails for some other reason. + */ + public final void setKeyEntry(String alias, byte[] key, + Certificate[] chain) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + keyStoreSpi.engineSetKeyEntry(alias, key, chain); + } + + /** + * Assigns the given trusted certificate to the given alias. + * + *

If the given alias identifies an existing entry + * created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}, + * the trusted certificate in the existing entry + * is overridden by the given certificate. + * + * @param alias the alias name + * @param cert the certificate + * + * @exception KeyStoreException if the keystore has not been initialized, + * or the given alias already exists and does not identify an + * entry containing a trusted certificate, + * or this operation fails for some other reason. + */ + public final void setCertificateEntry(String alias, Certificate cert) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + keyStoreSpi.engineSetCertificateEntry(alias, cert); + } + + /** + * Deletes the entry identified by the given alias from this keystore. + * + * @param alias the alias name + * + * @exception KeyStoreException if the keystore has not been initialized, + * or if the entry cannot be removed. + */ + public final void deleteEntry(String alias) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + keyStoreSpi.engineDeleteEntry(alias); + } + + /** + * Lists all the alias names of this keystore. + * + * @return enumeration of the alias names + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final Enumeration aliases() + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineAliases(); + } + + /** + * Checks if the given alias exists in this keystore. + * + * @param alias the alias name + * + * @return true if the alias exists, false otherwise + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final boolean containsAlias(String alias) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineContainsAlias(alias); + } + + /** + * Retrieves the number of entries in this keystore. + * + * @return the number of entries in this keystore + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final int size() + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineSize(); + } + + /** + * Returns true if the entry identified by the given alias + * was created by a call to {@code setKeyEntry}, + * or created by a call to {@code setEntry} with a + * {@code PrivateKeyEntry} or a {@code SecretKeyEntry}. + * + * @param alias the alias for the keystore entry to be checked + * + * @return true if the entry identified by the given alias is a + * key-related entry, false otherwise. + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final boolean isKeyEntry(String alias) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineIsKeyEntry(alias); + } + + /** + * Returns true if the entry identified by the given alias + * was created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}. + * + * @param alias the alias for the keystore entry to be checked + * + * @return true if the entry identified by the given alias contains a + * trusted certificate, false otherwise. + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final boolean isCertificateEntry(String alias) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineIsCertificateEntry(alias); + } + + /** + * Returns the (alias) name of the first keystore entry whose certificate + * matches the given certificate. + * + *

This method attempts to match the given certificate with each + * keystore entry. If the entry being considered was + * created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}, + * then the given certificate is compared to that entry's certificate. + * + *

If the entry being considered was + * created by a call to {@code setKeyEntry}, + * or created by a call to {@code setEntry} with a + * {@code PrivateKeyEntry}, + * then the given certificate is compared to the first + * element of that entry's certificate chain. + * + * @param cert the certificate to match with. + * + * @return the alias name of the first entry with a matching certificate, + * or null if no such entry exists in this keystore. + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + */ + public final String getCertificateAlias(Certificate cert) + throws KeyStoreException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineGetCertificateAlias(cert); + } + + /** + * Stores this keystore to the given output stream, and protects its + * integrity with the given password. + * + * @param stream the output stream to which this keystore is written. + * @param password the password to generate the keystore integrity check + * + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + * @exception IOException if there was an I/O problem with data + * @exception NoSuchAlgorithmException if the appropriate data integrity + * algorithm could not be found + * @exception CertificateException if any of the certificates included in + * the keystore data could not be stored + */ + public final void store(OutputStream stream, char[] password) + throws KeyStoreException, IOException, NoSuchAlgorithmException, + CertificateException + { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + keyStoreSpi.engineStore(stream, password); + } + + /** + * Stores this keystore using the given {@code LoadStoreParameter}. + * + * @param param the {@code LoadStoreParameter} + * that specifies how to store the keystore, + * which may be {@code null} + * + * @exception IllegalArgumentException if the given + * {@code LoadStoreParameter} + * input is not recognized + * @exception KeyStoreException if the keystore has not been initialized + * (loaded) + * @exception IOException if there was an I/O problem with data + * @exception NoSuchAlgorithmException if the appropriate data integrity + * algorithm could not be found + * @exception CertificateException if any of the certificates included in + * the keystore data could not be stored + * + * @since 1.5 + */ + public final void store(LoadStoreParameter param) + throws KeyStoreException, IOException, + NoSuchAlgorithmException, CertificateException { + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + keyStoreSpi.engineStore(param); + } + + /** + * Loads this KeyStore from the given input stream. + * + *

A password may be given to unlock the keystore + * (e.g. the keystore resides on a hardware token device), + * or to check the integrity of the keystore data. + * If a password is not given for integrity checking, + * then integrity checking is not performed. + * + *

In order to create an empty keystore, or if the keystore cannot + * be initialized from a stream, pass {@code null} + * as the {@code stream} argument. + * + *

Note that if this keystore has already been loaded, it is + * reinitialized and loaded again from the given input stream. + * + * @param stream the input stream from which the keystore is loaded, + * or {@code null} + * @param password the password used to check the integrity of + * the keystore, the password used to unlock the keystore, + * or {@code null} + * + * @exception IOException if there is an I/O or format problem with the + * keystore data, if a password is required but not given, + * or if the given password was incorrect. If the error is due to a + * wrong password, the {@link Throwable#getCause cause} of the + * {@code IOException} should be an + * {@code UnrecoverableKeyException} + * @exception NoSuchAlgorithmException if the algorithm used to check + * the integrity of the keystore cannot be found + * @exception CertificateException if any of the certificates in the + * keystore could not be loaded + */ + public final void load(InputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException + { + keyStoreSpi.engineLoad(stream, password); + initialized = true; + } + + /** + * Loads this keystore using the given {@code LoadStoreParameter}. + * + *

Note that if this KeyStore has already been loaded, it is + * reinitialized and loaded again from the given parameter. + * + * @param param the {@code LoadStoreParameter} + * that specifies how to load the keystore, + * which may be {@code null} + * + * @exception IllegalArgumentException if the given + * {@code LoadStoreParameter} + * input is not recognized + * @exception IOException if there is an I/O or format problem with the + * keystore data. If the error is due to an incorrect + * {@code ProtectionParameter} (e.g. wrong password) + * the {@link Throwable#getCause cause} of the + * {@code IOException} should be an + * {@code UnrecoverableKeyException} + * @exception NoSuchAlgorithmException if the algorithm used to check + * the integrity of the keystore cannot be found + * @exception CertificateException if any of the certificates in the + * keystore could not be loaded + * + * @since 1.5 + */ + public final void load(LoadStoreParameter param) + throws IOException, NoSuchAlgorithmException, + CertificateException { + + keyStoreSpi.engineLoad(param); + initialized = true; + } + + /** + * Gets a keystore {@code Entry} for the specified alias + * with the specified protection parameter. + * + * @param alias get the keystore {@code Entry} for this alias + * @param protParam the {@code ProtectionParameter} + * used to protect the {@code Entry}, + * which may be {@code null} + * + * @return the keystore {@code Entry} for the specified alias, + * or {@code null} if there is no such entry + * + * @exception NullPointerException if + * {@code alias} is {@code null} + * @exception NoSuchAlgorithmException if the algorithm for recovering the + * entry cannot be found + * @exception UnrecoverableEntryException if the specified + * {@code protParam} were insufficient or invalid + * @exception UnrecoverableKeyException if the entry is a + * {@code PrivateKeyEntry} or {@code SecretKeyEntry} + * and the specified {@code protParam} does not contain + * the information needed to recover the key (e.g. wrong password) + * @exception KeyStoreException if the keystore has not been initialized + * (loaded). + * @see #setEntry(String, KeyStore.Entry, KeyStore.ProtectionParameter) + * + * @since 1.5 + */ + public final Entry getEntry(String alias, ProtectionParameter protParam) + throws NoSuchAlgorithmException, UnrecoverableEntryException, + KeyStoreException { + + if (alias == null) { + throw new NullPointerException("invalid null input"); + } + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineGetEntry(alias, protParam); + } + + /** + * Saves a keystore {@code Entry} under the specified alias. + * The protection parameter is used to protect the + * {@code Entry}. + * + *

If an entry already exists for the specified alias, + * it is overridden. + * + * @param alias save the keystore {@code Entry} under this alias + * @param entry the {@code Entry} to save + * @param protParam the {@code ProtectionParameter} + * used to protect the {@code Entry}, + * which may be {@code null} + * + * @exception NullPointerException if + * {@code alias} or {@code entry} + * is {@code null} + * @exception KeyStoreException if the keystore has not been initialized + * (loaded), or if this operation fails for some other reason + * + * @see #getEntry(String, KeyStore.ProtectionParameter) + * + * @since 1.5 + */ + public final void setEntry(String alias, Entry entry, + ProtectionParameter protParam) + throws KeyStoreException { + if (alias == null || entry == null) { + throw new NullPointerException("invalid null input"); + } + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + keyStoreSpi.engineSetEntry(alias, entry, protParam); + } + + /** + * Determines if the keystore {@code Entry} for the specified + * {@code alias} is an instance or subclass of the specified + * {@code entryClass}. + * + * @param alias the alias name + * @param entryClass the entry class + * + * @return true if the keystore {@code Entry} for the specified + * {@code alias} is an instance or subclass of the + * specified {@code entryClass}, false otherwise + * + * @exception NullPointerException if + * {@code alias} or {@code entryClass} + * is {@code null} + * @exception KeyStoreException if the keystore has not been + * initialized (loaded) + * + * @since 1.5 + */ + public final boolean + entryInstanceOf(String alias, + Class entryClass) + throws KeyStoreException + { + + if (alias == null || entryClass == null) { + throw new NullPointerException("invalid null input"); + } + if (!initialized) { + throw new KeyStoreException("Uninitialized keystore"); + } + return keyStoreSpi.engineEntryInstanceOf(alias, entryClass); + } + + /** + * A description of a to-be-instantiated KeyStore object. + * + *

An instance of this class encapsulates the information needed to + * instantiate and initialize a KeyStore object. That process is + * triggered when the {@linkplain #getKeyStore} method is called. + * + *

This makes it possible to decouple configuration from KeyStore + * object creation and e.g. delay a password prompt until it is + * needed. + * + * @see KeyStore + * @see javax.net.ssl.KeyStoreBuilderParameters + * @since 1.5 + */ + public static abstract class Builder { + + // maximum times to try the callbackhandler if the password is wrong + static final int MAX_CALLBACK_TRIES = 3; + + /** + * Construct a new Builder. + */ + protected Builder() { + // empty + } + + /** + * Returns the KeyStore described by this object. + * + * @return the {@code KeyStore} described by this object + * @exception KeyStoreException if an error occurred during the + * operation, for example if the KeyStore could not be + * instantiated or loaded + */ + public abstract KeyStore getKeyStore() throws KeyStoreException; + + /** + * Returns the ProtectionParameters that should be used to obtain + * the {@link KeyStore.Entry Entry} with the given alias. + * The {@code getKeyStore} method must be invoked before this + * method may be called. + * + * @return the ProtectionParameters that should be used to obtain + * the {@link KeyStore.Entry Entry} with the given alias. + * @param alias the alias of the KeyStore entry + * @throws NullPointerException if alias is null + * @throws KeyStoreException if an error occurred during the + * operation + * @throws IllegalStateException if the getKeyStore method has + * not been invoked prior to calling this method + */ + public abstract ProtectionParameter getProtectionParameter(String alias) + throws KeyStoreException; + + /** + * Returns a new Builder that encapsulates the given KeyStore. + * The {@linkplain #getKeyStore} method of the returned object + * will return {@code keyStore}, the {@linkplain + * #getProtectionParameter getProtectionParameter()} method will + * return {@code protectionParameters}. + * + *

This is useful if an existing KeyStore object needs to be + * used with Builder-based APIs. + * + * @return a new Builder object + * @param keyStore the KeyStore to be encapsulated + * @param protectionParameter the ProtectionParameter used to + * protect the KeyStore entries + * @throws NullPointerException if keyStore or + * protectionParameters is null + * @throws IllegalArgumentException if the keyStore has not been + * initialized + */ + public static Builder newInstance(final KeyStore keyStore, + final ProtectionParameter protectionParameter) { + if ((keyStore == null) || (protectionParameter == null)) { + throw new NullPointerException(); + } + if (keyStore.initialized == false) { + throw new IllegalArgumentException("KeyStore not initialized"); + } + return new Builder() { + private volatile boolean getCalled; + + public KeyStore getKeyStore() { + getCalled = true; + return keyStore; + } + + public ProtectionParameter getProtectionParameter(String alias) + { + if (alias == null) { + throw new NullPointerException(); + } + if (getCalled == false) { + throw new IllegalStateException + ("getKeyStore() must be called first"); + } + return protectionParameter; + } + }; + } + + /** + * Returns a new Builder object. + * + *

The first call to the {@link #getKeyStore} method on the returned + * builder will create a KeyStore of type {@code type} and call + * its {@link KeyStore#load load()} method. + * The {@code inputStream} argument is constructed from + * {@code file}. + * If {@code protection} is a + * {@code PasswordProtection}, the password is obtained by + * calling the {@code getPassword} method. + * Otherwise, if {@code protection} is a + * {@code CallbackHandlerProtection}, the password is obtained + * by invoking the CallbackHandler. + * + *

Subsequent calls to {@link #getKeyStore} return the same object + * as the initial call. If the initial call to failed with a + * KeyStoreException, subsequent calls also throw a + * KeyStoreException. + * + *

The KeyStore is instantiated from {@code provider} if + * non-null. Otherwise, all installed providers are searched. + * + *

Calls to {@link #getProtectionParameter getProtectionParameter()} + * will return a {@link KeyStore.PasswordProtection PasswordProtection} + * object encapsulating the password that was used to invoke the + * {@code load} method. + * + *

Note that the {@link #getKeyStore} method is executed + * within the {@link AccessControlContext} of the code invoking this + * method. + * + * @return a new Builder object + * @param type the type of KeyStore to be constructed + * @param provider the provider from which the KeyStore is to + * be instantiated (or null) + * @param file the File that contains the KeyStore data + * @param protection the ProtectionParameter securing the KeyStore data + * @throws NullPointerException if type, file or protection is null + * @throws IllegalArgumentException if protection is not an instance + * of either PasswordProtection or CallbackHandlerProtection; or + * if file does not exist or does not refer to a normal file + */ + public static Builder newInstance(String type, Provider provider, + File file, ProtectionParameter protection) { + if ((type == null) || (file == null) || (protection == null)) { + throw new NullPointerException(); + } + if ((protection instanceof PasswordProtection == false) && + (protection instanceof CallbackHandlerProtection == false)) { + throw new IllegalArgumentException + ("Protection must be PasswordProtection or " + + "CallbackHandlerProtection"); + } + if (file.isFile() == false) { + throw new IllegalArgumentException + ("File does not exist or it does not refer " + + "to a normal file: " + file); + } + return new FileBuilder(type, provider, file, protection, + AccessController.getContext()); + } + + private static final class FileBuilder extends Builder { + + private final String type; + private final Provider provider; + private final File file; + private ProtectionParameter protection; + private ProtectionParameter keyProtection; + private final AccessControlContext context; + + private KeyStore keyStore; + + private Throwable oldException; + + FileBuilder(String type, Provider provider, File file, + ProtectionParameter protection, + AccessControlContext context) { + this.type = type; + this.provider = provider; + this.file = file; + this.protection = protection; + this.context = context; + } + + public synchronized KeyStore getKeyStore() throws KeyStoreException + { + if (keyStore != null) { + return keyStore; + } + if (oldException != null) { + throw new KeyStoreException + ("Previous KeyStore instantiation failed", + oldException); + } + PrivilegedExceptionAction action = + new PrivilegedExceptionAction() { + public KeyStore run() throws Exception { + if (protection instanceof CallbackHandlerProtection == false) { + return run0(); + } + // when using a CallbackHandler, + // reprompt if the password is wrong + int tries = 0; + while (true) { + tries++; + try { + return run0(); + } catch (IOException e) { + if ((tries < MAX_CALLBACK_TRIES) + && (e.getCause() instanceof UnrecoverableKeyException)) { + continue; + } + throw e; + } + } + } + public KeyStore run0() throws Exception { + KeyStore ks; + if (provider == null) { + ks = KeyStore.getInstance(type); + } else { + ks = KeyStore.getInstance(type, provider); + } + InputStream in = null; + char[] password = null; + try { + in = new FileInputStream(file); + if (protection instanceof PasswordProtection) { + password = + ((PasswordProtection)protection).getPassword(); + keyProtection = protection; + } else { + CallbackHandler handler = + ((CallbackHandlerProtection)protection) + .getCallbackHandler(); + PasswordCallback callback = new PasswordCallback + ("Password for keystore " + file.getName(), + false); + handler.handle(new Callback[] {callback}); + password = callback.getPassword(); + if (password == null) { + throw new KeyStoreException("No password" + + " provided"); + } + callback.clearPassword(); + keyProtection = new PasswordProtection(password); + } + ks.load(in, password); + return ks; + } finally { + if (in != null) { + in.close(); + } + } + } + }; + try { + keyStore = AccessController.doPrivileged(action, context); + return keyStore; + } catch (PrivilegedActionException e) { + oldException = e.getCause(); + throw new KeyStoreException + ("KeyStore instantiation failed", oldException); + } + } + + public synchronized ProtectionParameter + getProtectionParameter(String alias) { + if (alias == null) { + throw new NullPointerException(); + } + if (keyStore == null) { + throw new IllegalStateException + ("getKeyStore() must be called first"); + } + return keyProtection; + } + } + + /** + * Returns a new Builder object. + * + *

Each call to the {@link #getKeyStore} method on the returned + * builder will return a new KeyStore object of type {@code type}. + * Its {@link KeyStore#load(KeyStore.LoadStoreParameter) load()} + * method is invoked using a + * {@code LoadStoreParameter} that encapsulates + * {@code protection}. + * + *

The KeyStore is instantiated from {@code provider} if + * non-null. Otherwise, all installed providers are searched. + * + *

Calls to {@link #getProtectionParameter getProtectionParameter()} + * will return {@code protection}. + * + *

Note that the {@link #getKeyStore} method is executed + * within the {@link AccessControlContext} of the code invoking this + * method. + * + * @return a new Builder object + * @param type the type of KeyStore to be constructed + * @param provider the provider from which the KeyStore is to + * be instantiated (or null) + * @param protection the ProtectionParameter securing the Keystore + * @throws NullPointerException if type or protection is null + */ + public static Builder newInstance(final String type, + final Provider provider, final ProtectionParameter protection) { + if ((type == null) || (protection == null)) { + throw new NullPointerException(); + } + final AccessControlContext context = AccessController.getContext(); + return new Builder() { + private volatile boolean getCalled; + private IOException oldException; + + private final PrivilegedExceptionAction action + = new PrivilegedExceptionAction() { + + public KeyStore run() throws Exception { + KeyStore ks; + if (provider == null) { + ks = KeyStore.getInstance(type); + } else { + ks = KeyStore.getInstance(type, provider); + } + LoadStoreParameter param = new SimpleLoadStoreParameter(protection); + if (protection instanceof CallbackHandlerProtection == false) { + ks.load(param); + } else { + // when using a CallbackHandler, + // reprompt if the password is wrong + int tries = 0; + while (true) { + tries++; + try { + ks.load(param); + break; + } catch (IOException e) { + if (e.getCause() instanceof UnrecoverableKeyException) { + if (tries < MAX_CALLBACK_TRIES) { + continue; + } else { + oldException = e; + } + } + throw e; + } + } + } + getCalled = true; + return ks; + } + }; + + public synchronized KeyStore getKeyStore() + throws KeyStoreException { + if (oldException != null) { + throw new KeyStoreException + ("Previous KeyStore instantiation failed", + oldException); + } + try { + return AccessController.doPrivileged(action, context); + } catch (PrivilegedActionException e) { + Throwable cause = e.getCause(); + throw new KeyStoreException + ("KeyStore instantiation failed", cause); + } + } + + public ProtectionParameter getProtectionParameter(String alias) + { + if (alias == null) { + throw new NullPointerException(); + } + if (getCalled == false) { + throw new IllegalStateException + ("getKeyStore() must be called first"); + } + return protection; + } + }; + } + + } + + static class SimpleLoadStoreParameter implements LoadStoreParameter { + + private final ProtectionParameter protection; + + SimpleLoadStoreParameter(ProtectionParameter protection) { + this.protection = protection; + } + + public ProtectionParameter getProtectionParameter() { + return protection; + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyStoreException.java b/sources/net.sf.j2s.java.core/src/java/security/KeyStoreException.java new file mode 100644 index 000000000..cf56d6aa5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyStoreException.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1997, 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 java.security; + +/** + * This is the generic KeyStore exception. + * + * @author Jan Luehe + * + * + * @since 1.2 + */ + +public class KeyStoreException extends GeneralSecurityException { + + private static final long serialVersionUID = -1119353179322377262L; + + /** + * Constructs a KeyStoreException with no detail message. (A + * detail message is a String that describes this particular + * exception.) + */ + public KeyStoreException() { + super(); + } + + /** + * Constructs a KeyStoreException with the specified detail + * message. (A detail message is a String that describes this + * particular exception.) + * + * @param msg the detail message. + */ + public KeyStoreException(String msg) { + super(msg); + } + + /** + * Creates a {@code KeyStoreException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public KeyStoreException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code KeyStoreException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public KeyStoreException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/KeyStoreSpi.java b/sources/net.sf.j2s.java.core/src/java/security/KeyStoreSpi.java new file mode 100644 index 000000000..f71aed439 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/KeyStoreSpi.java @@ -0,0 +1,593 @@ +/* + * Copyright (c) 1998, 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 java.security; + +import java.io.*; +import java.util.*; + +import java.security.KeyStore.*; +import java.security.cert.Certificate; +import java.security.cert.CertificateException; + +import javax.crypto.SecretKey; + +import javax.security.auth.callback.*; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code KeyStore} class. + * All the abstract methods in this class must be implemented by each + * cryptographic service provider who wishes to supply the implementation + * of a keystore for a particular keystore type. + * + * @author Jan Luehe + * + * + * @see KeyStore + * + * @since 1.2 + */ + +public abstract class KeyStoreSpi { + + /** + * Returns the key associated with the given alias, using the given + * password to recover it. The key must have been associated with + * the alias by a call to {@code setKeyEntry}, + * or by a call to {@code setEntry} with a + * {@code PrivateKeyEntry} or {@code SecretKeyEntry}. + * + * @param alias the alias name + * @param password the password for recovering the key + * + * @return the requested key, or null if the given alias does not exist + * or does not identify a key-related entry. + * + * @exception NoSuchAlgorithmException if the algorithm for recovering the + * key cannot be found + * @exception UnrecoverableKeyException if the key cannot be recovered + * (e.g., the given password is wrong). + */ + public abstract Key engineGetKey(String alias, char[] password) + throws NoSuchAlgorithmException, UnrecoverableKeyException; + + /** + * Returns the certificate chain associated with the given alias. + * The certificate chain must have been associated with the alias + * by a call to {@code setKeyEntry}, + * or by a call to {@code setEntry} with a + * {@code PrivateKeyEntry}. + * + * @param alias the alias name + * + * @return the certificate chain (ordered with the user's certificate first + * and the root certificate authority last), or null if the given alias + * does not exist or does not contain a certificate chain + */ + public abstract Certificate[] engineGetCertificateChain(String alias); + + /** + * Returns the certificate associated with the given alias. + * + *

If the given alias name identifies an entry + * created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}, + * then the trusted certificate contained in that entry is returned. + * + *

If the given alias name identifies an entry + * created by a call to {@code setKeyEntry}, + * or created by a call to {@code setEntry} with a + * {@code PrivateKeyEntry}, + * then the first element of the certificate chain in that entry + * (if a chain exists) is returned. + * + * @param alias the alias name + * + * @return the certificate, or null if the given alias does not exist or + * does not contain a certificate. + */ + public abstract Certificate engineGetCertificate(String alias); + + /** + * Returns the creation date of the entry identified by the given alias. + * + * @param alias the alias name + * + * @return the creation date of this entry, or null if the given alias does + * not exist + */ + public abstract Date engineGetCreationDate(String alias); + + /** + * Assigns the given key to the given alias, protecting it with the given + * password. + * + *

If the given key is of type {@code java.security.PrivateKey}, + * it must be accompanied by a certificate chain certifying the + * corresponding public key. + * + *

If the given alias already exists, the keystore information + * associated with it is overridden by the given key (and possibly + * certificate chain). + * + * @param alias the alias name + * @param key the key to be associated with the alias + * @param password the password to protect the key + * @param chain the certificate chain for the corresponding public + * key (only required if the given key is of type + * {@code java.security.PrivateKey}). + * + * @exception KeyStoreException if the given key cannot be protected, or + * this operation fails for some other reason + */ + public abstract void engineSetKeyEntry(String alias, Key key, + char[] password, + Certificate[] chain) + throws KeyStoreException; + + /** + * Assigns the given key (that has already been protected) to the given + * alias. + * + *

If the protected key is of type + * {@code java.security.PrivateKey}, + * it must be accompanied by a certificate chain certifying the + * corresponding public key. + * + *

If the given alias already exists, the keystore information + * associated with it is overridden by the given key (and possibly + * certificate chain). + * + * @param alias the alias name + * @param key the key (in protected format) to be associated with the alias + * @param chain the certificate chain for the corresponding public + * key (only useful if the protected key is of type + * {@code java.security.PrivateKey}). + * + * @exception KeyStoreException if this operation fails. + */ + public abstract void engineSetKeyEntry(String alias, byte[] key, + Certificate[] chain) + throws KeyStoreException; + + /** + * Assigns the given certificate to the given alias. + * + *

If the given alias identifies an existing entry + * created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}, + * the trusted certificate in the existing entry + * is overridden by the given certificate. + * + * @param alias the alias name + * @param cert the certificate + * + * @exception KeyStoreException if the given alias already exists and does + * not identify an entry containing a trusted certificate, + * or this operation fails for some other reason. + */ + public abstract void engineSetCertificateEntry(String alias, + Certificate cert) + throws KeyStoreException; + + /** + * Deletes the entry identified by the given alias from this keystore. + * + * @param alias the alias name + * + * @exception KeyStoreException if the entry cannot be removed. + */ + public abstract void engineDeleteEntry(String alias) + throws KeyStoreException; + + /** + * Lists all the alias names of this keystore. + * + * @return enumeration of the alias names + */ + public abstract Enumeration engineAliases(); + + /** + * Checks if the given alias exists in this keystore. + * + * @param alias the alias name + * + * @return true if the alias exists, false otherwise + */ + public abstract boolean engineContainsAlias(String alias); + + /** + * Retrieves the number of entries in this keystore. + * + * @return the number of entries in this keystore + */ + public abstract int engineSize(); + + /** + * Returns true if the entry identified by the given alias + * was created by a call to {@code setKeyEntry}, + * or created by a call to {@code setEntry} with a + * {@code PrivateKeyEntry} or a {@code SecretKeyEntry}. + * + * @param alias the alias for the keystore entry to be checked + * + * @return true if the entry identified by the given alias is a + * key-related, false otherwise. + */ + public abstract boolean engineIsKeyEntry(String alias); + + /** + * Returns true if the entry identified by the given alias + * was created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}. + * + * @param alias the alias for the keystore entry to be checked + * + * @return true if the entry identified by the given alias contains a + * trusted certificate, false otherwise. + */ + public abstract boolean engineIsCertificateEntry(String alias); + + /** + * Returns the (alias) name of the first keystore entry whose certificate + * matches the given certificate. + * + *

This method attempts to match the given certificate with each + * keystore entry. If the entry being considered was + * created by a call to {@code setCertificateEntry}, + * or created by a call to {@code setEntry} with a + * {@code TrustedCertificateEntry}, + * then the given certificate is compared to that entry's certificate. + * + *

If the entry being considered was + * created by a call to {@code setKeyEntry}, + * or created by a call to {@code setEntry} with a + * {@code PrivateKeyEntry}, + * then the given certificate is compared to the first + * element of that entry's certificate chain. + * + * @param cert the certificate to match with. + * + * @return the alias name of the first entry with matching certificate, + * or null if no such entry exists in this keystore. + */ + public abstract String engineGetCertificateAlias(Certificate cert); + + /** + * Stores this keystore to the given output stream, and protects its + * integrity with the given password. + * + * @param stream the output stream to which this keystore is written. + * @param password the password to generate the keystore integrity check + * + * @exception IOException if there was an I/O problem with data + * @exception NoSuchAlgorithmException if the appropriate data integrity + * algorithm could not be found + * @exception CertificateException if any of the certificates included in + * the keystore data could not be stored + */ + public abstract void engineStore(OutputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException; + + /** + * Stores this keystore using the given + * {@code KeyStore.LoadStoreParmeter}. + * + * @param param the {@code KeyStore.LoadStoreParmeter} + * that specifies how to store the keystore, + * which may be {@code null} + * + * @exception IllegalArgumentException if the given + * {@code KeyStore.LoadStoreParmeter} + * input is not recognized + * @exception IOException if there was an I/O problem with data + * @exception NoSuchAlgorithmException if the appropriate data integrity + * algorithm could not be found + * @exception CertificateException if any of the certificates included in + * the keystore data could not be stored + * + * @since 1.5 + */ + public void engineStore(KeyStore.LoadStoreParameter param) + throws IOException, NoSuchAlgorithmException, + CertificateException { + throw new UnsupportedOperationException(); + } + + /** + * Loads the keystore from the given input stream. + * + *

A password may be given to unlock the keystore + * (e.g. the keystore resides on a hardware token device), + * or to check the integrity of the keystore data. + * If a password is not given for integrity checking, + * then integrity checking is not performed. + * + * @param stream the input stream from which the keystore is loaded, + * or {@code null} + * @param password the password used to check the integrity of + * the keystore, the password used to unlock the keystore, + * or {@code null} + * + * @exception IOException if there is an I/O or format problem with the + * keystore data, if a password is required but not given, + * or if the given password was incorrect. If the error is due to a + * wrong password, the {@link Throwable#getCause cause} of the + * {@code IOException} should be an + * {@code UnrecoverableKeyException} + * @exception NoSuchAlgorithmException if the algorithm used to check + * the integrity of the keystore cannot be found + * @exception CertificateException if any of the certificates in the + * keystore could not be loaded + */ + public abstract void engineLoad(InputStream stream, char[] password) + throws IOException, NoSuchAlgorithmException, CertificateException; + + /** + * Loads the keystore using the given + * {@code KeyStore.LoadStoreParameter}. + * + *

Note that if this KeyStore has already been loaded, it is + * reinitialized and loaded again from the given parameter. + * + * @param param the {@code KeyStore.LoadStoreParameter} + * that specifies how to load the keystore, + * which may be {@code null} + * + * @exception IllegalArgumentException if the given + * {@code KeyStore.LoadStoreParameter} + * input is not recognized + * @exception IOException if there is an I/O or format problem with the + * keystore data. If the error is due to an incorrect + * {@code ProtectionParameter} (e.g. wrong password) + * the {@link Throwable#getCause cause} of the + * {@code IOException} should be an + * {@code UnrecoverableKeyException} + * @exception NoSuchAlgorithmException if the algorithm used to check + * the integrity of the keystore cannot be found + * @exception CertificateException if any of the certificates in the + * keystore could not be loaded + * + * @since 1.5 + */ + public void engineLoad(KeyStore.LoadStoreParameter param) + throws IOException, NoSuchAlgorithmException, + CertificateException { + + if (param == null) { + engineLoad((InputStream)null, (char[])null); + return; + } + + if (param instanceof KeyStore.SimpleLoadStoreParameter) { + ProtectionParameter protection = param.getProtectionParameter(); + char[] password; + if (protection instanceof PasswordProtection) { + password = ((PasswordProtection)protection).getPassword(); + } else if (protection instanceof CallbackHandlerProtection) { + CallbackHandler handler = + ((CallbackHandlerProtection)protection).getCallbackHandler(); + PasswordCallback callback = + new PasswordCallback("Password: ", false); + try { + handler.handle(new Callback[] {callback}); + } catch (UnsupportedCallbackException e) { + throw new NoSuchAlgorithmException + ("Could not obtain password", e); + } + password = callback.getPassword(); + callback.clearPassword(); + if (password == null) { + throw new NoSuchAlgorithmException + ("No password provided"); + } + } else { + throw new NoSuchAlgorithmException("ProtectionParameter must" + + " be PasswordProtection or CallbackHandlerProtection"); + } + engineLoad(null, password); + return; + } + + throw new UnsupportedOperationException(); + } + + /** + * Gets a {@code KeyStore.Entry} for the specified alias + * with the specified protection parameter. + * + * @param alias get the {@code KeyStore.Entry} for this alias + * @param protParam the {@code ProtectionParameter} + * used to protect the {@code Entry}, + * which may be {@code null} + * + * @return the {@code KeyStore.Entry} for the specified alias, + * or {@code null} if there is no such entry + * + * @exception KeyStoreException if the operation failed + * @exception NoSuchAlgorithmException if the algorithm for recovering the + * entry cannot be found + * @exception UnrecoverableEntryException if the specified + * {@code protParam} were insufficient or invalid + * @exception UnrecoverableKeyException if the entry is a + * {@code PrivateKeyEntry} or {@code SecretKeyEntry} + * and the specified {@code protParam} does not contain + * the information needed to recover the key (e.g. wrong password) + * + * @since 1.5 + */ + public KeyStore.Entry engineGetEntry(String alias, + KeyStore.ProtectionParameter protParam) + throws KeyStoreException, NoSuchAlgorithmException, + UnrecoverableEntryException { + + if (!engineContainsAlias(alias)) { + return null; + } + + if (protParam == null) { + if (engineIsCertificateEntry(alias)) { + return new KeyStore.TrustedCertificateEntry + (engineGetCertificate(alias)); + } else { + throw new UnrecoverableKeyException + ("requested entry requires a password"); + } + } + + if (protParam instanceof KeyStore.PasswordProtection) { + if (engineIsCertificateEntry(alias)) { + throw new UnsupportedOperationException + ("trusted certificate entries are not password-protected"); + } else if (engineIsKeyEntry(alias)) { + KeyStore.PasswordProtection pp = + (KeyStore.PasswordProtection)protParam; + char[] password = pp.getPassword(); + + Key key = engineGetKey(alias, password); + if (key instanceof PrivateKey) { + Certificate[] chain = engineGetCertificateChain(alias); + return new KeyStore.PrivateKeyEntry((PrivateKey)key, chain); + } else if (key instanceof SecretKey) { + return new KeyStore.SecretKeyEntry((SecretKey)key); + } + } + } + + throw new UnsupportedOperationException(); + } + + /** + * Saves a {@code KeyStore.Entry} under the specified alias. + * The specified protection parameter is used to protect the + * {@code Entry}. + * + *

If an entry already exists for the specified alias, + * it is overridden. + * + * @param alias save the {@code KeyStore.Entry} under this alias + * @param entry the {@code Entry} to save + * @param protParam the {@code ProtectionParameter} + * used to protect the {@code Entry}, + * which may be {@code null} + * + * @exception KeyStoreException if this operation fails + * + * @since 1.5 + */ + public void engineSetEntry(String alias, KeyStore.Entry entry, + KeyStore.ProtectionParameter protParam) + throws KeyStoreException { + + // get password + if (protParam != null && + !(protParam instanceof KeyStore.PasswordProtection)) { + throw new KeyStoreException("unsupported protection parameter"); + } + KeyStore.PasswordProtection pProtect = null; + if (protParam != null) { + pProtect = (KeyStore.PasswordProtection)protParam; + } + + // set entry + if (entry instanceof KeyStore.TrustedCertificateEntry) { + if (protParam != null && pProtect.getPassword() != null) { + // pre-1.5 style setCertificateEntry did not allow password + throw new KeyStoreException + ("trusted certificate entries are not password-protected"); + } else { + KeyStore.TrustedCertificateEntry tce = + (KeyStore.TrustedCertificateEntry)entry; + engineSetCertificateEntry(alias, tce.getTrustedCertificate()); + return; + } + } else if (entry instanceof KeyStore.PrivateKeyEntry) { + if (pProtect == null || pProtect.getPassword() == null) { + // pre-1.5 style setKeyEntry required password + throw new KeyStoreException + ("non-null password required to create PrivateKeyEntry"); + } else { + engineSetKeyEntry + (alias, + ((KeyStore.PrivateKeyEntry)entry).getPrivateKey(), + pProtect.getPassword(), + ((KeyStore.PrivateKeyEntry)entry).getCertificateChain()); + return; + } + } else if (entry instanceof KeyStore.SecretKeyEntry) { + if (pProtect == null || pProtect.getPassword() == null) { + // pre-1.5 style setKeyEntry required password + throw new KeyStoreException + ("non-null password required to create SecretKeyEntry"); + } else { + engineSetKeyEntry + (alias, + ((KeyStore.SecretKeyEntry)entry).getSecretKey(), + pProtect.getPassword(), + (Certificate[])null); + return; + } + } + + throw new KeyStoreException + ("unsupported entry type: " + entry.getClass().getName()); + } + + /** + * Determines if the keystore {@code Entry} for the specified + * {@code alias} is an instance or subclass of the specified + * {@code entryClass}. + * + * @param alias the alias name + * @param entryClass the entry class + * + * @return true if the keystore {@code Entry} for the specified + * {@code alias} is an instance or subclass of the + * specified {@code entryClass}, false otherwise + * + * @since 1.5 + */ + public boolean + engineEntryInstanceOf(String alias, + Class entryClass) + { + if (entryClass == KeyStore.TrustedCertificateEntry.class) { + return engineIsCertificateEntry(alias); + } + if (entryClass == KeyStore.PrivateKeyEntry.class) { + return engineIsKeyEntry(alias) && + engineGetCertificate(alias) != null; + } + if (entryClass == KeyStore.SecretKeyEntry.class) { + return engineIsKeyEntry(alias) && + engineGetCertificate(alias) == null; + } + return false; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/MessageDigest.java b/sources/net.sf.j2s.java.core/src/java/security/MessageDigest.java new file mode 100644 index 000000000..cf3e3a3a1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/MessageDigest.java @@ -0,0 +1,600 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.util.*; +import java.lang.*; +import java.io.IOException; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.InputStream; +import java.io.ByteArrayInputStream; + +import java.nio.ByteBuffer; + +import sun.security.util.Debug; + +/** + * This MessageDigest class provides applications the functionality of a + * message digest algorithm, such as SHA-1 or SHA-256. + * Message digests are secure one-way hash functions that take arbitrary-sized + * data and output a fixed-length hash value. + * + *

A MessageDigest object starts out initialized. The data is + * processed through it using the {@link #update(byte) update} + * methods. At any point {@link #reset() reset} can be called + * to reset the digest. Once all the data to be updated has been + * updated, one of the {@link #digest() digest} methods should + * be called to complete the hash computation. + * + *

The {@code digest} method can be called once for a given number + * of updates. After {@code digest} has been called, the MessageDigest + * object is reset to its initialized state. + * + *

Implementations are free to implement the Cloneable interface. + * Client applications can test cloneability by attempting cloning + * and catching the CloneNotSupportedException: + * + *

{@code
+ * MessageDigest md = MessageDigest.getInstance("SHA");
+ *
+ * try {
+ *     md.update(toChapter1);
+ *     MessageDigest tc1 = md.clone();
+ *     byte[] toChapter1Digest = tc1.digest();
+ *     md.update(toChapter2);
+ *     ...etc.
+ * } catch (CloneNotSupportedException cnse) {
+ *     throw new DigestException("couldn't make digest of partial content");
+ * }
+ * }
+ * + *

Note that if a given implementation is not cloneable, it is + * still possible to compute intermediate digests by instantiating + * several instances, if the number of digests is known in advance. + * + *

Note that this class is abstract and extends from + * {@code MessageDigestSpi} for historical reasons. + * Application developers should only take notice of the methods defined in + * this {@code MessageDigest} class; all the methods in + * the superclass are intended for cryptographic service providers who wish to + * supply their own implementations of message digest algorithms. + * + *

Every implementation of the Java platform is required to support + * the following standard {@code MessageDigest} algorithms: + *

    + *
  • {@code MD5}
  • + *
  • {@code SHA-1}
  • + *
  • {@code SHA-256}
  • + *
+ * These algorithms are described in the + * MessageDigest section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + * @author Benjamin Renaud + * + * @see DigestInputStream + * @see DigestOutputStream + */ + +public abstract class MessageDigest extends MessageDigestSpi { + + private static final Debug pdebug = + Debug.getInstance("provider", "Provider"); + private static final boolean skipDebug = + Debug.isOn("engine=") && !Debug.isOn("messagedigest"); + + private String algorithm; + + // The state of this digest + private static final int INITIAL = 0; + private static final int IN_PROGRESS = 1; + private int state = INITIAL; + + // The provider + private Provider provider; + + /** + * Creates a message digest with the specified algorithm name. + * + * @param algorithm the standard name of the digest algorithm. + * See the MessageDigest section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + */ + protected MessageDigest(String algorithm) { + this.algorithm = algorithm; + } + + /** + * Returns a MessageDigest object that implements the specified digest + * algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new MessageDigest object encapsulating the + * MessageDigestSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the algorithm requested. + * See the MessageDigest section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return a Message Digest object that implements the specified algorithm. + * + * @exception NoSuchAlgorithmException if no Provider supports a + * MessageDigestSpi implementation for the + * specified algorithm. + * + * @see Provider + */ + public static MessageDigest getInstance(String algorithm) + throws NoSuchAlgorithmException { + try { + MessageDigest md; + Object[] objs = Security.getImpl(algorithm, "MessageDigest", + (String)null); + if (objs[0] instanceof MessageDigest) { + md = (MessageDigest)objs[0]; + } else { + md = new Delegate((MessageDigestSpi)objs[0], algorithm); + } + md.provider = (Provider)objs[1]; + + if (!skipDebug && pdebug != null) { + pdebug.println("MessageDigest." + algorithm + + " algorithm from: " + md.provider.getName()); + } + + return md; + + } catch(NoSuchProviderException e) { + throw new NoSuchAlgorithmException(algorithm + " not found"); + } + } + + /** + * Returns a MessageDigest object that implements the specified digest + * algorithm. + * + *

A new MessageDigest object encapsulating the + * MessageDigestSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the algorithm requested. + * See the MessageDigest section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the name of the provider. + * + * @return a MessageDigest object that implements the specified algorithm. + * + * @exception NoSuchAlgorithmException if a MessageDigestSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + */ + public static MessageDigest getInstance(String algorithm, String provider) + throws NoSuchAlgorithmException, NoSuchProviderException + { + if (provider == null || provider.length() == 0) + throw new IllegalArgumentException("missing provider"); + Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); + if (objs[0] instanceof MessageDigest) { + MessageDigest md = (MessageDigest)objs[0]; + md.provider = (Provider)objs[1]; + return md; + } else { + MessageDigest delegate = + new Delegate((MessageDigestSpi)objs[0], algorithm); + delegate.provider = (Provider)objs[1]; + return delegate; + } + } + + /** + * Returns a MessageDigest object that implements the specified digest + * algorithm. + * + *

A new MessageDigest object encapsulating the + * MessageDigestSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param algorithm the name of the algorithm requested. + * See the MessageDigest section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the provider. + * + * @return a MessageDigest object that implements the specified algorithm. + * + * @exception NoSuchAlgorithmException if a MessageDigestSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the specified provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static MessageDigest getInstance(String algorithm, + Provider provider) + throws NoSuchAlgorithmException + { + if (provider == null) + throw new IllegalArgumentException("missing provider"); + Object[] objs = Security.getImpl(algorithm, "MessageDigest", provider); + if (objs[0] instanceof MessageDigest) { + MessageDigest md = (MessageDigest)objs[0]; + md.provider = (Provider)objs[1]; + return md; + } else { + MessageDigest delegate = + new Delegate((MessageDigestSpi)objs[0], algorithm); + delegate.provider = (Provider)objs[1]; + return delegate; + } + } + + /** + * Returns the provider of this message digest object. + * + * @return the provider of this message digest object + */ + public final Provider getProvider() { + return this.provider; + } + + /** + * Updates the digest using the specified byte. + * + * @param input the byte with which to update the digest. + */ + public void update(byte input) { + engineUpdate(input); + state = IN_PROGRESS; + } + + /** + * Updates the digest using the specified array of bytes, starting + * at the specified offset. + * + * @param input the array of bytes. + * + * @param offset the offset to start from in the array of bytes. + * + * @param len the number of bytes to use, starting at + * {@code offset}. + */ + public void update(byte[] input, int offset, int len) { + if (input == null) { + throw new IllegalArgumentException("No input buffer given"); + } + if (input.length - offset < len) { + throw new IllegalArgumentException("Input buffer too short"); + } + engineUpdate(input, offset, len); + state = IN_PROGRESS; + } + + /** + * Updates the digest using the specified array of bytes. + * + * @param input the array of bytes. + */ + public void update(byte[] input) { + engineUpdate(input, 0, input.length); + state = IN_PROGRESS; + } + + /** + * Update the digest using the specified ByteBuffer. The digest is + * updated using the {@code input.remaining()} bytes starting + * at {@code input.position()}. + * Upon return, the buffer's position will be equal to its limit; + * its limit will not have changed. + * + * @param input the ByteBuffer + * @since 1.5 + */ + public final void update(ByteBuffer input) { + if (input == null) { + throw new NullPointerException(); + } + engineUpdate(input); + state = IN_PROGRESS; + } + + /** + * Completes the hash computation by performing final operations + * such as padding. The digest is reset after this call is made. + * + * @return the array of bytes for the resulting hash value. + */ + public byte[] digest() { + /* Resetting is the responsibility of implementors. */ + byte[] result = engineDigest(); + state = INITIAL; + return result; + } + + /** + * Completes the hash computation by performing final operations + * such as padding. The digest is reset after this call is made. + * + * @param buf output buffer for the computed digest + * + * @param offset offset into the output buffer to begin storing the digest + * + * @param len number of bytes within buf allotted for the digest + * + * @return the number of bytes placed into {@code buf} + * + * @exception DigestException if an error occurs. + */ + public int digest(byte[] buf, int offset, int len) throws DigestException { + if (buf == null) { + throw new IllegalArgumentException("No output buffer given"); + } + if (buf.length - offset < len) { + throw new IllegalArgumentException + ("Output buffer too small for specified offset and length"); + } + int numBytes = engineDigest(buf, offset, len); + state = INITIAL; + return numBytes; + } + + /** + * Performs a final update on the digest using the specified array + * of bytes, then completes the digest computation. That is, this + * method first calls {@link #update(byte[]) update(input)}, + * passing the input array to the {@code update} method, + * then calls {@link #digest() digest()}. + * + * @param input the input to be updated before the digest is + * completed. + * + * @return the array of bytes for the resulting hash value. + */ + public byte[] digest(byte[] input) { + update(input); + return digest(); + } + + /** + * Returns a string representation of this message digest object. + */ + public String toString() { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + PrintStream p = new PrintStream(baos); + p.print(algorithm+" Message Digest from "+provider.getName()+", "); + switch (state) { + case INITIAL: + p.print(""); + break; + case IN_PROGRESS: + p.print(""); + break; + } + p.println(); + return (baos.toString()); + } + + /** + * Compares two digests for equality. Does a simple byte compare. + * + * @param digesta one of the digests to compare. + * + * @param digestb the other digest to compare. + * + * @return true if the digests are equal, false otherwise. + */ + public static boolean isEqual(byte[] digesta, byte[] digestb) { + if (digesta.length != digestb.length) { + return false; + } + + int result = 0; + // time-constant comparison + for (int i = 0; i < digesta.length; i++) { + result |= digesta[i] ^ digestb[i]; + } + return result == 0; + } + + /** + * Resets the digest for further use. + */ + public void reset() { + engineReset(); + state = INITIAL; + } + + /** + * Returns a string that identifies the algorithm, independent of + * implementation details. The name should be a standard + * Java Security name (such as "SHA", "MD5", and so on). + * See the MessageDigest section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return the name of the algorithm + */ + public final String getAlgorithm() { + return this.algorithm; + } + + /** + * Returns the length of the digest in bytes, or 0 if this operation is + * not supported by the provider and the implementation is not cloneable. + * + * @return the digest length in bytes, or 0 if this operation is not + * supported by the provider and the implementation is not cloneable. + * + * @since 1.2 + */ + public final int getDigestLength() { + int digestLen = engineGetDigestLength(); + if (digestLen == 0) { + try { + MessageDigest md = (MessageDigest)clone(); + byte[] digest = md.digest(); + return digest.length; + } catch (CloneNotSupportedException e) { + return digestLen; + } + } + return digestLen; + } + + /** + * Returns a clone if the implementation is cloneable. + * + * @return a clone if the implementation is cloneable. + * + * @exception CloneNotSupportedException if this is called on an + * implementation that does not support {@code Cloneable}. + */ + public Object clone() throws CloneNotSupportedException { + if (this instanceof Cloneable) { + return super.clone(); + } else { + throw new CloneNotSupportedException(); + } + } + + + + + /* + * The following class allows providers to extend from MessageDigestSpi + * rather than from MessageDigest. It represents a MessageDigest with an + * encapsulated, provider-supplied SPI object (of type MessageDigestSpi). + * If the provider implementation is an instance of MessageDigestSpi, + * the getInstance() methods above return an instance of this class, with + * the SPI object encapsulated. + * + * Note: All SPI methods from the original MessageDigest class have been + * moved up the hierarchy into a new class (MessageDigestSpi), which has + * been interposed in the hierarchy between the API (MessageDigest) + * and its original parent (Object). + */ + + static class Delegate extends MessageDigest { + + // The provider implementation (delegate) + private MessageDigestSpi digestSpi; + + // constructor + public Delegate(MessageDigestSpi digestSpi, String algorithm) { + super(algorithm); + this.digestSpi = digestSpi; + } + + /** + * Returns a clone if the delegate is cloneable. + * + * @return a clone if the delegate is cloneable. + * + * @exception CloneNotSupportedException if this is called on a + * delegate that does not support {@code Cloneable}. + */ + public Object clone() throws CloneNotSupportedException { + if (digestSpi instanceof Cloneable) { + MessageDigestSpi digestSpiClone = + (MessageDigestSpi)digestSpi.clone(); + // Because 'algorithm', 'provider', and 'state' are private + // members of our supertype, we must perform a cast to + // access them. + MessageDigest that = + new Delegate(digestSpiClone, + ((MessageDigest)this).algorithm); + that.provider = ((MessageDigest)this).provider; + that.state = ((MessageDigest)this).state; + return that; + } else { + throw new CloneNotSupportedException(); + } + } + + protected int engineGetDigestLength() { + return digestSpi.engineGetDigestLength(); + } + + protected void engineUpdate(byte input) { + digestSpi.engineUpdate(input); + } + + protected void engineUpdate(byte[] input, int offset, int len) { + digestSpi.engineUpdate(input, offset, len); + } + + protected void engineUpdate(ByteBuffer input) { + digestSpi.engineUpdate(input); + } + + protected byte[] engineDigest() { + return digestSpi.engineDigest(); + } + + protected int engineDigest(byte[] buf, int offset, int len) + throws DigestException { + return digestSpi.engineDigest(buf, offset, len); + } + + protected void engineReset() { + digestSpi.engineReset(); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/MessageDigestSpi.java b/sources/net.sf.j2s.java.core/src/java/security/MessageDigestSpi.java new file mode 100644 index 000000000..0d5ace1f7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/MessageDigestSpi.java @@ -0,0 +1,206 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.nio.ByteBuffer; + +import sun.security.jca.JCAUtil; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code MessageDigest} class, which provides the functionality + * of a message digest algorithm, such as MD5 or SHA. Message digests are + * secure one-way hash functions that take arbitrary-sized data and output a + * fixed-length hash value. + * + *

All the abstract methods in this class must be implemented by a + * cryptographic service provider who wishes to supply the implementation + * of a particular message digest algorithm. + * + *

Implementations are free to implement the Cloneable interface. + * + * @author Benjamin Renaud + * + * + * @see MessageDigest + */ + +public abstract class MessageDigestSpi { + + // for re-use in engineUpdate(ByteBuffer input) + private byte[] tempArray; + + /** + * Returns the digest length in bytes. + * + *

This concrete method has been added to this previously-defined + * abstract class. (For backwards compatibility, it cannot be abstract.) + * + *

The default behavior is to return 0. + * + *

This method may be overridden by a provider to return the digest + * length. + * + * @return the digest length in bytes. + * + * @since 1.2 + */ + protected int engineGetDigestLength() { + return 0; + } + + /** + * Updates the digest using the specified byte. + * + * @param input the byte to use for the update. + */ + protected abstract void engineUpdate(byte input); + + /** + * Updates the digest using the specified array of bytes, + * starting at the specified offset. + * + * @param input the array of bytes to use for the update. + * + * @param offset the offset to start from in the array of bytes. + * + * @param len the number of bytes to use, starting at + * {@code offset}. + */ + protected abstract void engineUpdate(byte[] input, int offset, int len); + + /** + * Update the digest using the specified ByteBuffer. The digest is + * updated using the {@code input.remaining()} bytes starting + * at {@code input.position()}. + * Upon return, the buffer's position will be equal to its limit; + * its limit will not have changed. + * + * @param input the ByteBuffer + * @since 1.5 + */ + protected void engineUpdate(ByteBuffer input) { + if (input.hasRemaining() == false) { + return; + } + if (input.hasArray()) { + byte[] b = input.array(); + int ofs = input.arrayOffset(); + int pos = input.position(); + int lim = input.limit(); + engineUpdate(b, ofs + pos, lim - pos); + input.position(lim); + } else { + int len = input.remaining(); + int n = JCAUtil.getTempArraySize(len); + if ((tempArray == null) || (n > tempArray.length)) { + tempArray = new byte[n]; + } + while (len > 0) { + int chunk = Math.min(len, tempArray.length); + input.get(tempArray, 0, chunk); + engineUpdate(tempArray, 0, chunk); + len -= chunk; + } + } + } + + /** + * Completes the hash computation by performing final + * operations such as padding. Once {@code engineDigest} has + * been called, the engine should be reset (see + * {@link #engineReset() engineReset}). + * Resetting is the responsibility of the + * engine implementor. + * + * @return the array of bytes for the resulting hash value. + */ + protected abstract byte[] engineDigest(); + + /** + * Completes the hash computation by performing final + * operations such as padding. Once {@code engineDigest} has + * been called, the engine should be reset (see + * {@link #engineReset() engineReset}). + * Resetting is the responsibility of the + * engine implementor. + * + * This method should be abstract, but we leave it concrete for + * binary compatibility. Knowledgeable providers should override this + * method. + * + * @param buf the output buffer in which to store the digest + * + * @param offset offset to start from in the output buffer + * + * @param len number of bytes within buf allotted for the digest. + * Both this default implementation and the SUN provider do not + * return partial digests. The presence of this parameter is solely + * for consistency in our API's. If the value of this parameter is less + * than the actual digest length, the method will throw a DigestException. + * This parameter is ignored if its value is greater than or equal to + * the actual digest length. + * + * @return the length of the digest stored in the output buffer. + * + * @exception DigestException if an error occurs. + * + * @since 1.2 + */ + protected int engineDigest(byte[] buf, int offset, int len) + throws DigestException { + + byte[] digest = engineDigest(); + if (len < digest.length) + throw new DigestException("partial digests not returned"); + if (buf.length - offset < digest.length) + throw new DigestException("insufficient space in the output " + + "buffer to store the digest"); + System.arraycopy(digest, 0, buf, offset, digest.length); + return digest.length; + } + + /** + * Resets the digest for further use. + */ + protected abstract void engineReset(); + + /** + * Returns a clone if the implementation is cloneable. + * + * @return a clone if the implementation is cloneable. + * + * @exception CloneNotSupportedException if this is called on an + * implementation that does not support {@code Cloneable}. + */ + public Object clone() throws CloneNotSupportedException { + if (this instanceof Cloneable) { + return super.clone(); + } else { + throw new CloneNotSupportedException(); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/NoSuchAlgorithmException.java b/sources/net.sf.j2s.java.core/src/java/security/NoSuchAlgorithmException.java new file mode 100644 index 000000000..951e44e41 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/NoSuchAlgorithmException.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * This exception is thrown when a particular cryptographic algorithm is + * requested but is not available in the environment. + * + * @author Benjamin Renaud + */ + +public class NoSuchAlgorithmException extends GeneralSecurityException { + + private static final long serialVersionUID = -7443947487218346562L; + + /** + * Constructs a NoSuchAlgorithmException with no detail + * message. A detail message is a String that describes this + * particular exception. + */ + public NoSuchAlgorithmException() { + super(); + } + + /** + * Constructs a NoSuchAlgorithmException with the specified + * detail message. A detail message is a String that describes + * this particular exception, which may, for example, specify which + * algorithm is not available. + * + * @param msg the detail message. + */ + public NoSuchAlgorithmException(String msg) { + super(msg); + } + + /** + * Creates a {@code NoSuchAlgorithmException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public NoSuchAlgorithmException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code NoSuchAlgorithmException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public NoSuchAlgorithmException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/NoSuchProviderException.java b/sources/net.sf.j2s.java.core/src/java/security/NoSuchProviderException.java new file mode 100644 index 000000000..9874adb14 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/NoSuchProviderException.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1996, 2003, 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 java.security; + +/** + * This exception is thrown when a particular security provider is + * requested but is not available in the environment. + * + * @author Benjamin Renaud + */ + +public class NoSuchProviderException extends GeneralSecurityException { + + private static final long serialVersionUID = 8488111756688534474L; + + /** + * Constructs a NoSuchProviderException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public NoSuchProviderException() { + super(); + } + + /** + * Constructs a NoSuchProviderException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public NoSuchProviderException(String msg) { + super(msg); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/PKCS12Attribute.java b/sources/net.sf.j2s.java.core/src/java/security/PKCS12Attribute.java new file mode 100644 index 000000000..e38986288 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/PKCS12Attribute.java @@ -0,0 +1,285 @@ +/* + * 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 java.security; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.Arrays; +import java.util.regex.Pattern; +import sun.security.util.*; + +/** + * An attribute associated with a PKCS12 keystore entry. + * The attribute name is an ASN.1 Object Identifier and the attribute + * value is a set of ASN.1 types. + * + * @since 1.8 + */ +public final class PKCS12Attribute implements KeyStore.Entry.Attribute { + + private static final Pattern COLON_SEPARATED_HEX_PAIRS = + Pattern.compile("^[0-9a-fA-F]{2}(:[0-9a-fA-F]{2})+$"); + private String name; + private String value; + private byte[] encoded; + private int hashValue = -1; + + /** + * Constructs a PKCS12 attribute from its name and value. + * The name is an ASN.1 Object Identifier represented as a list of + * dot-separated integers. + * A string value is represented as the string itself. + * A binary value is represented as a string of colon-separated + * pairs of hexadecimal digits. + * Multi-valued attributes are represented as a comma-separated + * list of values, enclosed in square brackets. See + * {@link Arrays#toString(java.lang.Object[])}. + *

+ * A string value will be DER-encoded as an ASN.1 UTF8String and a + * binary value will be DER-encoded as an ASN.1 Octet String. + * + * @param name the attribute's identifier + * @param value the attribute's value + * + * @exception NullPointerException if {@code name} or {@code value} + * is {@code null} + * @exception IllegalArgumentException if {@code name} or + * {@code value} is incorrectly formatted + */ + public PKCS12Attribute(String name, String value) { + if (name == null || value == null) { + throw new NullPointerException(); + } + // Validate name + ObjectIdentifier type; + try { + type = new ObjectIdentifier(name); + } catch (IOException e) { + throw new IllegalArgumentException("Incorrect format: name", e); + } + this.name = name; + + // Validate value + int length = value.length(); + String[] values; + if (value.charAt(0) == '[' && value.charAt(length - 1) == ']') { + values = value.substring(1, length - 1).split(", "); + } else { + values = new String[]{ value }; + } + this.value = value; + + try { + this.encoded = encode(type, values); + } catch (IOException e) { + throw new IllegalArgumentException("Incorrect format: value", e); + } + } + + /** + * Constructs a PKCS12 attribute from its ASN.1 DER encoding. + * The DER encoding is specified by the following ASN.1 definition: + *

+     *
+     * Attribute ::= SEQUENCE {
+     *     type   AttributeType,
+     *     values SET OF AttributeValue
+     * }
+     * AttributeType ::= OBJECT IDENTIFIER
+     * AttributeValue ::= ANY defined by type
+     *
+     * 
+ * + * @param encoded the attribute's ASN.1 DER encoding. It is cloned + * to prevent subsequent modificaion. + * + * @exception NullPointerException if {@code encoded} is + * {@code null} + * @exception IllegalArgumentException if {@code encoded} is + * incorrectly formatted + */ + public PKCS12Attribute(byte[] encoded) { + if (encoded == null) { + throw new NullPointerException(); + } + this.encoded = encoded.clone(); + + try { + parse(encoded); + } catch (IOException e) { + throw new IllegalArgumentException("Incorrect format: encoded", e); + } + } + + /** + * Returns the attribute's ASN.1 Object Identifier represented as a + * list of dot-separated integers. + * + * @return the attribute's identifier + */ + @Override + public String getName() { + return name; + } + + /** + * Returns the attribute's ASN.1 DER-encoded value as a string. + * An ASN.1 DER-encoded value is returned in one of the following + * {@code String} formats: + *
    + *
  • the DER encoding of a basic ASN.1 type that has a natural + * string representation is returned as the string itself. + * Such types are currently limited to BOOLEAN, INTEGER, + * OBJECT IDENTIFIER, UTCTime, GeneralizedTime and the + * following six ASN.1 string types: UTF8String, + * PrintableString, T61String, IA5String, BMPString and + * GeneralString. + *
  • the DER encoding of any other ASN.1 type is not decoded but + * returned as a binary string of colon-separated pairs of + * hexadecimal digits. + *
+ * Multi-valued attributes are represented as a comma-separated + * list of values, enclosed in square brackets. See + * {@link Arrays#toString(java.lang.Object[])}. + * + * @return the attribute value's string encoding + */ + @Override + public String getValue() { + return value; + } + + /** + * Returns the attribute's ASN.1 DER encoding. + * + * @return a clone of the attribute's DER encoding + */ + public byte[] getEncoded() { + return encoded.clone(); + } + + /** + * Compares this {@code PKCS12Attribute} and a specified object for + * equality. + * + * @param obj the comparison object + * + * @return true if {@code obj} is a {@code PKCS12Attribute} and + * their DER encodings are equal. + */ + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof PKCS12Attribute)) { + return false; + } + return Arrays.equals(encoded, ((PKCS12Attribute) obj).getEncoded()); + } + + /** + * Returns the hashcode for this {@code PKCS12Attribute}. + * The hash code is computed from its DER encoding. + * + * @return the hash code + */ + @Override + public int hashCode() { + if (hashValue == -1) { + Arrays.hashCode(encoded); + } + return hashValue; + } + + /** + * Returns a string representation of this {@code PKCS12Attribute}. + * + * @return a name/value pair separated by an 'equals' symbol + */ + @Override + public String toString() { + return (name + "=" + value); + } + + private byte[] encode(ObjectIdentifier type, String[] values) + throws IOException { + DerOutputStream attribute = new DerOutputStream(); + attribute.putOID(type); + DerOutputStream attrContent = new DerOutputStream(); + for (String value : values) { + if (COLON_SEPARATED_HEX_PAIRS.matcher(value).matches()) { + byte[] bytes = + new BigInteger(value.replace(":", ""), 16).toByteArray(); + if (bytes[0] == 0) { + bytes = Arrays.copyOfRange(bytes, 1, bytes.length); + } + attrContent.putOctetString(bytes); + } else { + attrContent.putUTF8String(value); + } + } + attribute.write(DerValue.tag_Set, attrContent); + DerOutputStream attributeValue = new DerOutputStream(); + attributeValue.write(DerValue.tag_Sequence, attribute); + + return attributeValue.toByteArray(); + } + + private void parse(byte[] encoded) throws IOException { + DerInputStream attributeValue = new DerInputStream(encoded); + DerValue[] attrSeq = attributeValue.getSequence(2); + ObjectIdentifier type = attrSeq[0].getOID(); + DerInputStream attrContent = + new DerInputStream(attrSeq[1].toByteArray()); + DerValue[] attrValueSet = attrContent.getSet(1); + String[] values = new String[attrValueSet.length]; + String printableString; + for (int i = 0; i < attrValueSet.length; i++) { + if (attrValueSet[i].tag == DerValue.tag_OctetString) { + values[i] = Debug.toString(attrValueSet[i].getOctetString()); + } else if ((printableString = attrValueSet[i].getAsString()) + != null) { + values[i] = printableString; + } else if (attrValueSet[i].tag == DerValue.tag_ObjectId) { + values[i] = attrValueSet[i].getOID().toString(); + } else if (attrValueSet[i].tag == DerValue.tag_GeneralizedTime) { + values[i] = attrValueSet[i].getGeneralizedTime().toString(); + } else if (attrValueSet[i].tag == DerValue.tag_UtcTime) { + values[i] = attrValueSet[i].getUTCTime().toString(); + } else if (attrValueSet[i].tag == DerValue.tag_Integer) { + values[i] = attrValueSet[i].getBigInteger().toString(); + } else if (attrValueSet[i].tag == DerValue.tag_Boolean) { + values[i] = String.valueOf(attrValueSet[i].getBoolean()); + } else { + values[i] = Debug.toString(attrValueSet[i].getDataBytes()); + } + } + + this.name = type.toString(); + this.value = values.length == 1 ? values[0] : Arrays.toString(values); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Permission.java b/sources/net.sf.j2s.java.core/src/java/security/Permission.java new file mode 100644 index 000000000..088f97c35 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Permission.java @@ -0,0 +1,231 @@ +/* + * Copyright (c) 1997, 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 java.security; + +/** + * Abstract class for representing access to a system resource. + * All permissions have a name (whose interpretation depends on the subclass), + * as well as abstract functions for defining the semantics of the + * particular Permission subclass. + * + *

Most Permission objects also include an "actions" list that tells the actions + * that are permitted for the object. For example, + * for a {@code java.io.FilePermission} object, the permission name is + * the pathname of a file (or directory), and the actions list + * (such as "read, write") specifies which actions are granted for the + * specified file (or for files in the specified directory). + * The actions list is optional for Permission objects, such as + * {@code java.lang.RuntimePermission}, + * that don't need such a list; you either have the named permission (such + * as "system.exit") or you don't. + * + *

An important method that must be implemented by each subclass is + * the {@code implies} method to compare Permissions. Basically, + * "permission p1 implies permission p2" means that + * if one is granted permission p1, one is naturally granted permission p2. + * Thus, this is not an equality test, but rather more of a + * subset test. + * + *

Permission objects are similar to String objects in that they + * are immutable once they have been created. Subclasses should not + * provide methods that can change the state of a permission + * once it has been created. + * + * @see Permissions + * @see PermissionCollection + * + * + * @author Marianne Mueller + * @author Roland Schemers + */ + +public abstract class Permission implements Guard, java.io.Serializable { + + private static final long serialVersionUID = -5636570222231596674L; + + private String name; + + /** + * Constructs a permission with the specified name. + * + * @param name name of the Permission object being created. + * + */ + + public Permission(String name) { + this.name = name; + } + + /** + * Implements the guard interface for a permission. The + * {@code SecurityManager.checkPermission} method is called, + * passing this permission object as the permission to check. + * Returns silently if access is granted. Otherwise, throws + * a SecurityException. + * + * @param object the object being guarded (currently ignored). + * + * @throws SecurityException + * if a security manager exists and its + * {@code checkPermission} method doesn't allow access. + * + * @see Guard + * @see GuardedObject + * @see SecurityManager#checkPermission + * + */ + public void checkGuard(Object object) throws SecurityException { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) sm.checkPermission(this); + } + + /** + * Checks if the specified permission's actions are "implied by" + * this object's actions. + *

+ * This must be implemented by subclasses of Permission, as they are the + * only ones that can impose semantics on a Permission object. + * + *

The {@code implies} method is used by the AccessController to determine + * whether or not a requested permission is implied by another permission that + * is known to be valid in the current execution context. + * + * @param permission the permission to check against. + * + * @return true if the specified permission is implied by this object, + * false if not. + */ + + public abstract boolean implies(Permission permission); + + /** + * Checks two Permission objects for equality. + *

+ * Do not use the {@code equals} method for making access control + * decisions; use the {@code implies} method. + * + * @param obj the object we are testing for equality with this object. + * + * @return true if both Permission objects are equivalent. + */ + + public abstract boolean equals(Object obj); + + /** + * Returns the hash code value for this Permission object. + *

+ * The required {@code hashCode} behavior for Permission Objects is + * the following: + *

    + *
  • Whenever it is invoked on the same Permission object more than + * once during an execution of a Java application, the + * {@code hashCode} method + * must consistently return the same integer. This integer need not + * remain consistent from one execution of an application to another + * execution of the same application. + *
  • If two Permission objects are equal according to the + * {@code equals} + * method, then calling the {@code hashCode} method on each of the + * two Permission objects must produce the same integer result. + *
+ * + * @return a hash code value for this object. + */ + + public abstract int hashCode(); + + /** + * Returns the name of this Permission. + * For example, in the case of a {@code java.io.FilePermission}, + * the name will be a pathname. + * + * @return the name of this Permission. + * + */ + + public final String getName() { + return name; + } + + /** + * Returns the actions as a String. This is abstract + * so subclasses can defer creating a String representation until + * one is needed. Subclasses should always return actions in what they + * consider to be their + * canonical form. For example, two FilePermission objects created via + * the following: + * + *
+     *   perm1 = new FilePermission(p1,"read,write");
+     *   perm2 = new FilePermission(p2,"write,read");
+     * 
+ * + * both return + * "read,write" when the {@code getActions} method is invoked. + * + * @return the actions of this Permission. + * + */ + + public abstract String getActions(); + + /** + * Returns an empty PermissionCollection for a given Permission object, or null if + * one is not defined. Subclasses of class Permission should + * override this if they need to store their permissions in a particular + * PermissionCollection object in order to provide the correct semantics + * when the {@code PermissionCollection.implies} method is called. + * If null is returned, + * then the caller of this method is free to store permissions of this + * type in any PermissionCollection they choose (one that uses a Hashtable, + * one that uses a Vector, etc). + * + * @return a new PermissionCollection object for this type of Permission, or + * null if one is not defined. + */ + + public PermissionCollection newPermissionCollection() { + return null; + } + + /** + * Returns a string describing this Permission. The convention is to + * specify the class name, the permission name, and the actions in + * the following format: '("ClassName" "name" "actions")', or + * '("ClassName" "name")' if actions list is null or empty. + * + * @return information about this Permission. + */ + public String toString() { + String actions = getActions(); + if ((actions == null) || (actions.length() == 0)) { // OPTIONAL + return "(\"" + getClass().getName() + "\" \"" + name + "\")"; + } else { + return "(\"" + getClass().getName() + "\" \"" + name + + "\" \"" + actions + "\")"; + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/PermissionCollection.java b/sources/net.sf.j2s.java.core/src/java/security/PermissionCollection.java new file mode 100644 index 000000000..3f13b9f93 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/PermissionCollection.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.util.*; + +/** + * Abstract class representing a collection of Permission objects. + * + *

With a PermissionCollection, you can: + *

    + *
  • add a permission to the collection using the {@code add} method. + *
  • check to see if a particular permission is implied in the + * collection, using the {@code implies} method. + *
  • enumerate all the permissions, using the {@code elements} method. + *
+ * + *

When it is desirable to group together a number of Permission objects + * of the same type, the {@code newPermissionCollection} method on that + * particular type of Permission object should first be called. The default + * behavior (from the Permission class) is to simply return null. + * Subclasses of class Permission override the method if they need to store + * their permissions in a particular PermissionCollection object in order + * to provide the correct semantics when the + * {@code PermissionCollection.implies} method is called. + * If a non-null value is returned, that PermissionCollection must be used. + * If null is returned, then the caller of {@code newPermissionCollection} + * is free to store permissions of the + * given type in any PermissionCollection they choose + * (one that uses a Hashtable, one that uses a Vector, etc). + * + *

The PermissionCollection returned by the + * {@code Permission.newPermissionCollection} + * method is a homogeneous collection, which stores only Permission objects + * for a given Permission type. A PermissionCollection may also be + * heterogeneous. For example, Permissions is a PermissionCollection + * subclass that represents a collection of PermissionCollections. + * That is, its members are each a homogeneous PermissionCollection. + * For example, a Permissions object might have a FilePermissionCollection + * for all the FilePermission objects, a SocketPermissionCollection for all the + * SocketPermission objects, and so on. Its {@code add} method adds a + * permission to the appropriate collection. + * + *

Whenever a permission is added to a heterogeneous PermissionCollection + * such as Permissions, and the PermissionCollection doesn't yet contain a + * PermissionCollection of the specified permission's type, the + * PermissionCollection should call + * the {@code newPermissionCollection} method on the permission's class + * to see if it requires a special PermissionCollection. If + * {@code newPermissionCollection} + * returns null, the PermissionCollection + * is free to store the permission in any type of PermissionCollection it + * desires (one using a Hashtable, one using a Vector, etc.). For example, + * the Permissions object uses a default PermissionCollection implementation + * that stores the permission objects in a Hashtable. + * + *

Subclass implementations of PermissionCollection should assume + * that they may be called simultaneously from multiple threads, + * and therefore should be synchronized properly. Furthermore, + * Enumerations returned via the {@code elements} method are + * not fail-fast. Modifications to a collection should not be + * performed while enumerating over that collection. + * + * @see Permission + * @see Permissions + * + * + * @author Roland Schemers + */ + +public abstract class PermissionCollection implements java.io.Serializable { + + private static final long serialVersionUID = -6727011328946861783L; + + // when set, add will throw an exception. + private volatile boolean readOnly; + + /** + * Adds a permission object to the current collection of permission objects. + * + * @param permission the Permission object to add. + * + * @exception SecurityException - if this PermissionCollection object + * has been marked readonly + * @exception IllegalArgumentException - if this PermissionCollection + * object is a homogeneous collection and the permission + * is not of the correct type. + */ + public abstract void add(Permission permission); + + /** + * Checks to see if the specified permission is implied by + * the collection of Permission objects held in this PermissionCollection. + * + * @param permission the Permission object to compare. + * + * @return true if "permission" is implied by the permissions in + * the collection, false if not. + */ + public abstract boolean implies(Permission permission); + + /** + * Returns an enumeration of all the Permission objects in the collection. + * + * @return an enumeration of all the Permissions. + */ + public abstract Enumeration elements(); + + /** + * Marks this PermissionCollection object as "readonly". After + * a PermissionCollection object + * is marked as readonly, no new Permission objects can be added to it + * using {@code add}. + */ + public void setReadOnly() { + readOnly = true; + } + + /** + * Returns true if this PermissionCollection object is marked as readonly. + * If it is readonly, no new Permission objects can be added to it + * using {@code add}. + * + *

By default, the object is not readonly. It can be set to + * readonly by a call to {@code setReadOnly}. + * + * @return true if this PermissionCollection object is marked as readonly, + * false otherwise. + */ + public boolean isReadOnly() { + return readOnly; + } + + /** + * Returns a string describing this PermissionCollection object, + * providing information about all the permissions it contains. + * The format is: + *

+     * super.toString() (
+     *   // enumerate all the Permission
+     *   // objects and call toString() on them,
+     *   // one per line..
+     * )
+ * + * {@code super.toString} is a call to the {@code toString} + * method of this + * object's superclass, which is Object. The result is + * this PermissionCollection's type name followed by this object's + * hashcode, thus enabling clients to differentiate different + * PermissionCollections object, even if they contain the same permissions. + * + * @return information about this PermissionCollection object, + * as described above. + * + */ + public String toString() { + Enumeration enum_ = elements(); + StringBuilder sb = new StringBuilder(); + sb.append(super.toString()+" (\n"); + while (enum_.hasMoreElements()) { + try { + sb.append(" "); + sb.append(enum_.nextElement().toString()); + sb.append("\n"); + } catch (NoSuchElementException e){ + // ignore + } + } + sb.append(")\n"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Permissions.java b/sources/net.sf.j2s.java.core/src/java/security/Permissions.java new file mode 100644 index 000000000..cce9f5f56 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Permissions.java @@ -0,0 +1,603 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.NoSuchElementException; +import java.util.Map; +import java.util.HashMap; +import java.util.List; +import java.util.Iterator; +import java.util.Collections; +import java.io.Serializable; +import java.io.ObjectStreamField; +import java.io.ObjectOutputStream; +import java.io.ObjectInputStream; +import java.io.IOException; + + +/** + * This class represents a heterogeneous collection of Permissions. That is, + * it contains different types of Permission objects, organized into + * PermissionCollections. For example, if any + * {@code java.io.FilePermission} objects are added to an instance of + * this class, they are all stored in a single + * PermissionCollection. It is the PermissionCollection returned by a call to + * the {@code newPermissionCollection} method in the FilePermission class. + * Similarly, any {@code java.lang.RuntimePermission} objects are + * stored in the PermissionCollection returned by a call to the + * {@code newPermissionCollection} method in the + * RuntimePermission class. Thus, this class represents a collection of + * PermissionCollections. + * + *

When the {@code add} method is called to add a Permission, the + * Permission is stored in the appropriate PermissionCollection. If no such + * collection exists yet, the Permission object's class is determined and the + * {@code newPermissionCollection} method is called on that class to create + * the PermissionCollection and add it to the Permissions object. If + * {@code newPermissionCollection} returns null, then a default + * PermissionCollection that uses a hashtable will be created and used. Each + * hashtable entry stores a Permission object as both the key and the value. + * + *

Enumerations returned via the {@code elements} method are + * not fail-fast. Modifications to a collection should not be + * performed while enumerating over that collection. + * + * @see Permission + * @see PermissionCollection + * @see AllPermission + * + * + * @author Marianne Mueller + * @author Roland Schemers + * + * @serial exclude + */ + +public final class Permissions extends PermissionCollection +implements Serializable +{ + /** + * Key is permissions Class, value is PermissionCollection for that class. + * Not serialized; see serialization section at end of class. + */ + private transient Map, PermissionCollection> permsMap; + + // optimization. keep track of whether unresolved permissions need to be + // checked + private transient boolean hasUnresolved = false; + + // optimization. keep track of the AllPermission collection + // - package private for ProtectionDomain optimization + PermissionCollection allPermission; + + /** + * Creates a new Permissions object containing no PermissionCollections. + */ + public Permissions() { + permsMap = new HashMap, PermissionCollection>(11); + allPermission = null; + } + + /** + * Adds a permission object to the PermissionCollection for the class the + * permission belongs to. For example, if permission is a + * FilePermission, it is added to the FilePermissionCollection stored + * in this Permissions object. + * + * This method creates + * a new PermissionCollection object (and adds the permission to it) + * if an appropriate collection does not yet exist.

+ * + * @param permission the Permission object to add. + * + * @exception SecurityException if this Permissions object is + * marked as readonly. + * + * @see PermissionCollection#isReadOnly() + */ + + public void add(Permission permission) { + if (isReadOnly()) + throw new SecurityException( + "attempt to add a Permission to a readonly Permissions object"); + + PermissionCollection pc; + + synchronized (this) { + pc = getPermissionCollection(permission, true); + pc.add(permission); + } + + // No sync; staleness -> optimizations delayed, which is OK + if (permission instanceof AllPermission) { + allPermission = pc; + } + if (permission instanceof UnresolvedPermission) { + hasUnresolved = true; + } + } + + /** + * Checks to see if this object's PermissionCollection for permissions of + * the specified permission's class implies the permissions + * expressed in the permission object. Returns true if the + * combination of permissions in the appropriate PermissionCollection + * (e.g., a FilePermissionCollection for a FilePermission) together + * imply the specified permission. + * + *

For example, suppose there is a FilePermissionCollection in this + * Permissions object, and it contains one FilePermission that specifies + * "read" access for all files in all subdirectories of the "/tmp" + * directory, and another FilePermission that specifies "write" access + * for all files in the "/tmp/scratch/foo" directory. + * Then if the {@code implies} method + * is called with a permission specifying both "read" and "write" access + * to files in the "/tmp/scratch/foo" directory, {@code true} is + * returned. + * + *

Additionally, if this PermissionCollection contains the + * AllPermission, this method will always return true. + *

+ * @param permission the Permission object to check. + * + * @return true if "permission" is implied by the permissions in the + * PermissionCollection it + * belongs to, false if not. + */ + + public boolean implies(Permission permission) { + // No sync; staleness -> skip optimization, which is OK + if (allPermission != null) { + return true; // AllPermission has already been added + } else { + synchronized (this) { + PermissionCollection pc = getPermissionCollection(permission, + false); + if (pc != null) { + return pc.implies(permission); + } else { + // none found + return false; + } + } + } + } + + /** + * Returns an enumeration of all the Permission objects in all the + * PermissionCollections in this Permissions object. + * + * @return an enumeration of all the Permissions. + */ + + public Enumeration elements() { + // go through each Permissions in the hash table + // and call their elements() function. + + synchronized (this) { + return new PermissionsEnumerator(permsMap.values().iterator()); + } + } + + /** + * Gets the PermissionCollection in this Permissions object for + * permissions whose type is the same as that of p. + * For example, if p is a FilePermission, + * the FilePermissionCollection + * stored in this Permissions object will be returned. + * + * If createEmpty is true, + * this method creates a new PermissionCollection object for the specified + * type of permission objects if one does not yet exist. + * To do so, it first calls the {@code newPermissionCollection} method + * on p. Subclasses of class Permission + * override that method if they need to store their permissions in a + * particular PermissionCollection object in order to provide the + * correct semantics when the {@code PermissionCollection.implies} + * method is called. + * If the call returns a PermissionCollection, that collection is stored + * in this Permissions object. If the call returns null and createEmpty + * is true, then + * this method instantiates and stores a default PermissionCollection + * that uses a hashtable to store its permission objects. + * + * createEmpty is ignored when creating empty PermissionCollection + * for unresolved permissions because of the overhead of determining the + * PermissionCollection to use. + * + * createEmpty should be set to false when this method is invoked from + * implies() because it incurs the additional overhead of creating and + * adding an empty PermissionCollection that will just return false. + * It should be set to true when invoked from add(). + */ + private PermissionCollection getPermissionCollection(Permission p, + boolean createEmpty) { + Class c = p.getClass(); + + PermissionCollection pc = permsMap.get(c); + + if (!hasUnresolved && !createEmpty) { + return pc; + } else if (pc == null) { + + // Check for unresolved permissions + pc = (hasUnresolved ? getUnresolvedPermissions(p) : null); + + // if still null, create a new collection + if (pc == null && createEmpty) { + + pc = p.newPermissionCollection(); + + // still no PermissionCollection? + // We'll give them a PermissionsHash. + if (pc == null) + pc = new PermissionsHash(); + } + + if (pc != null) { + permsMap.put(c, pc); + } + } + return pc; + } + + /** + * Resolves any unresolved permissions of type p. + * + * @param p the type of unresolved permission to resolve + * + * @return PermissionCollection containing the unresolved permissions, + * or null if there were no unresolved permissions of type p. + * + */ + private PermissionCollection getUnresolvedPermissions(Permission p) + { + // Called from within synchronized method so permsMap doesn't need lock + + UnresolvedPermissionCollection uc = + (UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class); + + // we have no unresolved permissions if uc is null + if (uc == null) + return null; + + List unresolvedPerms = + uc.getUnresolvedPermissions(p); + + // we have no unresolved permissions of this type if unresolvedPerms is null + if (unresolvedPerms == null) + return null; + + java.security.cert.Certificate certs[] = null; + + Object signers[] = p.getClass().getSigners(); + + int n = 0; + if (signers != null) { + for (int j=0; j < signers.length; j++) { + if (signers[j] instanceof java.security.cert.Certificate) { + n++; + } + } + certs = new java.security.cert.Certificate[n]; + n = 0; + for (int j=0; j < signers.length; j++) { + if (signers[j] instanceof java.security.cert.Certificate) { + certs[n++] = (java.security.cert.Certificate)signers[j]; + } + } + } + + PermissionCollection pc = null; + synchronized (unresolvedPerms) { + int len = unresolvedPerms.size(); + for (int i = 0; i < len; i++) { + UnresolvedPermission up = unresolvedPerms.get(i); + Permission perm = up.resolve(p, certs); + if (perm != null) { + if (pc == null) { + pc = p.newPermissionCollection(); + if (pc == null) + pc = new PermissionsHash(); + } + pc.add(perm); + } + } + } + return pc; + } + + private static final long serialVersionUID = 4858622370623524688L; + + // Need to maintain serialization interoperability with earlier releases, + // which had the serializable field: + // private Hashtable perms; + + /** + * @serialField perms java.util.Hashtable + * A table of the Permission classes and PermissionCollections. + * @serialField allPermission java.security.PermissionCollection + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("perms", Hashtable.class), + new ObjectStreamField("allPermission", PermissionCollection.class), + }; + + /** + * @serialData Default fields. + */ + /* + * Writes the contents of the permsMap field out as a Hashtable for + * serialization compatibility with earlier releases. allPermission + * unchanged. + */ + private void writeObject(ObjectOutputStream out) throws IOException { + // Don't call out.defaultWriteObject() + + // Copy perms into a Hashtable + Hashtable, PermissionCollection> perms = + new Hashtable<>(permsMap.size()*2); // no sync; estimate + synchronized (this) { + perms.putAll(permsMap); + } + + // Write out serializable fields + ObjectOutputStream.PutField pfields = out.putFields(); + + pfields.put("allPermission", allPermission); // no sync; staleness OK + pfields.put("perms", perms); + out.writeFields(); + } + + /* + * Reads in a Hashtable of Class/PermissionCollections and saves them in the + * permsMap field. Reads in allPermission. + */ + private void readObject(ObjectInputStream in) throws IOException, + ClassNotFoundException { + // Don't call defaultReadObject() + + // Read in serialized fields + ObjectInputStream.GetField gfields = in.readFields(); + + // Get allPermission + allPermission = (PermissionCollection) gfields.get("allPermission", null); + + // Get permissions + // writeObject writes a Hashtable, PermissionCollection> for + // the perms key, so this cast is safe, unless the data is corrupt. + @SuppressWarnings("unchecked") + Hashtable, PermissionCollection> perms = + (Hashtable, PermissionCollection>)gfields.get("perms", null); + permsMap = new HashMap, PermissionCollection>(perms.size()*2); + permsMap.putAll(perms); + + // Set hasUnresolved + UnresolvedPermissionCollection uc = + (UnresolvedPermissionCollection) permsMap.get(UnresolvedPermission.class); + hasUnresolved = (uc != null && uc.elements().hasMoreElements()); + } +} + +final class PermissionsEnumerator implements Enumeration { + + // all the perms + private Iterator perms; + // the current set + private Enumeration permset; + + PermissionsEnumerator(Iterator e) { + perms = e; + permset = getNextEnumWithMore(); + } + + // No need to synchronize; caller should sync on object as required + public boolean hasMoreElements() { + // if we enter with permissionimpl null, we know + // there are no more left. + + if (permset == null) + return false; + + // try to see if there are any left in the current one + + if (permset.hasMoreElements()) + return true; + + // get the next one that has something in it... + permset = getNextEnumWithMore(); + + // if it is null, we are done! + return (permset != null); + } + + // No need to synchronize; caller should sync on object as required + public Permission nextElement() { + + // hasMoreElements will update permset to the next permset + // with something in it... + + if (hasMoreElements()) { + return permset.nextElement(); + } else { + throw new NoSuchElementException("PermissionsEnumerator"); + } + + } + + private Enumeration getNextEnumWithMore() { + while (perms.hasNext()) { + PermissionCollection pc = perms.next(); + Enumeration next =pc.elements(); + if (next.hasMoreElements()) + return next; + } + return null; + + } +} + +/** + * A PermissionsHash stores a homogeneous set of permissions in a hashtable. + * + * @see Permission + * @see Permissions + * + * + * @author Roland Schemers + * + * @serial include + */ + +final class PermissionsHash extends PermissionCollection +implements Serializable +{ + /** + * Key and value are (same) permissions objects. + * Not serialized; see serialization section at end of class. + */ + private transient Map permsMap; + + /** + * Create an empty PermissionsHash object. + */ + + PermissionsHash() { + permsMap = new HashMap(11); + } + + /** + * Adds a permission to the PermissionsHash. + * + * @param permission the Permission object to add. + */ + + public void add(Permission permission) { + synchronized (this) { + permsMap.put(permission, permission); + } + } + + /** + * Check and see if this set of permissions implies the permissions + * expressed in "permission". + * + * @param permission the Permission object to compare + * + * @return true if "permission" is a proper subset of a permission in + * the set, false if not. + */ + + public boolean implies(Permission permission) { + // attempt a fast lookup and implies. If that fails + // then enumerate through all the permissions. + synchronized (this) { + Permission p = permsMap.get(permission); + + // If permission is found, then p.equals(permission) + if (p == null) { + for (Permission p_ : permsMap.values()) { + if (p_.implies(permission)) + return true; + } + return false; + } else { + return true; + } + } + } + + /** + * Returns an enumeration of all the Permission objects in the container. + * + * @return an enumeration of all the Permissions. + */ + + public Enumeration elements() { + // Convert Iterator of Map values into an Enumeration + synchronized (this) { + return Collections.enumeration(permsMap.values()); + } + } + + private static final long serialVersionUID = -8491988220802933440L; + // Need to maintain serialization interoperability with earlier releases, + // which had the serializable field: + // private Hashtable perms; + /** + * @serialField perms java.util.Hashtable + * A table of the Permissions (both key and value are same). + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("perms", Hashtable.class), + }; + + /** + * @serialData Default fields. + */ + /* + * Writes the contents of the permsMap field out as a Hashtable for + * serialization compatibility with earlier releases. + */ + private void writeObject(ObjectOutputStream out) throws IOException { + // Don't call out.defaultWriteObject() + + // Copy perms into a Hashtable + Hashtable perms = + new Hashtable<>(permsMap.size()*2); + synchronized (this) { + perms.putAll(permsMap); + } + + // Write out serializable fields + ObjectOutputStream.PutField pfields = out.putFields(); + pfields.put("perms", perms); + out.writeFields(); + } + + /* + * Reads in a Hashtable of Permission/Permission and saves them in the + * permsMap field. + */ + private void readObject(ObjectInputStream in) throws IOException, + ClassNotFoundException { + // Don't call defaultReadObject() + + // Read in serialized fields + ObjectInputStream.GetField gfields = in.readFields(); + + // Get permissions + // writeObject writes a Hashtable, PermissionCollection> for + // the perms key, so this cast is safe, unless the data is corrupt. + @SuppressWarnings("unchecked") + Hashtable perms = + (Hashtable)gfields.get("perms", null); + permsMap = new HashMap(perms.size()*2); + permsMap.putAll(perms); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Policy.java b/sources/net.sf.j2s.java.core/src/java/security/Policy.java new file mode 100644 index 000000000..a07c4aef2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Policy.java @@ -0,0 +1,856 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.util.Enumeration; +import java.util.WeakHashMap; +import java.util.concurrent.atomic.AtomicReference; +import sun.security.jca.GetInstance; +import sun.security.util.Debug; +import sun.security.util.SecurityConstants; + + +/** + * A Policy object is responsible for determining whether code executing + * in the Java runtime environment has permission to perform a + * security-sensitive operation. + * + *

There is only one Policy object installed in the runtime at any + * given time. A Policy object can be installed by calling the + * {@code setPolicy} method. The installed Policy object can be + * obtained by calling the {@code getPolicy} method. + * + *

If no Policy object has been installed in the runtime, a call to + * {@code getPolicy} installs an instance of the default Policy + * implementation (a default subclass implementation of this abstract class). + * The default Policy implementation can be changed by setting the value + * of the {@code policy.provider} security property to the fully qualified + * name of the desired Policy subclass implementation. + * + *

Application code can directly subclass Policy to provide a custom + * implementation. In addition, an instance of a Policy object can be + * constructed by invoking one of the {@code getInstance} factory methods + * with a standard type. The default policy type is "JavaPolicy". + * + *

Once a Policy instance has been installed (either by default, or by + * calling {@code setPolicy}), the Java runtime invokes its + * {@code implies} method when it needs to + * determine whether executing code (encapsulated in a ProtectionDomain) + * can perform SecurityManager-protected operations. How a Policy object + * retrieves its policy data is up to the Policy implementation itself. + * The policy data may be stored, for example, in a flat ASCII file, + * in a serialized binary file of the Policy class, or in a database. + * + *

The {@code refresh} method causes the policy object to + * refresh/reload its data. This operation is implementation-dependent. + * For example, if the policy object stores its data in configuration files, + * calling {@code refresh} will cause it to re-read the configuration + * policy files. If a refresh operation is not supported, this method does + * nothing. Note that refreshed policy may not have an effect on classes + * in a particular ProtectionDomain. This is dependent on the Policy + * provider's implementation of the {@code implies} + * method and its PermissionCollection caching strategy. + * + * @author Roland Schemers + * @author Gary Ellison + * @see java.security.Provider + * @see java.security.ProtectionDomain + * @see java.security.Permission + * @see java.security.Security security properties + */ + +public /*abstract*/ class Policy { + + /** + * A read-only empty PermissionCollection instance. + * @since 1.6 + */ + public static final PermissionCollection UNSUPPORTED_EMPTY_COLLECTION = + new UnsupportedEmptyCollection(); +// +// // Information about the system-wide policy. +// private static class PolicyInfo { +// // the system-wide policy +// final Policy policy; +// // a flag indicating if the system-wide policy has been initialized +// final boolean initialized; +// +// PolicyInfo(Policy policy, boolean initialized) { +// this.policy = policy; +// this.initialized = initialized; +// } +// } +// +// // PolicyInfo is stored in an AtomicReference +// private static AtomicReference policy = +// new AtomicReference<>(new PolicyInfo(null, false)); +// +// private static final Debug debug = Debug.getInstance("policy"); +// +// // Cache mapping ProtectionDomain.Key to PermissionCollection +// private WeakHashMap pdMapping; +// +// /** package private for AccessControlContext and ProtectionDomain */ +// static boolean isSet() +// { +// PolicyInfo pi = policy.get(); +// return pi.policy != null && pi.initialized == true; +// } +// +// private static void checkPermission(String type) { +// SecurityManager sm = System.getSecurityManager(); +// if (sm != null) { +// sm.checkPermission(new SecurityPermission("createPolicy." + type)); +// } +// } +// + /** + * Returns the installed Policy object. This value should not be cached, + * as it may be changed by a call to {@code setPolicy}. + * This method first calls + * {@code SecurityManager.checkPermission} with a + * {@code SecurityPermission("getPolicy")} permission + * to ensure it's ok to get the Policy object. + * + * @return the installed Policy. + * + * @throws SecurityException + * if a security manager exists and its + * {@code checkPermission} method doesn't allow + * getting the Policy object. + * + * @see SecurityManager#checkPermission(Permission) + * @see #setPolicy(java.security.Policy) + */ + public static Policy getPolicy() + { +// SecurityManager sm = System.getSecurityManager(); +// if (sm != null) +// sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION); + return getPolicyNoCheck(); + } + + /** + * Returns the installed Policy object, skipping the security check. + * Used by ProtectionDomain and getPolicy. + * + * @return the installed Policy. + */ + static Policy getPolicyNoCheck() + { + return new Policy(); +// PolicyInfo pi = policy.get(); +// // Use double-check idiom to avoid locking if system-wide policy is +// // already initialized +// if (pi.initialized == false || pi.policy == null) { +// synchronized (Policy.class) { +// PolicyInfo pinfo = policy.get(); +// if (pinfo.policy == null) { +// String policy_class = AccessController.doPrivileged( +// new PrivilegedAction() { +// public String run() { +// return Security.getProperty("policy.provider"); +// } +// }); +// if (policy_class == null) { +// policy_class = "sun.security.provider.PolicyFile"; +// } +// +// try { +// pinfo = new PolicyInfo( +// (Policy) Class.forName(policy_class).newInstance(), +// true); +// } catch (Exception e) { +// /* +// * The policy_class seems to be an extension +// * so we have to bootstrap loading it via a policy +// * provider that is on the bootclasspath. +// * If it loads then shift gears to using the configured +// * provider. +// */ +// +// // install the bootstrap provider to avoid recursion +// Policy polFile = new sun.security.provider.PolicyFile(); +// pinfo = new PolicyInfo(polFile, false); +// policy.set(pinfo); +// +// final String pc = policy_class; +// Policy pol = AccessController.doPrivileged( +// new PrivilegedAction() { +// public Policy run() { +// try { +// ClassLoader cl = +// ClassLoader.getSystemClassLoader(); +// // we want the extension loader +// ClassLoader extcl = null; +// while (cl != null) { +// extcl = cl; +// cl = cl.getParent(); +// } +// return (extcl != null ? (Policy)Class.forName( +// pc, true, extcl).newInstance() : null); +// } catch (Exception e) { +// if (debug != null) { +// debug.println("policy provider " + +// pc + +// " not available"); +// e.printStackTrace(); +// } +// return null; +// } +// } +// }); +// /* +// * if it loaded install it as the policy provider. Otherwise +// * continue to use the system default implementation +// */ +// if (pol != null) { +// pinfo = new PolicyInfo(pol, true); +// } else { +// if (debug != null) { +// debug.println("using sun.security.provider.PolicyFile"); +// } +// pinfo = new PolicyInfo(polFile, true); +// } +// } +// policy.set(pinfo); +// } +// return pinfo.policy; +// } +// } +// return pi.policy; + } + + /** + * Sets the system-wide Policy object. This method first calls + * {@code SecurityManager.checkPermission} with a + * {@code SecurityPermission("setPolicy")} + * permission to ensure it's ok to set the Policy. + * + * @param p the new system Policy object. + * + * @throws SecurityException + * if a security manager exists and its + * {@code checkPermission} method doesn't allow + * setting the Policy. + * + * @see SecurityManager#checkPermission(Permission) + * @see #getPolicy() + * + */ + public static void setPolicy(Policy p) + { +// SecurityManager sm = System.getSecurityManager(); +// if (sm != null) sm.checkPermission( +// new SecurityPermission("setPolicy")); +// if (p != null) { +// initPolicy(p); +// } +// synchronized (Policy.class) { +// policy.set(new PolicyInfo(p, p != null)); +// } + } + + /** + * Initialize superclass state such that a legacy provider can + * handle queries for itself. + * + * @since 1.4 + */ + private static void initPolicy (final Policy p) { +// /* +// * A policy provider not on the bootclasspath could trigger +// * security checks fulfilling a call to either Policy.implies +// * or Policy.getPermissions. If this does occur the provider +// * must be able to answer for it's own ProtectionDomain +// * without triggering additional security checks, otherwise +// * the policy implementation will end up in an infinite +// * recursion. +// * +// * To mitigate this, the provider can collect it's own +// * ProtectionDomain and associate a PermissionCollection while +// * it is being installed. The currently installed policy +// * provider (if there is one) will handle calls to +// * Policy.implies or Policy.getPermissions during this +// * process. +// * +// * This Policy superclass caches away the ProtectionDomain and +// * statically binds permissions so that legacy Policy +// * implementations will continue to function. +// */ +// +// ProtectionDomain policyDomain = +// AccessController.doPrivileged(new PrivilegedAction() { +// public ProtectionDomain run() { +// return p.getClass().getProtectionDomain(); +// } +// }); +// +// /* +// * Collect the permissions granted to this protection domain +// * so that the provider can be security checked while processing +// * calls to Policy.implies or Policy.getPermissions. +// */ +// PermissionCollection policyPerms = null; +// synchronized (p) { +// if (p.pdMapping == null) { +// p.pdMapping = new WeakHashMap<>(); +// } +// } +// +// if (policyDomain.getCodeSource() != null) { +// Policy pol = policy.get().policy; +// if (pol != null) { +// policyPerms = pol.getPermissions(policyDomain); +// } +// +// if (policyPerms == null) { // assume it has all +// policyPerms = new Permissions(); +// policyPerms.add(SecurityConstants.ALL_PERMISSION); +// } +// +// synchronized (p.pdMapping) { +// // cache of pd to permissions +// p.pdMapping.put(policyDomain.key, policyPerms); +// } +// } +// return; + } + + + /** + * Returns a Policy object of the specified type. + * + *

This method traverses the list of registered security providers, + * starting with the most preferred Provider. + * A new Policy object encapsulating the + * PolicySpi implementation from the first + * Provider that supports the specified type is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param type the specified Policy type. See the Policy section in the + * + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for a list of standard Policy types. + * + * @param params parameters for the Policy, which may be null. + * + * @return the new Policy object. + * + * @exception SecurityException if the caller does not have permission + * to get a Policy instance for the specified type. + * + * @exception NullPointerException if the specified type is null. + * + * @exception IllegalArgumentException if the specified parameters + * are not understood by the PolicySpi implementation + * from the selected Provider. + * + * @exception NoSuchAlgorithmException if no Provider supports a PolicySpi + * implementation for the specified type. + * + * @see Provider + * @since 1.6 + */ + public static Policy getInstance(String type, Policy.Parameters params) + throws NoSuchAlgorithmException { + return new Policy(); +// +// // checkPermission(type); +// try { +// GetInstance.Instance instance = GetInstance.getInstance("Policy", +// PolicySpi.class, +// type, +// params); +// return new PolicyDelegate((PolicySpi)instance.impl, +// instance.provider, +// type, +// params); +// } catch (NoSuchAlgorithmException nsae) { +// return handleException(nsae); +// } + } + + /** + * Returns a Policy object of the specified type. + * + *

A new Policy object encapsulating the + * PolicySpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param type the specified Policy type. See the Policy section in the + * + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for a list of standard Policy types. + * + * @param params parameters for the Policy, which may be null. + * + * @param provider the provider. + * + * @return the new Policy object. + * + * @exception SecurityException if the caller does not have permission + * to get a Policy instance for the specified type. + * + * @exception NullPointerException if the specified type is null. + * + * @exception IllegalArgumentException if the specified provider + * is null or empty, + * or if the specified parameters are not understood by + * the PolicySpi implementation from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception NoSuchAlgorithmException if the specified provider does not + * support a PolicySpi implementation for the specified type. + * + * @see Provider + * @since 1.6 + */ + public static Policy getInstance(String type, + Policy.Parameters params, + String provider) + throws NoSuchProviderException, NoSuchAlgorithmException { +return new Policy(); +// +// if (provider == null || provider.length() == 0) { +// throw new IllegalArgumentException("missing provider"); +// } +// +//// checkPermission(type); +// try { +// GetInstance.Instance instance = GetInstance.getInstance("Policy", +// PolicySpi.class, +// type, +// params, +// provider); +// return new PolicyDelegate((PolicySpi)instance.impl, +// instance.provider, +// type, +// params); +// } catch (NoSuchAlgorithmException nsae) { +// return handleException(nsae); +// } + } + + /** + * Returns a Policy object of the specified type. + * + *

A new Policy object encapsulating the + * PolicySpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param type the specified Policy type. See the Policy section in the + * + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for a list of standard Policy types. + * + * @param params parameters for the Policy, which may be null. + * + * @param provider the Provider. + * + * @return the new Policy object. + * + * @exception SecurityException if the caller does not have permission + * to get a Policy instance for the specified type. + * + * @exception NullPointerException if the specified type is null. + * + * @exception IllegalArgumentException if the specified Provider is null, + * or if the specified parameters are not understood by + * the PolicySpi implementation from the specified Provider. + * + * @exception NoSuchAlgorithmException if the specified Provider does not + * support a PolicySpi implementation for the specified type. + * + * @see Provider + * @since 1.6 + */ + public static Policy getInstance(String type, + Policy.Parameters params, + Provider provider) + throws NoSuchAlgorithmException { + + return new Policy(); +// if (provider == null) { +// throw new IllegalArgumentException("missing provider"); +// } +// +// checkPermission(type); +// try { +// GetInstance.Instance instance = GetInstance.getInstance("Policy", +// PolicySpi.class, +// type, +// params, +// provider); +// return new PolicyDelegate((PolicySpi)instance.impl, +// instance.provider, +// type, +// params); +// } catch (NoSuchAlgorithmException nsae) { +// return handleException(nsae); +// } + } +// +// private static Policy handleException(NoSuchAlgorithmException nsae) +// throws NoSuchAlgorithmException { +// Throwable cause = nsae.getCause(); +// if (cause instanceof IllegalArgumentException) { +// throw (IllegalArgumentException)cause; +// } +// throw nsae; +// } + + /** + * Return the Provider of this Policy. + * + *

This Policy instance will only have a Provider if it + * was obtained via a call to {@code Policy.getInstance}. + * Otherwise this method returns null. + * + * @return the Provider of this Policy, or null. + * + * @since 1.6 + */ + public Provider getProvider() { + return null; + } + + /** + * Return the type of this Policy. + * + *

This Policy instance will only have a type if it + * was obtained via a call to {@code Policy.getInstance}. + * Otherwise this method returns null. + * + * @return the type of this Policy, or null. + * + * @since 1.6 + */ + public String getType() { + return null; + } + + /** + * Return Policy parameters. + * + *

This Policy instance will only have parameters if it + * was obtained via a call to {@code Policy.getInstance}. + * Otherwise this method returns null. + * + * @return Policy parameters, or null. + * + * @since 1.6 + */ + public Policy.Parameters getParameters() { + return null; + } + + /** + * Return a PermissionCollection object containing the set of + * permissions granted to the specified CodeSource. + * + *

Applications are discouraged from calling this method + * since this operation may not be supported by all policy implementations. + * Applications should solely rely on the {@code implies} method + * to perform policy checks. If an application absolutely must call + * a getPermissions method, it should call + * {@code getPermissions(ProtectionDomain)}. + * + *

The default implementation of this method returns + * Policy.UNSUPPORTED_EMPTY_COLLECTION. This method can be + * overridden if the policy implementation can return a set of + * permissions granted to a CodeSource. + * + * @param codesource the CodeSource to which the returned + * PermissionCollection has been granted. + * + * @return a set of permissions granted to the specified CodeSource. + * If this operation is supported, the returned + * set of permissions must be a new mutable instance + * and it must support heterogeneous Permission types. + * If this operation is not supported, + * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. + */ + public PermissionCollection getPermissions(CodeSource codesource) { + return Policy.UNSUPPORTED_EMPTY_COLLECTION; + } + + /** + * Return a PermissionCollection object containing the set of + * permissions granted to the specified ProtectionDomain. + * + *

Applications are discouraged from calling this method + * since this operation may not be supported by all policy implementations. + * Applications should rely on the {@code implies} method + * to perform policy checks. + * + *

The default implementation of this method first retrieves + * the permissions returned via {@code getPermissions(CodeSource)} + * (the CodeSource is taken from the specified ProtectionDomain), + * as well as the permissions located inside the specified ProtectionDomain. + * All of these permissions are then combined and returned in a new + * PermissionCollection object. If {@code getPermissions(CodeSource)} + * returns Policy.UNSUPPORTED_EMPTY_COLLECTION, then this method + * returns the permissions contained inside the specified ProtectionDomain + * in a new PermissionCollection object. + * + *

This method can be overridden if the policy implementation + * supports returning a set of permissions granted to a ProtectionDomain. + * + * @param domain the ProtectionDomain to which the returned + * PermissionCollection has been granted. + * + * @return a set of permissions granted to the specified ProtectionDomain. + * If this operation is supported, the returned + * set of permissions must be a new mutable instance + * and it must support heterogeneous Permission types. + * If this operation is not supported, + * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. + * + * @since 1.4 + */ + public PermissionCollection getPermissions(ProtectionDomain domain) { + //if (domain == null) + return new Permissions(); +// +// if (pdMapping == null) { +// initPolicy(this); +// } +// +// synchronized (pdMapping) { +// pc = pdMapping.get(domain.key); +// } +// +// if (pc != null) { +// Permissions perms = new Permissions(); +// synchronized (pc) { +// for (Enumeration e = pc.elements() ; e.hasMoreElements() ;) { +// perms.add(e.nextElement()); +// } +// } +// return perms; +// } +// +// pc = getPermissions(domain.getCodeSource()); +// if (pc == null || pc == UNSUPPORTED_EMPTY_COLLECTION) { +// pc = new Permissions(); +// } +// +// addStaticPerms(pc, domain.getPermissions()); +// return pc; + } + +// /** +// * add static permissions to provided permission collection +// */ +// private void addStaticPerms(PermissionCollection perms, +// PermissionCollection statics) { +// if (statics != null) { +// synchronized (statics) { +// Enumeration e = statics.elements(); +// while (e.hasMoreElements()) { +// perms.add(e.nextElement()); +// } +// } +// } +// } +// + /** + * Evaluates the global policy for the permissions granted to + * the ProtectionDomain and tests whether the permission is + * granted. + * + * @param domain the ProtectionDomain to test + * @param permission the Permission object to be tested for implication. + * + * @return true if "permission" is a proper subset of a permission + * granted to this ProtectionDomain. + * + * @see java.security.ProtectionDomain + * @since 1.4 + */ + public boolean implies(ProtectionDomain domain, Permission permission) { + return true; +// PermissionCollection pc; +// +// if (pdMapping == null) { +// initPolicy(this); +// } +// +// synchronized (pdMapping) { +// pc = pdMapping.get(domain.key); +// } +// +// if (pc != null) { +// return pc.implies(permission); +// } +// +// pc = getPermissions(domain); +// if (pc == null) { +// return false; +// } +// +// synchronized (pdMapping) { +// // cache it +// pdMapping.put(domain.key, pc); +// } +// +// return pc.implies(permission); + } + + /** + * Refreshes/reloads the policy configuration. The behavior of this method + * depends on the implementation. For example, calling {@code refresh} + * on a file-based policy will cause the file to be re-read. + * + *

The default implementation of this method does nothing. + * This method should be overridden if a refresh operation is supported + * by the policy implementation. + */ + public void refresh() { } + +// /** +// * This subclass is returned by the getInstance calls. All Policy calls +// * are delegated to the underlying PolicySpi. +// */ +// private static class PolicyDelegate extends Policy { +// +// private PolicySpi spi; +// private Provider p; +// private String type; +// private Policy.Parameters params; +// +// private PolicyDelegate(PolicySpi spi, Provider p, +// String type, Policy.Parameters params) { +// this.spi = spi; +// this.p = p; +// this.type = type; +// this.params = params; +// } +// +// @Override public String getType() { return type; } +// +// @Override public Policy.Parameters getParameters() { return params; } +// +// @Override public Provider getProvider() { return p; } +// +// @Override +// public PermissionCollection getPermissions(CodeSource codesource) { +// return spi.engineGetPermissions(codesource); +// } +// @Override +// public PermissionCollection getPermissions(ProtectionDomain domain) { +// return spi.engineGetPermissions(domain); +// } +// @Override +// public boolean implies(ProtectionDomain domain, Permission perm) { +// return spi.engineImplies(domain, perm); +// } +// @Override +// public void refresh() { +// spi.engineRefresh(); +// } +// } +// + /** + * This represents a marker interface for Policy parameters. + * + * @since 1.6 + */ + public static interface Parameters { } + + /** + * This class represents a read-only empty PermissionCollection object that + * is returned from the {@code getPermissions(CodeSource)} and + * {@code getPermissions(ProtectionDomain)} + * methods in the Policy class when those operations are not + * supported by the Policy implementation. + */ + private static class UnsupportedEmptyCollection + extends PermissionCollection { + + private static final long serialVersionUID = -8492269157353014774L; + + private Permissions perms; + + /** + * Create a read-only empty PermissionCollection object. + */ + public UnsupportedEmptyCollection() { + this.perms = new Permissions(); + perms.setReadOnly(); + } + + /** + * Adds a permission object to the current collection of permission + * objects. + * + * @param permission the Permission object to add. + * + * @exception SecurityException - if this PermissionCollection object + * has been marked readonly + */ + @Override public void add(Permission permission) { + perms.add(permission); + } + + /** + * Checks to see if the specified permission is implied by the + * collection of Permission objects held in this PermissionCollection. + * + * @param permission the Permission object to compare. + * + * @return true if "permission" is implied by the permissions in + * the collection, false if not. + */ + @Override public boolean implies(Permission permission) { + return perms.implies(permission); + } + + /** + * Returns an enumeration of all the Permission objects in the + * collection. + * + * @return an enumeration of all the Permissions. + */ + @Override public Enumeration elements() { + return perms.elements(); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/PolicySpi.java b/sources/net.sf.j2s.java.core/src/java/security/PolicySpi.java new file mode 100644 index 000000000..608ce1fa7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/PolicySpi.java @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2005, 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 java.security; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code Policy} class. + * All the abstract methods in this class must be implemented by each + * service provider who wishes to supply a Policy implementation. + * + *

Subclass implementations of this abstract class must provide + * a public constructor that takes a {@code Policy.Parameters} + * object as an input parameter. This constructor also must throw + * an IllegalArgumentException if it does not understand the + * {@code Policy.Parameters} input. + * + * + * @since 1.6 + */ + +public abstract class PolicySpi { + + /** + * Check whether the policy has granted a Permission to a ProtectionDomain. + * + * @param domain the ProtectionDomain to check. + * + * @param permission check whether this permission is granted to the + * specified domain. + * + * @return boolean true if the permission is granted to the domain. + */ + protected abstract boolean engineImplies + (ProtectionDomain domain, Permission permission); + + /** + * Refreshes/reloads the policy configuration. The behavior of this method + * depends on the implementation. For example, calling {@code refresh} + * on a file-based policy will cause the file to be re-read. + * + *

The default implementation of this method does nothing. + * This method should be overridden if a refresh operation is supported + * by the policy implementation. + */ + protected void engineRefresh() { } + + /** + * Return a PermissionCollection object containing the set of + * permissions granted to the specified CodeSource. + * + *

The default implementation of this method returns + * Policy.UNSUPPORTED_EMPTY_COLLECTION object. This method can be + * overridden if the policy implementation can return a set of + * permissions granted to a CodeSource. + * + * @param codesource the CodeSource to which the returned + * PermissionCollection has been granted. + * + * @return a set of permissions granted to the specified CodeSource. + * If this operation is supported, the returned + * set of permissions must be a new mutable instance + * and it must support heterogeneous Permission types. + * If this operation is not supported, + * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. + */ + protected PermissionCollection engineGetPermissions + (CodeSource codesource) { + return Policy.UNSUPPORTED_EMPTY_COLLECTION; + } + + /** + * Return a PermissionCollection object containing the set of + * permissions granted to the specified ProtectionDomain. + * + *

The default implementation of this method returns + * Policy.UNSUPPORTED_EMPTY_COLLECTION object. This method can be + * overridden if the policy implementation can return a set of + * permissions granted to a ProtectionDomain. + * + * @param domain the ProtectionDomain to which the returned + * PermissionCollection has been granted. + * + * @return a set of permissions granted to the specified ProtectionDomain. + * If this operation is supported, the returned + * set of permissions must be a new mutable instance + * and it must support heterogeneous Permission types. + * If this operation is not supported, + * Policy.UNSUPPORTED_EMPTY_COLLECTION is returned. + */ + protected PermissionCollection engineGetPermissions + (ProtectionDomain domain) { + return Policy.UNSUPPORTED_EMPTY_COLLECTION; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Principal.java b/sources/net.sf.j2s.java.core/src/java/security/Principal.java new file mode 100644 index 000000000..a538e707e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Principal.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import javax.security.auth.Subject; + +/** + * This interface represents the abstract notion of a principal, which + * can be used to represent any entity, such as an individual, a + * corporation, and a login id. + * + * @see java.security.cert.X509Certificate + * + * @author Li Gong + */ +public interface Principal { + + /** + * Compares this principal to the specified object. Returns true + * if the object passed in matches the principal represented by + * the implementation of this interface. + * + * @param another principal to compare with. + * + * @return true if the principal passed in is the same as that + * encapsulated by this principal, and false otherwise. + */ + public boolean equals(Object another); + + /** + * Returns a string representation of this principal. + * + * @return a string representation of this principal. + */ + public String toString(); + + /** + * Returns a hashcode for this principal. + * + * @return a hashcode for this principal. + */ + public int hashCode(); + + /** + * Returns the name of this principal. + * + * @return the name of this principal. + */ + public String getName(); + + /** + * Returns true if the specified subject is implied by this principal. + * + *

The default implementation of this method returns true if + * {@code subject} is non-null and contains at least one principal that + * is equal to this principal. + * + *

Subclasses may override this with a different implementation, if + * necessary. + * + * @param subject the {@code Subject} + * @return true if {@code subject} is non-null and is + * implied by this principal, or false otherwise. + * @since 1.8 + */ + public default boolean implies(Subject subject) { + if (subject == null) + return false; + return subject.getPrincipals().contains(this); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/PrivateKey.java b/sources/net.sf.j2s.java.core/src/java/security/PrivateKey.java new file mode 100644 index 000000000..7d8a7ea70 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/PrivateKey.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * A private key. + * The purpose of this interface is to group (and provide type safety + * for) all private key interfaces. + *

+ * Note: The specialized private key interfaces extend this interface. + * See, for example, the {@code DSAPrivateKey} interface in + * {@link java.security.interfaces}. + *

+ * Implementations should override the default {@code destroy} and + * {@code isDestroyed} methods from the + * {@link javax.security.auth.Destroyable} interface to enable + * sensitive key information to be destroyed, cleared, or in the case + * where such information is immutable, unreferenced. + * Finally, since {@code PrivateKey} is {@code Serializable}, implementations + * should also override + * {@link java.io.ObjectOutputStream#writeObject(java.lang.Object)} + * to prevent keys that have been destroyed from being serialized. + * + * @see Key + * @see PublicKey + * @see Certificate + * @see Signature#initVerify + * @see java.security.interfaces.DSAPrivateKey + * @see java.security.interfaces.RSAPrivateKey + * @see java.security.interfaces.RSAPrivateCrtKey + * + * @author Benjamin Renaud + * @author Josh Bloch + */ + +public interface PrivateKey extends Key, javax.security.auth.Destroyable { + + // Declare serialVersionUID to be compatible with JDK1.1 + /** + * The class fingerprint that is set to indicate serialization + * compatibility with a previous version of the class. + */ + static final long serialVersionUID = 6034044314589513430L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/PrivilegedAction.java b/sources/net.sf.j2s.java.core/src/java/security/PrivilegedAction.java index 23707756a..b993cea4d 100644 --- a/sources/net.sf.j2s.java.core/src/java/security/PrivilegedAction.java +++ b/sources/net.sf.j2s.java.core/src/java/security/PrivilegedAction.java @@ -1,6 +1,56 @@ +/* + * Copyright (c) 1998, 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 java.security; + +/** + * A computation to be performed with privileges enabled. The computation is + * performed by invoking {@code AccessController.doPrivileged} on the + * {@code PrivilegedAction} object. This interface is used only for + * computations that do not throw checked exceptions; computations that + * throw checked exceptions must use {@code PrivilegedExceptionAction} + * instead. + * + * @see AccessController + * @see AccessController#doPrivileged(PrivilegedAction) + * @see PrivilegedExceptionAction + */ + public interface PrivilegedAction { + /** + * Performs the computation. This method will be called by + * {@code AccessController.doPrivileged} after enabling privileges. + * + * @return a class-dependent value that may represent the results of the + * computation. Each class that implements + * {@code PrivilegedAction} + * should document what (if anything) this value represents. + * @see AccessController#doPrivileged(PrivilegedAction) + * @see AccessController#doPrivileged(PrivilegedAction, + * AccessControlContext) + */ T run(); } - diff --git a/sources/net.sf.j2s.java.core/src/java/security/PrivilegedActionException.java b/sources/net.sf.j2s.java.core/src/java/security/PrivilegedActionException.java new file mode 100644 index 000000000..2de696985 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/PrivilegedActionException.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 1998, 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 java.security; + +/** + * This exception is thrown by + * {@code doPrivileged(PrivilegedExceptionAction)} and + * {@code doPrivileged(PrivilegedExceptionAction, + * AccessControlContext context)} to indicate + * that the action being performed threw a checked exception. The exception + * thrown by the action can be obtained by calling the + * {@code getException} method. In effect, an + * {@code PrivilegedActionException} is a "wrapper" + * for an exception thrown by a privileged action. + * + *

As of release 1.4, this exception has been retrofitted to conform to + * the general purpose exception-chaining mechanism. The "exception thrown + * by the privileged computation" that is provided at construction time and + * accessed via the {@link #getException()} method is now known as the + * cause, and may be accessed via the {@link Throwable#getCause()} + * method, as well as the aforementioned "legacy method." + * + * @see PrivilegedExceptionAction + * @see AccessController#doPrivileged(PrivilegedExceptionAction) + * @see AccessController#doPrivileged(PrivilegedExceptionAction,AccessControlContext) + */ +public class PrivilegedActionException extends Exception { + // use serialVersionUID from JDK 1.2.2 for interoperability + private static final long serialVersionUID = 4724086851538908602L; + + /** + * @serial + */ + private Exception exception; + + /** + * Constructs a new PrivilegedActionException "wrapping" + * the specific Exception. + * + * @param exception The exception thrown + */ + public PrivilegedActionException(Exception exception) { + super((Throwable)null); // Disallow initCause + this.exception = exception; + } + + /** + * Returns the exception thrown by the privileged computation that + * resulted in this {@code PrivilegedActionException}. + * + *

This method predates the general-purpose exception chaining facility. + * The {@link Throwable#getCause()} method is now the preferred means of + * obtaining this information. + * + * @return the exception thrown by the privileged computation that + * resulted in this {@code PrivilegedActionException}. + * @see PrivilegedExceptionAction + * @see AccessController#doPrivileged(PrivilegedExceptionAction) + * @see AccessController#doPrivileged(PrivilegedExceptionAction, + * AccessControlContext) + */ + public Exception getException() { + return exception; + } + + /** + * Returns the cause of this exception (the exception thrown by + * the privileged computation that resulted in this + * {@code PrivilegedActionException}). + * + * @return the cause of this exception. + * @since 1.4 + */ + public Throwable getCause() { + return exception; + } + + public String toString() { + String s = getClass().getName(); + return (exception != null) ? (s + ": " + exception.toString()) : s; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/PrivilegedExceptionAction.java b/sources/net.sf.j2s.java.core/src/java/security/PrivilegedExceptionAction.java index 19dda96b5..59a9ba7dc 100644 --- a/sources/net.sf.j2s.java.core/src/java/security/PrivilegedExceptionAction.java +++ b/sources/net.sf.j2s.java.core/src/java/security/PrivilegedExceptionAction.java @@ -1,6 +1,62 @@ +/* + * Copyright (c) 1998, 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 java.security; + +/** + * A computation to be performed with privileges enabled, that throws one or + * more checked exceptions. The computation is performed by invoking + * {@code AccessController.doPrivileged} on the + * {@code PrivilegedExceptionAction} object. This interface is + * used only for computations that throw checked exceptions; + * computations that do not throw + * checked exceptions should use {@code PrivilegedAction} instead. + * + * @see AccessController + * @see AccessController#doPrivileged(PrivilegedExceptionAction) + * @see AccessController#doPrivileged(PrivilegedExceptionAction, + * AccessControlContext) + * @see PrivilegedAction + */ + public interface PrivilegedExceptionAction { + /** + * Performs the computation. This method will be called by + * {@code AccessController.doPrivileged} after enabling privileges. + * + * @return a class-dependent value that may represent the results of the + * computation. Each class that implements + * {@code PrivilegedExceptionAction} should document what + * (if anything) this value represents. + * @throws Exception an exceptional condition has occurred. Each class + * that implements {@code PrivilegedExceptionAction} should + * document the exceptions that its run method can throw. + * @see AccessController#doPrivileged(PrivilegedExceptionAction) + * @see AccessController#doPrivileged(PrivilegedExceptionAction,AccessControlContext) + */ + T run() throws Exception; } - diff --git a/sources/net.sf.j2s.java.core/src/java/security/ProtectionDomain.java b/sources/net.sf.j2s.java.core/src/java/security/ProtectionDomain.java new file mode 100644 index 000000000..8a7f4746a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/ProtectionDomain.java @@ -0,0 +1,482 @@ +/* + * Copyright (c) 1997, 2014, 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 java.security; + +/** + * + *

+ * This ProtectionDomain class encapsulates the characteristics of a domain, + * which encloses a set of classes whose instances are granted a set + * of permissions when being executed on behalf of a given set of Principals. + *

+ * A static set of permissions can be bound to a ProtectionDomain when it is + * constructed; such permissions are granted to the domain regardless of the + * Policy in force. However, to support dynamic security policies, a + * ProtectionDomain can also be constructed such that it is dynamically + * mapped to a set of permissions by the current Policy whenever a permission + * is checked. + *

+ * + * @author Li Gong + * @author Roland Schemers + * @author Gary Ellison + */ + +public class ProtectionDomain { +// private static class JavaSecurityAccessImpl implements JavaSecurityAccess { +// +// private JavaSecurityAccessImpl() { +// } +// +// @Override +// public T doIntersectionPrivilege( +// PrivilegedAction action, +// final AccessControlContext stack, +// final AccessControlContext context) { +// if (action == null) { +// throw new NullPointerException(); +// } +// +// return AccessController.doPrivileged( +// action, +// getCombinedACC(context, stack) +// ); +// } +// +// @Override +// public T doIntersectionPrivilege( +// PrivilegedAction action, +// AccessControlContext context) { +// return doIntersectionPrivilege(action, +// AccessController.getContext(), context); +// } +// +// private static AccessControlContext getCombinedACC(AccessControlContext context, AccessControlContext stack) { +// AccessControlContext acc = new AccessControlContext(context, stack.getCombiner(), true); +// +// return new AccessControlContext(stack.getContext(), acc).optimize(); +// } +// } +// +// static { +// // Set up JavaSecurityAccess in SharedSecrets +// SharedSecrets.setJavaSecurityAccess(new JavaSecurityAccessImpl()); +// } +// +// /* CodeSource */ +// private CodeSource codesource ; +// +// /* ClassLoader the protection domain was consed from */ +// private ClassLoader classloader; +// +// /* Principals running-as within this protection domain */ +// private Principal[] principals; +// +// /* the rights this protection domain is granted */ +// private PermissionCollection permissions; +// +// /* if the permissions object has AllPermission */ +// private boolean hasAllPerm = false; +// +// /* the PermissionCollection is static (pre 1.4 constructor) +// or dynamic (via a policy refresh) */ +// private boolean staticPermissions; +// +// /* +// * An object used as a key when the ProtectionDomain is stored in a Map. +// */ +// final Key key = new Key(); +// +// private static final Debug debug = Debug.getInstance("domain"); +// + /** + * Creates a new ProtectionDomain with the given CodeSource and + * Permissions. If the permissions object is not null, then + * {@code setReadOnly())} will be called on the passed in + * Permissions object. The only permissions granted to this domain + * are the ones specified; the current Policy will not be consulted. + * + * @param codesource the codesource associated with this domain + * @param permissions the permissions granted to this domain + */ + public ProtectionDomain(CodeSource codesource, + PermissionCollection permissions) { +// this.codesource = codesource; +// if (permissions != null) { +// this.permissions = permissions; +// this.permissions.setReadOnly(); +// if (permissions instanceof Permissions && +// ((Permissions)permissions).allPermission != null) { +// hasAllPerm = true; +// } +// } +// this.classloader = null; +// this.principals = new Principal[0]; +// staticPermissions = true; + } + + /** + * Creates a new ProtectionDomain qualified by the given CodeSource, + * Permissions, ClassLoader and array of Principals. If the + * permissions object is not null, then {@code setReadOnly()} + * will be called on the passed in Permissions object. + * The permissions granted to this domain are dynamic; they include + * both the static permissions passed to this constructor, and any + * permissions granted to this domain by the current Policy at the + * time a permission is checked. + *

+ * This constructor is typically used by + * {@link SecureClassLoader ClassLoaders} + * and {@link DomainCombiner DomainCombiners} which delegate to + * {@code Policy} to actively associate the permissions granted to + * this domain. This constructor affords the + * Policy provider the opportunity to augment the supplied + * PermissionCollection to reflect policy changes. + *

+ * + * @param codesource the CodeSource associated with this domain + * @param permissions the permissions granted to this domain + * @param classloader the ClassLoader associated with this domain + * @param principals the array of Principals associated with this + * domain. The contents of the array are copied to protect against + * subsequent modification. + * @see Policy#refresh + * @see Policy#getPermissions(ProtectionDomain) + * @since 1.4 + */ + public ProtectionDomain(CodeSource codesource, + PermissionCollection permissions, + ClassLoader classloader, + Principal[] principals) { +// this.codesource = codesource; +// if (permissions != null) { +// this.permissions = permissions; +// this.permissions.setReadOnly(); +// if (permissions instanceof Permissions && +// ((Permissions)permissions).allPermission != null) { +// hasAllPerm = true; +// } +// } +// this.classloader = classloader; +// this.principals = (principals != null ? principals.clone(): +// new Principal[0]); +// staticPermissions = false; + } + + /** + * Returns the CodeSource of this domain. + * @return the CodeSource of this domain which may be null. + * @since 1.2 + */ + public final CodeSource getCodeSource() { + return null; + // return this.codesource; + } + + + /** + * Returns the ClassLoader of this domain. + * @return the ClassLoader of this domain which may be null. + * + * @since 1.4 + */ + public final ClassLoader getClassLoader() { + return this.getClass().getClassLoader();//null;//this.classloader; + } + + + /** + * Returns an array of principals for this domain. + * @return a non-null array of principals for this domain. + * Returns a new array each time this method is called. + * + * @since 1.4 + */ + public final Principal[] getPrincipals() { + return null;//this.principals.clone(); + } + + /** + * Returns the static permissions granted to this domain. + * + * @return the static set of permissions for this domain which may be null. + * @see Policy#refresh + * @see Policy#getPermissions(ProtectionDomain) + */ + public final PermissionCollection getPermissions() { + return null;//permissions; + } + + /** + * Check and see if this ProtectionDomain implies the permissions + * expressed in the Permission object. + *

+ * The set of permissions evaluated is a function of whether the + * ProtectionDomain was constructed with a static set of permissions + * or it was bound to a dynamically mapped set of permissions. + *

+ * If the ProtectionDomain was constructed to a + * {@link #ProtectionDomain(CodeSource, PermissionCollection) + * statically bound} PermissionCollection then the permission will + * only be checked against the PermissionCollection supplied at + * construction. + *

+ * However, if the ProtectionDomain was constructed with + * the constructor variant which supports + * {@link #ProtectionDomain(CodeSource, PermissionCollection, + * ClassLoader, java.security.Principal[]) dynamically binding} + * permissions, then the permission will be checked against the + * combination of the PermissionCollection supplied at construction and + * the current Policy binding. + *

+ * + * @param permission the Permission object to check. + * + * @return true if "permission" is implicit to this ProtectionDomain. + */ + public boolean implies(Permission permission) { + +// if (hasAllPerm) { +// // internal permission collection already has AllPermission - +// // no need to go to policy +// return true; +// } +// +// if (!staticPermissions && +// Policy.getPolicyNoCheck().implies(this, permission)) +// return true; +// if (permissions != null) +// return permissions.implies(permission); +// +// return false; +// } +// +// // called by the VM -- do not remove +// boolean impliesCreateAccessControlContext() { +// return implies(SecurityConstants.CREATE_ACC_PERMISSION); + return true; + } + +// /** +// * Convert a ProtectionDomain to a String. +// */ +// @Override public String toString() { +// String pals = ""; +// if (principals != null && principals.length > 0) { +// StringBuilder palBuf = new StringBuilder("(principals "); +// +// for (int i = 0; i < principals.length; i++) { +// palBuf.append(principals[i].getClass().getName() + +// " \"" + principals[i].getName() + +// "\""); +// if (i < principals.length-1) +// palBuf.append(",\n"); +// else +// palBuf.append(")\n"); +// } +// pals = palBuf.toString(); +// } +// +// // Check if policy is set; we don't want to load +// // the policy prematurely here +// PermissionCollection pc = Policy.isSet() && seeAllp() ? +// mergePermissions(): +// getPermissions(); +// +// return "ProtectionDomain "+ +// " "+codesource+"\n"+ +// " "+classloader+"\n"+ +// " "+pals+"\n"+ +// " "+pc+"\n"; +// } +// +// /** +// * Return true (merge policy permissions) in the following cases: +// * +// * . SecurityManager is null +// * +// * . SecurityManager is not null, +// * debug is not null, +// * SecurityManager impelmentation is in bootclasspath, +// * Policy implementation is in bootclasspath +// * (the bootclasspath restrictions avoid recursion) +// * +// * . SecurityManager is not null, +// * debug is null, +// * caller has Policy.getPolicy permission +// */ +// private static boolean seeAllp() { +// SecurityManager sm = System.getSecurityManager(); +// +// if (sm == null) { +// return true; +// } else { +// if (debug != null) { +// if (sm.getClass().getClassLoader() == null && +// Policy.getPolicyNoCheck().getClass().getClassLoader() +// == null) { +// return true; +// } +// } else { +// try { +// sm.checkPermission(SecurityConstants.GET_POLICY_PERMISSION); +// return true; +// } catch (SecurityException se) { +// // fall thru and return false +// } +// } +// } +// +// return false; +// } +// +// private PermissionCollection mergePermissions() { +// if (staticPermissions) +// return permissions; +// +// PermissionCollection perms = +// java.security.AccessController.doPrivileged +// (new java.security.PrivilegedAction() { +// public PermissionCollection run() { +// Policy p = Policy.getPolicyNoCheck(); +// return p.getPermissions(ProtectionDomain.this); +// } +// }); +// +// Permissions mergedPerms = new Permissions(); +// int swag = 32; +// int vcap = 8; +// Enumeration e; +// List pdVector = new ArrayList<>(vcap); +// List plVector = new ArrayList<>(swag); +// +// // +// // Build a vector of domain permissions for subsequent merge +// if (permissions != null) { +// synchronized (permissions) { +// e = permissions.elements(); +// while (e.hasMoreElements()) { +// pdVector.add(e.nextElement()); +// } +// } +// } +// +// // +// // Build a vector of Policy permissions for subsequent merge +// if (perms != null) { +// synchronized (perms) { +// e = perms.elements(); +// while (e.hasMoreElements()) { +// plVector.add(e.nextElement()); +// vcap++; +// } +// } +// } +// +// if (perms != null && permissions != null) { +// // +// // Weed out the duplicates from the policy. Unless a refresh +// // has occurred since the pd was consed this should result in +// // an empty vector. +// synchronized (permissions) { +// e = permissions.elements(); // domain vs policy +// while (e.hasMoreElements()) { +// Permission pdp = e.nextElement(); +// Class pdpClass = pdp.getClass(); +// String pdpActions = pdp.getActions(); +// String pdpName = pdp.getName(); +// for (int i = 0; i < plVector.size(); i++) { +// Permission pp = plVector.get(i); +// if (pdpClass.isInstance(pp)) { +// // The equals() method on some permissions +// // have some side effects so this manual +// // comparison is sufficient. +// if (pdpName.equals(pp.getName()) && +// pdpActions.equals(pp.getActions())) { +// plVector.remove(i); +// break; +// } +// } +// } +// } +// } +// } +// +// if (perms !=null) { +// // the order of adding to merged perms and permissions +// // needs to preserve the bugfix 4301064 +// +// for (int i = plVector.size()-1; i >= 0; i--) { +// mergedPerms.add(plVector.get(i)); +// } +// } +// if (permissions != null) { +// for (int i = pdVector.size()-1; i >= 0; i--) { +// mergedPerms.add(pdVector.get(i)); +// } +// } +// +// return mergedPerms; +// } +// +// /** +// * Used for storing ProtectionDomains as keys in a Map. +// */ +// final static class Key {} +// +// // A cache of ProtectionDomains and their Permissions +// private static class PDCache implements ProtectionDomainCache { +// // We must wrap the PermissionCollection in a WeakReference as there +// // are some PermissionCollections which contain strong references +// // back to a ProtectionDomain and otherwise would never be removed +// // from the WeakHashMap +// private final Map> +// map = new WeakHashMap<>(); +// +// @Override +// public synchronized void put(ProtectionDomain pd, +// PermissionCollection pc) { +// map.put(pd == null ? null : pd.key, new WeakReference<>(pc)); +// } +// +// @Override +// public synchronized PermissionCollection get(ProtectionDomain pd) { +// WeakReference ref = +// map.get(pd == null ? null : pd.key); +// return ref == null ? null : ref.get(); +// } +// } +// +// static { +// SharedSecrets.setJavaSecurityProtectionDomainAccess( +// new JavaSecurityProtectionDomainAccess() { +// @Override +// public ProtectionDomainCache getProtectionDomainCache() { +// return new PDCache(); +// } +// }); +// } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Provider.java b/sources/net.sf.j2s.java.core/src/java/security/Provider.java new file mode 100644 index 000000000..6c41702a6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Provider.java @@ -0,0 +1,1863 @@ +/* + * Copyright (c) 1996, 2014, 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 java.security; + +import static java.util.Locale.ENGLISH; + +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectInputStream; +//import java.lang.ref.Reference; +//import java.lang.ref.WeakReference; +import java.lang.reflect.Constructor; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import java.util.function.BiConsumer; +import java.util.function.BiFunction; +import java.util.function.Function; + +/** + * This class represents a "provider" for the + * Java Security API, where a provider implements some or all parts of + * Java Security. Services that a provider may implement include: + * + *

    + * + *
  • Algorithms (such as DSA, RSA, MD5 or SHA-1). + * + *
  • Key generation, conversion, and management facilities (such as for + * algorithm-specific keys). + * + *
+ * + *

Each provider has a name and a version number, and is configured + * in each runtime it is installed in. + * + *

See The Provider Class + * in the "Java Cryptography Architecture API Specification & Reference" + * for information about how a particular type of provider, the + * cryptographic service provider, works and is installed. However, + * please note that a provider can be used to implement any security + * service in Java that uses a pluggable architecture with a choice + * of implementations that fit underneath. + * + *

Some provider implementations may encounter unrecoverable internal + * errors during their operation, for example a failure to communicate with a + * security token. A {@link ProviderException} should be used to indicate + * such errors. + * + *

The service type {@code Provider} is reserved for use by the + * security framework. Services of this type cannot be added, removed, + * or modified by applications. + * The following attributes are automatically placed in each Provider object: + * + * + * + * + * + * + * + * + + * + * + *
Attributes Automatically Placed in a Provider Object
NameValue
{@code Provider.id name}{@code String.valueOf(provider.getName())}
{@code Provider.id version}{@code String.valueOf(provider.getVersion())}
{@code Provider.id info}{@code String.valueOf(provider.getInfo())}
{@code Provider.id className}{@code provider.getClass().getName()}
+ * + * @author Benjamin Renaud + * @author Andreas Sterbenz + */ +public abstract class Provider extends Properties { + + // Declare serialVersionUID to be compatible with JDK1.1 + static final long serialVersionUID = -4298000515446427739L; + + private static final sun.security.util.Debug debug = + sun.security.util.Debug.getInstance + ("provider", "Provider"); + + /** + * The provider name. + * + * @serial + */ + private String name; + + /** + * A description of the provider and its services. + * + * @serial + */ + private String info; + + /** + * The provider version number. + * + * @serial + */ + private double version; + + + private transient Set> entrySet = null; + private transient int entrySetCallCount = 0; + + private transient boolean initialized; + + /** + * Constructs a provider with the specified name, version number, + * and information. + * + * @param name the provider name. + * + * @param version the provider version number. + * + * @param info a description of the provider and its services. + */ + protected Provider(String name, double version, String info) { + this.name = name; + this.version = version; + this.info = info; + putId(); + initialized = true; + } + + /** + * Returns the name of this provider. + * + * @return the name of this provider. + */ + public String getName() { + return name; + } + + /** + * Returns the version number for this provider. + * + * @return the version number for this provider. + */ + public double getVersion() { + return version; + } + + /** + * Returns a human-readable description of the provider and its + * services. This may return an HTML page, with relevant links. + * + * @return a description of the provider and its services. + */ + public String getInfo() { + return info; + } + + /** + * Returns a string with the name and the version number + * of this provider. + * + * @return the string with the name and the version number + * for this provider. + */ + public String toString() { + return name + " version " + version; + } + + /* + * override the following methods to ensure that provider + * information can only be changed if the caller has the appropriate + * permissions. + */ + + /** + * Clears this provider so that it no longer contains the properties + * used to look up facilities implemented by the provider. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "clearProviderProperties."+name} + * (where {@code name} is the provider name) to see if it's ok to clear + * this provider. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to clear this provider + * + * @since 1.2 + */ + @Override + public synchronized void clear() { + check("clearProviderProperties."+name); + if (debug != null) { + debug.println("Remove " + name + " provider properties"); + } + implClear(); + } + + /** + * Reads a property list (key and element pairs) from the input stream. + * + * @param inStream the input stream. + * @exception IOException if an error occurred when reading from the + * input stream. + * @see java.util.Properties#load + */ + @Override + public synchronized void load(InputStream inStream) throws IOException { + check("putProviderProperty."+name); + if (debug != null) { + debug.println("Load " + name + " provider properties"); + } + Properties tempProperties = new Properties(); + tempProperties.load(inStream); + implPutAll(tempProperties); + } + + /** + * Copies all of the mappings from the specified Map to this provider. + * These mappings will replace any properties that this provider had + * for any of the keys currently in the specified Map. + * + * @since 1.2 + */ + @Override + public synchronized void putAll(Map t) { + check("putProviderProperty."+name); + if (debug != null) { + debug.println("Put all " + name + " provider properties"); + } + implPutAll(t); + } + + /** + * Returns an unmodifiable Set view of the property entries contained + * in this Provider. + * + * @see java.util.Map.Entry + * @since 1.2 + */ + @Override + public synchronized Set> entrySet() { + checkInitialized(); + if (entrySet == null) { + if (entrySetCallCount++ == 0) // Initial call + entrySet = Collections.unmodifiableMap(this).entrySet(); + else + return super.entrySet(); // Recursive call + } + + // This exception will be thrown if the implementation of + // Collections.unmodifiableMap.entrySet() is changed such that it + // no longer calls entrySet() on the backing Map. (Provider's + // entrySet implementation depends on this "implementation detail", + // which is unlikely to change. + if (entrySetCallCount != 2) + throw new RuntimeException("Internal error."); + + return entrySet; + } + + /** + * Returns an unmodifiable Set view of the property keys contained in + * this provider. + * + * @since 1.2 + */ + @Override + public Set keySet() { + checkInitialized(); + return Collections.unmodifiableSet(super.keySet()); + } + + /** + * Returns an unmodifiable Collection view of the property values + * contained in this provider. + * + * @since 1.2 + */ + @Override + public Collection values() { + checkInitialized(); + return Collections.unmodifiableCollection(super.values()); + } + + /** + * Sets the {@code key} property to have the specified + * {@code value}. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "putProviderProperty."+name}, + * where {@code name} is the provider name, to see if it's ok to set this + * provider's property values. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values. + * + * @since 1.2 + */ + @Override + public synchronized Object put(Object key, Object value) { + check("putProviderProperty."+name); + if (debug != null) { + debug.println("Set " + name + " provider property [" + + key + "/" + value +"]"); + } + return implPut(key, value); + } + + /** + * If the specified key is not already associated with a value (or is mapped + * to {@code null}) associates it with the given value and returns + * {@code null}, else returns the current value. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "putProviderProperty."+name}, + * where {@code name} is the provider name, to see if it's ok to set this + * provider's property values. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values. + * + * @since 1.8 + */ + @Override + public synchronized Object putIfAbsent(Object key, Object value) { + check("putProviderProperty."+name); + if (debug != null) { + debug.println("Set " + name + " provider property [" + + key + "/" + value +"]"); + } + return implPutIfAbsent(key, value); + } + + /** + * Removes the {@code key} property (and its corresponding + * {@code value}). + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "removeProviderProperty."+name}, + * where {@code name} is the provider name, to see if it's ok to remove this + * provider's properties. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to remove this provider's properties. + * + * @since 1.2 + */ + @Override + public synchronized Object remove(Object key) { + check("removeProviderProperty."+name); + if (debug != null) { + debug.println("Remove " + name + " provider property " + key); + } + return implRemove(key); + } + + /** + * Removes the entry for the specified key only if it is currently + * mapped to the specified value. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "removeProviderProperty."+name}, + * where {@code name} is the provider name, to see if it's ok to remove this + * provider's properties. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to remove this provider's properties. + * + * @since 1.8 + */ + @Override + public synchronized boolean remove(Object key, Object value) { + check("removeProviderProperty."+name); + if (debug != null) { + debug.println("Remove " + name + " provider property " + key); + } + return implRemove(key, value); + } + + /** + * Replaces the entry for the specified key only if currently + * mapped to the specified value. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "putProviderProperty."+name}, + * where {@code name} is the provider name, to see if it's ok to set this + * provider's property values. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values. + * + * @since 1.8 + */ + @Override + public synchronized boolean replace(Object key, Object oldValue, + Object newValue) { + check("putProviderProperty." + name); + + if (debug != null) { + debug.println("Replace " + name + " provider property " + key); + } + return implReplace(key, oldValue, newValue); + } + + /** + * Replaces the entry for the specified key only if it is + * currently mapped to some value. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "putProviderProperty."+name}, + * where {@code name} is the provider name, to see if it's ok to set this + * provider's property values. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values. + * + * @since 1.8 + */ + @Override + public synchronized Object replace(Object key, Object value) { + check("putProviderProperty." + name); + + if (debug != null) { + debug.println("Replace " + name + " provider property " + key); + } + return implReplace(key, value); + } + + /** + * Replaces each entry's value with the result of invoking the given + * function on that entry, in the order entries are returned by an entry + * set iterator, until all entries have been processed or the function + * throws an exception. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the string {@code "putProviderProperty."+name}, + * where {@code name} is the provider name, to see if it's ok to set this + * provider's property values. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values. + * + * @since 1.8 + */ + @Override + public synchronized void replaceAll(BiFunction function) { + check("putProviderProperty." + name); + + if (debug != null) { + debug.println("ReplaceAll " + name + " provider property "); + } + implReplaceAll(function); + } + + /** + * Attempts to compute a mapping for the specified key and its + * current mapped value (or {@code null} if there is no current + * mapping). + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the strings {@code "putProviderProperty."+name} + * and {@code "removeProviderProperty."+name}, where {@code name} is the + * provider name, to see if it's ok to set this provider's property values + * and remove this provider's properties. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values or remove properties. + * + * @since 1.8 + */ + @Override + public synchronized Object compute(Object key, + BiFunction remappingFunction) { + check("putProviderProperty." + name); + check("removeProviderProperty" + name); + + if (debug != null) { + debug.println("Compute " + name + " provider property " + key); + } + return implCompute(key, remappingFunction); + } + + /** + * If the specified key is not already associated with a value (or + * is mapped to {@code null}), attempts to compute its value using + * the given mapping function and enters it into this map unless + * {@code null}. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the strings {@code "putProviderProperty."+name} + * and {@code "removeProviderProperty."+name}, where {@code name} is the + * provider name, to see if it's ok to set this provider's property values + * and remove this provider's properties. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values and remove properties. + * + * @since 1.8 + */ + @Override + public synchronized Object computeIfAbsent(Object key, Function mappingFunction) { + check("putProviderProperty." + name); + check("removeProviderProperty" + name); + + if (debug != null) { + debug.println("ComputeIfAbsent " + name + " provider property " + + key); + } + return implComputeIfAbsent(key, mappingFunction); + } + + /** + * If the value for the specified key is present and non-null, attempts to + * compute a new mapping given the key and its current mapped value. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the strings {@code "putProviderProperty."+name} + * and {@code "removeProviderProperty."+name}, where {@code name} is the + * provider name, to see if it's ok to set this provider's property values + * and remove this provider's properties. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values or remove properties. + * + * @since 1.8 + */ + @Override + public synchronized Object computeIfPresent(Object key, BiFunction remappingFunction) { + check("putProviderProperty." + name); + check("removeProviderProperty" + name); + + if (debug != null) { + debug.println("ComputeIfPresent " + name + " provider property " + + key); + } + return implComputeIfPresent(key, remappingFunction); + } + + /** + * If the specified key is not already associated with a value or is + * associated with null, associates it with the given value. Otherwise, + * replaces the value with the results of the given remapping function, + * or removes if the result is null. This method may be of use when + * combining multiple mapped values for a key. + * + *

If a security manager is enabled, its {@code checkSecurityAccess} + * method is called with the strings {@code "putProviderProperty."+name} + * and {@code "removeProviderProperty."+name}, where {@code name} is the + * provider name, to see if it's ok to set this provider's property values + * and remove this provider's properties. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to set property values or remove properties. + * + * @since 1.8 + */ + @Override + public synchronized Object merge(Object key, Object value, BiFunction remappingFunction) { + check("putProviderProperty." + name); + check("removeProviderProperty" + name); + + if (debug != null) { + debug.println("Merge " + name + " provider property " + key); + } + return implMerge(key, value, remappingFunction); + } + + // let javadoc show doc from superclass + @Override + public Object get(Object key) { + checkInitialized(); + return super.get(key); + } + /** + * @since 1.8 + */ + @Override + public synchronized Object getOrDefault(Object key, Object defaultValue) { + checkInitialized(); + return super.getOrDefault(key, defaultValue); + } + + /** + * @since 1.8 + */ + @Override + public synchronized void forEach(BiConsumer action) { + checkInitialized(); + super.forEach(action); + } + + // let javadoc show doc from superclass + @Override + public Enumeration keys() { + checkInitialized(); + return super.keys(); + } + + // let javadoc show doc from superclass + @Override + public Enumeration elements() { + checkInitialized(); + return super.elements(); + } + + // let javadoc show doc from superclass + public String getProperty(String key) { + checkInitialized(); + return super.getProperty(key); + } + + private void checkInitialized() { + if (!initialized) { + throw new IllegalStateException(); + } + } + + private void check(String directive) { + checkInitialized(); + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkSecurityAccess(directive); + } + } + + // legacy properties changed since last call to any services method? + private transient boolean legacyChanged; + // serviceMap changed since last call to getServices() + private transient boolean servicesChanged; + + // Map + private transient Map legacyStrings; + + // Map + // used for services added via putService(), initialized on demand + private transient Map serviceMap; + + // Map + // used for services added via legacy methods, init on demand + private transient Map legacyMap; + + // Set + // Unmodifiable set of all services. Initialized on demand. + private transient Set serviceSet; + + // register the id attributes for this provider + // this is to ensure that equals() and hashCode() do not incorrectly + // report to different provider objects as the same + private void putId() { + // note: name and info may be null + super.put("Provider.id name", String.valueOf(name)); + super.put("Provider.id version", String.valueOf(version)); + super.put("Provider.id info", String.valueOf(info)); + super.put("Provider.id className", this.getClass().getName()); + } + + private void readObject(ObjectInputStream in) + throws IOException, ClassNotFoundException { + Map copy = new HashMap<>(); + for (Map.Entry entry : super.entrySet()) { + copy.put(entry.getKey(), entry.getValue()); + } + defaults = null; + in.defaultReadObject(); + implClear(); + initialized = true; + putAll(copy); + } + + private boolean checkLegacy(Object key) { + String keyString = (String)key; + if (keyString.startsWith("Provider.")) { + return false; + } + + legacyChanged = true; + if (legacyStrings == null) { + legacyStrings = new LinkedHashMap(); + } + return true; + } + + /** + * Copies all of the mappings from the specified Map to this provider. + * Internal method to be called AFTER the security check has been + * performed. + */ + private void implPutAll(Map t) { + for (Map.Entry e : t.entrySet()) { + implPut(e.getKey(), e.getValue()); + } + } + + private Object implRemove(Object key) { + if (key instanceof String) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.remove((String)key); + } + return super.remove(key); + } + + private boolean implRemove(Object key, Object value) { + if (key instanceof String && value instanceof String) { + if (!checkLegacy(key)) { + return false; + } + legacyStrings.remove((String)key, value); + } + return super.remove(key, value); + } + + private boolean implReplace(Object key, Object oldValue, Object newValue) { + if ((key instanceof String) && (oldValue instanceof String) && + (newValue instanceof String)) { + if (!checkLegacy(key)) { + return false; + } + legacyStrings.replace((String)key, (String)oldValue, + (String)newValue); + } + return super.replace(key, oldValue, newValue); + } + + private Object implReplace(Object key, Object value) { + if ((key instanceof String) && (value instanceof String)) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.replace((String)key, (String)value); + } + return super.replace(key, value); + } + + private void implReplaceAll(BiFunction function) { + legacyChanged = true; + if (legacyStrings == null) { + legacyStrings = new LinkedHashMap(); + } else { + legacyStrings.replaceAll((BiFunction) function); + } + super.replaceAll(function); + } + + + private Object implMerge(Object key, Object value, BiFunction remappingFunction) { + if ((key instanceof String) && (value instanceof String)) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.merge((String)key, (String)value, + (BiFunction) remappingFunction); + } + return super.merge(key, value, remappingFunction); + } + + private Object implCompute(Object key, BiFunction remappingFunction) { + if (key instanceof String) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.computeIfAbsent((String) key, + (Function) remappingFunction); + } + return super.compute(key, remappingFunction); + } + + private Object implComputeIfAbsent(Object key, Function mappingFunction) { + if (key instanceof String) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.computeIfAbsent((String) key, + (Function) mappingFunction); + } + return super.computeIfAbsent(key, mappingFunction); + } + + private Object implComputeIfPresent(Object key, BiFunction remappingFunction) { + if (key instanceof String) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.computeIfPresent((String) key, + (BiFunction) remappingFunction); + } + return super.computeIfPresent(key, remappingFunction); + } + + private Object implPut(Object key, Object value) { + if ((key instanceof String) && (value instanceof String)) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.put((String)key, (String)value); + } + return super.put(key, value); + } + + private Object implPutIfAbsent(Object key, Object value) { + if ((key instanceof String) && (value instanceof String)) { + if (!checkLegacy(key)) { + return null; + } + legacyStrings.putIfAbsent((String)key, (String)value); + } + return super.putIfAbsent(key, value); + } + + private void implClear() { + if (legacyStrings != null) { + legacyStrings.clear(); + } + if (legacyMap != null) { + legacyMap.clear(); + } + if (serviceMap != null) { + serviceMap.clear(); + } + legacyChanged = false; + servicesChanged = false; + serviceSet = null; + super.clear(); + putId(); + } + + // used as key in the serviceMap and legacyMap HashMaps + private static class ServiceKey { + private final String type; + private final String algorithm; + private final String originalAlgorithm; + private ServiceKey(String type, String algorithm, boolean intern) { + this.type = type; + this.originalAlgorithm = algorithm; + algorithm = algorithm.toUpperCase(ENGLISH); + this.algorithm = intern ? algorithm.intern() : algorithm; + } + public int hashCode() { + return type.hashCode() + algorithm.hashCode(); + } + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof ServiceKey == false) { + return false; + } + ServiceKey other = (ServiceKey)obj; + return this.type.equals(other.type) + && this.algorithm.equals(other.algorithm); + } + boolean matches(String type, String algorithm) { + return (this.type == type) && (this.originalAlgorithm == algorithm); + } + } + + /** + * Ensure all the legacy String properties are fully parsed into + * service objects. + */ + private void ensureLegacyParsed() { + if ((legacyChanged == false) || (legacyStrings == null)) { + return; + } + serviceSet = null; + if (legacyMap == null) { + legacyMap = new LinkedHashMap(); + } else { + legacyMap.clear(); + } + for (Map.Entry entry : legacyStrings.entrySet()) { + parseLegacyPut(entry.getKey(), entry.getValue()); + } + removeInvalidServices(legacyMap); + legacyChanged = false; + } + + /** + * Remove all invalid services from the Map. Invalid services can only + * occur if the legacy properties are inconsistent or incomplete. + */ + private void removeInvalidServices(Map map) { + for (Iterator> t = + map.entrySet().iterator(); t.hasNext(); ) { + Service s = t.next().getValue(); + if (s.isValid() == false) { + t.remove(); + } + } + } + + private String[] getTypeAndAlgorithm(String key) { + int i = key.indexOf("."); + if (i < 1) { + if (debug != null) { + debug.println("Ignoring invalid entry in provider " + + name + ":" + key); + } + return null; + } + String type = key.substring(0, i); + String alg = key.substring(i + 1); + return new String[] {type, alg}; + } + + private final static String ALIAS_PREFIX = "Alg.Alias."; + private final static String ALIAS_PREFIX_LOWER = "alg.alias."; + private final static int ALIAS_LENGTH = ALIAS_PREFIX.length(); + + private void parseLegacyPut(String name, String value) { + if (name.toLowerCase(ENGLISH).startsWith(ALIAS_PREFIX_LOWER)) { + // e.g. put("Alg.Alias.MessageDigest.SHA", "SHA-1"); + // aliasKey ~ MessageDigest.SHA + String stdAlg = value; + String aliasKey = name.substring(ALIAS_LENGTH); + String[] typeAndAlg = getTypeAndAlgorithm(aliasKey); + if (typeAndAlg == null) { + return; + } + String type = getEngineName(typeAndAlg[0]); + String aliasAlg = typeAndAlg[1].intern(); + ServiceKey key = new ServiceKey(type, stdAlg, true); + Service s = legacyMap.get(key); + if (s == null) { + s = new Service(this); + s.type = type; + s.algorithm = stdAlg; + legacyMap.put(key, s); + } + legacyMap.put(new ServiceKey(type, aliasAlg, true), s); + s.addAlias(aliasAlg); + } else { + String[] typeAndAlg = getTypeAndAlgorithm(name); + if (typeAndAlg == null) { + return; + } + int i = typeAndAlg[1].indexOf(' '); + if (i == -1) { + // e.g. put("MessageDigest.SHA-1", "sun.security.provider.SHA"); + String type = getEngineName(typeAndAlg[0]); + String stdAlg = typeAndAlg[1].intern(); + String className = value; + ServiceKey key = new ServiceKey(type, stdAlg, true); + Service s = legacyMap.get(key); + if (s == null) { + s = new Service(this); + s.type = type; + s.algorithm = stdAlg; + legacyMap.put(key, s); + } + s.className = className; + } else { // attribute + // e.g. put("MessageDigest.SHA-1 ImplementedIn", "Software"); + String attributeValue = value; + String type = getEngineName(typeAndAlg[0]); + String attributeString = typeAndAlg[1]; + String stdAlg = attributeString.substring(0, i).intern(); + String attributeName = attributeString.substring(i + 1); + // kill additional spaces + while (attributeName.startsWith(" ")) { + attributeName = attributeName.substring(1); + } + attributeName = attributeName.intern(); + ServiceKey key = new ServiceKey(type, stdAlg, true); + Service s = legacyMap.get(key); + if (s == null) { + s = new Service(this); + s.type = type; + s.algorithm = stdAlg; + legacyMap.put(key, s); + } + s.addAttribute(attributeName, attributeValue); + } + } + } + + /** + * Get the service describing this Provider's implementation of the + * specified type of this algorithm or alias. If no such + * implementation exists, this method returns null. If there are two + * matching services, one added to this provider using + * {@link #putService putService()} and one added via {@link #put put()}, + * the service added via {@link #putService putService()} is returned. + * + * @param type the type of {@link Service service} requested + * (for example, {@code MessageDigest}) + * @param algorithm the case insensitive algorithm name (or alternate + * alias) of the service requested (for example, {@code SHA-1}) + * + * @return the service describing this Provider's matching service + * or null if no such service exists + * + * @throws NullPointerException if type or algorithm is null + * + * @since 1.5 + */ + public synchronized Service getService(String type, String algorithm) { + checkInitialized(); + // avoid allocating a new key object if possible + ServiceKey key = previousKey; + if (key.matches(type, algorithm) == false) { + key = new ServiceKey(type, algorithm, false); + previousKey = key; + } + if (serviceMap != null) { + Service service = serviceMap.get(key); + if (service != null) { + return service; + } + } + ensureLegacyParsed(); + return (legacyMap != null) ? legacyMap.get(key) : null; + } + + // ServiceKey from previous getService() call + // by re-using it if possible we avoid allocating a new object + // and the toUpperCase() call. + // re-use will occur e.g. as the framework traverses the provider + // list and queries each provider with the same values until it finds + // a matching service + private static volatile ServiceKey previousKey = + new ServiceKey("", "", false); + + /** + * Get an unmodifiable Set of all services supported by + * this Provider. + * + * @return an unmodifiable Set of all services supported by + * this Provider + * + * @since 1.5 + */ + public synchronized Set getServices() { + checkInitialized(); + if (legacyChanged || servicesChanged) { + serviceSet = null; + } + if (serviceSet == null) { + ensureLegacyParsed(); + Set set = new LinkedHashSet<>(); + if (serviceMap != null) { + set.addAll(serviceMap.values()); + } + if (legacyMap != null) { + set.addAll(legacyMap.values()); + } + serviceSet = Collections.unmodifiableSet(set); + servicesChanged = false; + } + return serviceSet; + } + + /** + * Add a service. If a service of the same type with the same algorithm + * name exists and it was added using {@link #putService putService()}, + * it is replaced by the new service. + * This method also places information about this service + * in the provider's Hashtable values in the format described in the + * + * Java Cryptography Architecture API Specification & Reference . + * + *

Also, if there is a security manager, its + * {@code checkSecurityAccess} method is called with the string + * {@code "putProviderProperty."+name}, where {@code name} is + * the provider name, to see if it's ok to set this provider's property + * values. If the default implementation of {@code checkSecurityAccess} + * is used (that is, that method is not overriden), then this results in + * a call to the security manager's {@code checkPermission} method with + * a {@code SecurityPermission("putProviderProperty."+name)} + * permission. + * + * @param s the Service to add + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method denies + * access to set property values. + * @throws NullPointerException if s is null + * + * @since 1.5 + */ + protected synchronized void putService(Service s) { + check("putProviderProperty." + name); + if (debug != null) { + debug.println(name + ".putService(): " + s); + } + if (s == null) { + throw new NullPointerException(); + } + if (s.getProvider() != this) { + throw new IllegalArgumentException + ("service.getProvider() must match this Provider object"); + } + if (serviceMap == null) { + serviceMap = new LinkedHashMap(); + } + servicesChanged = true; + String type = s.getType(); + String algorithm = s.getAlgorithm(); + ServiceKey key = new ServiceKey(type, algorithm, true); + // remove existing service + implRemoveService(serviceMap.get(key)); + serviceMap.put(key, s); + for (String alias : s.getAliases()) { + serviceMap.put(new ServiceKey(type, alias, true), s); + } + putPropertyStrings(s); + } + + /** + * Put the string properties for this Service in this Provider's + * Hashtable. + */ + private void putPropertyStrings(Service s) { + String type = s.getType(); + String algorithm = s.getAlgorithm(); + // use super() to avoid permission check and other processing + super.put(type + "." + algorithm, s.getClassName()); + for (String alias : s.getAliases()) { + super.put(ALIAS_PREFIX + type + "." + alias, algorithm); + } + for (Map.Entry entry : s.attributes.entrySet()) { + String key = type + "." + algorithm + " " + entry.getKey(); + super.put(key, entry.getValue()); + } + } + + /** + * Remove the string properties for this Service from this Provider's + * Hashtable. + */ + private void removePropertyStrings(Service s) { + String type = s.getType(); + String algorithm = s.getAlgorithm(); + // use super() to avoid permission check and other processing + super.remove(type + "." + algorithm); + for (String alias : s.getAliases()) { + super.remove(ALIAS_PREFIX + type + "." + alias); + } + for (Map.Entry entry : s.attributes.entrySet()) { + String key = type + "." + algorithm + " " + entry.getKey(); + super.remove(key); + } + } + + /** + * Remove a service previously added using + * {@link #putService putService()}. The specified service is removed from + * this provider. It will no longer be returned by + * {@link #getService getService()} and its information will be removed + * from this provider's Hashtable. + * + *

Also, if there is a security manager, its + * {@code checkSecurityAccess} method is called with the string + * {@code "removeProviderProperty."+name}, where {@code name} is + * the provider name, to see if it's ok to remove this provider's + * properties. If the default implementation of + * {@code checkSecurityAccess} is used (that is, that method is not + * overriden), then this results in a call to the security manager's + * {@code checkPermission} method with a + * {@code SecurityPermission("removeProviderProperty."+name)} + * permission. + * + * @param s the Service to be removed + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method denies + * access to remove this provider's properties. + * @throws NullPointerException if s is null + * + * @since 1.5 + */ + protected synchronized void removeService(Service s) { + check("removeProviderProperty." + name); + if (debug != null) { + debug.println(name + ".removeService(): " + s); + } + if (s == null) { + throw new NullPointerException(); + } + implRemoveService(s); + } + + private void implRemoveService(Service s) { + if ((s == null) || (serviceMap == null)) { + return; + } + String type = s.getType(); + String algorithm = s.getAlgorithm(); + ServiceKey key = new ServiceKey(type, algorithm, false); + Service oldService = serviceMap.get(key); + if (s != oldService) { + return; + } + servicesChanged = true; + serviceMap.remove(key); + for (String alias : s.getAliases()) { + serviceMap.remove(new ServiceKey(type, alias, false)); + } + removePropertyStrings(s); + } + + // Wrapped String that behaves in a case insensitive way for equals/hashCode + private static class UString { + final String string; + final String lowerString; + + UString(String s) { + this.string = s; + this.lowerString = s.toLowerCase(ENGLISH); + } + + public int hashCode() { + return lowerString.hashCode(); + } + + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof UString == false) { + return false; + } + UString other = (UString)obj; + return lowerString.equals(other.lowerString); + } + + public String toString() { + return string; + } + } + + // describe relevant properties of a type of engine + private static class EngineDescription { + final String name; + final boolean supportsParameter; + final String constructorParameterClassName; + private volatile Class constructorParameterClass; + + EngineDescription(String name, boolean sp, String paramName) { + this.name = name; + this.supportsParameter = sp; + this.constructorParameterClassName = paramName; + } + Class getConstructorParameterClass() throws ClassNotFoundException { + Class clazz = constructorParameterClass; + if (clazz == null) { + clazz = Class.forName(constructorParameterClassName); + constructorParameterClass = clazz; + } + return clazz; + } + } + + // built in knowledge of the engine types shipped as part of the JDK + private static final Map knownEngines; + + private static void addEngine(String name, boolean sp, String paramName) { + EngineDescription ed = new EngineDescription(name, sp, paramName); + // also index by canonical name to avoid toLowerCase() for some lookups + knownEngines.put(name.toLowerCase(ENGLISH), ed); + knownEngines.put(name, ed); + } + + static { + knownEngines = new HashMap(); + // JCA + addEngine("AlgorithmParameterGenerator", false, null); + addEngine("AlgorithmParameters", false, null); + addEngine("KeyFactory", false, null); + addEngine("KeyPairGenerator", false, null); + addEngine("KeyStore", false, null); + addEngine("MessageDigest", false, null); + addEngine("SecureRandom", false, null); + addEngine("Signature", true, null); + addEngine("CertificateFactory", false, null); + addEngine("CertPathBuilder", false, null); + addEngine("CertPathValidator", false, null); + addEngine("CertStore", false, + "java.security.cert.CertStoreParameters"); + // JCE + addEngine("Cipher", true, null); + addEngine("ExemptionMechanism", false, null); + addEngine("Mac", true, null); + addEngine("KeyAgreement", true, null); + addEngine("KeyGenerator", false, null); + addEngine("SecretKeyFactory", false, null); + // JSSE + addEngine("KeyManagerFactory", false, null); + addEngine("SSLContext", false, null); + addEngine("TrustManagerFactory", false, null); + // JGSS + addEngine("GssApiMechanism", false, null); + // SASL + addEngine("SaslClientFactory", false, null); + addEngine("SaslServerFactory", false, null); + // POLICY + addEngine("Policy", false, + "java.security.Policy$Parameters"); + // CONFIGURATION + addEngine("Configuration", false, + "javax.security.auth.login.Configuration$Parameters"); + // XML DSig + addEngine("XMLSignatureFactory", false, null); + addEngine("KeyInfoFactory", false, null); + addEngine("TransformService", false, null); + // Smart Card I/O + addEngine("TerminalFactory", false, + "java.lang.Object"); + } + + // get the "standard" (mixed-case) engine name for arbitary case engine name + // if there is no known engine by that name, return s + private static String getEngineName(String s) { + // try original case first, usually correct + EngineDescription e = knownEngines.get(s); + if (e == null) { + e = knownEngines.get(s.toLowerCase(ENGLISH)); + } + return (e == null) ? s : e.name; + } + + /** + * The description of a security service. It encapsulates the properties + * of a service and contains a factory method to obtain new implementation + * instances of this service. + * + *

Each service has a provider that offers the service, a type, + * an algorithm name, and the name of the class that implements the + * service. Optionally, it also includes a list of alternate algorithm + * names for this service (aliases) and attributes, which are a map of + * (name, value) String pairs. + * + *

This class defines the methods {@link #supportsParameter + * supportsParameter()} and {@link #newInstance newInstance()} + * which are used by the Java security framework when it searches for + * suitable services and instantiates them. The valid arguments to those + * methods depend on the type of service. For the service types defined + * within Java SE, see the + * + * Java Cryptography Architecture API Specification & Reference + * for the valid values. + * Note that components outside of Java SE can define additional types of + * services and their behavior. + * + *

Instances of this class are immutable. + * + * @since 1.5 + */ + public static class Service { + + private String type, algorithm, className; + private final Provider provider; + private List aliases; + private Map attributes; + + // Reference to the cached implementation Class object + private volatile Class classRef; + + // flag indicating whether this service has its attributes for + // supportedKeyFormats or supportedKeyClasses set + // if null, the values have not been initialized + // if TRUE, at least one of supportedFormats/Classes is non null + private volatile Boolean hasKeyAttributes; + + // supported encoding formats + private String[] supportedFormats; + + // names of the supported key (super) classes + private Class[] supportedClasses; + + // whether this service has been registered with the Provider + private boolean registered; + + private static final Class[] CLASS0 = new Class[0]; + + // this constructor and these methods are used for parsing + // the legacy string properties. + + private Service(Provider provider) { + this.provider = provider; + aliases = Collections.emptyList(); + attributes = Collections.emptyMap(); + } + + private boolean isValid() { + return (type != null) && (algorithm != null) && (className != null); + } + + private void addAlias(String alias) { + if (aliases.isEmpty()) { + aliases = new ArrayList(2); + } + aliases.add(alias); + } + + void addAttribute(String type, String value) { + if (attributes.isEmpty()) { + attributes = new HashMap(8); + } + attributes.put(new UString(type), value); + } + + /** + * Construct a new service. + * + * @param provider the provider that offers this service + * @param type the type of this service + * @param algorithm the algorithm name + * @param className the name of the class implementing this service + * @param aliases List of aliases or null if algorithm has no aliases + * @param attributes Map of attributes or null if this implementation + * has no attributes + * + * @throws NullPointerException if provider, type, algorithm, or + * className is null + */ + public Service(Provider provider, String type, String algorithm, + String className, List aliases, + Map attributes) { + if ((provider == null) || (type == null) || + (algorithm == null) || (className == null)) { + throw new NullPointerException(); + } + this.provider = provider; + this.type = getEngineName(type); + this.algorithm = algorithm; + this.className = className; + if (aliases == null) { + this.aliases = Collections.emptyList(); + } else { + this.aliases = new ArrayList(aliases); + } + if (attributes == null) { + this.attributes = Collections.emptyMap(); + } else { + this.attributes = new HashMap(); + for (Map.Entry entry : attributes.entrySet()) { + this.attributes.put(new UString(entry.getKey()), entry.getValue()); + } + } + } + + /** + * Get the type of this service. For example, {@code MessageDigest}. + * + * @return the type of this service + */ + public final String getType() { + return type; + } + + /** + * Return the name of the algorithm of this service. For example, + * {@code SHA-1}. + * + * @return the algorithm of this service + */ + public final String getAlgorithm() { + return algorithm; + } + + /** + * Return the Provider of this service. + * + * @return the Provider of this service + */ + public final Provider getProvider() { + return provider; + } + + /** + * Return the name of the class implementing this service. + * + * @return the name of the class implementing this service + */ + public final String getClassName() { + return className; + } + + // internal only + private final List getAliases() { + return aliases; + } + + /** + * Return the value of the specified attribute or null if this + * attribute is not set for this Service. + * + * @param name the name of the requested attribute + * + * @return the value of the specified attribute or null if the + * attribute is not present + * + * @throws NullPointerException if name is null + */ + public final String getAttribute(String name) { + if (name == null) { + throw new NullPointerException(); + } + return attributes.get(new UString(name)); + } + + /** + * Return a new instance of the implementation described by this + * service. The security provider framework uses this method to + * construct implementations. Applications will typically not need + * to call it. + * + *

The default implementation uses reflection to invoke the + * standard constructor for this type of service. + * Security providers can override this method to implement + * instantiation in a different way. + * For details and the values of constructorParameter that are + * valid for the various types of services see the + * + * Java Cryptography Architecture API Specification & + * Reference. + * + * @param constructorParameter the value to pass to the constructor, + * or null if this type of service does not use a constructorParameter. + * + * @return a new implementation of this service + * + * @throws InvalidParameterException if the value of + * constructorParameter is invalid for this type of service. + * @throws NoSuchAlgorithmException if instantiation failed for + * any other reason. + */ + public Object newInstance(Object constructorParameter) + throws NoSuchAlgorithmException { + if (registered == false) { + if (provider.getService(type, algorithm) != this) { + throw new NoSuchAlgorithmException + ("Service not registered with Provider " + + provider.getName() + ": " + this); + } + registered = true; + } + try { + EngineDescription cap = knownEngines.get(type); + if (cap == null) { + // unknown engine type, use generic code + // this is the code path future for non-core + // optional packages + return newInstanceGeneric(constructorParameter); + } + if (cap.constructorParameterClassName == null) { + if (constructorParameter != null) { + throw new InvalidParameterException + ("constructorParameter not used with " + type + + " engines"); + } + Class clazz = getImplClass(); + Class[] empty = {}; + Constructor con = clazz.getConstructor(empty); + return con.newInstance(); + } else { + Class paramClass = cap.getConstructorParameterClass(); + if (constructorParameter != null) { + Class argClass = constructorParameter.getClass(); + if (paramClass.isAssignableFrom(argClass) == false) { + throw new InvalidParameterException + ("constructorParameter must be instanceof " + + cap.constructorParameterClassName.replace('$', '.') + + " for engine type " + type); + } + } + Class clazz = getImplClass(); + Constructor cons = clazz.getConstructor(paramClass); + return cons.newInstance(constructorParameter); + } + } catch (NoSuchAlgorithmException e) { + throw e; + } catch (InvocationTargetException e) { + throw new NoSuchAlgorithmException + ("Error constructing implementation (algorithm: " + + algorithm + ", provider: " + provider.getName() + + ", class: " + className + ")", e.getCause()); + } catch (Exception e) { + throw new NoSuchAlgorithmException + ("Error constructing implementation (algorithm: " + + algorithm + ", provider: " + provider.getName() + + ", class: " + className + ")", e); + } + } + + // return the implementation Class object for this service + private Class getImplClass() throws NoSuchAlgorithmException { + try { + // Class ref = classRef; + Class clazz = classRef; + if (clazz == null) { + ClassLoader cl = provider.getClass().getClassLoader(); + if (cl == null) { + clazz = Class.forName(className); + } else { + clazz = cl.loadClass(className); + } + if (!Modifier.isPublic(clazz.getModifiers())) { + throw new NoSuchAlgorithmException + ("class configured for " + type + " (provider: " + + provider.getName() + ") is not public."); + } + classRef = clazz; + } + return clazz; + } catch (ClassNotFoundException e) { + throw new NoSuchAlgorithmException + ("class configured for " + type + " (provider: " + + provider.getName() + ") cannot be found.", e); + } + } + + /** + * Generic code path for unknown engine types. Call the + * no-args constructor if constructorParameter is null, otherwise + * use the first matching constructor. + */ + private Object newInstanceGeneric(Object constructorParameter) + throws Exception { + Class clazz = getImplClass(); + if (constructorParameter == null) { + // create instance with public no-arg constructor if it exists + try { + Class[] empty = {}; + Constructor con = clazz.getConstructor(empty); + return con.newInstance(); + } catch (NoSuchMethodException e) { + throw new NoSuchAlgorithmException("No public no-arg " + + "constructor found in class " + className); + } + } + Class argClass = constructorParameter.getClass(); + Constructor[] cons = clazz.getConstructors(); + // find first public constructor that can take the + // argument as parameter + for (Constructor con : cons) { + Class[] paramTypes = con.getParameterTypes(); + if (paramTypes.length != 1) { + continue; + } + if (paramTypes[0].isAssignableFrom(argClass) == false) { + continue; + } + return con.newInstance(constructorParameter); + } + throw new NoSuchAlgorithmException("No public constructor matching " + + argClass.getName() + " found in class " + className); + } + + /** + * Test whether this Service can use the specified parameter. + * Returns false if this service cannot use the parameter. Returns + * true if this service can use the parameter, if a fast test is + * infeasible, or if the status is unknown. + * + *

The security provider framework uses this method with + * some types of services to quickly exclude non-matching + * implementations for consideration. + * Applications will typically not need to call it. + * + *

For details and the values of parameter that are valid for the + * various types of services see the top of this class and the + * + * Java Cryptography Architecture API Specification & + * Reference. + * Security providers can override it to implement their own test. + * + * @param parameter the parameter to test + * + * @return false if this this service cannot use the specified + * parameter; true if it can possibly use the parameter + * + * @throws InvalidParameterException if the value of parameter is + * invalid for this type of service or if this method cannot be + * used with this type of service + */ + public boolean supportsParameter(Object parameter) { + EngineDescription cap = knownEngines.get(type); + if (cap == null) { + // unknown engine type, return true by default + return true; + } + if (cap.supportsParameter == false) { + throw new InvalidParameterException("supportsParameter() not " + + "used with " + type + " engines"); + } + // allow null for keys without attributes for compatibility + if ((parameter != null) && (parameter instanceof Key == false)) { + throw new InvalidParameterException + ("Parameter must be instanceof Key for engine " + type); + } + if (hasKeyAttributes() == false) { + return true; + } + if (parameter == null) { + return false; + } + Key key = (Key)parameter; + if (supportsKeyFormat(key)) { + return true; + } + if (supportsKeyClass(key)) { + return true; + } + return false; + } + + /** + * Return whether this service has its Supported* properties for + * keys defined. Parses the attributes if not yet initialized. + */ + private boolean hasKeyAttributes() { + Boolean b = hasKeyAttributes; + if (b == null) { + synchronized (this) { + String s; + s = getAttribute("SupportedKeyFormats"); + if (s != null) { + supportedFormats = s.split("\\|"); + } + s = getAttribute("SupportedKeyClasses"); + if (s != null) { + String[] classNames = s.split("\\|"); + List> classList = + new ArrayList<>(classNames.length); + for (String className : classNames) { + Class clazz = getKeyClass(className); + if (clazz != null) { + classList.add(clazz); + } + } + supportedClasses = classList.toArray(CLASS0); + } + boolean bool = (supportedFormats != null) + || (supportedClasses != null); + b = Boolean.valueOf(bool); + hasKeyAttributes = b; + } + } + return b.booleanValue(); + } + + // get the key class object of the specified name + private Class getKeyClass(String name) { + try { + return Class.forName(name); + } catch (ClassNotFoundException e) { + // ignore + } + try { + ClassLoader cl = provider.getClass().getClassLoader(); + if (cl != null) { + return cl.loadClass(name); + } + } catch (ClassNotFoundException e) { + // ignore + } + return null; + } + + private boolean supportsKeyFormat(Key key) { + if (supportedFormats == null) { + return false; + } + String format = key.getFormat(); + if (format == null) { + return false; + } + for (String supportedFormat : supportedFormats) { + if (supportedFormat.equals(format)) { + return true; + } + } + return false; + } + + private boolean supportsKeyClass(Key key) { + if (supportedClasses == null) { + return false; + } + Class keyClass = key.getClass(); + for (Class clazz : supportedClasses) { + if (clazz.isAssignableFrom(keyClass)) { + return true; + } + } + return false; + } + + /** + * Return a String representation of this service. + * + * @return a String representation of this service. + */ + public String toString() { + String aString = aliases.isEmpty() + ? "" : "\r\n aliases: " + aliases.toString(); + String attrs = attributes.isEmpty() + ? "" : "\r\n attributes: " + attributes.toString(); + return provider.getName() + ": " + type + "." + algorithm + + " -> " + className + aString + attrs + "\r\n"; + } + + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/ProviderException.java b/sources/net.sf.j2s.java.core/src/java/security/ProviderException.java new file mode 100644 index 000000000..b372ee757 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/ProviderException.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * A runtime exception for Provider exceptions (such as + * misconfiguration errors or unrecoverable internal errors), + * which may be subclassed by Providers to + * throw specialized, provider-specific runtime errors. + * + * @author Benjamin Renaud + */ +public class ProviderException extends RuntimeException { + + private static final long serialVersionUID = 5256023526693665674L; + + /** + * Constructs a ProviderException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public ProviderException() { + super(); + } + + /** + * Constructs a ProviderException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param s the detail message. + */ + public ProviderException(String s) { + super(s); + } + + /** + * Creates a {@code ProviderException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public ProviderException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code ProviderException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public ProviderException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/PublicKey.java b/sources/net.sf.j2s.java.core/src/java/security/PublicKey.java new file mode 100644 index 000000000..df49807ee --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/PublicKey.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + *

A public key. This interface contains no methods or constants. + * It merely serves to group (and provide type safety for) all public key + * interfaces. + * + * Note: The specialized public key interfaces extend this interface. + * See, for example, the DSAPublicKey interface in + * {@code java.security.interfaces}. + * + * @see Key + * @see PrivateKey + * @see Certificate + * @see Signature#initVerify + * @see java.security.interfaces.DSAPublicKey + * @see java.security.interfaces.RSAPublicKey + * + */ + +public interface PublicKey extends Key { + // Declare serialVersionUID to be compatible with JDK1.1 + /** + * The class fingerprint that is set to indicate serialization + * compatibility with a previous version of the class. + */ + static final long serialVersionUID = 7187392471159151072L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/SecureClassLoader.java b/sources/net.sf.j2s.java.core/src/java/security/SecureClassLoader.java new file mode 100644 index 000000000..145f4fc48 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/SecureClassLoader.java @@ -0,0 +1,227 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.util.HashMap; +import java.util.ArrayList; +import java.net.URL; + +import sun.security.util.Debug; + +/** + * This class extends ClassLoader with additional support for defining + * classes with an associated code source and permissions which are + * retrieved by the system policy by default. + * + * @author Li Gong + * @author Roland Schemers + */ +public class SecureClassLoader extends ClassLoader { + /* + * If initialization succeed this is set to true and security checks will + * succeed. Otherwise the object is not initialized and the object is + * useless. + */ + private final boolean initialized; + + // HashMap that maps CodeSource to ProtectionDomain + // @GuardedBy("pdcache") + private final HashMap pdcache = + new HashMap<>(11); + + private static final Debug debug = Debug.getInstance("scl"); + + static { + ClassLoader.registerAsParallelCapable(); + } + + /** + * Creates a new SecureClassLoader using the specified parent + * class loader for delegation. + * + *

If there is a security manager, this method first + * calls the security manager's {@code checkCreateClassLoader} + * method to ensure creation of a class loader is allowed. + *

+ * @param parent the parent ClassLoader + * @exception SecurityException if a security manager exists and its + * {@code checkCreateClassLoader} method doesn't allow + * creation of a class loader. + * @see SecurityManager#checkCreateClassLoader + */ + protected SecureClassLoader(ClassLoader parent) { + super(parent); + // this is to make the stack depth consistent with 1.1 + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkCreateClassLoader(); + } + initialized = true; + } + + /** + * Creates a new SecureClassLoader using the default parent class + * loader for delegation. + * + *

If there is a security manager, this method first + * calls the security manager's {@code checkCreateClassLoader} + * method to ensure creation of a class loader is allowed. + * + * @exception SecurityException if a security manager exists and its + * {@code checkCreateClassLoader} method doesn't allow + * creation of a class loader. + * @see SecurityManager#checkCreateClassLoader + */ + protected SecureClassLoader() { + super(); + // this is to make the stack depth consistent with 1.1 + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkCreateClassLoader(); + } + initialized = true; + } + + /** + * Converts an array of bytes into an instance of class Class, + * with an optional CodeSource. Before the + * class can be used it must be resolved. + *

+ * If a non-null CodeSource is supplied a ProtectionDomain is + * constructed and associated with the class being defined. + *

+ * @param name the expected name of the class, or {@code null} + * if not known, using '.' and not '/' as the separator + * and without a trailing ".class" suffix. + * @param b the bytes that make up the class data. The bytes in + * positions {@code off} through {@code off+len-1} + * should have the format of a valid class file as defined by + * The Java™ Virtual Machine Specification. + * @param off the start offset in {@code b} of the class data + * @param len the length of the class data + * @param cs the associated CodeSource, or {@code null} if none + * @return the {@code Class} object created from the data, + * and optional CodeSource. + * @exception ClassFormatError if the data did not contain a valid class + * @exception IndexOutOfBoundsException if either {@code off} or + * {@code len} is negative, or if + * {@code off+len} is greater than {@code b.length}. + * + * @exception SecurityException if an attempt is made to add this class + * to a package that contains classes that were signed by + * a different set of certificates than this class, or if + * the class name begins with "java.". + */ + protected final Class defineClass(String name, + byte[] b, int off, int len, + CodeSource cs) + { + return defineClass(name, b, off, len, getProtectionDomain(cs)); + } + + /** + * Converts a {@link java.nio.ByteBuffer ByteBuffer} + * into an instance of class {@code Class}, with an optional CodeSource. + * Before the class can be used it must be resolved. + *

+ * If a non-null CodeSource is supplied a ProtectionDomain is + * constructed and associated with the class being defined. + *

+ * @param name the expected name of the class, or {@code null} + * if not known, using '.' and not '/' as the separator + * and without a trailing ".class" suffix. + * @param b the bytes that make up the class data. The bytes from positions + * {@code b.position()} through {@code b.position() + b.limit() -1} + * should have the format of a valid class file as defined by + * The Java™ Virtual Machine Specification. + * @param cs the associated CodeSource, or {@code null} if none + * @return the {@code Class} object created from the data, + * and optional CodeSource. + * @exception ClassFormatError if the data did not contain a valid class + * @exception SecurityException if an attempt is made to add this class + * to a package that contains classes that were signed by + * a different set of certificates than this class, or if + * the class name begins with "java.". + * + * @since 1.5 + */ + protected final Class defineClass(String name, java.nio.ByteBuffer b, + CodeSource cs) + { + return defineClass(name, b, getProtectionDomain(cs)); + } + + /** + * Returns the permissions for the given CodeSource object. + *

+ * This method is invoked by the defineClass method which takes + * a CodeSource as an argument when it is constructing the + * ProtectionDomain for the class being defined. + *

+ * @param codesource the codesource. + * + * @return the permissions granted to the codesource. + * + */ + protected PermissionCollection getPermissions(CodeSource codesource) + { + check(); + return new Permissions(); // ProtectionDomain defers the binding + } + + /* + * Returned cached ProtectionDomain for the specified CodeSource. + */ + private ProtectionDomain getProtectionDomain(CodeSource cs) { + if (cs == null) + return null; + + ProtectionDomain pd = null; + synchronized (pdcache) { + pd = pdcache.get(cs); + if (pd == null) { + PermissionCollection perms = getPermissions(cs); + pd = new ProtectionDomain(cs, perms, this, null); + pdcache.put(cs, pd); + if (debug != null) { + debug.println(" getPermissions "+ pd); + debug.println(""); + } + } + } + return pd; + } + + /* + * Check to make sure the class loader has been initialized. + */ + private void check() { + if (!initialized) { + throw new SecurityException("ClassLoader object not initialized"); + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/SecureRandom.java b/sources/net.sf.j2s.java.core/src/java/security/SecureRandom.java new file mode 100644 index 000000000..3481e2178 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/SecureRandom.java @@ -0,0 +1,688 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.util.*; +import java.util.regex.*; + +import java.security.Provider.Service; + +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; +import sun.security.util.Debug; + +/** + * This class provides a cryptographically strong random number + * generator (RNG). + * + *

A cryptographically strong random number + * minimally complies with the statistical random number generator tests + * specified in + * FIPS 140-2, Security Requirements for Cryptographic Modules, + * section 4.9.1. + * Additionally, SecureRandom must produce non-deterministic output. + * Therefore any seed material passed to a SecureRandom object must be + * unpredictable, and all SecureRandom output sequences must be + * cryptographically strong, as described in + * + * RFC 1750: Randomness Recommendations for Security. + * + *

A caller obtains a SecureRandom instance via the + * no-argument constructor or one of the {@code getInstance} methods: + * + *

+ *      SecureRandom random = new SecureRandom();
+ * 
+ * + *

Many SecureRandom implementations are in the form of a pseudo-random + * number generator (PRNG), which means they use a deterministic algorithm + * to produce a pseudo-random sequence from a true random seed. + * Other implementations may produce true random numbers, + * and yet others may use a combination of both techniques. + * + *

Typical callers of SecureRandom invoke the following methods + * to retrieve random bytes: + * + *

+ *      SecureRandom random = new SecureRandom();
+ *      byte bytes[] = new byte[20];
+ *      random.nextBytes(bytes);
+ * 
+ * + *

Callers may also invoke the {@code generateSeed} method + * to generate a given number of seed bytes (to seed other random number + * generators, for example): + *

+ *      byte seed[] = random.generateSeed(20);
+ * 
+ * + * Note: Depending on the implementation, the {@code generateSeed} and + * {@code nextBytes} methods may block as entropy is being gathered, + * for example, if they need to read from /dev/random on various Unix-like + * operating systems. + * + * @see java.security.SecureRandomSpi + * @see java.util.Random + * + * @author Benjamin Renaud + * @author Josh Bloch + */ + +public class SecureRandom extends java.util.Random { + + private static final Debug pdebug = + Debug.getInstance("provider", "Provider"); + private static final boolean skipDebug = + Debug.isOn("engine=") && !Debug.isOn("securerandom"); + + /** + * The provider. + * + * @serial + * @since 1.2 + */ + private Provider provider = null; + + /** + * The provider implementation. + * + * @serial + * @since 1.2 + */ + private SecureRandomSpi secureRandomSpi = null; + + /* + * The algorithm name of null if unknown. + * + * @serial + * @since 1.5 + */ + private String algorithm; + + // Seed Generator + private static volatile SecureRandom seedGenerator = null; + + /** + * Constructs a secure random number generator (RNG) implementing the + * default random number algorithm. + * + *

This constructor traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new SecureRandom object encapsulating the + * SecureRandomSpi implementation from the first + * Provider that supports a SecureRandom (RNG) algorithm is returned. + * If none of the Providers support a RNG algorithm, + * then an implementation-specific default is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

See the SecureRandom section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard RNG algorithm names. + * + *

The returned SecureRandom object has not been seeded. To seed the + * returned object, call the {@code setSeed} method. + * If {@code setSeed} is not called, the first call to + * {@code nextBytes} will force the SecureRandom object to seed itself. + * This self-seeding will not occur if {@code setSeed} was + * previously called. + */ + public SecureRandom() { + /* + * This call to our superclass constructor will result in a call + * to our own {@code setSeed} method, which will return + * immediately when it is passed zero. + */ + super(0); + getDefaultPRNG(false, null); + } + + /** + * Constructs a secure random number generator (RNG) implementing the + * default random number algorithm. + * The SecureRandom instance is seeded with the specified seed bytes. + * + *

This constructor traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new SecureRandom object encapsulating the + * SecureRandomSpi implementation from the first + * Provider that supports a SecureRandom (RNG) algorithm is returned. + * If none of the Providers support a RNG algorithm, + * then an implementation-specific default is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

See the SecureRandom section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard RNG algorithm names. + * + * @param seed the seed. + */ + public SecureRandom(byte seed[]) { + super(0); + getDefaultPRNG(true, seed); + } + + private void getDefaultPRNG(boolean setSeed, byte[] seed) { + String prng = getPrngAlgorithm(); + if (prng == null) { + // bummer, get the SUN implementation + prng = "SHA1PRNG"; + this.secureRandomSpi = new sun.security.provider.SecureRandom(); + this.provider = Providers.getSunProvider(); + if (setSeed) { + this.secureRandomSpi.engineSetSeed(seed); + } + } else { + try { + SecureRandom random = SecureRandom.getInstance(prng); + this.secureRandomSpi = random.getSecureRandomSpi(); + this.provider = random.getProvider(); + if (setSeed) { + this.secureRandomSpi.engineSetSeed(seed); + } + } catch (NoSuchAlgorithmException nsae) { + // never happens, because we made sure the algorithm exists + throw new RuntimeException(nsae); + } + } + // JDK 1.1 based implementations subclass SecureRandom instead of + // SecureRandomSpi. They will also go through this code path because + // they must call a SecureRandom constructor as it is their superclass. + // If we are dealing with such an implementation, do not set the + // algorithm value as it would be inaccurate. + if (getClass() == SecureRandom.class) { + this.algorithm = prng; + } + } + + /** + * Creates a SecureRandom object. + * + * @param secureRandomSpi the SecureRandom implementation. + * @param provider the provider. + */ + protected SecureRandom(SecureRandomSpi secureRandomSpi, + Provider provider) { + this(secureRandomSpi, provider, null); + } + + private SecureRandom(SecureRandomSpi secureRandomSpi, Provider provider, + String algorithm) { + super(0); + this.secureRandomSpi = secureRandomSpi; + this.provider = provider; + this.algorithm = algorithm; + + if (!skipDebug && pdebug != null) { + pdebug.println("SecureRandom." + algorithm + + " algorithm from: " + this.provider.getName()); + } + } + + /** + * Returns a SecureRandom object that implements the specified + * Random Number Generator (RNG) algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new SecureRandom object encapsulating the + * SecureRandomSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

The returned SecureRandom object has not been seeded. To seed the + * returned object, call the {@code setSeed} method. + * If {@code setSeed} is not called, the first call to + * {@code nextBytes} will force the SecureRandom object to seed itself. + * This self-seeding will not occur if {@code setSeed} was + * previously called. + * + * @param algorithm the name of the RNG algorithm. + * See the SecureRandom section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard RNG algorithm names. + * + * @return the new SecureRandom object. + * + * @exception NoSuchAlgorithmException if no Provider supports a + * SecureRandomSpi implementation for the + * specified algorithm. + * + * @see Provider + * + * @since 1.2 + */ + public static SecureRandom getInstance(String algorithm) + throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("SecureRandom", + SecureRandomSpi.class, algorithm); + return new SecureRandom((SecureRandomSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns a SecureRandom object that implements the specified + * Random Number Generator (RNG) algorithm. + * + *

A new SecureRandom object encapsulating the + * SecureRandomSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

The returned SecureRandom object has not been seeded. To seed the + * returned object, call the {@code setSeed} method. + * If {@code setSeed} is not called, the first call to + * {@code nextBytes} will force the SecureRandom object to seed itself. + * This self-seeding will not occur if {@code setSeed} was + * previously called. + * + * @param algorithm the name of the RNG algorithm. + * See the SecureRandom section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard RNG algorithm names. + * + * @param provider the name of the provider. + * + * @return the new SecureRandom object. + * + * @exception NoSuchAlgorithmException if a SecureRandomSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + * + * @since 1.2 + */ + public static SecureRandom getInstance(String algorithm, String provider) + throws NoSuchAlgorithmException, NoSuchProviderException { + Instance instance = GetInstance.getInstance("SecureRandom", + SecureRandomSpi.class, algorithm, provider); + return new SecureRandom((SecureRandomSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns a SecureRandom object that implements the specified + * Random Number Generator (RNG) algorithm. + * + *

A new SecureRandom object encapsulating the + * SecureRandomSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + *

The returned SecureRandom object has not been seeded. To seed the + * returned object, call the {@code setSeed} method. + * If {@code setSeed} is not called, the first call to + * {@code nextBytes} will force the SecureRandom object to seed itself. + * This self-seeding will not occur if {@code setSeed} was + * previously called. + * + * @param algorithm the name of the RNG algorithm. + * See the SecureRandom section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard RNG algorithm names. + * + * @param provider the provider. + * + * @return the new SecureRandom object. + * + * @exception NoSuchAlgorithmException if a SecureRandomSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the specified provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static SecureRandom getInstance(String algorithm, + Provider provider) throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("SecureRandom", + SecureRandomSpi.class, algorithm, provider); + return new SecureRandom((SecureRandomSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns the SecureRandomSpi of this SecureRandom object. + */ + SecureRandomSpi getSecureRandomSpi() { + return secureRandomSpi; + } + + /** + * Returns the provider of this SecureRandom object. + * + * @return the provider of this SecureRandom object. + */ + public final Provider getProvider() { + return provider; + } + + /** + * Returns the name of the algorithm implemented by this SecureRandom + * object. + * + * @return the name of the algorithm or {@code unknown} + * if the algorithm name cannot be determined. + * @since 1.5 + */ + public String getAlgorithm() { + return (algorithm != null) ? algorithm : "unknown"; + } + + /** + * Reseeds this random object. The given seed supplements, rather than + * replaces, the existing seed. Thus, repeated calls are guaranteed + * never to reduce randomness. + * + * @param seed the seed. + * + * @see #getSeed + */ + synchronized public void setSeed(byte[] seed) { + secureRandomSpi.engineSetSeed(seed); + } + + /** + * Reseeds this random object, using the eight bytes contained + * in the given {@code long seed}. The given seed supplements, + * rather than replaces, the existing seed. Thus, repeated calls + * are guaranteed never to reduce randomness. + * + *

This method is defined for compatibility with + * {@code java.util.Random}. + * + * @param seed the seed. + * + * @see #getSeed + */ + @Override + public void setSeed(long seed) { + /* + * Ignore call from super constructor (as well as any other calls + * unfortunate enough to be passing 0). It's critical that we + * ignore call from superclass constructor, as digest has not + * yet been initialized at that point. + */ + if (seed != 0) { + secureRandomSpi.engineSetSeed(longToByteArray(seed)); + } + } + + /** + * Generates a user-specified number of random bytes. + * + *

If a call to {@code setSeed} had not occurred previously, + * the first call to this method forces this SecureRandom object + * to seed itself. This self-seeding will not occur if + * {@code setSeed} was previously called. + * + * @param bytes the array to be filled in with random bytes. + */ + @Override + synchronized public void nextBytes(byte[] bytes) { + secureRandomSpi.engineNextBytes(bytes); + } + + /** + * Generates an integer containing the user-specified number of + * pseudo-random bits (right justified, with leading zeros). This + * method overrides a {@code java.util.Random} method, and serves + * to provide a source of random bits to all of the methods inherited + * from that class (for example, {@code nextInt}, + * {@code nextLong}, and {@code nextFloat}). + * + * @param numBits number of pseudo-random bits to be generated, where + * {@code 0 <= numBits <= 32}. + * + * @return an {@code int} containing the user-specified number + * of pseudo-random bits (right justified, with leading zeros). + */ + @Override + final protected int next(int numBits) { + int numBytes = (numBits+7)/8; + byte b[] = new byte[numBytes]; + int next = 0; + + nextBytes(b); + for (int i = 0; i < numBytes; i++) { + next = (next << 8) + (b[i] & 0xFF); + } + + return next >>> (numBytes*8 - numBits); + } + + /** + * Returns the given number of seed bytes, computed using the seed + * generation algorithm that this class uses to seed itself. This + * call may be used to seed other random number generators. + * + *

This method is only included for backwards compatibility. + * The caller is encouraged to use one of the alternative + * {@code getInstance} methods to obtain a SecureRandom object, and + * then call the {@code generateSeed} method to obtain seed bytes + * from that object. + * + * @param numBytes the number of seed bytes to generate. + * + * @return the seed bytes. + * + * @see #setSeed + */ + public static byte[] getSeed(int numBytes) { + if (seedGenerator == null) { + seedGenerator = new SecureRandom(); + } + return seedGenerator.generateSeed(numBytes); + } + + /** + * Returns the given number of seed bytes, computed using the seed + * generation algorithm that this class uses to seed itself. This + * call may be used to seed other random number generators. + * + * @param numBytes the number of seed bytes to generate. + * + * @return the seed bytes. + */ + public byte[] generateSeed(int numBytes) { + return secureRandomSpi.engineGenerateSeed(numBytes); + } + + /** + * Helper function to convert a long into a byte array (least significant + * byte first). + */ + private static byte[] longToByteArray(long l) { + byte[] retVal = new byte[8]; + + for (int i = 0; i < 8; i++) { + retVal[i] = (byte) l; + l >>= 8; + } + + return retVal; + } + + /** + * Gets a default PRNG algorithm by looking through all registered + * providers. Returns the first PRNG algorithm of the first provider that + * has registered a SecureRandom implementation, or null if none of the + * registered providers supplies a SecureRandom implementation. + */ + private static String getPrngAlgorithm() { + for (Provider p : Providers.getProviderList().providers()) { + for (Service s : p.getServices()) { + if (s.getType().equals("SecureRandom")) { + return s.getAlgorithm(); + } + } + } + return null; + } + + /* + * Lazily initialize since Pattern.compile() is heavy. + * Effective Java (2nd Edition), Item 71. + */ + private static final class StrongPatternHolder { + /* + * Entries are alg:prov separated by , + * Allow for prepended/appended whitespace between entries. + * + * Capture groups: + * 1 - alg + * 2 - :prov (optional) + * 3 - prov (optional) + * 4 - ,nextEntry (optional) + * 5 - nextEntry (optional) + */ + private static Pattern pattern = + Pattern.compile( + "\\s*([\\S&&[^:,]]*)(\\:([\\S&&[^,]]*))?\\s*(\\,(.*))?"); + } + + /** + * Returns a {@code SecureRandom} object that was selected by using + * the algorithms/providers specified in the {@code + * securerandom.strongAlgorithms} {@link Security} property. + *

+ * Some situations require strong random values, such as when + * creating high-value/long-lived secrets like RSA public/private + * keys. To help guide applications in selecting a suitable strong + * {@code SecureRandom} implementation, Java distributions + * include a list of known strong {@code SecureRandom} + * implementations in the {@code securerandom.strongAlgorithms} + * Security property. + *

+ * Every implementation of the Java platform is required to + * support at least one strong {@code SecureRandom} implementation. + * + * @return a strong {@code SecureRandom} implementation as indicated + * by the {@code securerandom.strongAlgorithms} Security property + * + * @throws NoSuchAlgorithmException if no algorithm is available + * + * @see Security#getProperty(String) + * + * @since 1.8 + */ + public static SecureRandom getInstanceStrong() + throws NoSuchAlgorithmException { + + String property = AccessController.doPrivileged( + new PrivilegedAction() { + @Override + public String run() { + return Security.getProperty( + "securerandom.strongAlgorithms"); + } + }); + + if ((property == null) || (property.length() == 0)) { + throw new NoSuchAlgorithmException( + "Null/empty securerandom.strongAlgorithms Security Property"); + } + + String remainder = property; + while (remainder != null) { + Matcher m; + if ((m = StrongPatternHolder.pattern.matcher( + remainder)).matches()) { + + String alg = m.group(1); + String prov = m.group(3); + + try { + if (prov == null) { + return SecureRandom.getInstance(alg); + } else { + return SecureRandom.getInstance(alg, prov); + } + } catch (NoSuchAlgorithmException | + NoSuchProviderException e) { + } + remainder = m.group(5); + } else { + remainder = null; + } + } + + throw new NoSuchAlgorithmException( + "No strong SecureRandom impls available: " + property); + } + + // Declare serialVersionUID to be compatible with JDK1.1 + static final long serialVersionUID = 4940670005562187L; + + // Retain unused values serialized from JDK1.1 + /** + * @serial + */ + private byte[] state; + /** + * @serial + */ + private MessageDigest digest = null; + /** + * @serial + * + * We know that the MessageDigest class does not implement + * java.io.Serializable. However, since this field is no longer + * used, it will always be NULL and won't affect the serialization + * of the SecureRandom class itself. + */ + private byte[] randomBytes; + /** + * @serial + */ + private int randomBytesUsed; + /** + * @serial + */ + private long counter; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/SecureRandomSpi.java b/sources/net.sf.j2s.java.core/src/java/security/SecureRandomSpi.java new file mode 100644 index 000000000..ef6c24336 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/SecureRandomSpi.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1998, 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 java.security; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code SecureRandom} class. + * All the abstract methods in this class must be implemented by each + * service provider who wishes to supply the implementation + * of a cryptographically strong pseudo-random number generator. + * + * + * @see SecureRandom + * @since 1.2 + */ + +public abstract class SecureRandomSpi implements java.io.Serializable { + + private static final long serialVersionUID = -2991854161009191830L; + + /** + * Reseeds this random object. The given seed supplements, rather than + * replaces, the existing seed. Thus, repeated calls are guaranteed + * never to reduce randomness. + * + * @param seed the seed. + */ + protected abstract void engineSetSeed(byte[] seed); + + /** + * Generates a user-specified number of random bytes. + * + *

If a call to {@code engineSetSeed} had not occurred previously, + * the first call to this method forces this SecureRandom implementation + * to seed itself. This self-seeding will not occur if + * {@code engineSetSeed} was previously called. + * + * @param bytes the array to be filled in with random bytes. + */ + protected abstract void engineNextBytes(byte[] bytes); + + /** + * Returns the given number of seed bytes. This call may be used to + * seed other random number generators. + * + * @param numBytes the number of seed bytes to generate. + * + * @return the seed bytes. + */ + protected abstract byte[] engineGenerateSeed(int numBytes); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Security.java b/sources/net.sf.j2s.java.core/src/java/security/Security.java new file mode 100644 index 000000000..0db09da70 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Security.java @@ -0,0 +1,1126 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.io.*; +import java.net.URL; +import sun.security.util.Debug; +import sun.security.util.PropertyExpander; + +import sun.security.jca.*; + +/** + *

This class centralizes all security properties and common security + * methods. One of its primary uses is to manage providers. + * + *

The default values of security properties are read from an + * implementation-specific location, which is typically the properties file + * {@code lib/security/java.security} in the Java installation directory. + * + * @author Benjamin Renaud + */ + +public final class Security { + + /* Are we debugging? -- for developers */ + private static final Debug sdebug = + Debug.getInstance("properties"); + + /* The java.security properties */ + private static Properties props; + + // An element in the cache + private static class ProviderProperty { + String className; + Provider provider; + } + + static { + // doPrivileged here because there are multiple + // things in initialize that might require privs. + // (the FileInputStream call and the File.exists call, + // the securityPropFile call, etc) + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + initialize(); + return null; + } + }); + } + + private static void initialize() { + props = new Properties(); + boolean loadedProps = false; + boolean overrideAll = false; + + // first load the system properties file + // to determine the value of security.overridePropertiesFile + File propFile = securityPropFile("java.security"); + if (propFile.exists()) { + InputStream is = null; + try { + FileInputStream fis = new FileInputStream(propFile); + is = new BufferedInputStream(fis); + props.load(is); + loadedProps = true; + + if (sdebug != null) { + sdebug.println("reading security properties file: " + + propFile); + } + } catch (IOException e) { + if (sdebug != null) { + sdebug.println("unable to load security properties from " + + propFile); + e.printStackTrace(); + } + } finally { + if (is != null) { + try { + is.close(); + } catch (IOException ioe) { + if (sdebug != null) { + sdebug.println("unable to close input stream"); + } + } + } + } + } + + if ("true".equalsIgnoreCase(props.getProperty + ("security.overridePropertiesFile"))) { + + String extraPropFile = System.getProperty + ("java.security.properties"); + if (extraPropFile != null && extraPropFile.startsWith("=")) { + overrideAll = true; + extraPropFile = extraPropFile.substring(1); + } + + if (overrideAll) { + props = new Properties(); + if (sdebug != null) { + sdebug.println + ("overriding other security properties files!"); + } + } + + // now load the user-specified file so its values + // will win if they conflict with the earlier values + if (extraPropFile != null) { + BufferedInputStream bis = null; + try { + URL propURL; + + extraPropFile = PropertyExpander.expand(extraPropFile); + propFile = new File(extraPropFile); + if (propFile.exists()) { + propURL = new URL + ("file:" + propFile.getCanonicalPath()); + } else { + propURL = new URL(extraPropFile); + } + bis = new BufferedInputStream(propURL.openStream()); + props.load(bis); + loadedProps = true; + + if (sdebug != null) { + sdebug.println("reading security properties file: " + + propURL); + if (overrideAll) { + sdebug.println + ("overriding other security properties files!"); + } + } + } catch (Exception e) { + if (sdebug != null) { + sdebug.println + ("unable to load security properties from " + + extraPropFile); + e.printStackTrace(); + } + } finally { + if (bis != null) { + try { + bis.close(); + } catch (IOException ioe) { + if (sdebug != null) { + sdebug.println("unable to close input stream"); + } + } + } + } + } + } + + if (!loadedProps) { + initializeStatic(); + if (sdebug != null) { + sdebug.println("unable to load security properties " + + "-- using defaults"); + } + } + + } + + /* + * Initialize to default values, if /lib/java.security + * is not found. + */ + private static void initializeStatic() { + props.put("security.provider.1", "sun.security.provider.Sun"); + props.put("security.provider.2", "sun.security.rsa.SunRsaSign"); + props.put("security.provider.3", "com.sun.net.ssl.internal.ssl.Provider"); + props.put("security.provider.4", "com.sun.crypto.provider.SunJCE"); + props.put("security.provider.5", "sun.security.jgss.SunProvider"); + props.put("security.provider.6", "com.sun.security.sasl.Provider"); + } + + /** + * Don't let anyone instantiate this. + */ + private Security() { + } + + private static File securityPropFile(String filename) { + // maybe check for a system property which will specify where to + // look. Someday. + String sep = File.separator; + return new File(System.getProperty("java.home") + sep + "lib" + sep + + "security" + sep + filename); + } + + /** + * Looks up providers, and returns the property (and its associated + * provider) mapping the key, if any. + * The order in which the providers are looked up is the + * provider-preference order, as specificed in the security + * properties file. + */ + private static ProviderProperty getProviderProperty(String key) { + ProviderProperty entry = null; + + List providers = Providers.getProviderList().providers(); + for (int i = 0; i < providers.size(); i++) { + + String matchKey = null; + Provider prov = providers.get(i); + String prop = prov.getProperty(key); + + if (prop == null) { + // Is there a match if we do a case-insensitive property name + // comparison? Let's try ... + for (Enumeration e = prov.keys(); + e.hasMoreElements() && prop == null; ) { + matchKey = (String)e.nextElement(); + if (key.equalsIgnoreCase(matchKey)) { + prop = prov.getProperty(matchKey); + break; + } + } + } + + if (prop != null) { + ProviderProperty newEntry = new ProviderProperty(); + newEntry.className = prop; + newEntry.provider = prov; + return newEntry; + } + } + + return entry; + } + + /** + * Returns the property (if any) mapping the key for the given provider. + */ + private static String getProviderProperty(String key, Provider provider) { + String prop = provider.getProperty(key); + if (prop == null) { + // Is there a match if we do a case-insensitive property name + // comparison? Let's try ... + for (Enumeration e = provider.keys(); + e.hasMoreElements() && prop == null; ) { + String matchKey = (String)e.nextElement(); + if (key.equalsIgnoreCase(matchKey)) { + prop = provider.getProperty(matchKey); + break; + } + } + } + return prop; + } + + /** + * Gets a specified property for an algorithm. The algorithm name + * should be a standard name. See the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * One possible use is by specialized algorithm parsers, which may map + * classes to algorithms which they understand (much like Key parsers + * do). + * + * @param algName the algorithm name. + * + * @param propName the name of the property to get. + * + * @return the value of the specified property. + * + * @deprecated This method used to return the value of a proprietary + * property in the master file of the "SUN" Cryptographic Service + * Provider in order to determine how to parse algorithm-specific + * parameters. Use the new provider-based and algorithm-independent + * {@code AlgorithmParameters} and {@code KeyFactory} engine + * classes (introduced in the J2SE version 1.2 platform) instead. + */ + @Deprecated + public static String getAlgorithmProperty(String algName, + String propName) { + ProviderProperty entry = getProviderProperty("Alg." + propName + + "." + algName); + if (entry != null) { + return entry.className; + } else { + return null; + } + } + + /** + * Adds a new provider, at a specified position. The position is + * the preference order in which providers are searched for + * requested algorithms. The position is 1-based, that is, + * 1 is most preferred, followed by 2, and so on. + * + *

If the given provider is installed at the requested position, + * the provider that used to be at that position, and all providers + * with a position greater than {@code position}, are shifted up + * one position (towards the end of the list of installed providers). + * + *

A provider cannot be added if it is already installed. + * + *

If there is a security manager, the + * {@link java.lang.SecurityManager#checkSecurityAccess} method is called + * with the {@code "insertProvider"} permission target name to see if + * it's ok to add a new provider. If this permission check is denied, + * {@code checkSecurityAccess} is called again with the + * {@code "insertProvider."+provider.getName()} permission target name. If + * both checks are denied, a {@code SecurityException} is thrown. + * + * @param provider the provider to be added. + * + * @param position the preference position that the caller would + * like for this provider. + * + * @return the actual preference position in which the provider was + * added, or -1 if the provider was not added because it is + * already installed. + * + * @throws NullPointerException if provider is null + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to add a new provider + * + * @see #getProvider + * @see #removeProvider + * @see java.security.SecurityPermission + */ + public static synchronized int insertProviderAt(Provider provider, + int position) { + String providerName = provider.getName(); + checkInsertProvider(providerName); + ProviderList list = Providers.getFullProviderList(); + ProviderList newList = ProviderList.insertAt(list, provider, position - 1); + if (list == newList) { + return -1; + } + Providers.setProviderList(newList); + return newList.getIndex(providerName) + 1; + } + + /** + * Adds a provider to the next position available. + * + *

If there is a security manager, the + * {@link java.lang.SecurityManager#checkSecurityAccess} method is called + * with the {@code "insertProvider"} permission target name to see if + * it's ok to add a new provider. If this permission check is denied, + * {@code checkSecurityAccess} is called again with the + * {@code "insertProvider."+provider.getName()} permission target name. If + * both checks are denied, a {@code SecurityException} is thrown. + * + * @param provider the provider to be added. + * + * @return the preference position in which the provider was + * added, or -1 if the provider was not added because it is + * already installed. + * + * @throws NullPointerException if provider is null + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies access to add a new provider + * + * @see #getProvider + * @see #removeProvider + * @see java.security.SecurityPermission + */ + public static int addProvider(Provider provider) { + /* + * We can't assign a position here because the statically + * registered providers may not have been installed yet. + * insertProviderAt() will fix that value after it has + * loaded the static providers. + */ + return insertProviderAt(provider, 0); + } + + /** + * Removes the provider with the specified name. + * + *

When the specified provider is removed, all providers located + * at a position greater than where the specified provider was are shifted + * down one position (towards the head of the list of installed + * providers). + * + *

This method returns silently if the provider is not installed or + * if name is null. + * + *

First, if there is a security manager, its + * {@code checkSecurityAccess} + * method is called with the string {@code "removeProvider."+name} + * to see if it's ok to remove the provider. + * If the default implementation of {@code checkSecurityAccess} + * is used (i.e., that method is not overriden), then this will result in + * a call to the security manager's {@code checkPermission} method + * with a {@code SecurityPermission("removeProvider."+name)} + * permission. + * + * @param name the name of the provider to remove. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkSecurityAccess} method + * denies + * access to remove the provider + * + * @see #getProvider + * @see #addProvider + */ + public static synchronized void removeProvider(String name) { + check("removeProvider." + name); + ProviderList list = Providers.getFullProviderList(); + ProviderList newList = ProviderList.remove(list, name); + Providers.setProviderList(newList); + } + + /** + * Returns an array containing all the installed providers. The order of + * the providers in the array is their preference order. + * + * @return an array of all the installed providers. + */ + public static Provider[] getProviders() { + return Providers.getFullProviderList().toArray(); + } + + /** + * Returns the provider installed with the specified name, if + * any. Returns null if no provider with the specified name is + * installed or if name is null. + * + * @param name the name of the provider to get. + * + * @return the provider of the specified name. + * + * @see #removeProvider + * @see #addProvider + */ + public static Provider getProvider(String name) { + return Providers.getProviderList().getProvider(name); + } + + /** + * Returns an array containing all installed providers that satisfy the + * specified selection criterion, or null if no such providers have been + * installed. The returned providers are ordered + * according to their + * {@linkplain #insertProviderAt(java.security.Provider, int) preference order}. + * + *

A cryptographic service is always associated with a particular + * algorithm or type. For example, a digital signature service is + * always associated with a particular algorithm (e.g., DSA), + * and a CertificateFactory service is always associated with + * a particular certificate type (e.g., X.509). + * + *

The selection criterion must be specified in one of the following two + * formats: + *

    + *
  • {@literal .} + *

    The cryptographic service name must not contain any dots. + *

    A + * provider satisfies the specified selection criterion iff the provider + * implements the + * specified algorithm or type for the specified cryptographic service. + *

    For example, "CertificateFactory.X.509" + * would be satisfied by any provider that supplied + * a CertificateFactory implementation for X.509 certificates. + *

  • {@literal . + * :} + *

    The cryptographic service name must not contain any dots. There + * must be one or more space characters between the + * {@literal } and the + * {@literal }. + *

    A provider satisfies this selection criterion iff the + * provider implements the specified algorithm or type for the specified + * cryptographic service and its implementation meets the + * constraint expressed by the specified attribute name/value pair. + *

    For example, "Signature.SHA1withDSA KeySize:1024" would be + * satisfied by any provider that implemented + * the SHA1withDSA signature algorithm with a keysize of 1024 (or larger). + * + *

+ * + *

See the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard cryptographic service names, standard + * algorithm names and standard attribute names. + * + * @param filter the criterion for selecting + * providers. The filter is case-insensitive. + * + * @return all the installed providers that satisfy the selection + * criterion, or null if no such providers have been installed. + * + * @throws InvalidParameterException + * if the filter is not in the required format + * @throws NullPointerException if filter is null + * + * @see #getProviders(java.util.Map) + * @since 1.3 + */ + public static Provider[] getProviders(String filter) { + String key = null; + String value = null; + int index = filter.indexOf(':'); + + if (index == -1) { + key = filter; + value = ""; + } else { + key = filter.substring(0, index); + value = filter.substring(index + 1); + } + + Hashtable hashtableFilter = new Hashtable<>(1); + hashtableFilter.put(key, value); + + return (getProviders(hashtableFilter)); + } + + /** + * Returns an array containing all installed providers that satisfy the + * specified* selection criteria, or null if no such providers have been + * installed. The returned providers are ordered + * according to their + * {@linkplain #insertProviderAt(java.security.Provider, int) + * preference order}. + * + *

The selection criteria are represented by a map. + * Each map entry represents a selection criterion. + * A provider is selected iff it satisfies all selection + * criteria. The key for any entry in such a map must be in one of the + * following two formats: + *

    + *
  • {@literal .} + *

    The cryptographic service name must not contain any dots. + *

    The value associated with the key must be an empty string. + *

    A provider + * satisfies this selection criterion iff the provider implements the + * specified algorithm or type for the specified cryptographic service. + *

  • {@literal }. + * {@literal } + *

    The cryptographic service name must not contain any dots. There + * must be one or more space characters between the + * {@literal } + * and the {@literal }. + *

    The value associated with the key must be a non-empty string. + * A provider satisfies this selection criterion iff the + * provider implements the specified algorithm or type for the specified + * cryptographic service and its implementation meets the + * constraint expressed by the specified attribute name/value pair. + *

+ * + *

See the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard cryptographic service names, standard + * algorithm names and standard attribute names. + * + * @param filter the criteria for selecting + * providers. The filter is case-insensitive. + * + * @return all the installed providers that satisfy the selection + * criteria, or null if no such providers have been installed. + * + * @throws InvalidParameterException + * if the filter is not in the required format + * @throws NullPointerException if filter is null + * + * @see #getProviders(java.lang.String) + * @since 1.3 + */ + public static Provider[] getProviders(Map filter) { + // Get all installed providers first. + // Then only return those providers who satisfy the selection criteria. + Provider[] allProviders = Security.getProviders(); + Set keySet = filter.keySet(); + LinkedHashSet candidates = new LinkedHashSet<>(5); + + // Returns all installed providers + // if the selection criteria is null. + if ((keySet == null) || (allProviders == null)) { + return allProviders; + } + + boolean firstSearch = true; + + // For each selection criterion, remove providers + // which don't satisfy the criterion from the candidate set. + for (Iterator ite = keySet.iterator(); ite.hasNext(); ) { + String key = ite.next(); + String value = filter.get(key); + + LinkedHashSet newCandidates = getAllQualifyingCandidates(key, value, + allProviders); + if (firstSearch) { + candidates = newCandidates; + firstSearch = false; + } + + if ((newCandidates != null) && !newCandidates.isEmpty()) { + // For each provider in the candidates set, if it + // isn't in the newCandidate set, we should remove + // it from the candidate set. + for (Iterator cansIte = candidates.iterator(); + cansIte.hasNext(); ) { + Provider prov = cansIte.next(); + if (!newCandidates.contains(prov)) { + cansIte.remove(); + } + } + } else { + candidates = null; + break; + } + } + + if ((candidates == null) || (candidates.isEmpty())) + return null; + + Object[] candidatesArray = candidates.toArray(); + Provider[] result = new Provider[candidatesArray.length]; + + for (int i = 0; i < result.length; i++) { + result[i] = (Provider)candidatesArray[i]; + } + + return result; + } + + // Map containing cached Spi Class objects of the specified type + private static final Map> spiMap = + new ConcurrentHashMap<>(); + + /** + * Return the Class object for the given engine type + * (e.g. "MessageDigest"). Works for Spis in the java.security package + * only. + */ + private static Class getSpiClass(String type) { + Class clazz = spiMap.get(type); + if (clazz != null) { + return clazz; + } + try { + clazz = Class.forName("java.security." + type + "Spi"); + spiMap.put(type, clazz); + return clazz; + } catch (ClassNotFoundException e) { + throw new AssertionError("Spi class not found", e); + } + } + + /* + * Returns an array of objects: the first object in the array is + * an instance of an implementation of the requested algorithm + * and type, and the second object in the array identifies the provider + * of that implementation. + * The {@code provider} argument can be null, in which case all + * configured providers will be searched in order of preference. + */ + static Object[] getImpl(String algorithm, String type, String provider) + throws NoSuchAlgorithmException, NoSuchProviderException { + if (provider == null) { + return GetInstance.getInstance + (type, getSpiClass(type), algorithm).toArray(); + } else { + return GetInstance.getInstance + (type, getSpiClass(type), algorithm, provider).toArray(); + } + } + + static Object[] getImpl(String algorithm, String type, String provider, + Object params) throws NoSuchAlgorithmException, + NoSuchProviderException, InvalidAlgorithmParameterException { + if (provider == null) { + return GetInstance.getInstance + (type, getSpiClass(type), algorithm, params).toArray(); + } else { + return GetInstance.getInstance + (type, getSpiClass(type), algorithm, params, provider).toArray(); + } + } + + /* + * Returns an array of objects: the first object in the array is + * an instance of an implementation of the requested algorithm + * and type, and the second object in the array identifies the provider + * of that implementation. + * The {@code provider} argument cannot be null. + */ + static Object[] getImpl(String algorithm, String type, Provider provider) + throws NoSuchAlgorithmException { + return GetInstance.getInstance + (type, getSpiClass(type), algorithm, provider).toArray(); + } + + static Object[] getImpl(String algorithm, String type, Provider provider, + Object params) throws NoSuchAlgorithmException, + InvalidAlgorithmParameterException { + return GetInstance.getInstance + (type, getSpiClass(type), algorithm, params, provider).toArray(); + } + + /** + * Gets a security property value. + * + *

First, if there is a security manager, its + * {@code checkPermission} method is called with a + * {@code java.security.SecurityPermission("getProperty."+key)} + * permission to see if it's ok to retrieve the specified + * security property value.. + * + * @param key the key of the property being retrieved. + * + * @return the value of the security property corresponding to key. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkPermission} method + * denies + * access to retrieve the specified security property value + * @throws NullPointerException is key is null + * + * @see #setProperty + * @see java.security.SecurityPermission + */ + public static String getProperty(String key) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new SecurityPermission("getProperty."+ + key)); + } + String name = props.getProperty(key); + if (name != null) + name = name.trim(); // could be a class name with trailing ws + return name; + } + + /** + * Sets a security property value. + * + *

First, if there is a security manager, its + * {@code checkPermission} method is called with a + * {@code java.security.SecurityPermission("setProperty."+key)} + * permission to see if it's ok to set the specified + * security property value. + * + * @param key the name of the property to be set. + * + * @param datum the value of the property to be set. + * + * @throws SecurityException + * if a security manager exists and its {@link + * java.lang.SecurityManager#checkPermission} method + * denies access to set the specified security property value + * @throws NullPointerException if key or datum is null + * + * @see #getProperty + * @see java.security.SecurityPermission + */ + public static void setProperty(String key, String datum) { + check("setProperty."+key); + props.put(key, datum); + invalidateSMCache(key); /* See below. */ + } + + /* + * Implementation detail: If the property we just set in + * setProperty() was either "package.access" or + * "package.definition", we need to signal to the SecurityManager + * class that the value has just changed, and that it should + * invalidate it's local cache values. + * + * Rather than create a new API entry for this function, + * we use reflection to set a private variable. + */ + private static void invalidateSMCache(String key) { + + final boolean pa = key.equals("package.access"); + final boolean pd = key.equals("package.definition"); + + if (pa || pd) { + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + try { + /* Get the class via the bootstrap class loader. */ + Class cl = Class.forName( + "java.lang.SecurityManager", false, null); + Field f = null; + boolean accessible = false; + + if (pa) { + f = cl.getDeclaredField("packageAccessValid"); + accessible = f.isAccessible(); + f.setAccessible(true); + } else { + f = cl.getDeclaredField("packageDefinitionValid"); + accessible = f.isAccessible(); + f.setAccessible(true); + } + f.setBoolean(f, false); + f.setAccessible(accessible); + } + catch (Exception e1) { + /* If we couldn't get the class, it hasn't + * been loaded yet. If there is no such + * field, we shouldn't try to set it. There + * shouldn't be a security execption, as we + * are loaded by boot class loader, and we + * are inside a doPrivileged() here. + * + * NOOP: don't do anything... + */ + } + return null; + } /* run */ + }); /* PrivilegedAction */ + } /* if */ + } + + private static void check(String directive) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkSecurityAccess(directive); + } + } + + private static void checkInsertProvider(String name) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + try { + security.checkSecurityAccess("insertProvider"); + } catch (SecurityException se1) { + try { + security.checkSecurityAccess("insertProvider." + name); + } catch (SecurityException se2) { + // throw first exception, but add second to suppressed + se1.addSuppressed(se2); + throw se1; + } + } + } + } + + /* + * Returns all providers who satisfy the specified + * criterion. + */ + private static LinkedHashSet getAllQualifyingCandidates( + String filterKey, + String filterValue, + Provider[] allProviders) { + String[] filterComponents = getFilterComponents(filterKey, + filterValue); + + // The first component is the service name. + // The second is the algorithm name. + // If the third isn't null, that is the attrinute name. + String serviceName = filterComponents[0]; + String algName = filterComponents[1]; + String attrName = filterComponents[2]; + + return getProvidersNotUsingCache(serviceName, algName, attrName, + filterValue, allProviders); + } + + private static LinkedHashSet getProvidersNotUsingCache( + String serviceName, + String algName, + String attrName, + String filterValue, + Provider[] allProviders) { + LinkedHashSet candidates = new LinkedHashSet<>(5); + for (int i = 0; i < allProviders.length; i++) { + if (isCriterionSatisfied(allProviders[i], serviceName, + algName, + attrName, filterValue)) { + candidates.add(allProviders[i]); + } + } + return candidates; + } + + /* + * Returns true if the given provider satisfies + * the selection criterion key:value. + */ + private static boolean isCriterionSatisfied(Provider prov, + String serviceName, + String algName, + String attrName, + String filterValue) { + String key = serviceName + '.' + algName; + + if (attrName != null) { + key += ' ' + attrName; + } + // Check whether the provider has a property + // whose key is the same as the given key. + String propValue = getProviderProperty(key, prov); + + if (propValue == null) { + // Check whether we have an alias instead + // of a standard name in the key. + String standardName = getProviderProperty("Alg.Alias." + + serviceName + "." + + algName, + prov); + if (standardName != null) { + key = serviceName + "." + standardName; + + if (attrName != null) { + key += ' ' + attrName; + } + + propValue = getProviderProperty(key, prov); + } + + if (propValue == null) { + // The provider doesn't have the given + // key in its property list. + return false; + } + } + + // If the key is in the format of: + // ., + // there is no need to check the value. + + if (attrName == null) { + return true; + } + + // If we get here, the key must be in the + // format of . . + if (isStandardAttr(attrName)) { + return isConstraintSatisfied(attrName, filterValue, propValue); + } else { + return filterValue.equalsIgnoreCase(propValue); + } + } + + /* + * Returns true if the attribute is a standard attribute; + * otherwise, returns false. + */ + private static boolean isStandardAttr(String attribute) { + // For now, we just have two standard attributes: + // KeySize and ImplementedIn. + if (attribute.equalsIgnoreCase("KeySize")) + return true; + + if (attribute.equalsIgnoreCase("ImplementedIn")) + return true; + + return false; + } + + /* + * Returns true if the requested attribute value is supported; + * otherwise, returns false. + */ + private static boolean isConstraintSatisfied(String attribute, + String value, + String prop) { + // For KeySize, prop is the max key size the + // provider supports for a specific .. + if (attribute.equalsIgnoreCase("KeySize")) { + int requestedSize = Integer.parseInt(value); + int maxSize = Integer.parseInt(prop); + if (requestedSize <= maxSize) { + return true; + } else { + return false; + } + } + + // For Type, prop is the type of the implementation + // for a specific .. + if (attribute.equalsIgnoreCase("ImplementedIn")) { + return value.equalsIgnoreCase(prop); + } + + return false; + } + + static String[] getFilterComponents(String filterKey, String filterValue) { + int algIndex = filterKey.indexOf('.'); + + if (algIndex < 0) { + // There must be a dot in the filter, and the dot + // shouldn't be at the beginning of this string. + throw new InvalidParameterException("Invalid filter"); + } + + String serviceName = filterKey.substring(0, algIndex); + String algName = null; + String attrName = null; + + if (filterValue.length() == 0) { + // The filterValue is an empty string. So the filterKey + // should be in the format of .. + algName = filterKey.substring(algIndex + 1).trim(); + if (algName.length() == 0) { + // There must be a algorithm or type name. + throw new InvalidParameterException("Invalid filter"); + } + } else { + // The filterValue is a non-empty string. So the filterKey must be + // in the format of + // . + int attrIndex = filterKey.indexOf(' '); + + if (attrIndex == -1) { + // There is no attribute name in the filter. + throw new InvalidParameterException("Invalid filter"); + } else { + attrName = filterKey.substring(attrIndex + 1).trim(); + if (attrName.length() == 0) { + // There is no attribute name in the filter. + throw new InvalidParameterException("Invalid filter"); + } + } + + // There must be an algorithm name in the filter. + if ((attrIndex < algIndex) || + (algIndex == attrIndex - 1)) { + throw new InvalidParameterException("Invalid filter"); + } else { + algName = filterKey.substring(algIndex + 1, attrIndex); + } + } + + String[] result = new String[3]; + result[0] = serviceName; + result[1] = algName; + result[2] = attrName; + + return result; + } + + /** + * Returns a Set of Strings containing the names of all available + * algorithms or types for the specified Java cryptographic service + * (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore). Returns + * an empty Set if there is no provider that supports the + * specified service or if serviceName is null. For a complete list + * of Java cryptographic services, please see the + * Java + * Cryptography Architecture API Specification & Reference. + * Note: the returned set is immutable. + * + * @param serviceName the name of the Java cryptographic + * service (e.g., Signature, MessageDigest, Cipher, Mac, KeyStore). + * Note: this parameter is case-insensitive. + * + * @return a Set of Strings containing the names of all available + * algorithms or types for the specified Java cryptographic service + * or an empty set if no provider supports the specified service. + * + * @since 1.4 + **/ + public static Set getAlgorithms(String serviceName) { + + if ((serviceName == null) || (serviceName.length() == 0) || + (serviceName.endsWith("."))) { + return Collections.emptySet(); + } + + HashSet result = new HashSet<>(); + Provider[] providers = Security.getProviders(); + + for (int i = 0; i < providers.length; i++) { + // Check the keys for each provider. + for (Enumeration e = providers[i].keys(); + e.hasMoreElements(); ) { + String currentKey = + ((String)e.nextElement()).toUpperCase(Locale.ENGLISH); + if (currentKey.startsWith( + serviceName.toUpperCase(Locale.ENGLISH))) { + // We should skip the currentKey if it contains a + // whitespace. The reason is: such an entry in the + // provider property contains attributes for the + // implementation of an algorithm. We are only interested + // in entries which lead to the implementation + // classes. + if (currentKey.indexOf(" ") < 0) { + result.add(currentKey.substring( + serviceName.length() + 1)); + } + } + } + } + return Collections.unmodifiableSet(result); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/SecurityPermission.java b/sources/net.sf.j2s.java.core/src/java/security/SecurityPermission.java new file mode 100644 index 000000000..5bb74569d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/SecurityPermission.java @@ -0,0 +1,348 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.security.*; +import java.util.Enumeration; +import java.util.Hashtable; +import java.util.StringTokenizer; + +/** + * This class is for security permissions. + * A SecurityPermission contains a name (also referred to as a "target name") + * but no actions list; you either have the named permission + * or you don't. + *

+ * The target name is the name of a security configuration parameter (see below). + * Currently the SecurityPermission object is used to guard access + * to the Policy, Security, Provider, Signer, and Identity + * objects. + *

+ * The following table lists all the possible SecurityPermission target names, + * and for each provides a description of what the permission allows + * and a discussion of the risks of granting code the permission. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Permission Target NameWhat the Permission AllowsRisks of Allowing this Permission
createAccessControlContextCreation of an AccessControlContextThis allows someone to instantiate an AccessControlContext + * with a {@code DomainCombiner}. Extreme care must be taken when + * granting this permission. Malicious code could create a DomainCombiner + * that augments the set of permissions granted to code, and even grant the + * code {@link java.security.AllPermission}.
getDomainCombinerRetrieval of an AccessControlContext's DomainCombinerThis allows someone to retrieve an AccessControlContext's + * {@code DomainCombiner}. Since DomainCombiners may contain + * sensitive information, this could potentially lead to a privacy leak.
getPolicyRetrieval of the system-wide security policy (specifically, of the + * currently-installed Policy object)This allows someone to query the policy via the + * {@code getPermissions} call, + * which discloses which permissions would be granted to a given CodeSource. + * While revealing the policy does not compromise the security of + * the system, it does provide malicious code with additional information + * which it may use to better aim an attack. It is wise + * not to divulge more information than necessary.
setPolicySetting of the system-wide security policy (specifically, + * the Policy object)Granting this permission is extremely dangerous, as malicious + * code may grant itself all the necessary permissions it needs + * to successfully mount an attack on the system.
createPolicy.{policy type}Getting an instance of a Policy implementation from a providerGranting this permission enables code to obtain a Policy object. + * Malicious code may query the Policy object to determine what permissions + * have been granted to code other than itself.
getProperty.{key}Retrieval of the security property with the specified keyDepending on the particular key for which access has + * been granted, the code may have access to the list of security + * providers, as well as the location of the system-wide and user + * security policies. while revealing this information does not + * compromise the security of the system, it does provide malicious + * code with additional information which it may use to better aim + * an attack. +
setProperty.{key}Setting of the security property with the specified keyThis could include setting a security provider or defining + * the location of the system-wide security policy. Malicious + * code that has permission to set a new security provider may + * set a rogue provider that steals confidential information such + * as cryptographic private keys. In addition, malicious code with + * permission to set the location of the system-wide security policy + * may point it to a security policy that grants the attacker + * all the necessary permissions it requires to successfully mount + * an attack on the system. +
insertProviderAddition of a new providerThis would allow somebody to introduce a possibly + * malicious provider (e.g., one that discloses the private keys passed + * to it) as the highest-priority provider. This would be possible + * because the Security object (which manages the installed providers) + * currently does not check the integrity or authenticity of a provider + * before attaching it. The "insertProvider" permission subsumes the + * "insertProvider.{provider name}" permission (see the section below for + * more information). + *
removeProvider.{provider name}Removal of the specified providerThis may change the behavior or disable execution of other + * parts of the program. If a provider subsequently requested by the + * program has been removed, execution may fail. Also, if the removed + * provider is not explicitly requested by the rest of the program, but + * it would normally be the provider chosen when a cryptography service + * is requested (due to its previous order in the list of providers), + * a different provider will be chosen instead, or no suitable provider + * will be found, thereby resulting in program failure.
clearProviderProperties.{provider name}"Clearing" of a Provider so that it no longer contains the properties + * used to look up services implemented by the providerThis disables the lookup of services implemented by the provider. + * This may thus change the behavior or disable execution of other + * parts of the program that would normally utilize the Provider, as + * described under the "removeProvider.{provider name}" permission.
putProviderProperty.{provider name}Setting of properties for the specified ProviderThe provider properties each specify the name and location + * of a particular service implemented by the provider. By granting + * this permission, you let code replace the service specification + * with another one, thereby specifying a different implementation.
removeProviderProperty.{provider name}Removal of properties from the specified ProviderThis disables the lookup of services implemented by the + * provider. They are no longer accessible due to removal of the properties + * specifying their names and locations. This + * may change the behavior or disable execution of other + * parts of the program that would normally utilize the Provider, as + * described under the "removeProvider.{provider name}" permission.
+ * + *

+ * The following permissions have been superseded by newer permissions or are + * associated with classes that have been deprecated: {@link Identity}, + * {@link IdentityScope}, {@link Signer}. Use of them is discouraged. See the + * applicable classes for more information. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Permission Target NameWhat the Permission AllowsRisks of Allowing this Permission
insertProvider.{provider name}Addition of a new provider, with the specified nameUse of this permission is discouraged from further use because it is + * possible to circumvent the name restrictions by overriding the + * {@link java.security.Provider#getName} method. Also, there is an equivalent + * level of risk associated with granting code permission to insert a provider + * with a specific name, or any name it chooses. Users should use the + * "insertProvider" permission instead. + *

This would allow somebody to introduce a possibly + * malicious provider (e.g., one that discloses the private keys passed + * to it) as the highest-priority provider. This would be possible + * because the Security object (which manages the installed providers) + * currently does not check the integrity or authenticity of a provider + * before attaching it.

setSystemScopeSetting of the system identity scopeThis would allow an attacker to configure the system identity scope with + * certificates that should not be trusted, thereby granting applet or + * application code signed with those certificates privileges that + * would have been denied by the system's original identity scope.
setIdentityPublicKeySetting of the public key for an IdentityIf the identity is marked as "trusted", this allows an attacker to + * introduce a different public key (e.g., its own) that is not trusted + * by the system's identity scope, thereby granting applet or + * application code signed with that public key privileges that + * would have been denied otherwise.
setIdentityInfoSetting of a general information string for an IdentityThis allows attackers to set the general description for + * an identity. This may trick applications into using a different + * identity than intended or may prevent applications from finding a + * particular identity.
addIdentityCertificateAddition of a certificate for an IdentityThis allows attackers to set a certificate for + * an identity's public key. This is dangerous because it affects + * the trust relationship across the system. This public key suddenly + * becomes trusted to a wider audience than it otherwise would be.
removeIdentityCertificateRemoval of a certificate for an IdentityThis allows attackers to remove a certificate for + * an identity's public key. This is dangerous because it affects + * the trust relationship across the system. This public key suddenly + * becomes considered less trustworthy than it otherwise would be.
printIdentityViewing the name of a principal + * and optionally the scope in which it is used, and whether + * or not it is considered "trusted" in that scopeThe scope that is printed out may be a filename, in which case + * it may convey local system information. For example, here's a sample + * printout of an identity named "carol", who is + * marked not trusted in the user's identity database:
+ * carol[/home/luehe/identitydb.obj][not trusted]
getSignerPrivateKeyRetrieval of a Signer's private keyIt is very dangerous to allow access to a private key; private + * keys are supposed to be kept secret. Otherwise, code can use the + * private key to sign various files and claim the signature came from + * the Signer.
setSignerKeyPairSetting of the key pair (public key and private key) for a SignerThis would allow an attacker to replace somebody else's (the "target's") + * keypair with a possibly weaker keypair (e.g., a keypair of a smaller + * keysize). This also would allow the attacker to listen in on encrypted + * communication between the target and its peers. The target's peers + * might wrap an encryption session key under the target's "new" public + * key, which would allow the attacker (who possesses the corresponding + * private key) to unwrap the session key and decipher the communication + * data encrypted under that session key.
+ * + * @see java.security.BasicPermission + * @see java.security.Permission + * @see java.security.Permissions + * @see java.security.PermissionCollection + * @see java.lang.SecurityManager + * + * + * @author Marianne Mueller + * @author Roland Schemers + */ + +public final class SecurityPermission extends BasicPermission { + + private static final long serialVersionUID = 5236109936224050470L; + + /** + * Creates a new SecurityPermission with the specified name. + * The name is the symbolic name of the SecurityPermission. An asterisk + * may appear at the end of the name, following a ".", or by itself, to + * signify a wildcard match. + * + * @param name the name of the SecurityPermission + * + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. + */ + public SecurityPermission(String name) + { + super(name); + } + + /** + * Creates a new SecurityPermission object with the specified name. + * The name is the symbolic name of the SecurityPermission, and the + * actions String is currently unused and should be null. + * + * @param name the name of the SecurityPermission + * @param actions should be null. + * + * @throws NullPointerException if {@code name} is {@code null}. + * @throws IllegalArgumentException if {@code name} is empty. + */ + public SecurityPermission(String name, String actions) + { + super(name, actions); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Signature.java b/sources/net.sf.j2s.java.core/src/java/security/Signature.java new file mode 100644 index 000000000..dccbe0b9b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Signature.java @@ -0,0 +1,1341 @@ +/* + * Copyright (c) 1996, 2014, 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 java.security; + +import java.security.spec.AlgorithmParameterSpec; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; +import java.io.*; +import java.security.cert.Certificate; +import java.security.cert.X509Certificate; + +import java.nio.ByteBuffer; + +import java.security.Provider.Service; + +import javax.crypto.Cipher; +import javax.crypto.CipherSpi; +import javax.crypto.IllegalBlockSizeException; +import javax.crypto.BadPaddingException; +import javax.crypto.NoSuchPaddingException; + +import sun.security.util.Debug; +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; + +/** + * The Signature class is used to provide applications the functionality + * of a digital signature algorithm. Digital signatures are used for + * authentication and integrity assurance of digital data. + * + *

The signature algorithm can be, among others, the NIST standard + * DSA, using DSA and SHA-1. The DSA algorithm using the + * SHA-1 message digest algorithm can be specified as {@code SHA1withDSA}. + * In the case of RSA, there are multiple choices for the message digest + * algorithm, so the signing algorithm could be specified as, for example, + * {@code MD2withRSA}, {@code MD5withRSA}, or {@code SHA1withRSA}. + * The algorithm name must be specified, as there is no default. + * + *

A Signature object can be used to generate and verify digital + * signatures. + * + *

There are three phases to the use of a Signature object for + * either signing data or verifying a signature:

    + * + *
  1. Initialization, with either + * + *
      + * + *
    • a public key, which initializes the signature for + * verification (see {@link #initVerify(PublicKey) initVerify}), or + * + *
    • a private key (and optionally a Secure Random Number Generator), + * which initializes the signature for signing + * (see {@link #initSign(PrivateKey)} + * and {@link #initSign(PrivateKey, SecureRandom)}). + * + *
    + * + *
  2. Updating + * + *

    Depending on the type of initialization, this will update the + * bytes to be signed or verified. See the + * {@link #update(byte) update} methods. + * + *

  3. Signing or Verifying a signature on all updated bytes. See the + * {@link #sign() sign} methods and the {@link #verify(byte[]) verify} + * method. + * + *
+ * + *

Note that this class is abstract and extends from + * {@code SignatureSpi} for historical reasons. + * Application developers should only take notice of the methods defined in + * this {@code Signature} class; all the methods in + * the superclass are intended for cryptographic service providers who wish to + * supply their own implementations of digital signature algorithms. + * + *

Every implementation of the Java platform is required to support the + * following standard {@code Signature} algorithms: + *

    + *
  • {@code SHA1withDSA}
  • + *
  • {@code SHA1withRSA}
  • + *
  • {@code SHA256withRSA}
  • + *
+ * These algorithms are described in the + * Signature section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + * @author Benjamin Renaud + * + */ + +public abstract class Signature extends SignatureSpi { + + private static final Debug debug = + Debug.getInstance("jca", "Signature"); + + private static final Debug pdebug = + Debug.getInstance("provider", "Provider"); + private static final boolean skipDebug = + Debug.isOn("engine=") && !Debug.isOn("signature"); + + /* + * The algorithm for this signature object. + * This value is used to map an OID to the particular algorithm. + * The mapping is done in AlgorithmObject.algOID(String algorithm) + */ + private String algorithm; + + // The provider + Provider provider; + + /** + * Possible {@link #state} value, signifying that + * this signature object has not yet been initialized. + */ + protected final static int UNINITIALIZED = 0; + + /** + * Possible {@link #state} value, signifying that + * this signature object has been initialized for signing. + */ + protected final static int SIGN = 2; + + /** + * Possible {@link #state} value, signifying that + * this signature object has been initialized for verification. + */ + protected final static int VERIFY = 3; + + /** + * Current state of this signature object. + */ + protected int state = UNINITIALIZED; + + /** + * Creates a Signature object for the specified algorithm. + * + * @param algorithm the standard string name of the algorithm. + * See the Signature section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + */ + protected Signature(String algorithm) { + this.algorithm = algorithm; + } + + // name of the special signature alg + private final static String RSA_SIGNATURE = "NONEwithRSA"; + + // name of the equivalent cipher alg + private final static String RSA_CIPHER = "RSA/ECB/PKCS1Padding"; + + // all the services we need to lookup for compatibility with Cipher + private final static List rsaIds = Arrays.asList( + new ServiceId[] { + new ServiceId("Signature", "NONEwithRSA"), + new ServiceId("Cipher", "RSA/ECB/PKCS1Padding"), + new ServiceId("Cipher", "RSA/ECB"), + new ServiceId("Cipher", "RSA//PKCS1Padding"), + new ServiceId("Cipher", "RSA"), + } + ); + + /** + * Returns a Signature object that implements the specified signature + * algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new Signature object encapsulating the + * SignatureSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the standard name of the algorithm requested. + * See the Signature section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return the new Signature object. + * + * @exception NoSuchAlgorithmException if no Provider supports a + * Signature implementation for the + * specified algorithm. + * + * @see Provider + */ + public static Signature getInstance(String algorithm) + throws NoSuchAlgorithmException { + List list; + if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) { + list = GetInstance.getServices(rsaIds); + } else { + list = GetInstance.getServices("Signature", algorithm); + } + Iterator t = list.iterator(); + if (t.hasNext() == false) { + throw new NoSuchAlgorithmException + (algorithm + " Signature not available"); + } + // try services until we find an Spi or a working Signature subclass + NoSuchAlgorithmException failure; + do { + Service s = t.next(); + if (isSpi(s)) { + return new Delegate(s, t, algorithm); + } else { + // must be a subclass of Signature, disable dynamic selection + try { + Instance instance = + GetInstance.getInstance(s, SignatureSpi.class); + return getInstance(instance, algorithm); + } catch (NoSuchAlgorithmException e) { + failure = e; + } + } + } while (t.hasNext()); + throw failure; + } + + private static Signature getInstance(Instance instance, String algorithm) { + Signature sig; + if (instance.impl instanceof Signature) { + sig = (Signature)instance.impl; + sig.algorithm = algorithm; + } else { + SignatureSpi spi = (SignatureSpi)instance.impl; + sig = new Delegate(spi, algorithm); + } + sig.provider = instance.provider; + return sig; + } + + private final static Map signatureInfo; + + static { + signatureInfo = new ConcurrentHashMap(); + Boolean TRUE = Boolean.TRUE; + // pre-initialize with values for our SignatureSpi implementations + signatureInfo.put("sun.security.provider.DSA$RawDSA", TRUE); + signatureInfo.put("sun.security.provider.DSA$SHA1withDSA", TRUE); + signatureInfo.put("sun.security.rsa.RSASignature$MD2withRSA", TRUE); + signatureInfo.put("sun.security.rsa.RSASignature$MD5withRSA", TRUE); + signatureInfo.put("sun.security.rsa.RSASignature$SHA1withRSA", TRUE); + signatureInfo.put("sun.security.rsa.RSASignature$SHA256withRSA", TRUE); + signatureInfo.put("sun.security.rsa.RSASignature$SHA384withRSA", TRUE); + signatureInfo.put("sun.security.rsa.RSASignature$SHA512withRSA", TRUE); + signatureInfo.put("com.sun.net.ssl.internal.ssl.RSASignature", TRUE); + signatureInfo.put("sun.security.pkcs11.P11Signature", TRUE); + } + + private static boolean isSpi(Service s) { + if (s.getType().equals("Cipher")) { + // must be a CipherSpi, which we can wrap with the CipherAdapter + return true; + } + String className = s.getClassName(); + Boolean result = signatureInfo.get(className); + if (result == null) { + try { + Object instance = s.newInstance(null); + // Signature extends SignatureSpi + // so it is a "real" Spi if it is an + // instance of SignatureSpi but not Signature + boolean r = (instance instanceof SignatureSpi) + && (instance instanceof Signature == false); + if ((debug != null) && (r == false)) { + debug.println("Not a SignatureSpi " + className); + debug.println("Delayed provider selection may not be " + + "available for algorithm " + s.getAlgorithm()); + } + result = Boolean.valueOf(r); + signatureInfo.put(className, result); + } catch (Exception e) { + // something is wrong, assume not an SPI + return false; + } + } + return result.booleanValue(); + } + + /** + * Returns a Signature object that implements the specified signature + * algorithm. + * + *

A new Signature object encapsulating the + * SignatureSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the algorithm requested. + * See the Signature section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the name of the provider. + * + * @return the new Signature object. + * + * @exception NoSuchAlgorithmException if a SignatureSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see Provider + */ + public static Signature getInstance(String algorithm, String provider) + throws NoSuchAlgorithmException, NoSuchProviderException { + if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) { + // exception compatibility with existing code + if ((provider == null) || (provider.length() == 0)) { + throw new IllegalArgumentException("missing provider"); + } + Provider p = Security.getProvider(provider); + if (p == null) { + throw new NoSuchProviderException + ("no such provider: " + provider); + } + return getInstanceRSA(p); + } + Instance instance = GetInstance.getInstance + ("Signature", SignatureSpi.class, algorithm, provider); + return getInstance(instance, algorithm); + } + + /** + * Returns a Signature object that implements the specified + * signature algorithm. + * + *

A new Signature object encapsulating the + * SignatureSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param algorithm the name of the algorithm requested. + * See the Signature section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the provider. + * + * @return the new Signature object. + * + * @exception NoSuchAlgorithmException if a SignatureSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the provider is null. + * + * @see Provider + * + * @since 1.4 + */ + public static Signature getInstance(String algorithm, Provider provider) + throws NoSuchAlgorithmException { + if (algorithm.equalsIgnoreCase(RSA_SIGNATURE)) { + // exception compatibility with existing code + if (provider == null) { + throw new IllegalArgumentException("missing provider"); + } + return getInstanceRSA(provider); + } + Instance instance = GetInstance.getInstance + ("Signature", SignatureSpi.class, algorithm, provider); + return getInstance(instance, algorithm); + } + + // return an implementation for NONEwithRSA, which is a special case + // because of the Cipher.RSA/ECB/PKCS1Padding compatibility wrapper + private static Signature getInstanceRSA(Provider p) + throws NoSuchAlgorithmException { + // try Signature first + Service s = p.getService("Signature", RSA_SIGNATURE); + if (s != null) { + Instance instance = GetInstance.getInstance(s, SignatureSpi.class); + return getInstance(instance, RSA_SIGNATURE); + } + // check Cipher + try { + Cipher c = Cipher.getInstance(RSA_CIPHER, p); + return new Delegate(new CipherAdapter(c), RSA_SIGNATURE); + } catch (GeneralSecurityException e) { + // throw Signature style exception message to avoid confusion, + // but append Cipher exception as cause + throw new NoSuchAlgorithmException("no such algorithm: " + + RSA_SIGNATURE + " for provider " + p.getName(), e); + } + } + + /** + * Returns the provider of this signature object. + * + * @return the provider of this signature object + */ + public final Provider getProvider() { + chooseFirstProvider(); + return this.provider; + } + + void chooseFirstProvider() { + // empty, overridden in Delegate + } + + /** + * Initializes this object for verification. If this method is called + * again with a different argument, it negates the effect + * of this call. + * + * @param publicKey the public key of the identity whose signature is + * going to be verified. + * + * @exception InvalidKeyException if the key is invalid. + */ + public final void initVerify(PublicKey publicKey) + throws InvalidKeyException { + engineInitVerify(publicKey); + state = VERIFY; + + if (!skipDebug && pdebug != null) { + pdebug.println("Signature." + algorithm + + " verification algorithm from: " + this.provider.getName()); + } + } + + /** + * Initializes this object for verification, using the public key from + * the given certificate. + *

If the certificate is of type X.509 and has a key usage + * extension field marked as critical, and the value of the key usage + * extension field implies that the public key in + * the certificate and its corresponding private key are not + * supposed to be used for digital signatures, an + * {@code InvalidKeyException} is thrown. + * + * @param certificate the certificate of the identity whose signature is + * going to be verified. + * + * @exception InvalidKeyException if the public key in the certificate + * is not encoded properly or does not include required parameter + * information or cannot be used for digital signature purposes. + * @since 1.3 + */ + public final void initVerify(Certificate certificate) + throws InvalidKeyException { + // If the certificate is of type X509Certificate, + // we should check whether it has a Key Usage + // extension marked as critical. + if (certificate instanceof java.security.cert.X509Certificate) { + // Check whether the cert has a key usage extension + // marked as a critical extension. + // The OID for KeyUsage extension is 2.5.29.15. + X509Certificate cert = (X509Certificate)certificate; + Set critSet = cert.getCriticalExtensionOIDs(); + + if (critSet != null && !critSet.isEmpty() + && critSet.contains("2.5.29.15")) { + boolean[] keyUsageInfo = cert.getKeyUsage(); + // keyUsageInfo[0] is for digitalSignature. + if ((keyUsageInfo != null) && (keyUsageInfo[0] == false)) + throw new InvalidKeyException("Wrong key usage"); + } + } + + PublicKey publicKey = certificate.getPublicKey(); + engineInitVerify(publicKey); + state = VERIFY; + + if (!skipDebug && pdebug != null) { + pdebug.println("Signature." + algorithm + + " verification algorithm from: " + this.provider.getName()); + } + } + + /** + * Initialize this object for signing. If this method is called + * again with a different argument, it negates the effect + * of this call. + * + * @param privateKey the private key of the identity whose signature + * is going to be generated. + * + * @exception InvalidKeyException if the key is invalid. + */ + public final void initSign(PrivateKey privateKey) + throws InvalidKeyException { + engineInitSign(privateKey); + state = SIGN; + + if (!skipDebug && pdebug != null) { + pdebug.println("Signature." + algorithm + + " signing algorithm from: " + this.provider.getName()); + } + } + + /** + * Initialize this object for signing. If this method is called + * again with a different argument, it negates the effect + * of this call. + * + * @param privateKey the private key of the identity whose signature + * is going to be generated. + * + * @param random the source of randomness for this signature. + * + * @exception InvalidKeyException if the key is invalid. + */ + public final void initSign(PrivateKey privateKey, SecureRandom random) + throws InvalidKeyException { + engineInitSign(privateKey, random); + state = SIGN; + + if (!skipDebug && pdebug != null) { + pdebug.println("Signature." + algorithm + + " signing algorithm from: " + this.provider.getName()); + } + } + + /** + * Returns the signature bytes of all the data updated. + * The format of the signature depends on the underlying + * signature scheme. + * + *

A call to this method resets this signature object to the state + * it was in when previously initialized for signing via a + * call to {@code initSign(PrivateKey)}. That is, the object is + * reset and available to generate another signature from the same + * signer, if desired, via new calls to {@code update} and + * {@code sign}. + * + * @return the signature bytes of the signing operation's result. + * + * @exception SignatureException if this signature object is not + * initialized properly or if this signature algorithm is unable to + * process the input data provided. + */ + public final byte[] sign() throws SignatureException { + if (state == SIGN) { + return engineSign(); + } + throw new SignatureException("object not initialized for " + + "signing"); + } + + /** + * Finishes the signature operation and stores the resulting signature + * bytes in the provided buffer {@code outbuf}, starting at + * {@code offset}. + * The format of the signature depends on the underlying + * signature scheme. + * + *

This signature object is reset to its initial state (the state it + * was in after a call to one of the {@code initSign} methods) and + * can be reused to generate further signatures with the same private key. + * + * @param outbuf buffer for the signature result. + * + * @param offset offset into {@code outbuf} where the signature is + * stored. + * + * @param len number of bytes within {@code outbuf} allotted for the + * signature. + * + * @return the number of bytes placed into {@code outbuf}. + * + * @exception SignatureException if this signature object is not + * initialized properly, if this signature algorithm is unable to + * process the input data provided, or if {@code len} is less + * than the actual signature length. + * + * @since 1.2 + */ + public final int sign(byte[] outbuf, int offset, int len) + throws SignatureException { + if (outbuf == null) { + throw new IllegalArgumentException("No output buffer given"); + } + if (offset < 0 || len < 0) { + throw new IllegalArgumentException("offset or len is less than 0"); + } + if (outbuf.length - offset < len) { + throw new IllegalArgumentException + ("Output buffer too small for specified offset and length"); + } + if (state != SIGN) { + throw new SignatureException("object not initialized for " + + "signing"); + } + return engineSign(outbuf, offset, len); + } + + /** + * Verifies the passed-in signature. + * + *

A call to this method resets this signature object to the state + * it was in when previously initialized for verification via a + * call to {@code initVerify(PublicKey)}. That is, the object is + * reset and available to verify another signature from the identity + * whose public key was specified in the call to {@code initVerify}. + * + * @param signature the signature bytes to be verified. + * + * @return true if the signature was verified, false if not. + * + * @exception SignatureException if this signature object is not + * initialized properly, the passed-in signature is improperly + * encoded or of the wrong type, if this signature algorithm is unable to + * process the input data provided, etc. + */ + public final boolean verify(byte[] signature) throws SignatureException { + if (state == VERIFY) { + return engineVerify(signature); + } + throw new SignatureException("object not initialized for " + + "verification"); + } + + /** + * Verifies the passed-in signature in the specified array + * of bytes, starting at the specified offset. + * + *

A call to this method resets this signature object to the state + * it was in when previously initialized for verification via a + * call to {@code initVerify(PublicKey)}. That is, the object is + * reset and available to verify another signature from the identity + * whose public key was specified in the call to {@code initVerify}. + * + * + * @param signature the signature bytes to be verified. + * @param offset the offset to start from in the array of bytes. + * @param length the number of bytes to use, starting at offset. + * + * @return true if the signature was verified, false if not. + * + * @exception SignatureException if this signature object is not + * initialized properly, the passed-in signature is improperly + * encoded or of the wrong type, if this signature algorithm is unable to + * process the input data provided, etc. + * @exception IllegalArgumentException if the {@code signature} + * byte array is null, or the {@code offset} or {@code length} + * is less than 0, or the sum of the {@code offset} and + * {@code length} is greater than the length of the + * {@code signature} byte array. + * @since 1.4 + */ + public final boolean verify(byte[] signature, int offset, int length) + throws SignatureException { + if (state == VERIFY) { + if (signature == null) { + throw new IllegalArgumentException("signature is null"); + } + if (offset < 0 || length < 0) { + throw new IllegalArgumentException + ("offset or length is less than 0"); + } + if (signature.length - offset < length) { + throw new IllegalArgumentException + ("signature too small for specified offset and length"); + } + + return engineVerify(signature, offset, length); + } + throw new SignatureException("object not initialized for " + + "verification"); + } + + /** + * Updates the data to be signed or verified by a byte. + * + * @param b the byte to use for the update. + * + * @exception SignatureException if this signature object is not + * initialized properly. + */ + public final void update(byte b) throws SignatureException { + if (state == VERIFY || state == SIGN) { + engineUpdate(b); + } else { + throw new SignatureException("object not initialized for " + + "signature or verification"); + } + } + + /** + * Updates the data to be signed or verified, using the specified + * array of bytes. + * + * @param data the byte array to use for the update. + * + * @exception SignatureException if this signature object is not + * initialized properly. + */ + public final void update(byte[] data) throws SignatureException { + update(data, 0, data.length); + } + + /** + * Updates the data to be signed or verified, using the specified + * array of bytes, starting at the specified offset. + * + * @param data the array of bytes. + * @param off the offset to start from in the array of bytes. + * @param len the number of bytes to use, starting at offset. + * + * @exception SignatureException if this signature object is not + * initialized properly. + */ + public final void update(byte[] data, int off, int len) + throws SignatureException { + if (state == SIGN || state == VERIFY) { + if (data == null) { + throw new IllegalArgumentException("data is null"); + } + if (off < 0 || len < 0) { + throw new IllegalArgumentException("off or len is less than 0"); + } + if (data.length - off < len) { + throw new IllegalArgumentException + ("data too small for specified offset and length"); + } + engineUpdate(data, off, len); + } else { + throw new SignatureException("object not initialized for " + + "signature or verification"); + } + } + + /** + * Updates the data to be signed or verified using the specified + * ByteBuffer. Processes the {@code data.remaining()} bytes + * starting at at {@code data.position()}. + * Upon return, the buffer's position will be equal to its limit; + * its limit will not have changed. + * + * @param data the ByteBuffer + * + * @exception SignatureException if this signature object is not + * initialized properly. + * @since 1.5 + */ + public final void update(ByteBuffer data) throws SignatureException { + if ((state != SIGN) && (state != VERIFY)) { + throw new SignatureException("object not initialized for " + + "signature or verification"); + } + if (data == null) { + throw new NullPointerException(); + } + engineUpdate(data); + } + + /** + * Returns the name of the algorithm for this signature object. + * + * @return the name of the algorithm for this signature object. + */ + public final String getAlgorithm() { + return this.algorithm; + } + + /** + * Returns a string representation of this signature object, + * providing information that includes the state of the object + * and the name of the algorithm used. + * + * @return a string representation of this signature object. + */ + public String toString() { + String initState = ""; + switch (state) { + case UNINITIALIZED: + initState = ""; + break; + case VERIFY: + initState = ""; + break; + case SIGN: + initState = ""; + break; + } + return "Signature object: " + getAlgorithm() + initState; + } + + /** + * Sets the specified algorithm parameter to the specified value. + * This method supplies a general-purpose mechanism through + * which it is possible to set the various parameters of this object. + * A parameter may be any settable parameter for the algorithm, such as + * a parameter size, or a source of random bits for signature generation + * (if appropriate), or an indication of whether or not to perform + * a specific but optional computation. A uniform algorithm-specific + * naming scheme for each parameter is desirable but left unspecified + * at this time. + * + * @param param the string identifier of the parameter. + * @param value the parameter value. + * + * @exception InvalidParameterException if {@code param} is an + * invalid parameter for this signature algorithm engine, + * the parameter is already set + * and cannot be set again, a security exception occurs, and so on. + * + * @see #getParameter + * + * @deprecated Use + * {@link #setParameter(java.security.spec.AlgorithmParameterSpec) + * setParameter}. + */ + @Deprecated + public final void setParameter(String param, Object value) + throws InvalidParameterException { + engineSetParameter(param, value); + } + + /** + * Initializes this signature engine with the specified parameter set. + * + * @param params the parameters + * + * @exception InvalidAlgorithmParameterException if the given parameters + * are inappropriate for this signature engine + * + * @see #getParameters + */ + public final void setParameter(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + engineSetParameter(params); + } + + /** + * Returns the parameters used with this signature object. + * + *

The returned parameters may be the same that were used to initialize + * this signature, or may contain a combination of default and randomly + * generated parameter values used by the underlying signature + * implementation if this signature requires algorithm parameters but + * was not initialized with any. + * + * @return the parameters used with this signature, or null if this + * signature does not use any parameters. + * + * @see #setParameter(AlgorithmParameterSpec) + * @since 1.4 + */ + public final AlgorithmParameters getParameters() { + return engineGetParameters(); + } + + /** + * Gets the value of the specified algorithm parameter. This method + * supplies a general-purpose mechanism through which it is possible to + * get the various parameters of this object. A parameter may be any + * settable parameter for the algorithm, such as a parameter size, or + * a source of random bits for signature generation (if appropriate), + * or an indication of whether or not to perform a specific but optional + * computation. A uniform algorithm-specific naming scheme for each + * parameter is desirable but left unspecified at this time. + * + * @param param the string name of the parameter. + * + * @return the object that represents the parameter value, or null if + * there is none. + * + * @exception InvalidParameterException if {@code param} is an invalid + * parameter for this engine, or another exception occurs while + * trying to get this parameter. + * + * @see #setParameter(String, Object) + * + * @deprecated + */ + @Deprecated + public final Object getParameter(String param) + throws InvalidParameterException { + return engineGetParameter(param); + } + + /** + * Returns a clone if the implementation is cloneable. + * + * @return a clone if the implementation is cloneable. + * + * @exception CloneNotSupportedException if this is called + * on an implementation that does not support {@code Cloneable}. + */ + public Object clone() throws CloneNotSupportedException { + if (this instanceof Cloneable) { + return super.clone(); + } else { + throw new CloneNotSupportedException(); + } + } + + /* + * The following class allows providers to extend from SignatureSpi + * rather than from Signature. It represents a Signature with an + * encapsulated, provider-supplied SPI object (of type SignatureSpi). + * If the provider implementation is an instance of SignatureSpi, the + * getInstance() methods above return an instance of this class, with + * the SPI object encapsulated. + * + * Note: All SPI methods from the original Signature class have been + * moved up the hierarchy into a new class (SignatureSpi), which has + * been interposed in the hierarchy between the API (Signature) + * and its original parent (Object). + */ + + @SuppressWarnings("deprecation") + private static class Delegate extends Signature { + + // The provider implementation (delegate) + // filled in once the provider is selected + private SignatureSpi sigSpi; + + // lock for mutex during provider selection + private final Object lock; + + // next service to try in provider selection + // null once provider is selected + private Service firstService; + + // remaining services to try in provider selection + // null once provider is selected + private Iterator serviceIterator; + + // constructor + Delegate(SignatureSpi sigSpi, String algorithm) { + super(algorithm); + this.sigSpi = sigSpi; + this.lock = null; // no lock needed + } + + // used with delayed provider selection + Delegate(Service service, + Iterator iterator, String algorithm) { + super(algorithm); + this.firstService = service; + this.serviceIterator = iterator; + this.lock = new Object(); + } + + /** + * Returns a clone if the delegate is cloneable. + * + * @return a clone if the delegate is cloneable. + * + * @exception CloneNotSupportedException if this is called on a + * delegate that does not support {@code Cloneable}. + */ + public Object clone() throws CloneNotSupportedException { + chooseFirstProvider(); + if (sigSpi instanceof Cloneable) { + SignatureSpi sigSpiClone = (SignatureSpi)sigSpi.clone(); + // Because 'algorithm' and 'provider' are private + // members of our supertype, we must perform a cast to + // access them. + Signature that = + new Delegate(sigSpiClone, ((Signature)this).algorithm); + that.provider = ((Signature)this).provider; + return that; + } else { + throw new CloneNotSupportedException(); + } + } + + private static SignatureSpi newInstance(Service s) + throws NoSuchAlgorithmException { + if (s.getType().equals("Cipher")) { + // must be NONEwithRSA + try { + Cipher c = Cipher.getInstance(RSA_CIPHER, s.getProvider()); + return new CipherAdapter(c); + } catch (NoSuchPaddingException e) { + throw new NoSuchAlgorithmException(e); + } + } else { + Object o = s.newInstance(null); + if (o instanceof SignatureSpi == false) { + throw new NoSuchAlgorithmException + ("Not a SignatureSpi: " + o.getClass().getName()); + } + return (SignatureSpi)o; + } + } + + // max number of debug warnings to print from chooseFirstProvider() + private static int warnCount = 10; + + /** + * Choose the Spi from the first provider available. Used if + * delayed provider selection is not possible because initSign()/ + * initVerify() is not the first method called. + */ + void chooseFirstProvider() { + if (sigSpi != null) { + return; + } + synchronized (lock) { + if (sigSpi != null) { + return; + } + if (debug != null) { + int w = --warnCount; + if (w >= 0) { + debug.println("Signature.init() not first method " + + "called, disabling delayed provider selection"); + if (w == 0) { + debug.println("Further warnings of this type will " + + "be suppressed"); + } + new Exception("Call trace").printStackTrace(); + } + } + Exception lastException = null; + while ((firstService != null) || serviceIterator.hasNext()) { + Service s; + if (firstService != null) { + s = firstService; + firstService = null; + } else { + s = serviceIterator.next(); + } + if (isSpi(s) == false) { + continue; + } + try { + sigSpi = newInstance(s); + provider = s.getProvider(); + // not needed any more + firstService = null; + serviceIterator = null; + return; + } catch (NoSuchAlgorithmException e) { + lastException = e; + } + } + ProviderException e = new ProviderException + ("Could not construct SignatureSpi instance"); + if (lastException != null) { + e.initCause(lastException); + } + throw e; + } + } + + private void chooseProvider(int type, Key key, SecureRandom random) + throws InvalidKeyException { + synchronized (lock) { + if (sigSpi != null) { + init(sigSpi, type, key, random); + return; + } + Exception lastException = null; + while ((firstService != null) || serviceIterator.hasNext()) { + Service s; + if (firstService != null) { + s = firstService; + firstService = null; + } else { + s = serviceIterator.next(); + } + // if provider says it does not support this key, ignore it + if (s.supportsParameter(key) == false) { + continue; + } + // if instance is not a SignatureSpi, ignore it + if (isSpi(s) == false) { + continue; + } + try { + SignatureSpi spi = newInstance(s); + init(spi, type, key, random); + provider = s.getProvider(); + sigSpi = spi; + firstService = null; + serviceIterator = null; + return; + } catch (Exception e) { + // NoSuchAlgorithmException from newInstance() + // InvalidKeyException from init() + // RuntimeException (ProviderException) from init() + if (lastException == null) { + lastException = e; + } + } + } + // no working provider found, fail + if (lastException instanceof InvalidKeyException) { + throw (InvalidKeyException)lastException; + } + if (lastException instanceof RuntimeException) { + throw (RuntimeException)lastException; + } + String k = (key != null) ? key.getClass().getName() : "(null)"; + throw new InvalidKeyException + ("No installed provider supports this key: " + + k, lastException); + } + } + + private final static int I_PUB = 1; + private final static int I_PRIV = 2; + private final static int I_PRIV_SR = 3; + + private void init(SignatureSpi spi, int type, Key key, + SecureRandom random) throws InvalidKeyException { + switch (type) { + case I_PUB: + spi.engineInitVerify((PublicKey)key); + break; + case I_PRIV: + spi.engineInitSign((PrivateKey)key); + break; + case I_PRIV_SR: + spi.engineInitSign((PrivateKey)key, random); + break; + default: + throw new AssertionError("Internal error: " + type); + } + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException { + if (sigSpi != null) { + sigSpi.engineInitVerify(publicKey); + } else { + chooseProvider(I_PUB, publicKey, null); + } + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException { + if (sigSpi != null) { + sigSpi.engineInitSign(privateKey); + } else { + chooseProvider(I_PRIV, privateKey, null); + } + } + + protected void engineInitSign(PrivateKey privateKey, SecureRandom sr) + throws InvalidKeyException { + if (sigSpi != null) { + sigSpi.engineInitSign(privateKey, sr); + } else { + chooseProvider(I_PRIV_SR, privateKey, sr); + } + } + + protected void engineUpdate(byte b) throws SignatureException { + chooseFirstProvider(); + sigSpi.engineUpdate(b); + } + + protected void engineUpdate(byte[] b, int off, int len) + throws SignatureException { + chooseFirstProvider(); + sigSpi.engineUpdate(b, off, len); + } + + protected void engineUpdate(ByteBuffer data) { + chooseFirstProvider(); + sigSpi.engineUpdate(data); + } + + protected byte[] engineSign() throws SignatureException { + chooseFirstProvider(); + return sigSpi.engineSign(); + } + + protected int engineSign(byte[] outbuf, int offset, int len) + throws SignatureException { + chooseFirstProvider(); + return sigSpi.engineSign(outbuf, offset, len); + } + + protected boolean engineVerify(byte[] sigBytes) + throws SignatureException { + chooseFirstProvider(); + return sigSpi.engineVerify(sigBytes); + } + + protected boolean engineVerify(byte[] sigBytes, int offset, int length) + throws SignatureException { + chooseFirstProvider(); + return sigSpi.engineVerify(sigBytes, offset, length); + } + + protected void engineSetParameter(String param, Object value) + throws InvalidParameterException { + chooseFirstProvider(); + sigSpi.engineSetParameter(param, value); + } + + protected void engineSetParameter(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + chooseFirstProvider(); + sigSpi.engineSetParameter(params); + } + + protected Object engineGetParameter(String param) + throws InvalidParameterException { + chooseFirstProvider(); + return sigSpi.engineGetParameter(param); + } + + protected AlgorithmParameters engineGetParameters() { + chooseFirstProvider(); + return sigSpi.engineGetParameters(); + } + } + + // adapter for RSA/ECB/PKCS1Padding ciphers + @SuppressWarnings("deprecation") + private static class CipherAdapter extends SignatureSpi { + + private final Cipher cipher; + + private ByteArrayOutputStream data; + + CipherAdapter(Cipher cipher) { + this.cipher = cipher; + } + + protected void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException { + cipher.init(Cipher.DECRYPT_MODE, publicKey); + if (data == null) { + data = new ByteArrayOutputStream(128); + } else { + data.reset(); + } + } + + protected void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException { + cipher.init(Cipher.ENCRYPT_MODE, privateKey); + data = null; + } + + protected void engineInitSign(PrivateKey privateKey, + SecureRandom random) throws InvalidKeyException { + cipher.init(Cipher.ENCRYPT_MODE, privateKey, random); + data = null; + } + + protected void engineUpdate(byte b) throws SignatureException { + engineUpdate(new byte[] {b}, 0, 1); + } + + protected void engineUpdate(byte[] b, int off, int len) + throws SignatureException { + if (data != null) { + data.write(b, off, len); + return; + } + byte[] out = cipher.update(b, off, len); + if ((out != null) && (out.length != 0)) { + throw new SignatureException + ("Cipher unexpectedly returned data"); + } + } + + protected byte[] engineSign() throws SignatureException { + try { + return cipher.doFinal(); + } catch (IllegalBlockSizeException e) { + throw new SignatureException("doFinal() failed", e); + } catch (BadPaddingException e) { + throw new SignatureException("doFinal() failed", e); + } + } + + protected boolean engineVerify(byte[] sigBytes) + throws SignatureException { + try { + byte[] out = cipher.doFinal(sigBytes); + byte[] dataBytes = data.toByteArray(); + data.reset(); + return Arrays.equals(out, dataBytes); + } catch (BadPaddingException e) { + // e.g. wrong public key used + // return false rather than throwing exception + return false; + } catch (IllegalBlockSizeException e) { + throw new SignatureException("doFinal() failed", e); + } + } + + protected void engineSetParameter(String param, Object value) + throws InvalidParameterException { + throw new InvalidParameterException("Parameters not supported"); + } + + protected Object engineGetParameter(String param) + throws InvalidParameterException { + throw new InvalidParameterException("Parameters not supported"); + } + + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/SignatureException.java b/sources/net.sf.j2s.java.core/src/java/security/SignatureException.java new file mode 100644 index 000000000..2e1fa592f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/SignatureException.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1996, 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 java.security; + +/** + * This is the generic Signature exception. + * + * @author Benjamin Renaud + */ + +public class SignatureException extends GeneralSecurityException { + + private static final long serialVersionUID = 7509989324975124438L; + + /** + * Constructs a SignatureException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public SignatureException() { + super(); + } + + /** + * Constructs a SignatureException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public SignatureException(String msg) { + super(msg); + } + + /** + * Creates a {@code SignatureException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public SignatureException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code SignatureException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public SignatureException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/SignatureSpi.java b/sources/net.sf.j2s.java.core/src/java/security/SignatureSpi.java new file mode 100644 index 000000000..d6d2bc39b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/SignatureSpi.java @@ -0,0 +1,390 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.security.spec.AlgorithmParameterSpec; +import java.util.*; +import java.io.*; + +import java.nio.ByteBuffer; + +import sun.security.jca.JCAUtil; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code Signature} class, which is used to provide the + * functionality of a digital signature algorithm. Digital signatures are used + * for authentication and integrity assurance of digital data. + *. + *

All the abstract methods in this class must be implemented by each + * cryptographic service provider who wishes to supply the implementation + * of a particular signature algorithm. + * + * @author Benjamin Renaud + * + * + * @see Signature + */ + +public abstract class SignatureSpi { + + /** + * Application-specified source of randomness. + */ + protected SecureRandom appRandom = null; + + /** + * Initializes this signature object with the specified + * public key for verification operations. + * + * @param publicKey the public key of the identity whose signature is + * going to be verified. + * + * @exception InvalidKeyException if the key is improperly + * encoded, parameters are missing, and so on. + */ + protected abstract void engineInitVerify(PublicKey publicKey) + throws InvalidKeyException; + + /** + * Initializes this signature object with the specified + * private key for signing operations. + * + * @param privateKey the private key of the identity whose signature + * will be generated. + * + * @exception InvalidKeyException if the key is improperly + * encoded, parameters are missing, and so on. + */ + protected abstract void engineInitSign(PrivateKey privateKey) + throws InvalidKeyException; + + /** + * Initializes this signature object with the specified + * private key and source of randomness for signing operations. + * + *

This concrete method has been added to this previously-defined + * abstract class. (For backwards compatibility, it cannot be abstract.) + * + * @param privateKey the private key of the identity whose signature + * will be generated. + * @param random the source of randomness + * + * @exception InvalidKeyException if the key is improperly + * encoded, parameters are missing, and so on. + */ + protected void engineInitSign(PrivateKey privateKey, + SecureRandom random) + throws InvalidKeyException { + this.appRandom = random; + engineInitSign(privateKey); + } + + /** + * Updates the data to be signed or verified + * using the specified byte. + * + * @param b the byte to use for the update. + * + * @exception SignatureException if the engine is not initialized + * properly. + */ + protected abstract void engineUpdate(byte b) throws SignatureException; + + /** + * Updates the data to be signed or verified, using the + * specified array of bytes, starting at the specified offset. + * + * @param b the array of bytes + * @param off the offset to start from in the array of bytes + * @param len the number of bytes to use, starting at offset + * + * @exception SignatureException if the engine is not initialized + * properly + */ + protected abstract void engineUpdate(byte[] b, int off, int len) + throws SignatureException; + + /** + * Updates the data to be signed or verified using the specified + * ByteBuffer. Processes the {@code data.remaining()} bytes + * starting at at {@code data.position()}. + * Upon return, the buffer's position will be equal to its limit; + * its limit will not have changed. + * + * @param input the ByteBuffer + * @since 1.5 + */ + protected void engineUpdate(ByteBuffer input) { + if (input.hasRemaining() == false) { + return; + } + try { + if (input.hasArray()) { + byte[] b = input.array(); + int ofs = input.arrayOffset(); + int pos = input.position(); + int lim = input.limit(); + engineUpdate(b, ofs + pos, lim - pos); + input.position(lim); + } else { + int len = input.remaining(); + byte[] b = new byte[JCAUtil.getTempArraySize(len)]; + while (len > 0) { + int chunk = Math.min(len, b.length); + input.get(b, 0, chunk); + engineUpdate(b, 0, chunk); + len -= chunk; + } + } + } catch (SignatureException e) { + // is specified to only occur when the engine is not initialized + // this case should never occur as it is caught in Signature.java + throw new ProviderException("update() failed", e); + } + } + + /** + * Returns the signature bytes of all the data + * updated so far. + * The format of the signature depends on the underlying + * signature scheme. + * + * @return the signature bytes of the signing operation's result. + * + * @exception SignatureException if the engine is not + * initialized properly or if this signature algorithm is unable to + * process the input data provided. + */ + protected abstract byte[] engineSign() throws SignatureException; + + /** + * Finishes this signature operation and stores the resulting signature + * bytes in the provided buffer {@code outbuf}, starting at + * {@code offset}. + * The format of the signature depends on the underlying + * signature scheme. + * + *

The signature implementation is reset to its initial state + * (the state it was in after a call to one of the + * {@code engineInitSign} methods) + * and can be reused to generate further signatures with the same private + * key. + * + * This method should be abstract, but we leave it concrete for + * binary compatibility. Knowledgeable providers should override this + * method. + * + * @param outbuf buffer for the signature result. + * + * @param offset offset into {@code outbuf} where the signature is + * stored. + * + * @param len number of bytes within {@code outbuf} allotted for the + * signature. + * Both this default implementation and the SUN provider do not + * return partial digests. If the value of this parameter is less + * than the actual signature length, this method will throw a + * SignatureException. + * This parameter is ignored if its value is greater than or equal to + * the actual signature length. + * + * @return the number of bytes placed into {@code outbuf} + * + * @exception SignatureException if the engine is not + * initialized properly, if this signature algorithm is unable to + * process the input data provided, or if {@code len} is less + * than the actual signature length. + * + * @since 1.2 + */ + protected int engineSign(byte[] outbuf, int offset, int len) + throws SignatureException { + byte[] sig = engineSign(); + if (len < sig.length) { + throw new SignatureException + ("partial signatures not returned"); + } + if (outbuf.length - offset < sig.length) { + throw new SignatureException + ("insufficient space in the output buffer to store the " + + "signature"); + } + System.arraycopy(sig, 0, outbuf, offset, sig.length); + return sig.length; + } + + /** + * Verifies the passed-in signature. + * + * @param sigBytes the signature bytes to be verified. + * + * @return true if the signature was verified, false if not. + * + * @exception SignatureException if the engine is not + * initialized properly, the passed-in signature is improperly + * encoded or of the wrong type, if this signature algorithm is unable to + * process the input data provided, etc. + */ + protected abstract boolean engineVerify(byte[] sigBytes) + throws SignatureException; + + /** + * Verifies the passed-in signature in the specified array + * of bytes, starting at the specified offset. + * + *

Note: Subclasses should overwrite the default implementation. + * + * + * @param sigBytes the signature bytes to be verified. + * @param offset the offset to start from in the array of bytes. + * @param length the number of bytes to use, starting at offset. + * + * @return true if the signature was verified, false if not. + * + * @exception SignatureException if the engine is not + * initialized properly, the passed-in signature is improperly + * encoded or of the wrong type, if this signature algorithm is unable to + * process the input data provided, etc. + * @since 1.4 + */ + protected boolean engineVerify(byte[] sigBytes, int offset, int length) + throws SignatureException { + byte[] sigBytesCopy = new byte[length]; + System.arraycopy(sigBytes, offset, sigBytesCopy, 0, length); + return engineVerify(sigBytesCopy); + } + + /** + * Sets the specified algorithm parameter to the specified + * value. This method supplies a general-purpose mechanism through + * which it is possible to set the various parameters of this object. + * A parameter may be any settable parameter for the algorithm, such as + * a parameter size, or a source of random bits for signature generation + * (if appropriate), or an indication of whether or not to perform + * a specific but optional computation. A uniform algorithm-specific + * naming scheme for each parameter is desirable but left unspecified + * at this time. + * + * @param param the string identifier of the parameter. + * + * @param value the parameter value. + * + * @exception InvalidParameterException if {@code param} is an + * invalid parameter for this signature algorithm engine, + * the parameter is already set + * and cannot be set again, a security exception occurs, and so on. + * + * @deprecated Replaced by {@link + * #engineSetParameter(java.security.spec.AlgorithmParameterSpec) + * engineSetParameter}. + */ + @Deprecated + protected abstract void engineSetParameter(String param, Object value) + throws InvalidParameterException; + + /** + *

This method is overridden by providers to initialize + * this signature engine with the specified parameter set. + * + * @param params the parameters + * + * @exception UnsupportedOperationException if this method is not + * overridden by a provider + * + * @exception InvalidAlgorithmParameterException if this method is + * overridden by a provider and the given parameters + * are inappropriate for this signature engine + */ + protected void engineSetParameter(AlgorithmParameterSpec params) + throws InvalidAlgorithmParameterException { + throw new UnsupportedOperationException(); + } + + /** + *

This method is overridden by providers to return the + * parameters used with this signature engine, or null + * if this signature engine does not use any parameters. + * + *

The returned parameters may be the same that were used to initialize + * this signature engine, or may contain a combination of default and + * randomly generated parameter values used by the underlying signature + * implementation if this signature engine requires algorithm parameters + * but was not initialized with any. + * + * @return the parameters used with this signature engine, or null if this + * signature engine does not use any parameters + * + * @exception UnsupportedOperationException if this method is + * not overridden by a provider + * @since 1.4 + */ + protected AlgorithmParameters engineGetParameters() { + throw new UnsupportedOperationException(); + } + + /** + * Gets the value of the specified algorithm parameter. + * This method supplies a general-purpose mechanism through which it + * is possible to get the various parameters of this object. A parameter + * may be any settable parameter for the algorithm, such as a parameter + * size, or a source of random bits for signature generation (if + * appropriate), or an indication of whether or not to perform a + * specific but optional computation. A uniform algorithm-specific + * naming scheme for each parameter is desirable but left unspecified + * at this time. + * + * @param param the string name of the parameter. + * + * @return the object that represents the parameter value, or null if + * there is none. + * + * @exception InvalidParameterException if {@code param} is an + * invalid parameter for this engine, or another exception occurs while + * trying to get this parameter. + * + * @deprecated + */ + @Deprecated + protected abstract Object engineGetParameter(String param) + throws InvalidParameterException; + + /** + * Returns a clone if the implementation is cloneable. + * + * @return a clone if the implementation is cloneable. + * + * @exception CloneNotSupportedException if this is called + * on an implementation that does not support {@code Cloneable}. + */ + public Object clone() throws CloneNotSupportedException { + if (this instanceof Cloneable) { + return super.clone(); + } else { + throw new CloneNotSupportedException(); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/SignedObject.java b/sources/net.sf.j2s.java.core/src/java/security/SignedObject.java new file mode 100644 index 000000000..9ac864ee8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/SignedObject.java @@ -0,0 +1,258 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.io.*; + +/** + *

SignedObject is a class for the purpose of creating authentic + * runtime objects whose integrity cannot be compromised without being + * detected. + * + *

More specifically, a SignedObject contains another Serializable + * object, the (to-be-)signed object and its signature. + * + *

The signed object is a "deep copy" (in serialized form) of an + * original object. Once the copy is made, further manipulation of + * the original object has no side effect on the copy. + * + *

The underlying signing algorithm is designated by the Signature + * object passed to the constructor and the {@code verify} method. + * A typical usage for signing is the following: + * + *

{@code
+ * Signature signingEngine = Signature.getInstance(algorithm,
+ *                                                 provider);
+ * SignedObject so = new SignedObject(myobject, signingKey,
+ *                                    signingEngine);
+ * }
+ * + *

A typical usage for verification is the following (having + * received SignedObject {@code so}): + * + *

{@code
+ * Signature verificationEngine =
+ *     Signature.getInstance(algorithm, provider);
+ * if (so.verify(publickey, verificationEngine))
+ *     try {
+ *         Object myobj = so.getObject();
+ *     } catch (java.lang.ClassNotFoundException e) {};
+ * }
+ * + *

Several points are worth noting. First, there is no need to + * initialize the signing or verification engine, as it will be + * re-initialized inside the constructor and the {@code verify} + * method. Secondly, for verification to succeed, the specified + * public key must be the public key corresponding to the private key + * used to generate the SignedObject. + * + *

More importantly, for flexibility reasons, the + * constructor and {@code verify} method allow for + * customized signature engines, which can implement signature + * algorithms that are not installed formally as part of a crypto + * provider. However, it is crucial that the programmer writing the + * verifier code be aware what {@code Signature} engine is being + * used, as its own implementation of the {@code verify} method + * is invoked to verify a signature. In other words, a malicious + * {@code Signature} may choose to always return true on + * verification in an attempt to bypass a security check. + * + *

The signature algorithm can be, among others, the NIST standard + * DSA, using DSA and SHA-1. The algorithm is specified using the + * same convention as that for signatures. The DSA algorithm using the + * SHA-1 message digest algorithm can be specified, for example, as + * "SHA/DSA" or "SHA-1/DSA" (they are equivalent). In the case of + * RSA, there are multiple choices for the message digest algorithm, + * so the signing algorithm could be specified as, for example, + * "MD2/RSA", "MD5/RSA" or "SHA-1/RSA". The algorithm name must be + * specified, as there is no default. + * + *

The name of the Cryptography Package Provider is designated + * also by the Signature parameter to the constructor and the + * {@code verify} method. If the provider is not + * specified, the default provider is used. Each installation can + * be configured to use a particular provider as default. + * + *

Potential applications of SignedObject include: + *

    + *
  • It can be used + * internally to any Java runtime as an unforgeable authorization + * token -- one that can be passed around without the fear that the + * token can be maliciously modified without being detected. + *
  • It + * can be used to sign and serialize data/object for storage outside + * the Java runtime (e.g., storing critical access control data on + * disk). + *
  • Nested SignedObjects can be used to construct a logical + * sequence of signatures, resembling a chain of authorization and + * delegation. + *
+ * + * @see Signature + * + * @author Li Gong + */ + +public final class SignedObject implements Serializable { + + private static final long serialVersionUID = 720502720485447167L; + + /* + * The original content is "deep copied" in its serialized format + * and stored in a byte array. The signature field is also in the + * form of byte array. + */ + + private byte[] content; + private byte[] signature; + private String thealgorithm; + + /** + * Constructs a SignedObject from any Serializable object. + * The given object is signed with the given signing key, using the + * designated signature engine. + * + * @param object the object to be signed. + * @param signingKey the private key for signing. + * @param signingEngine the signature signing engine. + * + * @exception IOException if an error occurs during serialization + * @exception InvalidKeyException if the key is invalid. + * @exception SignatureException if signing fails. + */ + public SignedObject(Serializable object, PrivateKey signingKey, + Signature signingEngine) + throws IOException, InvalidKeyException, SignatureException { + // creating a stream pipe-line, from a to b + ByteArrayOutputStream b = new ByteArrayOutputStream(); + ObjectOutput a = new ObjectOutputStream(b); + + // write and flush the object content to byte array + a.writeObject(object); + a.flush(); + a.close(); + this.content = b.toByteArray(); + b.close(); + + // now sign the encapsulated object + this.sign(signingKey, signingEngine); + } + + /** + * Retrieves the encapsulated object. + * The encapsulated object is de-serialized before it is returned. + * + * @return the encapsulated object. + * + * @exception IOException if an error occurs during de-serialization + * @exception ClassNotFoundException if an error occurs during + * de-serialization + */ + public Object getObject() + throws IOException, ClassNotFoundException + { + // creating a stream pipe-line, from b to a + ByteArrayInputStream b = new ByteArrayInputStream(this.content); + ObjectInput a = new ObjectInputStream(b); + Object obj = a.readObject(); + b.close(); + a.close(); + return obj; + } + + /** + * Retrieves the signature on the signed object, in the form of a + * byte array. + * + * @return the signature. Returns a new array each time this + * method is called. + */ + public byte[] getSignature() { + return this.signature.clone(); + } + + /** + * Retrieves the name of the signature algorithm. + * + * @return the signature algorithm name. + */ + public String getAlgorithm() { + return this.thealgorithm; + } + + /** + * Verifies that the signature in this SignedObject is the valid + * signature for the object stored inside, with the given + * verification key, using the designated verification engine. + * + * @param verificationKey the public key for verification. + * @param verificationEngine the signature verification engine. + * + * @exception SignatureException if signature verification failed. + * @exception InvalidKeyException if the verification key is invalid. + * + * @return {@code true} if the signature + * is valid, {@code false} otherwise + */ + public boolean verify(PublicKey verificationKey, + Signature verificationEngine) + throws InvalidKeyException, SignatureException { + verificationEngine.initVerify(verificationKey); + verificationEngine.update(this.content.clone()); + return verificationEngine.verify(this.signature.clone()); + } + + /* + * Signs the encapsulated object with the given signing key, using the + * designated signature engine. + * + * @param signingKey the private key for signing. + * @param signingEngine the signature signing engine. + * + * @exception InvalidKeyException if the key is invalid. + * @exception SignatureException if signing fails. + */ + private void sign(PrivateKey signingKey, Signature signingEngine) + throws InvalidKeyException, SignatureException { + // initialize the signing engine + signingEngine.initSign(signingKey); + signingEngine.update(this.content.clone()); + this.signature = signingEngine.sign().clone(); + this.thealgorithm = signingEngine.getAlgorithm(); + } + + /** + * readObject is called to restore the state of the SignedObject from + * a stream. + */ + private void readObject(java.io.ObjectInputStream s) + throws java.io.IOException, ClassNotFoundException { + java.io.ObjectInputStream.GetField fields = s.readFields(); + content = ((byte[])fields.get("content", null)).clone(); + signature = ((byte[])fields.get("signature", null)).clone(); + thealgorithm = (String)fields.get("thealgorithm", null); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Signer.java b/sources/net.sf.j2s.java.core/src/java/security/Signer.java new file mode 100644 index 000000000..077538da9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Signer.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 1996, 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 java.security; + +import java.io.*; + +/** + * This class is used to represent an Identity that can also digitally + * sign data. + * + *

The management of a signer's private keys is an important and + * sensitive issue that should be handled by subclasses as appropriate + * to their intended use. + * + * @see Identity + * + * @author Benjamin Renaud + * + * @deprecated This class is no longer used. Its functionality has been + * replaced by {@code java.security.KeyStore}, the + * {@code java.security.cert} package, and + * {@code java.security.Principal}. + */ +@Deprecated +public abstract class Signer extends Identity { + + private static final long serialVersionUID = -1763464102261361480L; + + /** + * The signer's private key. + * + * @serial + */ + private PrivateKey privateKey; + + /** + * Creates a signer. This constructor should only be used for + * serialization. + */ + protected Signer() { + super(); + } + + + /** + * Creates a signer with the specified identity name. + * + * @param name the identity name. + */ + public Signer(String name) { + super(name); + } + + /** + * Creates a signer with the specified identity name and scope. + * + * @param name the identity name. + * + * @param scope the scope of the identity. + * + * @exception KeyManagementException if there is already an identity + * with the same name in the scope. + */ + public Signer(String name, IdentityScope scope) + throws KeyManagementException { + super(name, scope); + } + + /** + * Returns this signer's private key. + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "getSignerPrivateKey"} + * as its argument to see if it's ok to return the private key. + * + * @return this signer's private key, or null if the private key has + * not yet been set. + * + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * returning the private key. + * + * @see SecurityManager#checkSecurityAccess + */ + public PrivateKey getPrivateKey() { + check("getSignerPrivateKey"); + return privateKey; + } + + /** + * Sets the key pair (public key and private key) for this signer. + * + *

First, if there is a security manager, its {@code checkSecurityAccess} + * method is called with {@code "setSignerKeyPair"} + * as its argument to see if it's ok to set the key pair. + * + * @param pair an initialized key pair. + * + * @exception InvalidParameterException if the key pair is not + * properly initialized. + * @exception KeyException if the key pair cannot be set for any + * other reason. + * @exception SecurityException if a security manager exists and its + * {@code checkSecurityAccess} method doesn't allow + * setting the key pair. + * + * @see SecurityManager#checkSecurityAccess + */ + public final void setKeyPair(KeyPair pair) + throws InvalidParameterException, KeyException { + check("setSignerKeyPair"); + final PublicKey pub = pair.getPublic(); + PrivateKey priv = pair.getPrivate(); + + if (pub == null || priv == null) { + throw new InvalidParameterException(); + } + try { + AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Void run() throws KeyManagementException { + setPublicKey(pub); + return null; + } + }); + } catch (PrivilegedActionException pae) { + throw (KeyManagementException) pae.getException(); + } + privateKey = priv; + } + + String printKeys() { + String keys = ""; + PublicKey publicKey = getPublicKey(); + if (publicKey != null && privateKey != null) { + keys = "\tpublic and private keys initialized"; + + } else { + keys = "\tno keys"; + } + return keys; + } + + /** + * Returns a string of information about the signer. + * + * @return a string of information about the signer. + */ + public String toString() { + return "[Signer]" + super.toString(); + } + + private static void check(String directive) { + SecurityManager security = System.getSecurityManager(); + if (security != null) { + security.checkSecurityAccess(directive); + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/Timestamp.java b/sources/net.sf.j2s.java.core/src/java/security/Timestamp.java new file mode 100644 index 000000000..f66d2883e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/Timestamp.java @@ -0,0 +1,164 @@ +/* + * Copyright (c) 2003, 2011, 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 java.security; + +import java.io.*; +import java.security.cert.Certificate; +import java.security.cert.CertPath; +import java.security.cert.X509Extension; +import java.util.Date; +import java.util.List; + +/** + * This class encapsulates information about a signed timestamp. + * It is immutable. + * It includes the timestamp's date and time as well as information about the + * Timestamping Authority (TSA) which generated and signed the timestamp. + * + * @since 1.5 + * @author Vincent Ryan + */ + +public final class Timestamp implements Serializable { + + private static final long serialVersionUID = -5502683707821851294L; + + /** + * The timestamp's date and time + * + * @serial + */ + private Date timestamp; + + /** + * The TSA's certificate path. + * + * @serial + */ + private CertPath signerCertPath; + + /* + * Hash code for this timestamp. + */ + private transient int myhash = -1; + + /** + * Constructs a Timestamp. + * + * @param timestamp is the timestamp's date and time. It must not be null. + * @param signerCertPath is the TSA's certificate path. It must not be null. + * @throws NullPointerException if timestamp or signerCertPath is null. + */ + public Timestamp(Date timestamp, CertPath signerCertPath) { + if (timestamp == null || signerCertPath == null) { + throw new NullPointerException(); + } + this.timestamp = new Date(timestamp.getTime()); // clone + this.signerCertPath = signerCertPath; + } + + /** + * Returns the date and time when the timestamp was generated. + * + * @return The timestamp's date and time. + */ + public Date getTimestamp() { + return new Date(timestamp.getTime()); // clone + } + + /** + * Returns the certificate path for the Timestamping Authority. + * + * @return The TSA's certificate path. + */ + public CertPath getSignerCertPath() { + return signerCertPath; + } + + /** + * Returns the hash code value for this timestamp. + * The hash code is generated using the date and time of the timestamp + * and the TSA's certificate path. + * + * @return a hash code value for this timestamp. + */ + public int hashCode() { + if (myhash == -1) { + myhash = timestamp.hashCode() + signerCertPath.hashCode(); + } + return myhash; + } + + /** + * Tests for equality between the specified object and this + * timestamp. Two timestamps are considered equal if the date and time of + * their timestamp's and their signer's certificate paths are equal. + * + * @param obj the object to test for equality with this timestamp. + * + * @return true if the timestamp are considered equal, false otherwise. + */ + public boolean equals(Object obj) { + if (obj == null || (!(obj instanceof Timestamp))) { + return false; + } + Timestamp that = (Timestamp)obj; + + if (this == that) { + return true; + } + return (timestamp.equals(that.getTimestamp()) && + signerCertPath.equals(that.getSignerCertPath())); + } + + /** + * Returns a string describing this timestamp. + * + * @return A string comprising the date and time of the timestamp and + * its signer's certificate. + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("("); + sb.append("timestamp: " + timestamp); + List certs = signerCertPath.getCertificates(); + if (!certs.isEmpty()) { + sb.append("TSA: " + certs.get(0)); + } else { + sb.append("TSA: "); + } + sb.append(")"); + return sb.toString(); + } + + // Explicitly reset hash code value to -1 + private void readObject(ObjectInputStream ois) + throws IOException, ClassNotFoundException { + ois.defaultReadObject(); + myhash = -1; + timestamp = new Date(timestamp.getTime()); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/URIParameter.java b/sources/net.sf.j2s.java.core/src/java/security/URIParameter.java new file mode 100644 index 000000000..5cce54424 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/URIParameter.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2005, 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 java.security; + +/** + * A parameter that contains a URI pointing to data intended for a + * PolicySpi or ConfigurationSpi implementation. + * + * @since 1.6 + */ +public class URIParameter implements + Policy.Parameters, javax.security.auth.login.Configuration.Parameters { + + private java.net.URI uri; + + /** + * Constructs a URIParameter with the URI pointing to + * data intended for an SPI implementation. + * + * @param uri the URI pointing to the data. + * + * @exception NullPointerException if the specified URI is null. + */ + public URIParameter(java.net.URI uri) { + if (uri == null) { + throw new NullPointerException("invalid null URI"); + } + this.uri = uri; + } + + /** + * Returns the URI. + * + * @return uri the URI. + */ + public java.net.URI getURI() { + return uri; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/UnrecoverableEntryException.java b/sources/net.sf.j2s.java.core/src/java/security/UnrecoverableEntryException.java new file mode 100644 index 000000000..0314e3d9c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/UnrecoverableEntryException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2003, 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 java.security; + +/** + * This exception is thrown if an entry in the keystore cannot be recovered. + * + * + * @since 1.5 + */ + +public class UnrecoverableEntryException extends GeneralSecurityException { + + private static final long serialVersionUID = -4527142945246286535L; + + /** + * Constructs an UnrecoverableEntryException with no detail message. + */ + public UnrecoverableEntryException() { + super(); + } + + /** + * Constructs an UnrecoverableEntryException with the specified detail + * message, which provides more information about why this exception + * has been thrown. + * + * @param msg the detail message. + */ + public UnrecoverableEntryException(String msg) { + super(msg); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/UnrecoverableKeyException.java b/sources/net.sf.j2s.java.core/src/java/security/UnrecoverableKeyException.java new file mode 100644 index 000000000..09fcc6ed5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/UnrecoverableKeyException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 1997, 2005, 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 java.security; + +/** + * This exception is thrown if a key in the keystore cannot be recovered. + * + * + * @since 1.2 + */ + +public class UnrecoverableKeyException extends UnrecoverableEntryException { + + private static final long serialVersionUID = 7275063078190151277L; + + /** + * Constructs an UnrecoverableKeyException with no detail message. + */ + public UnrecoverableKeyException() { + super(); + } + + /** + * Constructs an UnrecoverableKeyException with the specified detail + * message, which provides more information about why this exception + * has been thrown. + * + * @param msg the detail message. + */ + public UnrecoverableKeyException(String msg) { + super(msg); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/UnresolvedPermission.java b/sources/net.sf.j2s.java.core/src/java/security/UnresolvedPermission.java new file mode 100644 index 000000000..6c400382d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/UnresolvedPermission.java @@ -0,0 +1,602 @@ +/* + * Copyright (c) 1997, 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 java.security; + +import java.io.IOException; +import java.io.ByteArrayInputStream; +import java.util.ArrayList; +import java.util.Hashtable; +import java.lang.reflect.*; +import java.security.cert.*; + +/** + * The UnresolvedPermission class is used to hold Permissions that + * were "unresolved" when the Policy was initialized. + * An unresolved permission is one whose actual Permission class + * does not yet exist at the time the Policy is initialized (see below). + * + *

The policy for a Java runtime (specifying + * which permissions are available for code from various principals) + * is represented by a Policy object. + * Whenever a Policy is initialized or refreshed, Permission objects of + * appropriate classes are created for all permissions + * allowed by the Policy. + * + *

Many permission class types + * referenced by the policy configuration are ones that exist + * locally (i.e., ones that can be found on CLASSPATH). + * Objects for such permissions can be instantiated during + * Policy initialization. For example, it is always possible + * to instantiate a java.io.FilePermission, since the + * FilePermission class is found on the CLASSPATH. + * + *

Other permission classes may not yet exist during Policy + * initialization. For example, a referenced permission class may + * be in a JAR file that will later be loaded. + * For each such class, an UnresolvedPermission is instantiated. + * Thus, an UnresolvedPermission is essentially a "placeholder" + * containing information about the permission. + * + *

Later, when code calls AccessController.checkPermission + * on a permission of a type that was previously unresolved, + * but whose class has since been loaded, previously-unresolved + * permissions of that type are "resolved". That is, + * for each such UnresolvedPermission, a new object of + * the appropriate class type is instantiated, based on the + * information in the UnresolvedPermission. + * + *

To instantiate the new class, UnresolvedPermission assumes + * the class provides a zero, one, and/or two-argument constructor. + * The zero-argument constructor would be used to instantiate + * a permission without a name and without actions. + * A one-arg constructor is assumed to take a {@code String} + * name as input, and a two-arg constructor is assumed to take a + * {@code String} name and {@code String} actions + * as input. UnresolvedPermission may invoke a + * constructor with a {@code null} name and/or actions. + * If an appropriate permission constructor is not available, + * the UnresolvedPermission is ignored and the relevant permission + * will not be granted to executing code. + * + *

The newly created permission object replaces the + * UnresolvedPermission, which is removed. + * + *

Note that the {@code getName} method for an + * {@code UnresolvedPermission} returns the + * {@code type} (class name) for the underlying permission + * that has not been resolved. + * + * @see java.security.Permission + * @see java.security.Permissions + * @see java.security.PermissionCollection + * @see java.security.Policy + * + * + * @author Roland Schemers + */ + +public final class UnresolvedPermission extends Permission +implements java.io.Serializable +{ + + private static final long serialVersionUID = -4821973115467008846L; + + private static final sun.security.util.Debug debug = + sun.security.util.Debug.getInstance + ("policy,access", "UnresolvedPermission"); + + /** + * The class name of the Permission class that will be + * created when this unresolved permission is resolved. + * + * @serial + */ + private String type; + + /** + * The permission name. + * + * @serial + */ + private String name; + + /** + * The actions of the permission. + * + * @serial + */ + private String actions; + + private transient java.security.cert.Certificate certs[]; + + /** + * Creates a new UnresolvedPermission containing the permission + * information needed later to actually create a Permission of the + * specified class, when the permission is resolved. + * + * @param type the class name of the Permission class that will be + * created when this unresolved permission is resolved. + * @param name the name of the permission. + * @param actions the actions of the permission. + * @param certs the certificates the permission's class was signed with. + * This is a list of certificate chains, where each chain is composed of a + * signer certificate and optionally its supporting certificate chain. + * Each chain is ordered bottom-to-top (i.e., with the signer certificate + * first and the (root) certificate authority last). The signer + * certificates are copied from the array. Subsequent changes to + * the array will not affect this UnsolvedPermission. + */ + public UnresolvedPermission(String type, + String name, + String actions, + java.security.cert.Certificate certs[]) + { + super(type); + + if (type == null) + throw new NullPointerException("type can't be null"); + + this.type = type; + this.name = name; + this.actions = actions; + if (certs != null) { + // Extract the signer certs from the list of certificates. + for (int i=0; i signerCerts = + new ArrayList<>(); + i = 0; + while (i < certs.length) { + signerCerts.add(certs[i]); + while (((i+1) < certs.length) && + ((X509Certificate)certs[i]).getIssuerDN().equals( + ((X509Certificate)certs[i+1]).getSubjectDN())) { + i++; + } + i++; + } + this.certs = + new java.security.cert.Certificate[signerCerts.size()]; + signerCerts.toArray(this.certs); + } + } + } + } + + + private static final Class[] PARAMS0 = { }; + private static final Class[] PARAMS1 = { String.class }; + private static final Class[] PARAMS2 = { String.class, String.class }; + + /** + * try and resolve this permission using the class loader of the permission + * that was passed in. + */ + Permission resolve(Permission p, java.security.cert.Certificate certs[]) { + if (this.certs != null) { + // if p wasn't signed, we don't have a match + if (certs == null) { + return null; + } + + // all certs in this.certs must be present in certs + boolean match; + for (int i = 0; i < this.certs.length; i++) { + match = false; + for (int j = 0; j < certs.length; j++) { + if (this.certs[i].equals(certs[j])) { + match = true; + break; + } + } + if (!match) return null; + } + } + try { + Class pc = p.getClass(); + + if (name == null && actions == null) { + try { + Constructor c = pc.getConstructor(PARAMS0); + return (Permission)c.newInstance(new Object[] {}); + } catch (NoSuchMethodException ne) { + try { + Constructor c = pc.getConstructor(PARAMS1); + return (Permission) c.newInstance( + new Object[] { name}); + } catch (NoSuchMethodException ne1) { + Constructor c = pc.getConstructor(PARAMS2); + return (Permission) c.newInstance( + new Object[] { name, actions }); + } + } + } else { + if (name != null && actions == null) { + try { + Constructor c = pc.getConstructor(PARAMS1); + return (Permission) c.newInstance( + new Object[] { name}); + } catch (NoSuchMethodException ne) { + Constructor c = pc.getConstructor(PARAMS2); + return (Permission) c.newInstance( + new Object[] { name, actions }); + } + } else { + Constructor c = pc.getConstructor(PARAMS2); + return (Permission) c.newInstance( + new Object[] { name, actions }); + } + } + } catch (NoSuchMethodException nsme) { + if (debug != null ) { + debug.println("NoSuchMethodException:\n could not find " + + "proper constructor for " + type); + nsme.printStackTrace(); + } + return null; + } catch (Exception e) { + if (debug != null ) { + debug.println("unable to instantiate " + name); + e.printStackTrace(); + } + return null; + } + } + + /** + * This method always returns false for unresolved permissions. + * That is, an UnresolvedPermission is never considered to + * imply another permission. + * + * @param p the permission to check against. + * + * @return false. + */ + public boolean implies(Permission p) { + return false; + } + + /** + * Checks two UnresolvedPermission objects for equality. + * Checks that obj is an UnresolvedPermission, and has + * the same type (class) name, permission name, actions, and + * certificates as this object. + * + *

To determine certificate equality, this method only compares + * actual signer certificates. Supporting certificate chains + * are not taken into consideration by this method. + * + * @param obj the object we are testing for equality with this object. + * + * @return true if obj is an UnresolvedPermission, and has the same + * type (class) name, permission name, actions, and + * certificates as this object. + */ + public boolean equals(Object obj) { + if (obj == this) + return true; + + if (! (obj instanceof UnresolvedPermission)) + return false; + UnresolvedPermission that = (UnresolvedPermission) obj; + + // check type + if (!this.type.equals(that.type)) { + return false; + } + + // check name + if (this.name == null) { + if (that.name != null) { + return false; + } + } else if (!this.name.equals(that.name)) { + return false; + } + + // check actions + if (this.actions == null) { + if (that.actions != null) { + return false; + } + } else { + if (!this.actions.equals(that.actions)) { + return false; + } + } + + // check certs + if ((this.certs == null && that.certs != null) || + (this.certs != null && that.certs == null) || + (this.certs != null && that.certs != null && + this.certs.length != that.certs.length)) { + return false; + } + + int i,j; + boolean match; + + for (i = 0; this.certs != null && i < this.certs.length; i++) { + match = false; + for (j = 0; j < that.certs.length; j++) { + if (this.certs[i].equals(that.certs[j])) { + match = true; + break; + } + } + if (!match) return false; + } + + for (i = 0; that.certs != null && i < that.certs.length; i++) { + match = false; + for (j = 0; j < this.certs.length; j++) { + if (that.certs[i].equals(this.certs[j])) { + match = true; + break; + } + } + if (!match) return false; + } + return true; + } + + /** + * Returns the hash code value for this object. + * + * @return a hash code value for this object. + */ + + public int hashCode() { + int hash = type.hashCode(); + if (name != null) + hash ^= name.hashCode(); + if (actions != null) + hash ^= actions.hashCode(); + return hash; + } + + /** + * Returns the canonical string representation of the actions, + * which currently is the empty string "", since there are no actions for + * an UnresolvedPermission. That is, the actions for the + * permission that will be created when this UnresolvedPermission + * is resolved may be non-null, but an UnresolvedPermission + * itself is never considered to have any actions. + * + * @return the empty string "". + */ + public String getActions() + { + return ""; + } + + /** + * Get the type (class name) of the underlying permission that + * has not been resolved. + * + * @return the type (class name) of the underlying permission that + * has not been resolved + * + * @since 1.5 + */ + public String getUnresolvedType() { + return type; + } + + /** + * Get the target name of the underlying permission that + * has not been resolved. + * + * @return the target name of the underlying permission that + * has not been resolved, or {@code null}, + * if there is no target name + * + * @since 1.5 + */ + public String getUnresolvedName() { + return name; + } + + /** + * Get the actions for the underlying permission that + * has not been resolved. + * + * @return the actions for the underlying permission that + * has not been resolved, or {@code null} + * if there are no actions + * + * @since 1.5 + */ + public String getUnresolvedActions() { + return actions; + } + + /** + * Get the signer certificates (without any supporting chain) + * for the underlying permission that has not been resolved. + * + * @return the signer certificates for the underlying permission that + * has not been resolved, or null, if there are no signer certificates. + * Returns a new array each time this method is called. + * + * @since 1.5 + */ + public java.security.cert.Certificate[] getUnresolvedCerts() { + return (certs == null) ? null : certs.clone(); + } + + /** + * Returns a string describing this UnresolvedPermission. The convention + * is to specify the class name, the permission name, and the actions, in + * the following format: '(unresolved "ClassName" "name" "actions")'. + * + * @return information about this UnresolvedPermission. + */ + public String toString() { + return "(unresolved " + type + " " + name + " " + actions + ")"; + } + + /** + * Returns a new PermissionCollection object for storing + * UnresolvedPermission objects. + *

+ * @return a new PermissionCollection object suitable for + * storing UnresolvedPermissions. + */ + + public PermissionCollection newPermissionCollection() { + return new UnresolvedPermissionCollection(); + } + + /** + * Writes this object out to a stream (i.e., serializes it). + * + * @serialData An initial {@code String} denoting the + * {@code type} is followed by a {@code String} denoting the + * {@code name} is followed by a {@code String} denoting the + * {@code actions} is followed by an {@code int} indicating the + * number of certificates to follow + * (a value of "zero" denotes that there are no certificates associated + * with this object). + * Each certificate is written out starting with a {@code String} + * denoting the certificate type, followed by an + * {@code int} specifying the length of the certificate encoding, + * followed by the certificate encoding itself which is written out as an + * array of bytes. + */ + private void writeObject(java.io.ObjectOutputStream oos) + throws IOException + { + oos.defaultWriteObject(); + + if (certs==null || certs.length==0) { + oos.writeInt(0); + } else { + // write out the total number of certs + oos.writeInt(certs.length); + // write out each cert, including its type + for (int i=0; i < certs.length; i++) { + java.security.cert.Certificate cert = certs[i]; + try { + oos.writeUTF(cert.getType()); + byte[] encoded = cert.getEncoded(); + oos.writeInt(encoded.length); + oos.write(encoded); + } catch (CertificateEncodingException cee) { + throw new IOException(cee.getMessage()); + } + } + } + } + + /** + * Restores this object from a stream (i.e., deserializes it). + */ + private void readObject(java.io.ObjectInputStream ois) + throws IOException, ClassNotFoundException + { + CertificateFactory cf; + Hashtable cfs = null; + + ois.defaultReadObject(); + + if (type == null) + throw new NullPointerException("type can't be null"); + + // process any new-style certs in the stream (if present) + int size = ois.readInt(); + if (size > 0) { + // we know of 3 different cert types: X.509, PGP, SDSI, which + // could all be present in the stream at the same time + cfs = new Hashtable(3); + this.certs = new java.security.cert.Certificate[size]; + } + + for (int i=0; i> perms; + + /** + * Create an empty UnresolvedPermissionCollection object. + * + */ + public UnresolvedPermissionCollection() { + perms = new HashMap>(11); + } + + /** + * Adds a permission to this UnresolvedPermissionCollection. + * The key for the hash is the unresolved permission's type (class) name. + * + * @param permission the Permission object to add. + */ + + public void add(Permission permission) + { + if (! (permission instanceof UnresolvedPermission)) + throw new IllegalArgumentException("invalid permission: "+ + permission); + UnresolvedPermission up = (UnresolvedPermission) permission; + + List v; + synchronized (this) { + v = perms.get(up.getName()); + if (v == null) { + v = new ArrayList(); + perms.put(up.getName(), v); + } + } + synchronized (v) { + v.add(up); + } + } + + /** + * get any unresolved permissions of the same type as p, + * and return the List containing them. + */ + List getUnresolvedPermissions(Permission p) { + synchronized (this) { + return perms.get(p.getClass().getName()); + } + } + + /** + * always returns false for unresolved permissions + * + */ + public boolean implies(Permission permission) + { + return false; + } + + /** + * Returns an enumeration of all the UnresolvedPermission lists in the + * container. + * + * @return an enumeration of all the UnresolvedPermission objects. + */ + + public Enumeration elements() { + List results = + new ArrayList<>(); // where results are stored + + // Get iterator of Map values (which are lists of permissions) + synchronized (this) { + for (List l : perms.values()) { + synchronized (l) { + results.addAll(l); + } + } + } + + return Collections.enumeration(results); + } + + private static final long serialVersionUID = -7176153071733132400L; + + // Need to maintain serialization interoperability with earlier releases, + // which had the serializable field: + // private Hashtable permissions; // keyed on type + + /** + * @serialField permissions java.util.Hashtable + * A table of the UnresolvedPermissions keyed on type, value is Vector + * of permissions + */ + private static final ObjectStreamField[] serialPersistentFields = { + new ObjectStreamField("permissions", Hashtable.class), + }; + + /** + * @serialData Default field. + */ + /* + * Writes the contents of the perms field out as a Hashtable + * in which the values are Vectors for + * serialization compatibility with earlier releases. + */ + private void writeObject(ObjectOutputStream out) throws IOException { + // Don't call out.defaultWriteObject() + + // Copy perms into a Hashtable + Hashtable> permissions = + new Hashtable<>(perms.size()*2); + + // Convert each entry (List) into a Vector + synchronized (this) { + Set>> set = perms.entrySet(); + for (Map.Entry> e : set) { + // Convert list into Vector + List list = e.getValue(); + Vector vec = new Vector<>(list.size()); + synchronized (list) { + vec.addAll(list); + } + + // Add to Hashtable being serialized + permissions.put(e.getKey(), vec); + } + } + + // Write out serializable fields + ObjectOutputStream.PutField pfields = out.putFields(); + pfields.put("permissions", permissions); + out.writeFields(); + } + + /* + * Reads in a Hashtable in which the values are Vectors of + * UnresolvedPermissions and saves them in the perms field. + */ + private void readObject(ObjectInputStream in) throws IOException, + ClassNotFoundException { + // Don't call defaultReadObject() + + // Read in serialized fields + ObjectInputStream.GetField gfields = in.readFields(); + + // Get permissions + @SuppressWarnings("unchecked") + // writeObject writes a Hashtable> + // for the permissions key, so this cast is safe, unless the data is corrupt. + Hashtable> permissions = + (Hashtable>) + gfields.get("permissions", null); + perms = new HashMap>(permissions.size()*2); + + // Convert each entry (Vector) into a List + Set>> set = permissions.entrySet(); + for (Map.Entry> e : set) { + // Convert Vector into ArrayList + Vector vec = e.getValue(); + List list = new ArrayList<>(vec.size()); + list.addAll(vec); + + // Add to Hashtable being serialized + perms.put(e.getKey(), list); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/Acl.java b/sources/net.sf.j2s.java.core/src/java/security/acl/Acl.java new file mode 100644 index 000000000..b9cf0041d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/Acl.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 1996, 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 java.security.acl; + +import java.util.Enumeration; +import java.security.Principal; + +/** + * Interface representing an Access Control List (ACL). An Access + * Control List is a data structure used to guard access to + * resources.

+ * + * An ACL can be thought of as a data structure with multiple ACL + * entries. Each ACL entry, of interface type AclEntry, contains a + * set of permissions associated with a particular principal. (A + * principal represents an entity such as an individual user or a + * group). Additionally, each ACL entry is specified as being either + * positive or negative. If positive, the permissions are to be + * granted to the associated principal. If negative, the permissions + * are to be denied.

+ * + * The ACL Entries in each ACL observe the following rules: + * + *

  • Each principal can have at most one positive ACL entry and + * one negative entry; that is, multiple positive or negative ACL + * entries are not allowed for any principal. Each entry specifies + * the set of permissions that are to be granted (if positive) or + * denied (if negative). + * + *
  • If there is no entry for a particular principal, then the + * principal is considered to have a null (empty) permission set. + * + *
  • If there is a positive entry that grants a principal a + * particular permission, and a negative entry that denies the + * principal the same permission, the result is as though the + * permission was never granted or denied. + * + *
  • Individual permissions always override permissions of the + * group(s) to which the individual belongs. That is, individual + * negative permissions (specific denial of permissions) override the + * groups' positive permissions. And individual positive permissions + * override the groups' negative permissions. + * + *
+ * + * The {@code java.security.acl } package provides the + * interfaces to the ACL and related data structures (ACL entries, + * groups, permissions, etc.), and the {@code sun.security.acl } + * classes provide a default implementation of the interfaces. For + * example, {@code java.security.acl.Acl } provides the + * interface to an ACL and the {@code sun.security.acl.AclImpl } + * class provides the default implementation of the interface.

+ * + * The {@code java.security.acl.Acl } interface extends the + * {@code java.security.acl.Owner } interface. The Owner + * interface is used to maintain a list of owners for each ACL. Only + * owners are allowed to modify an ACL. For example, only an owner can + * call the ACL's {@code addEntry} method to add a new ACL entry + * to the ACL. + * + * @see java.security.acl.AclEntry + * @see java.security.acl.Owner + * @see java.security.acl.Acl#getPermissions + * + * @author Satish Dharmaraj + */ + +public interface Acl extends Owner { + + /** + * Sets the name of this ACL. + * + * @param caller the principal invoking this method. It must be an + * owner of this ACL. + * + * @param name the name to be given to this ACL. + * + * @exception NotOwnerException if the caller principal + * is not an owner of this ACL. + * + * @see #getName + */ + public void setName(Principal caller, String name) + throws NotOwnerException; + + /** + * Returns the name of this ACL. + * + * @return the name of this ACL. + * + * @see #setName + */ + public String getName(); + + /** + * Adds an ACL entry to this ACL. An entry associates a principal + * (e.g., an individual or a group) with a set of + * permissions. Each principal can have at most one positive ACL + * entry (specifying permissions to be granted to the principal) + * and one negative ACL entry (specifying permissions to be + * denied). If there is already an ACL entry of the same type + * (negative or positive) already in the ACL, false is returned. + * + * @param caller the principal invoking this method. It must be an + * owner of this ACL. + * + * @param entry the ACL entry to be added to this ACL. + * + * @return true on success, false if an entry of the same type + * (positive or negative) for the same principal is already + * present in this ACL. + * + * @exception NotOwnerException if the caller principal + * is not an owner of this ACL. + */ + public boolean addEntry(Principal caller, AclEntry entry) + throws NotOwnerException; + + /** + * Removes an ACL entry from this ACL. + * + * @param caller the principal invoking this method. It must be an + * owner of this ACL. + * + * @param entry the ACL entry to be removed from this ACL. + * + * @return true on success, false if the entry is not part of this ACL. + * + * @exception NotOwnerException if the caller principal is not + * an owner of this Acl. + */ + public boolean removeEntry(Principal caller, AclEntry entry) + throws NotOwnerException; + + /** + * Returns an enumeration for the set of allowed permissions for the + * specified principal (representing an entity such as an individual or + * a group). This set of allowed permissions is calculated as + * follows: + * + *

    + * + *
  • If there is no entry in this Access Control List for the + * specified principal, an empty permission set is returned. + * + *
  • Otherwise, the principal's group permission sets are determined. + * (A principal can belong to one or more groups, where a group is a + * group of principals, represented by the Group interface.) + * The group positive permission set is the union of all + * the positive permissions of each group that the principal belongs to. + * The group negative permission set is the union of all + * the negative permissions of each group that the principal belongs to. + * If there is a specific permission that occurs in both + * the positive permission set and the negative permission set, + * it is removed from both.

    + * + * The individual positive and negative permission sets are also + * determined. The positive permission set contains the permissions + * specified in the positive ACL entry (if any) for the principal. + * Similarly, the negative permission set contains the permissions + * specified in the negative ACL entry (if any) for the principal. + * The individual positive (or negative) permission set is considered + * to be null if there is not a positive (negative) ACL entry for the + * principal in this ACL.

    + * + * The set of permissions granted to the principal is then calculated + * using the simple rule that individual permissions always override + * the group permissions. That is, the principal's individual negative + * permission set (specific denial of permissions) overrides the group + * positive permission set, and the principal's individual positive + * permission set overrides the group negative permission set. + * + *

+ * + * @param user the principal whose permission set is to be returned. + * + * @return the permission set specifying the permissions the principal + * is allowed. + */ + public Enumeration getPermissions(Principal user); + + /** + * Returns an enumeration of the entries in this ACL. Each element in + * the enumeration is of type AclEntry. + * + * @return an enumeration of the entries in this ACL. + */ + public Enumeration entries(); + + /** + * Checks whether or not the specified principal has the specified + * permission. If it does, true is returned, otherwise false is returned. + * + * More specifically, this method checks whether the passed permission + * is a member of the allowed permission set of the specified principal. + * The allowed permission set is determined by the same algorithm as is + * used by the {@code getPermissions} method. + * + * @param principal the principal, assumed to be a valid authenticated + * Principal. + * + * @param permission the permission to be checked for. + * + * @return true if the principal has the specified permission, false + * otherwise. + * + * @see #getPermissions + */ + public boolean checkPermission(Principal principal, Permission permission); + + /** + * Returns a string representation of the + * ACL contents. + * + * @return a string representation of the ACL contents. + */ + public String toString(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/AclEntry.java b/sources/net.sf.j2s.java.core/src/java/security/acl/AclEntry.java new file mode 100644 index 000000000..cd9675f34 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/AclEntry.java @@ -0,0 +1,154 @@ +/* + * Copyright (c) 1996, 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 java.security.acl; + +import java.util.Enumeration; +import java.security.Principal; + +/** + * This is the interface used for representing one entry in an Access + * Control List (ACL).

+ * + * An ACL can be thought of as a data structure with multiple ACL entry + * objects. Each ACL entry object contains a set of permissions associated + * with a particular principal. (A principal represents an entity such as + * an individual user or a group). Additionally, each ACL entry is specified + * as being either positive or negative. If positive, the permissions are + * to be granted to the associated principal. If negative, the permissions + * are to be denied. Each principal can have at most one positive ACL entry + * and one negative entry; that is, multiple positive or negative ACL + * entries are not allowed for any principal. + * + * Note: ACL entries are by default positive. An entry becomes a + * negative entry only if the + * {@link #setNegativePermissions() setNegativePermissions} + * method is called on it. + * + * @see java.security.acl.Acl + * + * @author Satish Dharmaraj + */ +public interface AclEntry extends Cloneable { + + /** + * Specifies the principal for which permissions are granted or denied + * by this ACL entry. If a principal was already set for this ACL entry, + * false is returned, otherwise true is returned. + * + * @param user the principal to be set for this entry. + * + * @return true if the principal is set, false if there was + * already a principal set for this entry. + * + * @see #getPrincipal + */ + public boolean setPrincipal(Principal user); + + /** + * Returns the principal for which permissions are granted or denied by + * this ACL entry. Returns null if there is no principal set for this + * entry yet. + * + * @return the principal associated with this entry. + * + * @see #setPrincipal + */ + public Principal getPrincipal(); + + /** + * Sets this ACL entry to be a negative one. That is, the associated + * principal (e.g., a user or a group) will be denied the permission set + * specified in the entry. + * + * Note: ACL entries are by default positive. An entry becomes a + * negative entry only if this {@code setNegativePermissions} + * method is called on it. + */ + public void setNegativePermissions(); + + /** + * Returns true if this is a negative ACL entry (one denying the + * associated principal the set of permissions in the entry), false + * otherwise. + * + * @return true if this is a negative ACL entry, false if it's not. + */ + public boolean isNegative(); + + /** + * Adds the specified permission to this ACL entry. Note: An entry can + * have multiple permissions. + * + * @param permission the permission to be associated with + * the principal in this entry. + * + * @return true if the permission was added, false if the + * permission was already part of this entry's permission set. + */ + public boolean addPermission(Permission permission); + + /** + * Removes the specified permission from this ACL entry. + * + * @param permission the permission to be removed from this entry. + * + * @return true if the permission is removed, false if the + * permission was not part of this entry's permission set. + */ + public boolean removePermission(Permission permission); + + /** + * Checks if the specified permission is part of the + * permission set in this entry. + * + * @param permission the permission to be checked for. + * + * @return true if the permission is part of the + * permission set in this entry, false otherwise. + */ + public boolean checkPermission(Permission permission); + + /** + * Returns an enumeration of the permissions in this ACL entry. + * + * @return an enumeration of the permissions in this ACL entry. + */ + public Enumeration permissions(); + + /** + * Returns a string representation of the contents of this ACL entry. + * + * @return a string representation of the contents. + */ + public String toString(); + + /** + * Clones this ACL entry. + * + * @return a clone of this ACL entry. + */ + public Object clone(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/AclNotFoundException.java b/sources/net.sf.j2s.java.core/src/java/security/acl/AclNotFoundException.java new file mode 100644 index 000000000..6f08e178e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/AclNotFoundException.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1996, 2003, 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 java.security.acl; + +/** + * This is an exception that is thrown whenever a reference is made to a + * non-existent ACL (Access Control List). + * + * @author Satish Dharmaraj + */ +public class AclNotFoundException extends Exception { + + private static final long serialVersionUID = 5684295034092681791L; + + /** + * Constructs an AclNotFoundException. + */ + public AclNotFoundException() { + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/Group.java b/sources/net.sf.j2s.java.core/src/java/security/acl/Group.java new file mode 100644 index 000000000..ebd9c4452 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/Group.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 1996, 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 java.security.acl; + +import java.util.Enumeration; +import java.security.Principal; + +/** + * This interface is used to represent a group of principals. (A principal + * represents an entity such as an individual user or a company).

+ * + * Note that Group extends Principal. Thus, either a Principal or a Group can + * be passed as an argument to methods containing a Principal parameter. For + * example, you can add either a Principal or a Group to a Group object by + * calling the object's {@code addMember} method, passing it the + * Principal or Group. + * + * @author Satish Dharmaraj + */ +public interface Group extends Principal { + + /** + * Adds the specified member to the group. + * + * @param user the principal to add to this group. + * + * @return true if the member was successfully added, + * false if the principal was already a member. + */ + public boolean addMember(Principal user); + + /** + * Removes the specified member from the group. + * + * @param user the principal to remove from this group. + * + * @return true if the principal was removed, or + * false if the principal was not a member. + */ + public boolean removeMember(Principal user); + + /** + * Returns true if the passed principal is a member of the group. + * This method does a recursive search, so if a principal belongs to a + * group which is a member of this group, true is returned. + * + * @param member the principal whose membership is to be checked. + * + * @return true if the principal is a member of this group, + * false otherwise. + */ + public boolean isMember(Principal member); + + + /** + * Returns an enumeration of the members in the group. + * The returned objects can be instances of either Principal + * or Group (which is a subclass of Principal). + * + * @return an enumeration of the group members. + */ + public Enumeration members(); + +} diff --git a/sources/net.sf.j2s.java.core/unused/MenuContainer.java b/sources/net.sf.j2s.java.core/src/java/security/acl/LastOwnerException.java similarity index 67% rename from sources/net.sf.j2s.java.core/unused/MenuContainer.java rename to sources/net.sf.j2s.java.core/src/java/security/acl/LastOwnerException.java index 35532bfd5..196c8f1bd 100644 --- a/sources/net.sf.j2s.java.core/unused/MenuContainer.java +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/LastOwnerException.java @@ -1,8 +1,5 @@ /* - * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017 - * for use in SwingJS via transpilation into JavaScript using Java2Script. - * - * Copyright (c) 1995, 2004, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2003, 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 @@ -25,22 +22,24 @@ * or visit www.oracle.com if you need additional information or have any * questions. */ -package java.awt; + +package java.security.acl; /** - * The super class of all menu related containers. + * This is an exception that is thrown whenever an attempt is made to delete + * the last owner of an Access Control List. + * + * @see java.security.acl.Owner#deleteOwner * - * @author Arthur van Hoff + * @author Satish Dharmaraj */ +public class LastOwnerException extends Exception { -public interface MenuContainer { - Font getFont(); - //void remove(MenuComponent comp); + private static final long serialVersionUID = -5141997548211140359L; /** - * @deprecated As of JDK version 1.1 - * replaced by dispatchEvent(AWTEvent). + * Constructs a LastOwnerException. */ - @Deprecated - boolean postEvent(Event evt); + public LastOwnerException() { + } } diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/NotOwnerException.java b/sources/net.sf.j2s.java.core/src/java/security/acl/NotOwnerException.java new file mode 100644 index 000000000..0a4b04b22 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/NotOwnerException.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1996, 2003, 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 java.security.acl; + +/** + * This is an exception that is thrown whenever the modification of an object + * (such as an Access Control List) is only allowed to be done by an owner of + * the object, but the Principal attempting the modification is not an owner. + * + * @author Satish Dharmaraj + */ +public class NotOwnerException extends Exception { + + private static final long serialVersionUID = -5555597911163362399L; + + /** + * Constructs a NotOwnerException. + */ + public NotOwnerException() { + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/Owner.java b/sources/net.sf.j2s.java.core/src/java/security/acl/Owner.java new file mode 100644 index 000000000..2f649d40b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/Owner.java @@ -0,0 +1,95 @@ +/* + * Copyright (c) 1996, 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 java.security.acl; + +import java.security.Principal; + +/** + * Interface for managing owners of Access Control Lists (ACLs) or ACL + * configurations. (Note that the Acl interface in the + * {@code java.security.acl} package extends this Owner + * interface.) The initial owner Principal should be specified as an + * argument to the constructor of the class implementing this interface. + * + * @see java.security.acl.Acl + * + */ +public interface Owner { + + /** + * Adds an owner. Only owners can modify ACL contents. The caller + * principal must be an owner of the ACL in order to invoke this method. + * That is, only an owner can add another owner. The initial owner is + * configured at ACL construction time. + * + * @param caller the principal invoking this method. It must be an owner + * of the ACL. + * + * @param owner the owner that should be added to the list of owners. + * + * @return true if successful, false if owner is already an owner. + * @exception NotOwnerException if the caller principal is not an owner + * of the ACL. + */ + public boolean addOwner(Principal caller, Principal owner) + throws NotOwnerException; + + /** + * Deletes an owner. If this is the last owner in the ACL, an exception is + * raised.

+ * + * The caller principal must be an owner of the ACL in order to invoke + * this method. + * + * @param caller the principal invoking this method. It must be an owner + * of the ACL. + * + * @param owner the owner to be removed from the list of owners. + * + * @return true if the owner is removed, false if the owner is not part + * of the list of owners. + * + * @exception NotOwnerException if the caller principal is not an owner + * of the ACL. + * + * @exception LastOwnerException if there is only one owner left, so that + * deleteOwner would leave the ACL owner-less. + */ + public boolean deleteOwner(Principal caller, Principal owner) + throws NotOwnerException, LastOwnerException; + + /** + * Returns true if the given principal is an owner of the ACL. + * + * @param owner the principal to be checked to determine whether or not + * it is an owner. + * + * @return true if the passed principal is in the list of owners, false + * if not. + */ + public boolean isOwner(Principal owner); + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/Permission.java b/sources/net.sf.j2s.java.core/src/java/security/acl/Permission.java new file mode 100644 index 000000000..380a0102c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/Permission.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1996, 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 java.security.acl; + + +/** + * This interface represents a permission, such as that used to grant + * a particular type of access to a resource. + * + * @author Satish Dharmaraj + */ +public interface Permission { + + /** + * Returns true if the object passed matches the permission represented + * in this interface. + * + * @param another the Permission object to compare with. + * + * @return true if the Permission objects are equal, false otherwise + */ + public boolean equals(Object another); + + /** + * Prints a string representation of this permission. + * + * @return the string representation of the permission. + */ + public String toString(); + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/acl/package-info.java b/sources/net.sf.j2s.java.core/src/java/security/acl/package-info.java new file mode 100644 index 000000000..356c102e3 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/acl/package-info.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1998, 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. + */ + +/** + * The classes and interfaces in this package have been + * superseded by classes in the java.security package. + * See that package and, for example, java.security.Permission for details. + * + * @since JDK1.1 + */ +package java.security.acl; diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CRL.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CRL.java new file mode 100644 index 000000000..f8083c723 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CRL.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1998, 2006, 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 java.security.cert; + +/** + * This class is an abstraction of certificate revocation lists (CRLs) that + * have different formats but important common uses. For example, all CRLs + * share the functionality of listing revoked certificates, and can be queried + * on whether or not they list a given certificate. + *

+ * Specialized CRL types can be defined by subclassing off of this abstract + * class. + * + * @author Hemma Prafullchandra + * + * + * @see X509CRL + * @see CertificateFactory + * + * @since 1.2 + */ + +public abstract class CRL { + + // the CRL type + private String type; + + /** + * Creates a CRL of the specified type. + * + * @param type the standard name of the CRL type. + * See Appendix A in the + * Java Cryptography Architecture API Specification & Reference + * for information about standard CRL types. + */ + protected CRL(String type) { + this.type = type; + } + + /** + * Returns the type of this CRL. + * + * @return the type of this CRL. + */ + public final String getType() { + return this.type; + } + + /** + * Returns a string representation of this CRL. + * + * @return a string representation of this CRL. + */ + public abstract String toString(); + + /** + * Checks whether the given certificate is on this CRL. + * + * @param cert the certificate to check for. + * @return true if the given certificate is on this CRL, + * false otherwise. + */ + public abstract boolean isRevoked(Certificate cert); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CRLException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CRLException.java new file mode 100644 index 000000000..7a854316b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CRLException.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +import java.security.GeneralSecurityException; + +/** + * CRL (Certificate Revocation List) Exception. + * + * @author Hemma Prafullchandra + */ +public class CRLException extends GeneralSecurityException { + + private static final long serialVersionUID = -6694728944094197147L; + + /** + * Constructs a CRLException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public CRLException() { + super(); + } + + /** + * Constructs a CRLException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param message the detail message. + */ + public CRLException(String message) { + super(message); + } + + /** + * Creates a {@code CRLException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CRLException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code CRLException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CRLException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CRLReason.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CRLReason.java new file mode 100644 index 000000000..ac0b9e9c2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CRLReason.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2007, 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 java.security.cert; + +/** + * The CRLReason enumeration specifies the reason that a certificate + * is revoked, as defined in + * RFC 3280: Internet X.509 Public Key Infrastructure Certificate and CRL + * Profile. + * + * @author Sean Mullan + * @since 1.7 + * @see X509CRLEntry#getRevocationReason + * @see CertificateRevokedException#getRevocationReason + */ +public enum CRLReason { + /** + * This reason indicates that it is unspecified as to why the + * certificate has been revoked. + */ + UNSPECIFIED, + + /** + * This reason indicates that it is known or suspected that the + * certificate subject's private key has been compromised. It applies + * to end-entity certificates only. + */ + KEY_COMPROMISE, + + /** + * This reason indicates that it is known or suspected that the + * certificate subject's private key has been compromised. It applies + * to certificate authority (CA) certificates only. + */ + CA_COMPROMISE, + + /** + * This reason indicates that the subject's name or other information + * has changed. + */ + AFFILIATION_CHANGED, + + /** + * This reason indicates that the certificate has been superseded. + */ + SUPERSEDED, + + /** + * This reason indicates that the certificate is no longer needed. + */ + CESSATION_OF_OPERATION, + + /** + * This reason indicates that the certificate has been put on hold. + */ + CERTIFICATE_HOLD, + + /** + * Unused reason. + */ + UNUSED, + + /** + * This reason indicates that the certificate was previously on hold + * and should be removed from the CRL. It is for use with delta CRLs. + */ + REMOVE_FROM_CRL, + + /** + * This reason indicates that the privileges granted to the subject of + * the certificate have been withdrawn. + */ + PRIVILEGE_WITHDRAWN, + + /** + * This reason indicates that it is known or suspected that the + * certificate subject's private key has been compromised. It applies + * to authority attribute (AA) certificates only. + */ + AA_COMPROMISE +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CRLSelector.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CRLSelector.java new file mode 100644 index 000000000..7ab181d48 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CRLSelector.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +/** + * A selector that defines a set of criteria for selecting {@code CRL}s. + * Classes that implement this interface are often used to specify + * which {@code CRL}s should be retrieved from a {@code CertStore}. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this interface are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CRL + * @see CertStore + * @see CertStore#getCRLs + * + * @author Steve Hanna + * @since 1.4 + */ +public interface CRLSelector extends Cloneable { + + /** + * Decides whether a {@code CRL} should be selected. + * + * @param crl the {@code CRL} to be checked + * @return {@code true} if the {@code CRL} should be selected, + * {@code false} otherwise + */ + boolean match(CRL crl); + + /** + * Makes a copy of this {@code CRLSelector}. Changes to the + * copy will not affect the original and vice versa. + * + * @return a copy of this {@code CRLSelector} + */ + Object clone(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPath.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPath.java new file mode 100644 index 000000000..8717f9482 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPath.java @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.io.ByteArrayInputStream; +import java.io.NotSerializableException; +import java.io.ObjectStreamException; +import java.io.Serializable; +import java.util.Iterator; +import java.util.List; + +/** + * An immutable sequence of certificates (a certification path). + *

+ * This is an abstract class that defines the methods common to all + * {@code CertPath}s. Subclasses can handle different kinds of + * certificates (X.509, PGP, etc.). + *

+ * All {@code CertPath} objects have a type, a list of + * {@code Certificate}s, and one or more supported encodings. Because the + * {@code CertPath} class is immutable, a {@code CertPath} cannot + * change in any externally visible way after being constructed. This + * stipulation applies to all public fields and methods of this class and any + * added or overridden by subclasses. + *

+ * The type is a {@code String} that identifies the type of + * {@code Certificate}s in the certification path. For each + * certificate {@code cert} in a certification path {@code certPath}, + * {@code cert.getType().equals(certPath.getType())} must be + * {@code true}. + *

+ * The list of {@code Certificate}s is an ordered {@code List} of + * zero or more {@code Certificate}s. This {@code List} and all + * of the {@code Certificate}s contained in it must be immutable. + *

+ * Each {@code CertPath} object must support one or more encodings + * so that the object can be translated into a byte array for storage or + * transmission to other parties. Preferably, these encodings should be + * well-documented standards (such as PKCS#7). One of the encodings supported + * by a {@code CertPath} is considered the default encoding. This + * encoding is used if no encoding is explicitly requested (for the + * {@link #getEncoded() getEncoded()} method, for instance). + *

+ * All {@code CertPath} objects are also {@code Serializable}. + * {@code CertPath} objects are resolved into an alternate + * {@link CertPathRep CertPathRep} object during serialization. This allows + * a {@code CertPath} object to be serialized into an equivalent + * representation regardless of its underlying implementation. + *

+ * {@code CertPath} objects can be created with a + * {@code CertificateFactory} or they can be returned by other classes, + * such as a {@code CertPathBuilder}. + *

+ * By convention, X.509 {@code CertPath}s (consisting of + * {@code X509Certificate}s), are ordered starting with the target + * certificate and ending with a certificate issued by the trust anchor. That + * is, the issuer of one certificate is the subject of the following one. The + * certificate representing the {@link TrustAnchor TrustAnchor} should not be + * included in the certification path. Unvalidated X.509 {@code CertPath}s + * may not follow these conventions. PKIX {@code CertPathValidator}s will + * detect any departure from these conventions that cause the certification + * path to be invalid and throw a {@code CertPathValidatorException}. + * + *

Every implementation of the Java platform is required to support the + * following standard {@code CertPath} encodings: + *

    + *
  • {@code PKCS7}
  • + *
  • {@code PkiPath}
  • + *
+ * These encodings are described in the + * CertPath Encodings section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other encodings are supported. + *

+ * Concurrent Access + *

+ * All {@code CertPath} objects must be thread-safe. That is, multiple + * threads may concurrently invoke the methods defined in this class on a + * single {@code CertPath} object (or more than one) with no + * ill effects. This is also true for the {@code List} returned by + * {@code CertPath.getCertificates}. + *

+ * Requiring {@code CertPath} objects to be immutable and thread-safe + * allows them to be passed around to various pieces of code without worrying + * about coordinating access. Providing this thread-safety is + * generally not difficult, since the {@code CertPath} and + * {@code List} objects in question are immutable. + * + * @see CertificateFactory + * @see CertPathBuilder + * + * @author Yassir Elley + * @since 1.4 + */ +public abstract class CertPath implements Serializable { + + private static final long serialVersionUID = 6068470306649138683L; + + private String type; // the type of certificates in this chain + + /** + * Creates a {@code CertPath} of the specified type. + *

+ * This constructor is protected because most users should use a + * {@code CertificateFactory} to create {@code CertPath}s. + * + * @param type the standard name of the type of + * {@code Certificate}s in this path + */ + protected CertPath(String type) { + this.type = type; + } + + /** + * Returns the type of {@code Certificate}s in this certification + * path. This is the same string that would be returned by + * {@link java.security.cert.Certificate#getType() cert.getType()} + * for all {@code Certificate}s in the certification path. + * + * @return the type of {@code Certificate}s in this certification + * path (never null) + */ + public String getType() { + return type; + } + + /** + * Returns an iteration of the encodings supported by this certification + * path, with the default encoding first. Attempts to modify the returned + * {@code Iterator} via its {@code remove} method result in an + * {@code UnsupportedOperationException}. + * + * @return an {@code Iterator} over the names of the supported + * encodings (as Strings) + */ + public abstract Iterator getEncodings(); + + /** + * Compares this certification path for equality with the specified + * object. Two {@code CertPath}s are equal if and only if their + * types are equal and their certificate {@code List}s (and by + * implication the {@code Certificate}s in those {@code List}s) + * are equal. A {@code CertPath} is never equal to an object that is + * not a {@code CertPath}. + *

+ * This algorithm is implemented by this method. If it is overridden, + * the behavior specified here must be maintained. + * + * @param other the object to test for equality with this certification path + * @return true if the specified object is equal to this certification path, + * false otherwise + */ + public boolean equals(Object other) { + if (this == other) + return true; + + if (! (other instanceof CertPath)) + return false; + + CertPath otherCP = (CertPath) other; + if (! otherCP.getType().equals(type)) + return false; + + List thisCertList = this.getCertificates(); + List otherCertList = otherCP.getCertificates(); + return(thisCertList.equals(otherCertList)); + } + + /** + * Returns the hashcode for this certification path. The hash code of + * a certification path is defined to be the result of the following + * calculation: + *

{@code
+     *  hashCode = path.getType().hashCode();
+     *  hashCode = 31*hashCode + path.getCertificates().hashCode();
+     * }
+ * This ensures that {@code path1.equals(path2)} implies that + * {@code path1.hashCode()==path2.hashCode()} for any two certification + * paths, {@code path1} and {@code path2}, as required by the + * general contract of {@code Object.hashCode}. + * + * @return the hashcode value for this certification path + */ + public int hashCode() { + int hashCode = type.hashCode(); + hashCode = 31*hashCode + getCertificates().hashCode(); + return hashCode; + } + + /** + * Returns a string representation of this certification path. + * This calls the {@code toString} method on each of the + * {@code Certificate}s in the path. + * + * @return a string representation of this certification path + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + Iterator stringIterator = + getCertificates().iterator(); + + sb.append("\n" + type + " Cert Path: length = " + + getCertificates().size() + ".\n"); + sb.append("[\n"); + int i = 1; + while (stringIterator.hasNext()) { + sb.append("==========================================" + + "===============Certificate " + i + " start.\n"); + Certificate stringCert = stringIterator.next(); + sb.append(stringCert.toString()); + sb.append("\n========================================" + + "=================Certificate " + i + " end.\n\n\n"); + i++; + } + + sb.append("\n]"); + return sb.toString(); + } + + /** + * Returns the encoded form of this certification path, using the default + * encoding. + * + * @return the encoded bytes + * @exception CertificateEncodingException if an encoding error occurs + */ + public abstract byte[] getEncoded() + throws CertificateEncodingException; + + /** + * Returns the encoded form of this certification path, using the + * specified encoding. + * + * @param encoding the name of the encoding to use + * @return the encoded bytes + * @exception CertificateEncodingException if an encoding error occurs or + * the encoding requested is not supported + */ + public abstract byte[] getEncoded(String encoding) + throws CertificateEncodingException; + + /** + * Returns the list of certificates in this certification path. + * The {@code List} returned must be immutable and thread-safe. + * + * @return an immutable {@code List} of {@code Certificate}s + * (may be empty, but not null) + */ + public abstract List getCertificates(); + + /** + * Replaces the {@code CertPath} to be serialized with a + * {@code CertPathRep} object. + * + * @return the {@code CertPathRep} to be serialized + * + * @throws ObjectStreamException if a {@code CertPathRep} object + * representing this certification path could not be created + */ + protected Object writeReplace() throws ObjectStreamException { + try { + return new CertPathRep(type, getEncoded()); + } catch (CertificateException ce) { + NotSerializableException nse = + new NotSerializableException + ("java.security.cert.CertPath: " + type); + nse.initCause(ce); + throw nse; + } + } + + /** + * Alternate {@code CertPath} class for serialization. + * @since 1.4 + */ + protected static class CertPathRep implements Serializable { + + private static final long serialVersionUID = 3015633072427920915L; + + /** The Certificate type */ + private String type; + /** The encoded form of the cert path */ + private byte[] data; + + /** + * Creates a {@code CertPathRep} with the specified + * type and encoded form of a certification path. + * + * @param type the standard name of a {@code CertPath} type + * @param data the encoded form of the certification path + */ + protected CertPathRep(String type, byte[] data) { + this.type = type; + this.data = data; + } + + /** + * Returns a {@code CertPath} constructed from the type and data. + * + * @return the resolved {@code CertPath} object + * + * @throws ObjectStreamException if a {@code CertPath} could not + * be constructed + */ + protected Object readResolve() throws ObjectStreamException { + try { + CertificateFactory cf = CertificateFactory.getInstance(type); + return cf.generateCertPath(new ByteArrayInputStream(data)); + } catch (CertificateException ce) { + NotSerializableException nse = + new NotSerializableException + ("java.security.cert.CertPath: " + type); + nse.initCause(ce); + throw nse; + } + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilder.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilder.java new file mode 100644 index 000000000..6008e9ec1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilder.java @@ -0,0 +1,331 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.AccessController; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivilegedAction; +import java.security.Provider; +import java.security.Security; +import sun.security.util.Debug; + +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; + +/** + * A class for building certification paths (also known as certificate chains). + *

+ * This class uses a provider-based architecture. + * To create a {@code CertPathBuilder}, call + * one of the static {@code getInstance} methods, passing in the + * algorithm name of the {@code CertPathBuilder} desired and optionally + * the name of the provider desired. + * + *

Once a {@code CertPathBuilder} object has been created, certification + * paths can be constructed by calling the {@link #build build} method and + * passing it an algorithm-specific set of parameters. If successful, the + * result (including the {@code CertPath} that was built) is returned + * in an object that implements the {@code CertPathBuilderResult} + * interface. + * + *

The {@link #getRevocationChecker} method allows an application to specify + * additional algorithm-specific parameters and options used by the + * {@code CertPathBuilder} when checking the revocation status of certificates. + * Here is an example demonstrating how it is used with the PKIX algorithm: + * + *

+ * CertPathBuilder cpb = CertPathBuilder.getInstance("PKIX");
+ * PKIXRevocationChecker rc = (PKIXRevocationChecker)cpb.getRevocationChecker();
+ * rc.setOptions(EnumSet.of(Option.PREFER_CRLS));
+ * params.addCertPathChecker(rc);
+ * CertPathBuilderResult cpbr = cpb.build(params);
+ * 
+ * + *

Every implementation of the Java platform is required to support the + * following standard {@code CertPathBuilder} algorithm: + *

    + *
  • {@code PKIX}
  • + *
+ * This algorithm is described in the + * CertPathBuilder section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + *

+ * Concurrent Access + *

+ * The static methods of this class are guaranteed to be thread-safe. + * Multiple threads may concurrently invoke the static methods defined in + * this class with no ill effects. + *

+ * However, this is not true for the non-static methods defined by this class. + * Unless otherwise documented by a specific provider, threads that need to + * access a single {@code CertPathBuilder} instance concurrently should + * synchronize amongst themselves and provide the necessary locking. Multiple + * threads each manipulating a different {@code CertPathBuilder} instance + * need not synchronize. + * + * @see CertPath + * + * @since 1.4 + * @author Sean Mullan + * @author Yassir Elley + */ +public class CertPathBuilder { + + /* + * Constant to lookup in the Security properties file to determine + * the default certpathbuilder type. In the Security properties file, + * the default certpathbuilder type is given as: + *

+     * certpathbuilder.type=PKIX
+     * 
+ */ + private static final String CPB_TYPE = "certpathbuilder.type"; + private final CertPathBuilderSpi builderSpi; + private final Provider provider; + private final String algorithm; + + /** + * Creates a {@code CertPathBuilder} object of the given algorithm, + * and encapsulates the given provider implementation (SPI object) in it. + * + * @param builderSpi the provider implementation + * @param provider the provider + * @param algorithm the algorithm name + */ + protected CertPathBuilder(CertPathBuilderSpi builderSpi, Provider provider, + String algorithm) + { + this.builderSpi = builderSpi; + this.provider = provider; + this.algorithm = algorithm; + } + + /** + * Returns a {@code CertPathBuilder} object that implements the + * specified algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new CertPathBuilder object encapsulating the + * CertPathBuilderSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the requested {@code CertPathBuilder} + * algorithm. See the CertPathBuilder section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return a {@code CertPathBuilder} object that implements the + * specified algorithm. + * + * @throws NoSuchAlgorithmException if no Provider supports a + * CertPathBuilderSpi implementation for the + * specified algorithm. + * + * @see java.security.Provider + */ + public static CertPathBuilder getInstance(String algorithm) + throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("CertPathBuilder", + CertPathBuilderSpi.class, algorithm); + return new CertPathBuilder((CertPathBuilderSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns a {@code CertPathBuilder} object that implements the + * specified algorithm. + * + *

A new CertPathBuilder object encapsulating the + * CertPathBuilderSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the requested {@code CertPathBuilder} + * algorithm. See the CertPathBuilder section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the name of the provider. + * + * @return a {@code CertPathBuilder} object that implements the + * specified algorithm. + * + * @throws NoSuchAlgorithmException if a CertPathBuilderSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @throws NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the {@code provider} is + * null or empty. + * + * @see java.security.Provider + */ + public static CertPathBuilder getInstance(String algorithm, String provider) + throws NoSuchAlgorithmException, NoSuchProviderException { + Instance instance = GetInstance.getInstance("CertPathBuilder", + CertPathBuilderSpi.class, algorithm, provider); + return new CertPathBuilder((CertPathBuilderSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns a {@code CertPathBuilder} object that implements the + * specified algorithm. + * + *

A new CertPathBuilder object encapsulating the + * CertPathBuilderSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param algorithm the name of the requested {@code CertPathBuilder} + * algorithm. See the CertPathBuilder section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the provider. + * + * @return a {@code CertPathBuilder} object that implements the + * specified algorithm. + * + * @exception NoSuchAlgorithmException if a CertPathBuilderSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the {@code provider} is + * null. + * + * @see java.security.Provider + */ + public static CertPathBuilder getInstance(String algorithm, + Provider provider) throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("CertPathBuilder", + CertPathBuilderSpi.class, algorithm, provider); + return new CertPathBuilder((CertPathBuilderSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns the provider of this {@code CertPathBuilder}. + * + * @return the provider of this {@code CertPathBuilder} + */ + public final Provider getProvider() { + return this.provider; + } + + /** + * Returns the name of the algorithm of this {@code CertPathBuilder}. + * + * @return the name of the algorithm of this {@code CertPathBuilder} + */ + public final String getAlgorithm() { + return this.algorithm; + } + + /** + * Attempts to build a certification path using the specified algorithm + * parameter set. + * + * @param params the algorithm parameters + * @return the result of the build algorithm + * @throws CertPathBuilderException if the builder is unable to construct + * a certification path that satisfies the specified parameters + * @throws InvalidAlgorithmParameterException if the specified parameters + * are inappropriate for this {@code CertPathBuilder} + */ + public final CertPathBuilderResult build(CertPathParameters params) + throws CertPathBuilderException, InvalidAlgorithmParameterException + { + return builderSpi.engineBuild(params); + } + + /** + * Returns the default {@code CertPathBuilder} type as specified by + * the {@code certpathbuilder.type} security property, or the string + * {@literal "PKIX"} if no such property exists. + * + *

The default {@code CertPathBuilder} type can be used by + * applications that do not want to use a hard-coded type when calling one + * of the {@code getInstance} methods, and want to provide a default + * type in case a user does not specify its own. + * + *

The default {@code CertPathBuilder} type can be changed by + * setting the value of the {@code certpathbuilder.type} security property + * to the desired type. + * + * @see java.security.Security security properties + * @return the default {@code CertPathBuilder} type as specified + * by the {@code certpathbuilder.type} security property, or the string + * {@literal "PKIX"} if no such property exists. + */ + public final static String getDefaultType() { + String cpbtype = + AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return Security.getProperty(CPB_TYPE); + } + }); + return (cpbtype == null) ? "PKIX" : cpbtype; + } + + /** + * Returns a {@code CertPathChecker} that the encapsulated + * {@code CertPathBuilderSpi} implementation uses to check the revocation + * status of certificates. A PKIX implementation returns objects of + * type {@code PKIXRevocationChecker}. Each invocation of this method + * returns a new instance of {@code CertPathChecker}. + * + *

The primary purpose of this method is to allow callers to specify + * additional input parameters and options specific to revocation checking. + * See the class description for an example. + * + * @return a {@code CertPathChecker} + * @throws UnsupportedOperationException if the service provider does not + * support this method + * @since 1.8 + */ + public final CertPathChecker getRevocationChecker() { + return builderSpi.engineGetRevocationChecker(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderException.java new file mode 100644 index 000000000..cf9584792 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderException.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.GeneralSecurityException; + +/** + * An exception indicating one of a variety of problems encountered when + * building a certification path with a {@code CertPathBuilder}. + *

+ * A {@code CertPathBuilderException} provides support for wrapping + * exceptions. The {@link #getCause getCause} method returns the throwable, + * if any, that caused this exception to be thrown. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathBuilder + * + * @since 1.4 + * @author Sean Mullan + */ +public class CertPathBuilderException extends GeneralSecurityException { + + private static final long serialVersionUID = 5316471420178794402L; + + /** + * Creates a {@code CertPathBuilderException} with {@code null} + * as its detail message. + */ + public CertPathBuilderException() { + super(); + } + + /** + * Creates a {@code CertPathBuilderException} with the given + * detail message. The detail message is a {@code String} that + * describes this particular exception in more detail. + * + * @param msg the detail message + */ + public CertPathBuilderException(String msg) { + super(msg); + } + + /** + * Creates a {@code CertPathBuilderException} that wraps the specified + * throwable. This allows any exception to be converted into a + * {@code CertPathBuilderException}, while retaining information + * about the wrapped exception, which may be useful for debugging. The + * detail message is set to ({@code cause==null ? null : cause.toString()}) + * (which typically contains the class and detail message of + * cause). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public CertPathBuilderException(Throwable cause) { + super(cause); + } + + /** + * Creates a {@code CertPathBuilderException} with the specified + * detail message and cause. + * + * @param msg the detail message + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public CertPathBuilderException(String msg, Throwable cause) { + super(msg, cause); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderResult.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderResult.java new file mode 100644 index 000000000..ecf53bbe7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderResult.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +/** + * A specification of the result of a certification path builder algorithm. + * All results returned by the {@link CertPathBuilder#build + * CertPathBuilder.build} method must implement this interface. + *

+ * At a minimum, a {@code CertPathBuilderResult} contains the + * {@code CertPath} built by the {@code CertPathBuilder} instance. + * Implementations of this interface may add methods to return implementation + * or algorithm specific information, such as debugging information or + * certification path validation results. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this interface are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathBuilder + * + * @since 1.4 + * @author Sean Mullan + */ +public interface CertPathBuilderResult extends Cloneable { + + /** + * Returns the built certification path. + * + * @return the certification path (never {@code null}) + */ + CertPath getCertPath(); + + /** + * Makes a copy of this {@code CertPathBuilderResult}. Changes to the + * copy will not affect the original and vice versa. + * + * @return a copy of this {@code CertPathBuilderResult} + */ + Object clone(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderSpi.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderSpi.java new file mode 100644 index 000000000..e77554117 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathBuilderSpi.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.InvalidAlgorithmParameterException; + +/** + * The Service Provider Interface (SPI) + * for the {@link CertPathBuilder CertPathBuilder} class. All + * {@code CertPathBuilder} implementations must include a class (the + * SPI class) that extends this class ({@code CertPathBuilderSpi}) and + * implements all of its methods. In general, instances of this class should + * only be accessed through the {@code CertPathBuilder} class. For + * details, see the Java Cryptography Architecture. + *

+ * Concurrent Access + *

+ * Instances of this class need not be protected against concurrent + * access from multiple threads. Threads that need to access a single + * {@code CertPathBuilderSpi} instance concurrently should synchronize + * amongst themselves and provide the necessary locking before calling the + * wrapping {@code CertPathBuilder} object. + *

+ * However, implementations of {@code CertPathBuilderSpi} may still + * encounter concurrency issues, since multiple threads each + * manipulating a different {@code CertPathBuilderSpi} instance need not + * synchronize. + * + * @since 1.4 + * @author Sean Mullan + */ +public abstract class CertPathBuilderSpi { + + /** + * The default constructor. + */ + public CertPathBuilderSpi() { } + + /** + * Attempts to build a certification path using the specified + * algorithm parameter set. + * + * @param params the algorithm parameters + * @return the result of the build algorithm + * @throws CertPathBuilderException if the builder is unable to construct + * a certification path that satisfies the specified parameters + * @throws InvalidAlgorithmParameterException if the specified parameters + * are inappropriate for this {@code CertPathBuilder} + */ + public abstract CertPathBuilderResult engineBuild(CertPathParameters params) + throws CertPathBuilderException, InvalidAlgorithmParameterException; + + /** + * Returns a {@code CertPathChecker} that this implementation uses to + * check the revocation status of certificates. A PKIX implementation + * returns objects of type {@code PKIXRevocationChecker}. + * + *

The primary purpose of this method is to allow callers to specify + * additional input parameters and options specific to revocation checking. + * See the class description of {@code CertPathBuilder} for an example. + * + *

This method was added to version 1.8 of the Java Platform Standard + * Edition. In order to maintain backwards compatibility with existing + * service providers, this method cannot be abstract and by default throws + * an {@code UnsupportedOperationException}. + * + * @return a {@code CertPathChecker} that this implementation uses to + * check the revocation status of certificates + * @throws UnsupportedOperationException if this method is not supported + * @since 1.8 + */ + public CertPathChecker engineGetRevocationChecker() { + throw new UnsupportedOperationException(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathChecker.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathChecker.java new file mode 100644 index 000000000..c40a65b63 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathChecker.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2012, 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 java.security.cert; + +/** + *

Performs one or more checks on each {@code Certificate} of a + * {@code CertPath}. + * + *

A {@code CertPathChecker} implementation is typically created to extend + * a certification path validation algorithm. For example, an implementation + * may check for and process a critical private extension of each certificate + * in a certification path. + * + * @since 1.8 + */ +public interface CertPathChecker { + + /** + * Initializes the internal state of this {@code CertPathChecker}. + * + *

The {@code forward} flag specifies the order that certificates will + * be passed to the {@link #check check} method (forward or reverse). + * + * @param forward the order that certificates are presented to the + * {@code check} method. If {@code true}, certificates are + * presented from target to trust anchor (forward); if + * {@code false}, from trust anchor to target (reverse). + * @throws CertPathValidatorException if this {@code CertPathChecker} is + * unable to check certificates in the specified order + */ + void init(boolean forward) throws CertPathValidatorException; + + /** + * Indicates if forward checking is supported. Forward checking refers + * to the ability of the {@code CertPathChecker} to perform its checks + * when certificates are presented to the {@code check} method in the + * forward direction (from target to trust anchor). + * + * @return {@code true} if forward checking is supported, {@code false} + * otherwise + */ + boolean isForwardCheckingSupported(); + + /** + * Performs the check(s) on the specified certificate using its internal + * state. The certificates are presented in the order specified by the + * {@code init} method. + * + * @param cert the {@code Certificate} to be checked + * @throws CertPathValidatorException if the specified certificate does + * not pass the check + */ + void check(Certificate cert) throws CertPathValidatorException; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathHelperImpl.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathHelperImpl.java new file mode 100644 index 000000000..fd9e11198 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathHelperImpl.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2002, 2009, 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 java.security.cert; + +import java.util.*; + +import sun.security.provider.certpath.CertPathHelper; + +import sun.security.x509.GeneralNameInterface; + +/** + * Helper class that allows the Sun CertPath provider to access + * implementation dependent APIs in CertPath framework. + * + * @author Andreas Sterbenz + */ +class CertPathHelperImpl extends CertPathHelper { + + private CertPathHelperImpl() { + // empty + } + + /** + * Initialize the helper framework. This method must be called from + * the static initializer of each class that is the target of one of + * the methods in this class. This ensures that the helper is initialized + * prior to a tunneled call from the Sun provider. + */ + synchronized static void initialize() { + if (CertPathHelper.instance == null) { + CertPathHelper.instance = new CertPathHelperImpl(); + } + } + + protected void implSetPathToNames(X509CertSelector sel, + Set names) { + sel.setPathToNamesInternal(names); + } + + protected void implSetDateAndTime(X509CRLSelector sel, Date date, long skew) { + sel.setDateAndTime(date, skew); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathParameters.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathParameters.java new file mode 100644 index 000000000..ace1b21f6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathParameters.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +/** + * A specification of certification path algorithm parameters. + * The purpose of this interface is to group (and provide type safety for) + * all {@code CertPath} parameter specifications. All + * {@code CertPath} parameter specifications must implement this + * interface. + * + * @author Yassir Elley + * @see CertPathValidator#validate(CertPath, CertPathParameters) + * @see CertPathBuilder#build(CertPathParameters) + * @since 1.4 + */ +public interface CertPathParameters extends Cloneable { + + /** + * Makes a copy of this {@code CertPathParameters}. Changes to the + * copy will not affect the original and vice versa. + * + * @return a copy of this {@code CertPathParameters} + */ + Object clone(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidator.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidator.java new file mode 100644 index 000000000..bd2ff56dd --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidator.java @@ -0,0 +1,343 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.AccessController; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivilegedAction; +import java.security.Provider; +import java.security.Security; +import sun.security.util.Debug; + +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; + +/** + * A class for validating certification paths (also known as certificate + * chains). + *

+ * This class uses a provider-based architecture. + * To create a {@code CertPathValidator}, + * call one of the static {@code getInstance} methods, passing in the + * algorithm name of the {@code CertPathValidator} desired and + * optionally the name of the provider desired. + * + *

Once a {@code CertPathValidator} object has been created, it can + * be used to validate certification paths by calling the {@link #validate + * validate} method and passing it the {@code CertPath} to be validated + * and an algorithm-specific set of parameters. If successful, the result is + * returned in an object that implements the + * {@code CertPathValidatorResult} interface. + * + *

The {@link #getRevocationChecker} method allows an application to specify + * additional algorithm-specific parameters and options used by the + * {@code CertPathValidator} when checking the revocation status of + * certificates. Here is an example demonstrating how it is used with the PKIX + * algorithm: + * + *

+ * CertPathValidator cpv = CertPathValidator.getInstance("PKIX");
+ * PKIXRevocationChecker rc = (PKIXRevocationChecker)cpv.getRevocationChecker();
+ * rc.setOptions(EnumSet.of(Option.SOFT_FAIL));
+ * params.addCertPathChecker(rc);
+ * CertPathValidatorResult cpvr = cpv.validate(path, params);
+ * 
+ * + *

Every implementation of the Java platform is required to support the + * following standard {@code CertPathValidator} algorithm: + *

    + *
  • {@code PKIX}
  • + *
+ * This algorithm is described in the + * CertPathValidator section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other algorithms are supported. + * + *

+ * Concurrent Access + *

+ * The static methods of this class are guaranteed to be thread-safe. + * Multiple threads may concurrently invoke the static methods defined in + * this class with no ill effects. + *

+ * However, this is not true for the non-static methods defined by this class. + * Unless otherwise documented by a specific provider, threads that need to + * access a single {@code CertPathValidator} instance concurrently should + * synchronize amongst themselves and provide the necessary locking. Multiple + * threads each manipulating a different {@code CertPathValidator} + * instance need not synchronize. + * + * @see CertPath + * + * @since 1.4 + * @author Yassir Elley + */ +public class CertPathValidator { + + /* + * Constant to lookup in the Security properties file to determine + * the default certpathvalidator type. In the Security properties file, + * the default certpathvalidator type is given as: + *

+     * certpathvalidator.type=PKIX
+     * 
+ */ + private static final String CPV_TYPE = "certpathvalidator.type"; + private final CertPathValidatorSpi validatorSpi; + private final Provider provider; + private final String algorithm; + + /** + * Creates a {@code CertPathValidator} object of the given algorithm, + * and encapsulates the given provider implementation (SPI object) in it. + * + * @param validatorSpi the provider implementation + * @param provider the provider + * @param algorithm the algorithm name + */ + protected CertPathValidator(CertPathValidatorSpi validatorSpi, + Provider provider, String algorithm) + { + this.validatorSpi = validatorSpi; + this.provider = provider; + this.algorithm = algorithm; + } + + /** + * Returns a {@code CertPathValidator} object that implements the + * specified algorithm. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new CertPathValidator object encapsulating the + * CertPathValidatorSpi implementation from the first + * Provider that supports the specified algorithm is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the requested {@code CertPathValidator} + * algorithm. See the CertPathValidator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @return a {@code CertPathValidator} object that implements the + * specified algorithm. + * + * @exception NoSuchAlgorithmException if no Provider supports a + * CertPathValidatorSpi implementation for the + * specified algorithm. + * + * @see java.security.Provider + */ + public static CertPathValidator getInstance(String algorithm) + throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("CertPathValidator", + CertPathValidatorSpi.class, algorithm); + return new CertPathValidator((CertPathValidatorSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns a {@code CertPathValidator} object that implements the + * specified algorithm. + * + *

A new CertPathValidator object encapsulating the + * CertPathValidatorSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param algorithm the name of the requested {@code CertPathValidator} + * algorithm. See the CertPathValidator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the name of the provider. + * + * @return a {@code CertPathValidator} object that implements the + * specified algorithm. + * + * @exception NoSuchAlgorithmException if a CertPathValidatorSpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the {@code provider} is + * null or empty. + * + * @see java.security.Provider + */ + public static CertPathValidator getInstance(String algorithm, + String provider) throws NoSuchAlgorithmException, + NoSuchProviderException { + Instance instance = GetInstance.getInstance("CertPathValidator", + CertPathValidatorSpi.class, algorithm, provider); + return new CertPathValidator((CertPathValidatorSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns a {@code CertPathValidator} object that implements the + * specified algorithm. + * + *

A new CertPathValidator object encapsulating the + * CertPathValidatorSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param algorithm the name of the requested {@code CertPathValidator} + * algorithm. See the CertPathValidator section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard algorithm names. + * + * @param provider the provider. + * + * @return a {@code CertPathValidator} object that implements the + * specified algorithm. + * + * @exception NoSuchAlgorithmException if a CertPathValidatorSpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the {@code provider} is + * null. + * + * @see java.security.Provider + */ + public static CertPathValidator getInstance(String algorithm, + Provider provider) throws NoSuchAlgorithmException { + Instance instance = GetInstance.getInstance("CertPathValidator", + CertPathValidatorSpi.class, algorithm, provider); + return new CertPathValidator((CertPathValidatorSpi)instance.impl, + instance.provider, algorithm); + } + + /** + * Returns the {@code Provider} of this + * {@code CertPathValidator}. + * + * @return the {@code Provider} of this {@code CertPathValidator} + */ + public final Provider getProvider() { + return this.provider; + } + + /** + * Returns the algorithm name of this {@code CertPathValidator}. + * + * @return the algorithm name of this {@code CertPathValidator} + */ + public final String getAlgorithm() { + return this.algorithm; + } + + /** + * Validates the specified certification path using the specified + * algorithm parameter set. + *

+ * The {@code CertPath} specified must be of a type that is + * supported by the validation algorithm, otherwise an + * {@code InvalidAlgorithmParameterException} will be thrown. For + * example, a {@code CertPathValidator} that implements the PKIX + * algorithm validates {@code CertPath} objects of type X.509. + * + * @param certPath the {@code CertPath} to be validated + * @param params the algorithm parameters + * @return the result of the validation algorithm + * @exception CertPathValidatorException if the {@code CertPath} + * does not validate + * @exception InvalidAlgorithmParameterException if the specified + * parameters or the type of the specified {@code CertPath} are + * inappropriate for this {@code CertPathValidator} + */ + public final CertPathValidatorResult validate(CertPath certPath, + CertPathParameters params) + throws CertPathValidatorException, InvalidAlgorithmParameterException + { + return validatorSpi.engineValidate(certPath, params); + } + + /** + * Returns the default {@code CertPathValidator} type as specified by + * the {@code certpathvalidator.type} security property, or the string + * {@literal "PKIX"} if no such property exists. + * + *

The default {@code CertPathValidator} type can be used by + * applications that do not want to use a hard-coded type when calling one + * of the {@code getInstance} methods, and want to provide a default + * type in case a user does not specify its own. + * + *

The default {@code CertPathValidator} type can be changed by + * setting the value of the {@code certpathvalidator.type} security + * property to the desired type. + * + * @see java.security.Security security properties + * @return the default {@code CertPathValidator} type as specified + * by the {@code certpathvalidator.type} security property, or the string + * {@literal "PKIX"} if no such property exists. + */ + public final static String getDefaultType() { + String cpvtype = + AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return Security.getProperty(CPV_TYPE); + } + }); + return (cpvtype == null) ? "PKIX" : cpvtype; + } + + /** + * Returns a {@code CertPathChecker} that the encapsulated + * {@code CertPathValidatorSpi} implementation uses to check the revocation + * status of certificates. A PKIX implementation returns objects of + * type {@code PKIXRevocationChecker}. Each invocation of this method + * returns a new instance of {@code CertPathChecker}. + * + *

The primary purpose of this method is to allow callers to specify + * additional input parameters and options specific to revocation checking. + * See the class description for an example. + * + * @return a {@code CertPathChecker} + * @throws UnsupportedOperationException if the service provider does not + * support this method + * @since 1.8 + */ + public final CertPathChecker getRevocationChecker() { + return validatorSpi.engineGetRevocationChecker(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorException.java new file mode 100644 index 000000000..7e6b9165f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorException.java @@ -0,0 +1,296 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.io.InvalidObjectException; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.security.GeneralSecurityException; + +/** + * An exception indicating one of a variety of problems encountered when + * validating a certification path. + *

+ * A {@code CertPathValidatorException} provides support for wrapping + * exceptions. The {@link #getCause getCause} method returns the throwable, + * if any, that caused this exception to be thrown. + *

+ * A {@code CertPathValidatorException} may also include the + * certification path that was being validated when the exception was thrown, + * the index of the certificate in the certification path that caused the + * exception to be thrown, and the reason that caused the failure. Use the + * {@link #getCertPath getCertPath}, {@link #getIndex getIndex}, and + * {@link #getReason getReason} methods to retrieve this information. + * + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathValidator + * + * @since 1.4 + * @author Yassir Elley + */ +public class CertPathValidatorException extends GeneralSecurityException { + + private static final long serialVersionUID = -3083180014971893139L; + + /** + * @serial the index of the certificate in the certification path + * that caused the exception to be thrown + */ + private int index = -1; + + /** + * @serial the {@code CertPath} that was being validated when + * the exception was thrown + */ + private CertPath certPath; + + /** + * @serial the reason the validation failed + */ + private Reason reason = BasicReason.UNSPECIFIED; + + /** + * Creates a {@code CertPathValidatorException} with + * no detail message. + */ + public CertPathValidatorException() { + this(null, null); + } + + /** + * Creates a {@code CertPathValidatorException} with the given + * detail message. A detail message is a {@code String} that + * describes this particular exception. + * + * @param msg the detail message + */ + public CertPathValidatorException(String msg) { + this(msg, null); + } + + /** + * Creates a {@code CertPathValidatorException} that wraps the + * specified throwable. This allows any exception to be converted into a + * {@code CertPathValidatorException}, while retaining information + * about the wrapped exception, which may be useful for debugging. The + * detail message is set to ({@code cause==null ? null : cause.toString()}) + * (which typically contains the class and detail message of + * cause). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public CertPathValidatorException(Throwable cause) { + this((cause == null ? null : cause.toString()), cause); + } + + /** + * Creates a {@code CertPathValidatorException} with the specified + * detail message and cause. + * + * @param msg the detail message + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public CertPathValidatorException(String msg, Throwable cause) { + this(msg, cause, null, -1); + } + + /** + * Creates a {@code CertPathValidatorException} with the specified + * detail message, cause, certification path, and index. + * + * @param msg the detail message (or {@code null} if none) + * @param cause the cause (or {@code null} if none) + * @param certPath the certification path that was in the process of + * being validated when the error was encountered + * @param index the index of the certificate in the certification path + * that caused the error (or -1 if not applicable). Note that + * the list of certificates in a {@code CertPath} is zero based. + * @throws IndexOutOfBoundsException if the index is out of range + * {@code (index < -1 || (certPath != null && index >= + * certPath.getCertificates().size()) } + * @throws IllegalArgumentException if {@code certPath} is + * {@code null} and {@code index} is not -1 + */ + public CertPathValidatorException(String msg, Throwable cause, + CertPath certPath, int index) { + this(msg, cause, certPath, index, BasicReason.UNSPECIFIED); + } + + /** + * Creates a {@code CertPathValidatorException} with the specified + * detail message, cause, certification path, index, and reason. + * + * @param msg the detail message (or {@code null} if none) + * @param cause the cause (or {@code null} if none) + * @param certPath the certification path that was in the process of + * being validated when the error was encountered + * @param index the index of the certificate in the certification path + * that caused the error (or -1 if not applicable). Note that + * the list of certificates in a {@code CertPath} is zero based. + * @param reason the reason the validation failed + * @throws IndexOutOfBoundsException if the index is out of range + * {@code (index < -1 || (certPath != null && index >= + * certPath.getCertificates().size()) } + * @throws IllegalArgumentException if {@code certPath} is + * {@code null} and {@code index} is not -1 + * @throws NullPointerException if {@code reason} is {@code null} + * + * @since 1.7 + */ + public CertPathValidatorException(String msg, Throwable cause, + CertPath certPath, int index, Reason reason) { + super(msg, cause); + if (certPath == null && index != -1) { + throw new IllegalArgumentException(); + } + if (index < -1 || + (certPath != null && index >= certPath.getCertificates().size())) { + throw new IndexOutOfBoundsException(); + } + if (reason == null) { + throw new NullPointerException("reason can't be null"); + } + this.certPath = certPath; + this.index = index; + this.reason = reason; + } + + /** + * Returns the certification path that was being validated when + * the exception was thrown. + * + * @return the {@code CertPath} that was being validated when + * the exception was thrown (or {@code null} if not specified) + */ + public CertPath getCertPath() { + return this.certPath; + } + + /** + * Returns the index of the certificate in the certification path + * that caused the exception to be thrown. Note that the list of + * certificates in a {@code CertPath} is zero based. If no + * index has been set, -1 is returned. + * + * @return the index that has been set, or -1 if none has been set + */ + public int getIndex() { + return this.index; + } + + /** + * Returns the reason that the validation failed. The reason is + * associated with the index of the certificate returned by + * {@link #getIndex}. + * + * @return the reason that the validation failed, or + * {@code BasicReason.UNSPECIFIED} if a reason has not been + * specified + * + * @since 1.7 + */ + public Reason getReason() { + return this.reason; + } + + private void readObject(ObjectInputStream stream) + throws ClassNotFoundException, IOException { + stream.defaultReadObject(); + if (reason == null) { + reason = BasicReason.UNSPECIFIED; + } + if (certPath == null && index != -1) { + throw new InvalidObjectException("certpath is null and index != -1"); + } + if (index < -1 || + (certPath != null && index >= certPath.getCertificates().size())) { + throw new InvalidObjectException("index out of range"); + } + } + + /** + * The reason the validation algorithm failed. + * + * @since 1.7 + */ + public static interface Reason extends java.io.Serializable { } + + + /** + * The BasicReason enumerates the potential reasons that a certification + * path of any type may be invalid. + * + * @since 1.7 + */ + public static enum BasicReason implements Reason { + /** + * Unspecified reason. + */ + UNSPECIFIED, + + /** + * The certificate is expired. + */ + EXPIRED, + + /** + * The certificate is not yet valid. + */ + NOT_YET_VALID, + + /** + * The certificate is revoked. + */ + REVOKED, + + /** + * The revocation status of the certificate could not be determined. + */ + UNDETERMINED_REVOCATION_STATUS, + + /** + * The signature is invalid. + */ + INVALID_SIGNATURE, + + /** + * The public key or the signature algorithm has been constrained. + */ + ALGORITHM_CONSTRAINED + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorResult.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorResult.java new file mode 100644 index 000000000..ae07dc497 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorResult.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +/** + * A specification of the result of a certification path validator algorithm. + *

+ * The purpose of this interface is to group (and provide type safety + * for) all certification path validator results. All results returned + * by the {@link CertPathValidator#validate CertPathValidator.validate} + * method must implement this interface. + * + * @see CertPathValidator + * + * @since 1.4 + * @author Yassir Elley + */ +public interface CertPathValidatorResult extends Cloneable { + + /** + * Makes a copy of this {@code CertPathValidatorResult}. Changes to the + * copy will not affect the original and vice versa. + * + * @return a copy of this {@code CertPathValidatorResult} + */ + Object clone(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorSpi.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorSpi.java new file mode 100644 index 000000000..02d503c9e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertPathValidatorSpi.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.InvalidAlgorithmParameterException; + +/** + * + * The Service Provider Interface (SPI) + * for the {@link CertPathValidator CertPathValidator} class. All + * {@code CertPathValidator} implementations must include a class (the + * SPI class) that extends this class ({@code CertPathValidatorSpi}) + * and implements all of its methods. In general, instances of this class + * should only be accessed through the {@code CertPathValidator} class. + * For details, see the Java Cryptography Architecture. + *

+ * Concurrent Access + *

+ * Instances of this class need not be protected against concurrent + * access from multiple threads. Threads that need to access a single + * {@code CertPathValidatorSpi} instance concurrently should synchronize + * amongst themselves and provide the necessary locking before calling the + * wrapping {@code CertPathValidator} object. + *

+ * However, implementations of {@code CertPathValidatorSpi} may still + * encounter concurrency issues, since multiple threads each + * manipulating a different {@code CertPathValidatorSpi} instance need not + * synchronize. + * + * @since 1.4 + * @author Yassir Elley + */ +public abstract class CertPathValidatorSpi { + + /** + * The default constructor. + */ + public CertPathValidatorSpi() {} + + /** + * Validates the specified certification path using the specified + * algorithm parameter set. + *

+ * The {@code CertPath} specified must be of a type that is + * supported by the validation algorithm, otherwise an + * {@code InvalidAlgorithmParameterException} will be thrown. For + * example, a {@code CertPathValidator} that implements the PKIX + * algorithm validates {@code CertPath} objects of type X.509. + * + * @param certPath the {@code CertPath} to be validated + * @param params the algorithm parameters + * @return the result of the validation algorithm + * @exception CertPathValidatorException if the {@code CertPath} + * does not validate + * @exception InvalidAlgorithmParameterException if the specified + * parameters or the type of the specified {@code CertPath} are + * inappropriate for this {@code CertPathValidator} + */ + public abstract CertPathValidatorResult + engineValidate(CertPath certPath, CertPathParameters params) + throws CertPathValidatorException, InvalidAlgorithmParameterException; + + /** + * Returns a {@code CertPathChecker} that this implementation uses to + * check the revocation status of certificates. A PKIX implementation + * returns objects of type {@code PKIXRevocationChecker}. + * + *

The primary purpose of this method is to allow callers to specify + * additional input parameters and options specific to revocation checking. + * See the class description of {@code CertPathValidator} for an example. + * + *

This method was added to version 1.8 of the Java Platform Standard + * Edition. In order to maintain backwards compatibility with existing + * service providers, this method cannot be abstract and by default throws + * an {@code UnsupportedOperationException}. + * + * @return a {@code CertPathChecker} that this implementation uses to + * check the revocation status of certificates + * @throws UnsupportedOperationException if this method is not supported + * @since 1.8 + */ + public CertPathChecker engineGetRevocationChecker() { + throw new UnsupportedOperationException(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertSelector.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertSelector.java new file mode 100644 index 000000000..a06cc8480 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertSelector.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +/** + * A selector that defines a set of criteria for selecting + * {@code Certificate}s. Classes that implement this interface + * are often used to specify which {@code Certificate}s should + * be retrieved from a {@code CertStore}. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this interface are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see Certificate + * @see CertStore + * @see CertStore#getCertificates + * + * @author Steve Hanna + * @since 1.4 + */ +public interface CertSelector extends Cloneable { + + /** + * Decides whether a {@code Certificate} should be selected. + * + * @param cert the {@code Certificate} to be checked + * @return {@code true} if the {@code Certificate} + * should be selected, {@code false} otherwise + */ + boolean match(Certificate cert); + + /** + * Makes a copy of this {@code CertSelector}. Changes to the + * copy will not affect the original and vice versa. + * + * @return a copy of this {@code CertSelector} + */ + Object clone(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertStore.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStore.java new file mode 100644 index 000000000..1a8ed628c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStore.java @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.AccessController; +import java.security.InvalidAlgorithmParameterException; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.PrivilegedAction; +import java.security.Provider; +import java.security.Security; +import java.util.Collection; + +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; + +/** + * A class for retrieving {@code Certificate}s and {@code CRL}s + * from a repository. + *

+ * This class uses a provider-based architecture. + * To create a {@code CertStore}, call one of the static + * {@code getInstance} methods, passing in the type of + * {@code CertStore} desired, any applicable initialization parameters + * and optionally the name of the provider desired. + *

+ * Once the {@code CertStore} has been created, it can be used to + * retrieve {@code Certificate}s and {@code CRL}s by calling its + * {@link #getCertificates(CertSelector selector) getCertificates} and + * {@link #getCRLs(CRLSelector selector) getCRLs} methods. + *

+ * Unlike a {@link java.security.KeyStore KeyStore}, which provides access + * to a cache of private keys and trusted certificates, a + * {@code CertStore} is designed to provide access to a potentially + * vast repository of untrusted certificates and CRLs. For example, an LDAP + * implementation of {@code CertStore} provides access to certificates + * and CRLs stored in one or more directories using the LDAP protocol and the + * schema as defined in the RFC service attribute. + * + *

Every implementation of the Java platform is required to support the + * following standard {@code CertStore} type: + *

    + *
  • {@code Collection}
  • + *
+ * This type is described in the + * CertStore section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other types are supported. + * + *

+ * Concurrent Access + *

+ * All public methods of {@code CertStore} objects must be thread-safe. + * That is, multiple threads may concurrently invoke these methods on a + * single {@code CertStore} object (or more than one) with no + * ill effects. This allows a {@code CertPathBuilder} to search for a + * CRL while simultaneously searching for further certificates, for instance. + *

+ * The static methods of this class are also guaranteed to be thread-safe. + * Multiple threads may concurrently invoke the static methods defined in + * this class with no ill effects. + * + * @since 1.4 + * @author Sean Mullan, Steve Hanna + */ +public class CertStore { + /* + * Constant to lookup in the Security properties file to determine + * the default certstore type. In the Security properties file, the + * default certstore type is given as: + *

+     * certstore.type=LDAP
+     * 
+ */ + private static final String CERTSTORE_TYPE = "certstore.type"; + private CertStoreSpi storeSpi; + private Provider provider; + private String type; + private CertStoreParameters params; + + /** + * Creates a {@code CertStore} object of the given type, and + * encapsulates the given provider implementation (SPI object) in it. + * + * @param storeSpi the provider implementation + * @param provider the provider + * @param type the type + * @param params the initialization parameters (may be {@code null}) + */ + protected CertStore(CertStoreSpi storeSpi, Provider provider, + String type, CertStoreParameters params) { + this.storeSpi = storeSpi; + this.provider = provider; + this.type = type; + if (params != null) + this.params = (CertStoreParameters) params.clone(); + } + + /** + * Returns a {@code Collection} of {@code Certificate}s that + * match the specified selector. If no {@code Certificate}s + * match the selector, an empty {@code Collection} will be returned. + *

+ * For some {@code CertStore} types, the resulting + * {@code Collection} may not contain all of the + * {@code Certificate}s that match the selector. For instance, + * an LDAP {@code CertStore} may not search all entries in the + * directory. Instead, it may just search entries that are likely to + * contain the {@code Certificate}s it is looking for. + *

+ * Some {@code CertStore} implementations (especially LDAP + * {@code CertStore}s) may throw a {@code CertStoreException} + * unless a non-null {@code CertSelector} is provided that + * includes specific criteria that can be used to find the certificates. + * Issuer and/or subject names are especially useful criteria. + * + * @param selector A {@code CertSelector} used to select which + * {@code Certificate}s should be returned. Specify {@code null} + * to return all {@code Certificate}s (if supported). + * @return A {@code Collection} of {@code Certificate}s that + * match the specified selector (never {@code null}) + * @throws CertStoreException if an exception occurs + */ + public final Collection getCertificates + (CertSelector selector) throws CertStoreException { + return storeSpi.engineGetCertificates(selector); + } + + /** + * Returns a {@code Collection} of {@code CRL}s that + * match the specified selector. If no {@code CRL}s + * match the selector, an empty {@code Collection} will be returned. + *

+ * For some {@code CertStore} types, the resulting + * {@code Collection} may not contain all of the + * {@code CRL}s that match the selector. For instance, + * an LDAP {@code CertStore} may not search all entries in the + * directory. Instead, it may just search entries that are likely to + * contain the {@code CRL}s it is looking for. + *

+ * Some {@code CertStore} implementations (especially LDAP + * {@code CertStore}s) may throw a {@code CertStoreException} + * unless a non-null {@code CRLSelector} is provided that + * includes specific criteria that can be used to find the CRLs. + * Issuer names and/or the certificate to be checked are especially useful. + * + * @param selector A {@code CRLSelector} used to select which + * {@code CRL}s should be returned. Specify {@code null} + * to return all {@code CRL}s (if supported). + * @return A {@code Collection} of {@code CRL}s that + * match the specified selector (never {@code null}) + * @throws CertStoreException if an exception occurs + */ + public final Collection getCRLs(CRLSelector selector) + throws CertStoreException { + return storeSpi.engineGetCRLs(selector); + } + + /** + * Returns a {@code CertStore} object that implements the specified + * {@code CertStore} type and is initialized with the specified + * parameters. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new CertStore object encapsulating the + * CertStoreSpi implementation from the first + * Provider that supports the specified type is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

The {@code CertStore} that is returned is initialized with the + * specified {@code CertStoreParameters}. The type of parameters + * needed may vary between different types of {@code CertStore}s. + * Note that the specified {@code CertStoreParameters} object is + * cloned. + * + * @param type the name of the requested {@code CertStore} type. + * See the CertStore section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard types. + * + * @param params the initialization parameters (may be {@code null}). + * + * @return a {@code CertStore} object that implements the specified + * {@code CertStore} type. + * + * @throws NoSuchAlgorithmException if no Provider supports a + * CertStoreSpi implementation for the specified type. + * + * @throws InvalidAlgorithmParameterException if the specified + * initialization parameters are inappropriate for this + * {@code CertStore}. + * + * @see java.security.Provider + */ + public static CertStore getInstance(String type, CertStoreParameters params) + throws InvalidAlgorithmParameterException, + NoSuchAlgorithmException { + try { + Instance instance = GetInstance.getInstance("CertStore", + CertStoreSpi.class, type, params); + return new CertStore((CertStoreSpi)instance.impl, + instance.provider, type, params); + } catch (NoSuchAlgorithmException e) { + return handleException(e); + } + } + + private static CertStore handleException(NoSuchAlgorithmException e) + throws NoSuchAlgorithmException, InvalidAlgorithmParameterException { + Throwable cause = e.getCause(); + if (cause instanceof InvalidAlgorithmParameterException) { + throw (InvalidAlgorithmParameterException)cause; + } + throw e; + } + + /** + * Returns a {@code CertStore} object that implements the specified + * {@code CertStore} type. + * + *

A new CertStore object encapsulating the + * CertStoreSpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + *

The {@code CertStore} that is returned is initialized with the + * specified {@code CertStoreParameters}. The type of parameters + * needed may vary between different types of {@code CertStore}s. + * Note that the specified {@code CertStoreParameters} object is + * cloned. + * + * @param type the requested {@code CertStore} type. + * See the CertStore section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard types. + * + * @param params the initialization parameters (may be {@code null}). + * + * @param provider the name of the provider. + * + * @return a {@code CertStore} object that implements the + * specified type. + * + * @throws NoSuchAlgorithmException if a CertStoreSpi + * implementation for the specified type is not + * available from the specified provider. + * + * @throws InvalidAlgorithmParameterException if the specified + * initialization parameters are inappropriate for this + * {@code CertStore}. + * + * @throws NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the {@code provider} is + * null or empty. + * + * @see java.security.Provider + */ + public static CertStore getInstance(String type, + CertStoreParameters params, String provider) + throws InvalidAlgorithmParameterException, + NoSuchAlgorithmException, NoSuchProviderException { + try { + Instance instance = GetInstance.getInstance("CertStore", + CertStoreSpi.class, type, params, provider); + return new CertStore((CertStoreSpi)instance.impl, + instance.provider, type, params); + } catch (NoSuchAlgorithmException e) { + return handleException(e); + } + } + + /** + * Returns a {@code CertStore} object that implements the specified + * {@code CertStore} type. + * + *

A new CertStore object encapsulating the + * CertStoreSpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + *

The {@code CertStore} that is returned is initialized with the + * specified {@code CertStoreParameters}. The type of parameters + * needed may vary between different types of {@code CertStore}s. + * Note that the specified {@code CertStoreParameters} object is + * cloned. + * + * @param type the requested {@code CertStore} type. + * See the CertStore section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard types. + * + * @param params the initialization parameters (may be {@code null}). + * + * @param provider the provider. + * + * @return a {@code CertStore} object that implements the + * specified type. + * + * @exception NoSuchAlgorithmException if a CertStoreSpi + * implementation for the specified type is not available + * from the specified Provider object. + * + * @throws InvalidAlgorithmParameterException if the specified + * initialization parameters are inappropriate for this + * {@code CertStore} + * + * @exception IllegalArgumentException if the {@code provider} is + * null. + * + * @see java.security.Provider + */ + public static CertStore getInstance(String type, CertStoreParameters params, + Provider provider) throws NoSuchAlgorithmException, + InvalidAlgorithmParameterException { + try { + Instance instance = GetInstance.getInstance("CertStore", + CertStoreSpi.class, type, params, provider); + return new CertStore((CertStoreSpi)instance.impl, + instance.provider, type, params); + } catch (NoSuchAlgorithmException e) { + return handleException(e); + } + } + + /** + * Returns the parameters used to initialize this {@code CertStore}. + * Note that the {@code CertStoreParameters} object is cloned before + * it is returned. + * + * @return the parameters used to initialize this {@code CertStore} + * (may be {@code null}) + */ + public final CertStoreParameters getCertStoreParameters() { + return (params == null ? null : (CertStoreParameters) params.clone()); + } + + /** + * Returns the type of this {@code CertStore}. + * + * @return the type of this {@code CertStore} + */ + public final String getType() { + return this.type; + } + + /** + * Returns the provider of this {@code CertStore}. + * + * @return the provider of this {@code CertStore} + */ + public final Provider getProvider() { + return this.provider; + } + + /** + * Returns the default {@code CertStore} type as specified by the + * {@code certstore.type} security property, or the string + * {@literal "LDAP"} if no such property exists. + * + *

The default {@code CertStore} type can be used by applications + * that do not want to use a hard-coded type when calling one of the + * {@code getInstance} methods, and want to provide a default + * {@code CertStore} type in case a user does not specify its own. + * + *

The default {@code CertStore} type can be changed by setting + * the value of the {@code certstore.type} security property to the + * desired type. + * + * @see java.security.Security security properties + * @return the default {@code CertStore} type as specified by the + * {@code certstore.type} security property, or the string + * {@literal "LDAP"} if no such property exists. + */ + public final static String getDefaultType() { + String cstype; + cstype = AccessController.doPrivileged(new PrivilegedAction() { + public String run() { + return Security.getProperty(CERTSTORE_TYPE); + } + }); + if (cstype == null) { + cstype = "LDAP"; + } + return cstype; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreException.java new file mode 100644 index 000000000..77b1c2346 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreException.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.GeneralSecurityException; + +/** + * An exception indicating one of a variety of problems retrieving + * certificates and CRLs from a {@code CertStore}. + *

+ * A {@code CertStoreException} provides support for wrapping + * exceptions. The {@link #getCause getCause} method returns the throwable, + * if any, that caused this exception to be thrown. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertStore + * + * @since 1.4 + * @author Sean Mullan + */ +public class CertStoreException extends GeneralSecurityException { + + private static final long serialVersionUID = 2395296107471573245L; + + /** + * Creates a {@code CertStoreException} with {@code null} as + * its detail message. + */ + public CertStoreException() { + super(); + } + + /** + * Creates a {@code CertStoreException} with the given detail + * message. A detail message is a {@code String} that describes this + * particular exception. + * + * @param msg the detail message + */ + public CertStoreException(String msg) { + super(msg); + } + + /** + * Creates a {@code CertStoreException} that wraps the specified + * throwable. This allows any exception to be converted into a + * {@code CertStoreException}, while retaining information about the + * cause, which may be useful for debugging. The detail message is + * set to ({@code cause==null ? null : cause.toString()}) (which + * typically contains the class and detail message of cause). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public CertStoreException(Throwable cause) { + super(cause); + } + + /** + * Creates a {@code CertStoreException} with the specified detail + * message and cause. + * + * @param msg the detail message + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause getCause()} method). (A {@code null} value is + * permitted, and indicates that the cause is nonexistent or unknown.) + */ + public CertStoreException(String msg, Throwable cause) { + super(msg, cause); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreParameters.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreParameters.java new file mode 100644 index 000000000..9938ba254 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreParameters.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +/** + * A specification of {@code CertStore} parameters. + *

+ * The purpose of this interface is to group (and provide type safety for) + * all {@code CertStore} parameter specifications. All + * {@code CertStore} parameter specifications must implement this + * interface. + *

+ * Typically, a {@code CertStoreParameters} object is passed as a parameter + * to one of the {@link CertStore#getInstance CertStore.getInstance} methods. + * The {@code getInstance} method returns a {@code CertStore} that + * is used for retrieving {@code Certificate}s and {@code CRL}s. The + * {@code CertStore} that is returned is initialized with the specified + * parameters. The type of parameters needed may vary between different types + * of {@code CertStore}s. + * + * @see CertStore#getInstance + * + * @since 1.4 + * @author Steve Hanna + */ +public interface CertStoreParameters extends Cloneable { + + /** + * Makes a copy of this {@code CertStoreParameters}. + *

+ * The precise meaning of "copy" may depend on the class of + * the {@code CertStoreParameters} object. A typical implementation + * performs a "deep copy" of this object, but this is not an absolute + * requirement. Some implementations may perform a "shallow copy" of some + * or all of the fields of this object. + *

+ * Note that the {@code CertStore.getInstance} methods make a copy + * of the specified {@code CertStoreParameters}. A deep copy + * implementation of {@code clone} is safer and more robust, as it + * prevents the caller from corrupting a shared {@code CertStore} by + * subsequently modifying the contents of its initialization parameters. + * However, a shallow copy implementation of {@code clone} is more + * appropriate for applications that need to hold a reference to a + * parameter contained in the {@code CertStoreParameters}. For example, + * a shallow copy clone allows an application to release the resources of + * a particular {@code CertStore} initialization parameter immediately, + * rather than waiting for the garbage collection mechanism. This should + * be done with the utmost care, since the {@code CertStore} may still + * be in use by other threads. + *

+ * Each subclass should state the precise behavior of this method so + * that users and developers know what to expect. + * + * @return a copy of this {@code CertStoreParameters} + */ + Object clone(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreSpi.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreSpi.java new file mode 100644 index 000000000..fc98e9ebc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertStoreSpi.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.InvalidAlgorithmParameterException; +import java.util.Collection; + +/** + * The Service Provider Interface (SPI) + * for the {@link CertStore CertStore} class. All {@code CertStore} + * implementations must include a class (the SPI class) that extends + * this class ({@code CertStoreSpi}), provides a constructor with + * a single argument of type {@code CertStoreParameters}, and implements + * all of its methods. In general, instances of this class should only be + * accessed through the {@code CertStore} class. + * For details, see the Java Cryptography Architecture. + *

+ * Concurrent Access + *

+ * The public methods of all {@code CertStoreSpi} objects must be + * thread-safe. That is, multiple threads may concurrently invoke these + * methods on a single {@code CertStoreSpi} object (or more than one) + * with no ill effects. This allows a {@code CertPathBuilder} to search + * for a CRL while simultaneously searching for further certificates, for + * instance. + *

+ * Simple {@code CertStoreSpi} implementations will probably ensure + * thread safety by adding a {@code synchronized} keyword to their + * {@code engineGetCertificates} and {@code engineGetCRLs} methods. + * More sophisticated ones may allow truly concurrent access. + * + * @since 1.4 + * @author Steve Hanna + */ +public abstract class CertStoreSpi { + + /** + * The sole constructor. + * + * @param params the initialization parameters (may be {@code null}) + * @throws InvalidAlgorithmParameterException if the initialization + * parameters are inappropriate for this {@code CertStoreSpi} + */ + public CertStoreSpi(CertStoreParameters params) + throws InvalidAlgorithmParameterException { } + + /** + * Returns a {@code Collection} of {@code Certificate}s that + * match the specified selector. If no {@code Certificate}s + * match the selector, an empty {@code Collection} will be returned. + *

+ * For some {@code CertStore} types, the resulting + * {@code Collection} may not contain all of the + * {@code Certificate}s that match the selector. For instance, + * an LDAP {@code CertStore} may not search all entries in the + * directory. Instead, it may just search entries that are likely to + * contain the {@code Certificate}s it is looking for. + *

+ * Some {@code CertStore} implementations (especially LDAP + * {@code CertStore}s) may throw a {@code CertStoreException} + * unless a non-null {@code CertSelector} is provided that includes + * specific criteria that can be used to find the certificates. Issuer + * and/or subject names are especially useful criteria. + * + * @param selector A {@code CertSelector} used to select which + * {@code Certificate}s should be returned. Specify {@code null} + * to return all {@code Certificate}s (if supported). + * @return A {@code Collection} of {@code Certificate}s that + * match the specified selector (never {@code null}) + * @throws CertStoreException if an exception occurs + */ + public abstract Collection engineGetCertificates + (CertSelector selector) throws CertStoreException; + + /** + * Returns a {@code Collection} of {@code CRL}s that + * match the specified selector. If no {@code CRL}s + * match the selector, an empty {@code Collection} will be returned. + *

+ * For some {@code CertStore} types, the resulting + * {@code Collection} may not contain all of the + * {@code CRL}s that match the selector. For instance, + * an LDAP {@code CertStore} may not search all entries in the + * directory. Instead, it may just search entries that are likely to + * contain the {@code CRL}s it is looking for. + *

+ * Some {@code CertStore} implementations (especially LDAP + * {@code CertStore}s) may throw a {@code CertStoreException} + * unless a non-null {@code CRLSelector} is provided that includes + * specific criteria that can be used to find the CRLs. Issuer names + * and/or the certificate to be checked are especially useful. + * + * @param selector A {@code CRLSelector} used to select which + * {@code CRL}s should be returned. Specify {@code null} + * to return all {@code CRL}s (if supported). + * @return A {@code Collection} of {@code CRL}s that + * match the specified selector (never {@code null}) + * @throws CertStoreException if an exception occurs + */ + public abstract Collection engineGetCRLs + (CRLSelector selector) throws CertStoreException; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/Certificate.java b/sources/net.sf.j2s.java.core/src/java/security/cert/Certificate.java new file mode 100644 index 000000000..10544983d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/Certificate.java @@ -0,0 +1,307 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +import java.util.Arrays; + +import java.security.Provider; +import java.security.PublicKey; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.InvalidKeyException; +import java.security.SignatureException; + +import sun.security.x509.X509CertImpl; + +/** + *

Abstract class for managing a variety of identity certificates. + * An identity certificate is a binding of a principal to a public key which + * is vouched for by another principal. (A principal represents + * an entity such as an individual user, a group, or a corporation.) + *

+ * This class is an abstraction for certificates that have different + * formats but important common uses. For example, different types of + * certificates, such as X.509 and PGP, share general certificate + * functionality (like encoding and verifying) and + * some types of information (like a public key). + *

+ * X.509, PGP, and SDSI certificates can all be implemented by + * subclassing the Certificate class, even though they contain different + * sets of information, and they store and retrieve the information in + * different ways. + * + * @see X509Certificate + * @see CertificateFactory + * + * @author Hemma Prafullchandra + */ + +public abstract class Certificate implements java.io.Serializable { + + private static final long serialVersionUID = -3585440601605666277L; + + // the certificate type + private final String type; + + /** Cache the hash code for the certiticate */ + private int hash = -1; // Default to -1 + + /** + * Creates a certificate of the specified type. + * + * @param type the standard name of the certificate type. + * See the CertificateFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard certificate types. + */ + protected Certificate(String type) { + this.type = type; + } + + /** + * Returns the type of this certificate. + * + * @return the type of this certificate. + */ + public final String getType() { + return this.type; + } + + /** + * Compares this certificate for equality with the specified + * object. If the {@code other} object is an + * {@code instanceof} {@code Certificate}, then + * its encoded form is retrieved and compared with the + * encoded form of this certificate. + * + * @param other the object to test for equality with this certificate. + * @return true iff the encoded forms of the two certificates + * match, false otherwise. + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof Certificate)) { + return false; + } + try { + byte[] thisCert = X509CertImpl.getEncodedInternal(this); + byte[] otherCert = X509CertImpl.getEncodedInternal((Certificate)other); + + return Arrays.equals(thisCert, otherCert); + } catch (CertificateException e) { + return false; + } + } + + /** + * Returns a hashcode value for this certificate from its + * encoded form. + * + * @return the hashcode value. + */ + public int hashCode() { + int h = hash; + if (h == -1) { + try { + h = Arrays.hashCode(X509CertImpl.getEncodedInternal(this)); + } catch (CertificateException e) { + h = 0; + } + hash = h; + } + return h; + } + + /** + * Returns the encoded form of this certificate. It is + * assumed that each certificate type would have only a single + * form of encoding; for example, X.509 certificates would + * be encoded as ASN.1 DER. + * + * @return the encoded form of this certificate + * + * @exception CertificateEncodingException if an encoding error occurs. + */ + public abstract byte[] getEncoded() + throws CertificateEncodingException; + + /** + * Verifies that this certificate was signed using the + * private key that corresponds to the specified public key. + * + * @param key the PublicKey used to carry out the verification. + * + * @exception NoSuchAlgorithmException on unsupported signature + * algorithms. + * @exception InvalidKeyException on incorrect key. + * @exception NoSuchProviderException if there's no default provider. + * @exception SignatureException on signature errors. + * @exception CertificateException on encoding errors. + */ + public abstract void verify(PublicKey key) + throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, + SignatureException; + + /** + * Verifies that this certificate was signed using the + * private key that corresponds to the specified public key. + * This method uses the signature verification engine + * supplied by the specified provider. + * + * @param key the PublicKey used to carry out the verification. + * @param sigProvider the name of the signature provider. + * + * @exception NoSuchAlgorithmException on unsupported signature + * algorithms. + * @exception InvalidKeyException on incorrect key. + * @exception NoSuchProviderException on incorrect provider. + * @exception SignatureException on signature errors. + * @exception CertificateException on encoding errors. + */ + public abstract void verify(PublicKey key, String sigProvider) + throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, + SignatureException; + + /** + * Verifies that this certificate was signed using the + * private key that corresponds to the specified public key. + * This method uses the signature verification engine + * supplied by the specified provider. Note that the specified + * Provider object does not have to be registered in the provider list. + * + *

This method was added to version 1.8 of the Java Platform + * Standard Edition. In order to maintain backwards compatibility with + * existing service providers, this method cannot be {@code abstract} + * and by default throws an {@code UnsupportedOperationException}. + * + * @param key the PublicKey used to carry out the verification. + * @param sigProvider the signature provider. + * + * @exception NoSuchAlgorithmException on unsupported signature + * algorithms. + * @exception InvalidKeyException on incorrect key. + * @exception SignatureException on signature errors. + * @exception CertificateException on encoding errors. + * @exception UnsupportedOperationException if the method is not supported + * @since 1.8 + */ + public void verify(PublicKey key, Provider sigProvider) + throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + throw new UnsupportedOperationException(); + } + + /** + * Returns a string representation of this certificate. + * + * @return a string representation of this certificate. + */ + public abstract String toString(); + + /** + * Gets the public key from this certificate. + * + * @return the public key. + */ + public abstract PublicKey getPublicKey(); + + /** + * Alternate Certificate class for serialization. + * @since 1.3 + */ + protected static class CertificateRep implements java.io.Serializable { + + private static final long serialVersionUID = -8563758940495660020L; + + private String type; + private byte[] data; + + /** + * Construct the alternate Certificate class with the Certificate + * type and Certificate encoding bytes. + * + *

+ * + * @param type the standard name of the Certificate type.

+ * + * @param data the Certificate data. + */ + protected CertificateRep(String type, byte[] data) { + this.type = type; + this.data = data; + } + + /** + * Resolve the Certificate Object. + * + *

+ * + * @return the resolved Certificate Object + * + * @throws java.io.ObjectStreamException if the Certificate + * could not be resolved + */ + protected Object readResolve() throws java.io.ObjectStreamException { + try { + CertificateFactory cf = CertificateFactory.getInstance(type); + return cf.generateCertificate + (new java.io.ByteArrayInputStream(data)); + } catch (CertificateException e) { + throw new java.io.NotSerializableException + ("java.security.cert.Certificate: " + + type + + ": " + + e.getMessage()); + } + } + } + + /** + * Replace the Certificate to be serialized. + * + * @return the alternate Certificate object to be serialized + * + * @throws java.io.ObjectStreamException if a new object representing + * this Certificate could not be created + * @since 1.3 + */ + protected Object writeReplace() throws java.io.ObjectStreamException { + try { + return new CertificateRep(type, getEncoded()); + } catch (CertificateException e) { + throw new java.io.NotSerializableException + ("java.security.cert.Certificate: " + + type + + ": " + + e.getMessage()); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateEncodingException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateEncodingException.java new file mode 100644 index 000000000..618ee0a55 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateEncodingException.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +/** + * Certificate Encoding Exception. This is thrown whenever an error + * occurs while attempting to encode a certificate. + * + * @author Hemma Prafullchandra + */ +public class CertificateEncodingException extends CertificateException { + + private static final long serialVersionUID = 6219492851589449162L; + + /** + * Constructs a CertificateEncodingException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public CertificateEncodingException() { + super(); + } + + /** + * Constructs a CertificateEncodingException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param message the detail message. + */ + public CertificateEncodingException(String message) { + super(message); + } + + /** + * Creates a {@code CertificateEncodingException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CertificateEncodingException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code CertificateEncodingException} + * with the specified cause and a detail message of + * {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CertificateEncodingException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateException.java new file mode 100644 index 000000000..f66305400 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateException.java @@ -0,0 +1,88 @@ +/* + * Copyright (c) 1996, 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 java.security.cert; + +import java.security.GeneralSecurityException; + +/** + * This exception indicates one of a variety of certificate problems. + * + * @author Hemma Prafullchandra + * @see Certificate + */ +public class CertificateException extends GeneralSecurityException { + + private static final long serialVersionUID = 3192535253797119798L; + + /** + * Constructs a certificate exception with no detail message. A detail + * message is a String that describes this particular exception. + */ + public CertificateException() { + super(); + } + + /** + * Constructs a certificate exception with the given detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public CertificateException(String msg) { + super(msg); + } + + /** + * Creates a {@code CertificateException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CertificateException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code CertificateException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CertificateException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateExpiredException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateExpiredException.java new file mode 100644 index 000000000..9de0c236c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateExpiredException.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +/** + * Certificate Expired Exception. This is thrown whenever the current + * {@code Date} or the specified {@code Date} is after the + * {@code notAfter} date/time specified in the validity period + * of the certificate. + * + * @author Hemma Prafullchandra + */ +public class CertificateExpiredException extends CertificateException { + + private static final long serialVersionUID = 9071001339691533771L; + + /** + * Constructs a CertificateExpiredException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public CertificateExpiredException() { + super(); + } + + /** + * Constructs a CertificateExpiredException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param message the detail message. + */ + public CertificateExpiredException(String message) { + super(message); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateFactory.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateFactory.java new file mode 100644 index 000000000..f45866d1b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateFactory.java @@ -0,0 +1,537 @@ +/* + * Copyright (c) 1998, 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 java.security.cert; + +import java.io.InputStream; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.security.Provider; +import java.security.Security; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +import sun.security.jca.*; +import sun.security.jca.GetInstance.Instance; + +/** + * This class defines the functionality of a certificate factory, which is + * used to generate certificate, certification path ({@code CertPath}) + * and certificate revocation list (CRL) objects from their encodings. + * + *

For encodings consisting of multiple certificates, use + * {@code generateCertificates} when you want to + * parse a collection of possibly unrelated certificates. Otherwise, + * use {@code generateCertPath} when you want to generate + * a {@code CertPath} (a certificate chain) and subsequently + * validate it with a {@code CertPathValidator}. + * + *

A certificate factory for X.509 must return certificates that are an + * instance of {@code java.security.cert.X509Certificate}, and CRLs + * that are an instance of {@code java.security.cert.X509CRL}. + * + *

The following example reads a file with Base64 encoded certificates, + * which are each bounded at the beginning by -----BEGIN CERTIFICATE-----, and + * bounded at the end by -----END CERTIFICATE-----. We convert the + * {@code FileInputStream} (which does not support {@code mark} + * and {@code reset}) to a {@code BufferedInputStream} (which + * supports those methods), so that each call to + * {@code generateCertificate} consumes only one certificate, and the + * read position of the input stream is positioned to the next certificate in + * the file: + * + *

{@code
+ * FileInputStream fis = new FileInputStream(filename);
+ * BufferedInputStream bis = new BufferedInputStream(fis);
+ *
+ * CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ *
+ * while (bis.available() > 0) {
+ *    Certificate cert = cf.generateCertificate(bis);
+ *    System.out.println(cert.toString());
+ * }
+ * }
+ * + *

The following example parses a PKCS#7-formatted certificate reply stored + * in a file and extracts all the certificates from it: + * + *

+ * FileInputStream fis = new FileInputStream(filename);
+ * CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ * Collection c = cf.generateCertificates(fis);
+ * Iterator i = c.iterator();
+ * while (i.hasNext()) {
+ *    Certificate cert = (Certificate)i.next();
+ *    System.out.println(cert);
+ * }
+ * 
+ * + *

Every implementation of the Java platform is required to support the + * following standard {@code CertificateFactory} type: + *

    + *
  • {@code X.509}
  • + *
+ * and the following standard {@code CertPath} encodings: + *
    + *
  • {@code PKCS7}
  • + *
  • {@code PkiPath}
  • + *
+ * The type and encodings are described in the + * CertificateFactory section and the + * CertPath Encodings section of the + * Java Cryptography Architecture Standard Algorithm Name Documentation. + * Consult the release documentation for your implementation to see if any + * other types or encodings are supported. + * + * @author Hemma Prafullchandra + * @author Jan Luehe + * @author Sean Mullan + * + * @see Certificate + * @see X509Certificate + * @see CertPath + * @see CRL + * @see X509CRL + * + * @since 1.2 + */ + +public class CertificateFactory { + + // The certificate type + private String type; + + // The provider + private Provider provider; + + // The provider implementation + private CertificateFactorySpi certFacSpi; + + /** + * Creates a CertificateFactory object of the given type, and encapsulates + * the given provider implementation (SPI object) in it. + * + * @param certFacSpi the provider implementation. + * @param provider the provider. + * @param type the certificate type. + */ + protected CertificateFactory(CertificateFactorySpi certFacSpi, + Provider provider, String type) + { + this.certFacSpi = certFacSpi; + this.provider = provider; + this.type = type; + } + + /** + * Returns a certificate factory object that implements the + * specified certificate type. + * + *

This method traverses the list of registered security Providers, + * starting with the most preferred Provider. + * A new CertificateFactory object encapsulating the + * CertificateFactorySpi implementation from the first + * Provider that supports the specified type is returned. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param type the name of the requested certificate type. + * See the CertificateFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard certificate types. + * + * @return a certificate factory object for the specified type. + * + * @exception CertificateException if no Provider supports a + * CertificateFactorySpi implementation for the + * specified type. + * + * @see java.security.Provider + */ + public static final CertificateFactory getInstance(String type) + throws CertificateException { + try { + Instance instance = GetInstance.getInstance("CertificateFactory", + CertificateFactorySpi.class, type); + return new CertificateFactory((CertificateFactorySpi)instance.impl, + instance.provider, type); + } catch (NoSuchAlgorithmException e) { + throw new CertificateException(type + " not found", e); + } + } + + /** + * Returns a certificate factory object for the specified + * certificate type. + * + *

A new CertificateFactory object encapsulating the + * CertificateFactorySpi implementation from the specified provider + * is returned. The specified provider must be registered + * in the security provider list. + * + *

Note that the list of registered providers may be retrieved via + * the {@link Security#getProviders() Security.getProviders()} method. + * + * @param type the certificate type. + * See the CertificateFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard certificate types. + * + * @param provider the name of the provider. + * + * @return a certificate factory object for the specified type. + * + * @exception CertificateException if a CertificateFactorySpi + * implementation for the specified algorithm is not + * available from the specified provider. + * + * @exception NoSuchProviderException if the specified provider is not + * registered in the security provider list. + * + * @exception IllegalArgumentException if the provider name is null + * or empty. + * + * @see java.security.Provider + */ + public static final CertificateFactory getInstance(String type, + String provider) throws CertificateException, + NoSuchProviderException { + try { + Instance instance = GetInstance.getInstance("CertificateFactory", + CertificateFactorySpi.class, type, provider); + return new CertificateFactory((CertificateFactorySpi)instance.impl, + instance.provider, type); + } catch (NoSuchAlgorithmException e) { + throw new CertificateException(type + " not found", e); + } + } + + /** + * Returns a certificate factory object for the specified + * certificate type. + * + *

A new CertificateFactory object encapsulating the + * CertificateFactorySpi implementation from the specified Provider + * object is returned. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * @param type the certificate type. + * See the CertificateFactory section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard certificate types. + * @param provider the provider. + * + * @return a certificate factory object for the specified type. + * + * @exception CertificateException if a CertificateFactorySpi + * implementation for the specified algorithm is not available + * from the specified Provider object. + * + * @exception IllegalArgumentException if the {@code provider} is + * null. + * + * @see java.security.Provider + * + * @since 1.4 + */ + public static final CertificateFactory getInstance(String type, + Provider provider) throws CertificateException { + try { + Instance instance = GetInstance.getInstance("CertificateFactory", + CertificateFactorySpi.class, type, provider); + return new CertificateFactory((CertificateFactorySpi)instance.impl, + instance.provider, type); + } catch (NoSuchAlgorithmException e) { + throw new CertificateException(type + " not found", e); + } + } + + /** + * Returns the provider of this certificate factory. + * + * @return the provider of this certificate factory. + */ + public final Provider getProvider() { + return this.provider; + } + + /** + * Returns the name of the certificate type associated with this + * certificate factory. + * + * @return the name of the certificate type associated with this + * certificate factory. + */ + public final String getType() { + return this.type; + } + + /** + * Generates a certificate object and initializes it with + * the data read from the input stream {@code inStream}. + * + *

In order to take advantage of the specialized certificate format + * supported by this certificate factory, + * the returned certificate object can be typecast to the corresponding + * certificate class. For example, if this certificate + * factory implements X.509 certificates, the returned certificate object + * can be typecast to the {@code X509Certificate} class. + * + *

In the case of a certificate factory for X.509 certificates, the + * certificate provided in {@code inStream} must be DER-encoded and + * may be supplied in binary or printable (Base64) encoding. If the + * certificate is provided in Base64 encoding, it must be bounded at + * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at + * the end by -----END CERTIFICATE-----. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. Otherwise, each call to this + * method consumes one certificate and the read position of the + * input stream is positioned to the next available byte after + * the inherent end-of-certificate marker. If the data in the input stream + * does not contain an inherent end-of-certificate marker (other + * than EOF) and there is trailing data after the certificate is parsed, a + * {@code CertificateException} is thrown. + * + * @param inStream an input stream with the certificate data. + * + * @return a certificate object initialized with the data + * from the input stream. + * + * @exception CertificateException on parsing errors. + */ + public final Certificate generateCertificate(InputStream inStream) + throws CertificateException + { + return certFacSpi.engineGenerateCertificate(inStream); + } + + /** + * Returns an iteration of the {@code CertPath} encodings supported + * by this certificate factory, with the default encoding first. See + * the CertPath Encodings section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard encoding names and their formats. + *

+ * Attempts to modify the returned {@code Iterator} via its + * {@code remove} method result in an + * {@code UnsupportedOperationException}. + * + * @return an {@code Iterator} over the names of the supported + * {@code CertPath} encodings (as {@code String}s) + * @since 1.4 + */ + public final Iterator getCertPathEncodings() { + return(certFacSpi.engineGetCertPathEncodings()); + } + + /** + * Generates a {@code CertPath} object and initializes it with + * the data read from the {@code InputStream} inStream. The data + * is assumed to be in the default encoding. The name of the default + * encoding is the first element of the {@code Iterator} returned by + * the {@link #getCertPathEncodings getCertPathEncodings} method. + * + * @param inStream an {@code InputStream} containing the data + * @return a {@code CertPath} initialized with the data from the + * {@code InputStream} + * @exception CertificateException if an exception occurs while decoding + * @since 1.4 + */ + public final CertPath generateCertPath(InputStream inStream) + throws CertificateException + { + return(certFacSpi.engineGenerateCertPath(inStream)); + } + + /** + * Generates a {@code CertPath} object and initializes it with + * the data read from the {@code InputStream} inStream. The data + * is assumed to be in the specified encoding. See + * the CertPath Encodings section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard encoding names and their formats. + * + * @param inStream an {@code InputStream} containing the data + * @param encoding the encoding used for the data + * @return a {@code CertPath} initialized with the data from the + * {@code InputStream} + * @exception CertificateException if an exception occurs while decoding or + * the encoding requested is not supported + * @since 1.4 + */ + public final CertPath generateCertPath(InputStream inStream, + String encoding) throws CertificateException + { + return(certFacSpi.engineGenerateCertPath(inStream, encoding)); + } + + /** + * Generates a {@code CertPath} object and initializes it with + * a {@code List} of {@code Certificate}s. + *

+ * The certificates supplied must be of a type supported by the + * {@code CertificateFactory}. They will be copied out of the supplied + * {@code List} object. + * + * @param certificates a {@code List} of {@code Certificate}s + * @return a {@code CertPath} initialized with the supplied list of + * certificates + * @exception CertificateException if an exception occurs + * @since 1.4 + */ + public final CertPath + generateCertPath(List certificates) + throws CertificateException + { + return(certFacSpi.engineGenerateCertPath(certificates)); + } + + /** + * Returns a (possibly empty) collection view of the certificates read + * from the given input stream {@code inStream}. + * + *

In order to take advantage of the specialized certificate format + * supported by this certificate factory, each element in + * the returned collection view can be typecast to the corresponding + * certificate class. For example, if this certificate + * factory implements X.509 certificates, the elements in the returned + * collection can be typecast to the {@code X509Certificate} class. + * + *

In the case of a certificate factory for X.509 certificates, + * {@code inStream} may contain a sequence of DER-encoded certificates + * in the formats described for + * {@link #generateCertificate(java.io.InputStream) generateCertificate}. + * In addition, {@code inStream} may contain a PKCS#7 certificate + * chain. This is a PKCS#7 SignedData object, with the only + * significant field being certificates. In particular, the + * signature and the contents are ignored. This format allows multiple + * certificates to be downloaded at once. If no certificates are present, + * an empty collection is returned. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. + * + * @param inStream the input stream with the certificates. + * + * @return a (possibly empty) collection view of + * java.security.cert.Certificate objects + * initialized with the data from the input stream. + * + * @exception CertificateException on parsing errors. + */ + public final Collection generateCertificates + (InputStream inStream) throws CertificateException { + return certFacSpi.engineGenerateCertificates(inStream); + } + + /** + * Generates a certificate revocation list (CRL) object and initializes it + * with the data read from the input stream {@code inStream}. + * + *

In order to take advantage of the specialized CRL format + * supported by this certificate factory, + * the returned CRL object can be typecast to the corresponding + * CRL class. For example, if this certificate + * factory implements X.509 CRLs, the returned CRL object + * can be typecast to the {@code X509CRL} class. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. Otherwise, each call to this + * method consumes one CRL and the read position of the input stream + * is positioned to the next available byte after the inherent + * end-of-CRL marker. If the data in the + * input stream does not contain an inherent end-of-CRL marker (other + * than EOF) and there is trailing data after the CRL is parsed, a + * {@code CRLException} is thrown. + * + * @param inStream an input stream with the CRL data. + * + * @return a CRL object initialized with the data + * from the input stream. + * + * @exception CRLException on parsing errors. + */ + public final CRL generateCRL(InputStream inStream) + throws CRLException + { + return certFacSpi.engineGenerateCRL(inStream); + } + + /** + * Returns a (possibly empty) collection view of the CRLs read + * from the given input stream {@code inStream}. + * + *

In order to take advantage of the specialized CRL format + * supported by this certificate factory, each element in + * the returned collection view can be typecast to the corresponding + * CRL class. For example, if this certificate + * factory implements X.509 CRLs, the elements in the returned + * collection can be typecast to the {@code X509CRL} class. + * + *

In the case of a certificate factory for X.509 CRLs, + * {@code inStream} may contain a sequence of DER-encoded CRLs. + * In addition, {@code inStream} may contain a PKCS#7 CRL + * set. This is a PKCS#7 SignedData object, with the only + * significant field being crls. In particular, the + * signature and the contents are ignored. This format allows multiple + * CRLs to be downloaded at once. If no CRLs are present, + * an empty collection is returned. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. + * + * @param inStream the input stream with the CRLs. + * + * @return a (possibly empty) collection view of + * java.security.cert.CRL objects initialized with the data from the input + * stream. + * + * @exception CRLException on parsing errors. + */ + public final Collection generateCRLs(InputStream inStream) + throws CRLException { + return certFacSpi.engineGenerateCRLs(inStream); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateFactorySpi.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateFactorySpi.java new file mode 100644 index 000000000..35aee847b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateFactorySpi.java @@ -0,0 +1,315 @@ +/* + * Copyright (c) 1998, 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 java.security.cert; + +import java.io.InputStream; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.security.Provider; +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; + +/** + * This class defines the Service Provider Interface (SPI) + * for the {@code CertificateFactory} class. + * All the abstract methods in this class must be implemented by each + * cryptographic service provider who wishes to supply the implementation + * of a certificate factory for a particular certificate type, e.g., X.509. + * + *

Certificate factories are used to generate certificate, certification path + * ({@code CertPath}) and certificate revocation list (CRL) objects from + * their encodings. + * + *

A certificate factory for X.509 must return certificates that are an + * instance of {@code java.security.cert.X509Certificate}, and CRLs + * that are an instance of {@code java.security.cert.X509CRL}. + * + * @author Hemma Prafullchandra + * @author Jan Luehe + * @author Sean Mullan + * + * + * @see CertificateFactory + * @see Certificate + * @see X509Certificate + * @see CertPath + * @see CRL + * @see X509CRL + * + * @since 1.2 + */ + +public abstract class CertificateFactorySpi { + + /** + * Generates a certificate object and initializes it with + * the data read from the input stream {@code inStream}. + * + *

In order to take advantage of the specialized certificate format + * supported by this certificate factory, + * the returned certificate object can be typecast to the corresponding + * certificate class. For example, if this certificate + * factory implements X.509 certificates, the returned certificate object + * can be typecast to the {@code X509Certificate} class. + * + *

In the case of a certificate factory for X.509 certificates, the + * certificate provided in {@code inStream} must be DER-encoded and + * may be supplied in binary or printable (Base64) encoding. If the + * certificate is provided in Base64 encoding, it must be bounded at + * the beginning by -----BEGIN CERTIFICATE-----, and must be bounded at + * the end by -----END CERTIFICATE-----. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. Otherwise, each call to this + * method consumes one certificate and the read position of the input stream + * is positioned to the next available byte after the inherent + * end-of-certificate marker. If the data in the + * input stream does not contain an inherent end-of-certificate marker (other + * than EOF) and there is trailing data after the certificate is parsed, a + * {@code CertificateException} is thrown. + * + * @param inStream an input stream with the certificate data. + * + * @return a certificate object initialized with the data + * from the input stream. + * + * @exception CertificateException on parsing errors. + */ + public abstract Certificate engineGenerateCertificate(InputStream inStream) + throws CertificateException; + + /** + * Generates a {@code CertPath} object and initializes it with + * the data read from the {@code InputStream} inStream. The data + * is assumed to be in the default encoding. + * + *

This method was added to version 1.4 of the Java 2 Platform + * Standard Edition. In order to maintain backwards compatibility with + * existing service providers, this method cannot be {@code abstract} + * and by default throws an {@code UnsupportedOperationException}. + * + * @param inStream an {@code InputStream} containing the data + * @return a {@code CertPath} initialized with the data from the + * {@code InputStream} + * @exception CertificateException if an exception occurs while decoding + * @exception UnsupportedOperationException if the method is not supported + * @since 1.4 + */ + public CertPath engineGenerateCertPath(InputStream inStream) + throws CertificateException + { + throw new UnsupportedOperationException(); + } + + /** + * Generates a {@code CertPath} object and initializes it with + * the data read from the {@code InputStream} inStream. The data + * is assumed to be in the specified encoding. + * + *

This method was added to version 1.4 of the Java 2 Platform + * Standard Edition. In order to maintain backwards compatibility with + * existing service providers, this method cannot be {@code abstract} + * and by default throws an {@code UnsupportedOperationException}. + * + * @param inStream an {@code InputStream} containing the data + * @param encoding the encoding used for the data + * @return a {@code CertPath} initialized with the data from the + * {@code InputStream} + * @exception CertificateException if an exception occurs while decoding or + * the encoding requested is not supported + * @exception UnsupportedOperationException if the method is not supported + * @since 1.4 + */ + public CertPath engineGenerateCertPath(InputStream inStream, + String encoding) throws CertificateException + { + throw new UnsupportedOperationException(); + } + + /** + * Generates a {@code CertPath} object and initializes it with + * a {@code List} of {@code Certificate}s. + *

+ * The certificates supplied must be of a type supported by the + * {@code CertificateFactory}. They will be copied out of the supplied + * {@code List} object. + * + *

This method was added to version 1.4 of the Java 2 Platform + * Standard Edition. In order to maintain backwards compatibility with + * existing service providers, this method cannot be {@code abstract} + * and by default throws an {@code UnsupportedOperationException}. + * + * @param certificates a {@code List} of {@code Certificate}s + * @return a {@code CertPath} initialized with the supplied list of + * certificates + * @exception CertificateException if an exception occurs + * @exception UnsupportedOperationException if the method is not supported + * @since 1.4 + */ + public CertPath + engineGenerateCertPath(List certificates) + throws CertificateException + { + throw new UnsupportedOperationException(); + } + + /** + * Returns an iteration of the {@code CertPath} encodings supported + * by this certificate factory, with the default encoding first. See + * the CertPath Encodings section in the + * Java Cryptography Architecture Standard Algorithm Name Documentation + * for information about standard encoding names. + *

+ * Attempts to modify the returned {@code Iterator} via its + * {@code remove} method result in an + * {@code UnsupportedOperationException}. + * + *

This method was added to version 1.4 of the Java 2 Platform + * Standard Edition. In order to maintain backwards compatibility with + * existing service providers, this method cannot be {@code abstract} + * and by default throws an {@code UnsupportedOperationException}. + * + * @return an {@code Iterator} over the names of the supported + * {@code CertPath} encodings (as {@code String}s) + * @exception UnsupportedOperationException if the method is not supported + * @since 1.4 + */ + public Iterator engineGetCertPathEncodings() { + throw new UnsupportedOperationException(); + } + + /** + * Returns a (possibly empty) collection view of the certificates read + * from the given input stream {@code inStream}. + * + *

In order to take advantage of the specialized certificate format + * supported by this certificate factory, each element in + * the returned collection view can be typecast to the corresponding + * certificate class. For example, if this certificate + * factory implements X.509 certificates, the elements in the returned + * collection can be typecast to the {@code X509Certificate} class. + * + *

In the case of a certificate factory for X.509 certificates, + * {@code inStream} may contain a single DER-encoded certificate + * in the formats described for + * {@link CertificateFactory#generateCertificate(java.io.InputStream) + * generateCertificate}. + * In addition, {@code inStream} may contain a PKCS#7 certificate + * chain. This is a PKCS#7 SignedData object, with the only + * significant field being certificates. In particular, the + * signature and the contents are ignored. This format allows multiple + * certificates to be downloaded at once. If no certificates are present, + * an empty collection is returned. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. + * + * @param inStream the input stream with the certificates. + * + * @return a (possibly empty) collection view of + * java.security.cert.Certificate objects + * initialized with the data from the input stream. + * + * @exception CertificateException on parsing errors. + */ + public abstract Collection + engineGenerateCertificates(InputStream inStream) + throws CertificateException; + + /** + * Generates a certificate revocation list (CRL) object and initializes it + * with the data read from the input stream {@code inStream}. + * + *

In order to take advantage of the specialized CRL format + * supported by this certificate factory, + * the returned CRL object can be typecast to the corresponding + * CRL class. For example, if this certificate + * factory implements X.509 CRLs, the returned CRL object + * can be typecast to the {@code X509CRL} class. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. Otherwise, each call to this + * method consumes one CRL and the read position of the input stream + * is positioned to the next available byte after the inherent + * end-of-CRL marker. If the data in the + * input stream does not contain an inherent end-of-CRL marker (other + * than EOF) and there is trailing data after the CRL is parsed, a + * {@code CRLException} is thrown. + * + * @param inStream an input stream with the CRL data. + * + * @return a CRL object initialized with the data + * from the input stream. + * + * @exception CRLException on parsing errors. + */ + public abstract CRL engineGenerateCRL(InputStream inStream) + throws CRLException; + + /** + * Returns a (possibly empty) collection view of the CRLs read + * from the given input stream {@code inStream}. + * + *

In order to take advantage of the specialized CRL format + * supported by this certificate factory, each element in + * the returned collection view can be typecast to the corresponding + * CRL class. For example, if this certificate + * factory implements X.509 CRLs, the elements in the returned + * collection can be typecast to the {@code X509CRL} class. + * + *

In the case of a certificate factory for X.509 CRLs, + * {@code inStream} may contain a single DER-encoded CRL. + * In addition, {@code inStream} may contain a PKCS#7 CRL + * set. This is a PKCS#7 SignedData object, with the only + * significant field being crls. In particular, the + * signature and the contents are ignored. This format allows multiple + * CRLs to be downloaded at once. If no CRLs are present, + * an empty collection is returned. + * + *

Note that if the given input stream does not support + * {@link java.io.InputStream#mark(int) mark} and + * {@link java.io.InputStream#reset() reset}, this method will + * consume the entire input stream. + * + * @param inStream the input stream with the CRLs. + * + * @return a (possibly empty) collection view of + * java.security.cert.CRL objects initialized with the data from the input + * stream. + * + * @exception CRLException on parsing errors. + */ + public abstract Collection engineGenerateCRLs + (InputStream inStream) throws CRLException; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateNotYetValidException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateNotYetValidException.java new file mode 100644 index 000000000..e8722bd33 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateNotYetValidException.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +/** + * Certificate is not yet valid exception. This is thrown whenever + * the current {@code Date} or the specified {@code Date} + * is before the {@code notBefore} date/time in the Certificate + * validity period. + * + * @author Hemma Prafullchandra + */ +public class CertificateNotYetValidException extends CertificateException { + + static final long serialVersionUID = 4355919900041064702L; + + /** + * Constructs a CertificateNotYetValidException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public CertificateNotYetValidException() { + super(); + } + + /** + * Constructs a CertificateNotYetValidException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param message the detail message. + */ + public CertificateNotYetValidException(String message) { + super(message); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateParsingException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateParsingException.java new file mode 100644 index 000000000..06a7d603f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateParsingException.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +/** + * Certificate Parsing Exception. This is thrown whenever an + * invalid DER-encoded certificate is parsed or unsupported DER features + * are found in the Certificate. + * + * @author Hemma Prafullchandra + */ +public class CertificateParsingException extends CertificateException { + + private static final long serialVersionUID = -7989222416793322029L; + + /** + * Constructs a CertificateParsingException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public CertificateParsingException() { + super(); + } + + /** + * Constructs a CertificateParsingException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param message the detail message. + */ + public CertificateParsingException(String message) { + super(message); + } + + /** + * Creates a {@code CertificateParsingException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CertificateParsingException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code CertificateParsingException} with the + * specified cause and a detail message of + * {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public CertificateParsingException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateRevokedException.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateRevokedException.java new file mode 100644 index 000000000..505a007f5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CertificateRevokedException.java @@ -0,0 +1,247 @@ +/* + * Copyright (c) 2007, 2014, 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 java.security.cert; + +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.IOException; +import java.util.Collections; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import javax.security.auth.x500.X500Principal; + +import sun.security.util.ObjectIdentifier; +import sun.security.x509.InvalidityDateExtension; + +/** + * An exception that indicates an X.509 certificate is revoked. A + * {@code CertificateRevokedException} contains additional information + * about the revoked certificate, such as the date on which the + * certificate was revoked and the reason it was revoked. + * + * @author Sean Mullan + * @since 1.7 + * @see CertPathValidatorException + */ +public class CertificateRevokedException extends CertificateException { + + private static final long serialVersionUID = 7839996631571608627L; + + /** + * @serial the date on which the certificate was revoked + */ + private Date revocationDate; + /** + * @serial the revocation reason + */ + private final CRLReason reason; + /** + * @serial the {@code X500Principal} that represents the name of the + * authority that signed the certificate's revocation status information + */ + private final X500Principal authority; + + private transient Map extensions; + + /** + * Constructs a {@code CertificateRevokedException} with + * the specified revocation date, reason code, authority name, and map + * of extensions. + * + * @param revocationDate the date on which the certificate was revoked. The + * date is copied to protect against subsequent modification. + * @param reason the revocation reason + * @param extensions a map of X.509 Extensions. Each key is an OID String + * that maps to the corresponding Extension. The map is copied to + * prevent subsequent modification. + * @param authority the {@code X500Principal} that represents the name + * of the authority that signed the certificate's revocation status + * information + * @throws NullPointerException if {@code revocationDate}, + * {@code reason}, {@code authority}, or + * {@code extensions} is {@code null} + */ + public CertificateRevokedException(Date revocationDate, CRLReason reason, + X500Principal authority, Map extensions) { + if (revocationDate == null || reason == null || authority == null || + extensions == null) { + throw new NullPointerException(); + } + this.revocationDate = new Date(revocationDate.getTime()); + this.reason = reason; + this.authority = authority; + // make sure Map only contains correct types + this.extensions = Collections.checkedMap(new HashMap<>(), + String.class, Extension.class); + this.extensions.putAll(extensions); + } + + /** + * Returns the date on which the certificate was revoked. A new copy is + * returned each time the method is invoked to protect against subsequent + * modification. + * + * @return the revocation date + */ + public Date getRevocationDate() { + return (Date) revocationDate.clone(); + } + + /** + * Returns the reason the certificate was revoked. + * + * @return the revocation reason + */ + public CRLReason getRevocationReason() { + return reason; + } + + /** + * Returns the name of the authority that signed the certificate's + * revocation status information. + * + * @return the {@code X500Principal} that represents the name of the + * authority that signed the certificate's revocation status information + */ + public X500Principal getAuthorityName() { + return authority; + } + + /** + * Returns the invalidity date, as specified in the Invalidity Date + * extension of this {@code CertificateRevokedException}. The + * invalidity date is the date on which it is known or suspected that the + * private key was compromised or that the certificate otherwise became + * invalid. This implementation calls {@code getExtensions()} and + * checks the returned map for an entry for the Invalidity Date extension + * OID ("2.5.29.24"). If found, it returns the invalidity date in the + * extension; otherwise null. A new Date object is returned each time the + * method is invoked to protect against subsequent modification. + * + * @return the invalidity date, or {@code null} if not specified + */ + public Date getInvalidityDate() { + Extension ext = getExtensions().get("2.5.29.24"); + if (ext == null) { + return null; + } else { + try { + Date invalidity = InvalidityDateExtension.toImpl(ext).get("DATE"); + return new Date(invalidity.getTime()); + } catch (IOException ioe) { + return null; + } + } + } + + /** + * Returns a map of X.509 extensions containing additional information + * about the revoked certificate, such as the Invalidity Date + * Extension. Each key is an OID String that maps to the corresponding + * Extension. + * + * @return an unmodifiable map of X.509 extensions, or an empty map + * if there are no extensions + */ + public Map getExtensions() { + return Collections.unmodifiableMap(extensions); + } + + @Override + public String getMessage() { + return "Certificate has been revoked, reason: " + + reason + ", revocation date: " + revocationDate + + ", authority: " + authority + ", extension OIDs: " + + extensions.keySet(); + } + + /** + * Serialize this {@code CertificateRevokedException} instance. + * + * @serialData the size of the extensions map (int), followed by all of + * the extensions in the map, in no particular order. For each extension, + * the following data is emitted: the OID String (Object), the criticality + * flag (boolean), the length of the encoded extension value byte array + * (int), and the encoded extension value bytes. + */ + private void writeObject(ObjectOutputStream oos) throws IOException { + // Write out the non-transient fields + // (revocationDate, reason, authority) + oos.defaultWriteObject(); + + // Write out the size (number of mappings) of the extensions map + oos.writeInt(extensions.size()); + + // For each extension in the map, the following are emitted (in order): + // the OID String (Object), the criticality flag (boolean), the length + // of the encoded extension value byte array (int), and the encoded + // extension value byte array. The extensions themselves are emitted + // in no particular order. + for (Map.Entry entry : extensions.entrySet()) { + Extension ext = entry.getValue(); + oos.writeObject(ext.getId()); + oos.writeBoolean(ext.isCritical()); + byte[] extVal = ext.getValue(); + oos.writeInt(extVal.length); + oos.write(extVal); + } + } + + /** + * Deserialize the {@code CertificateRevokedException} instance. + */ + private void readObject(ObjectInputStream ois) + throws IOException, ClassNotFoundException { + // Read in the non-transient fields + // (revocationDate, reason, authority) + ois.defaultReadObject(); + + // Defensively copy the revocation date + revocationDate = new Date(revocationDate.getTime()); + + // Read in the size (number of mappings) of the extensions map + // and create the extensions map + int size = ois.readInt(); + if (size == 0) { + extensions = Collections.emptyMap(); + } else { + extensions = new HashMap(size); + } + + // Read in the extensions and put the mappings in the extensions map + for (int i = 0; i < size; i++) { + String oid = (String) ois.readObject(); + boolean critical = ois.readBoolean(); + int length = ois.readInt(); + byte[] extVal = new byte[length]; + ois.readFully(extVal); + Extension ext = sun.security.x509.Extension.newExtension + (new ObjectIdentifier(oid), critical, extVal); + extensions.put(oid, ext); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/CollectionCertStoreParameters.java b/sources/net.sf.j2s.java.core/src/java/security/cert/CollectionCertStoreParameters.java new file mode 100644 index 000000000..12bd358cf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/CollectionCertStoreParameters.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.io.Serializable; +import java.util.Collection; +import java.util.Collections; + +/** + * Parameters used as input for the Collection {@code CertStore} + * algorithm. + *

+ * This class is used to provide necessary configuration parameters + * to implementations of the Collection {@code CertStore} + * algorithm. The only parameter included in this class is the + * {@code Collection} from which the {@code CertStore} will + * retrieve certificates and CRLs. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @since 1.4 + * @author Steve Hanna + * @see java.util.Collection + * @see CertStore + */ +public class CollectionCertStoreParameters + implements CertStoreParameters { + + private Collection coll; + + /** + * Creates an instance of {@code CollectionCertStoreParameters} + * which will allow certificates and CRLs to be retrieved from the + * specified {@code Collection}. If the specified + * {@code Collection} contains an object that is not a + * {@code Certificate} or {@code CRL}, that object will be + * ignored by the Collection {@code CertStore}. + *

+ * The {@code Collection} is not copied. Instead, a + * reference is used. This allows the caller to subsequently add or + * remove {@code Certificates} or {@code CRL}s from the + * {@code Collection}, thus changing the set of + * {@code Certificates} or {@code CRL}s available to the + * Collection {@code CertStore}. The Collection {@code CertStore} + * will not modify the contents of the {@code Collection}. + *

+ * If the {@code Collection} will be modified by one thread while + * another thread is calling a method of a Collection {@code CertStore} + * that has been initialized with this {@code Collection}, the + * {@code Collection} must have fail-fast iterators. + * + * @param collection a {@code Collection} of + * {@code Certificate}s and {@code CRL}s + * @exception NullPointerException if {@code collection} is + * {@code null} + */ + public CollectionCertStoreParameters(Collection collection) { + if (collection == null) + throw new NullPointerException(); + coll = collection; + } + + /** + * Creates an instance of {@code CollectionCertStoreParameters} with + * the default parameter values (an empty and immutable + * {@code Collection}). + */ + public CollectionCertStoreParameters() { + coll = Collections.EMPTY_SET; + } + + /** + * Returns the {@code Collection} from which {@code Certificate}s + * and {@code CRL}s are retrieved. This is not a copy of the + * {@code Collection}, it is a reference. This allows the caller to + * subsequently add or remove {@code Certificates} or + * {@code CRL}s from the {@code Collection}. + * + * @return the {@code Collection} (never null) + */ + public Collection getCollection() { + return coll; + } + + /** + * Returns a copy of this object. Note that only a reference to the + * {@code Collection} is copied, and not the contents. + * + * @return the copy + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + /* Cannot happen */ + throw new InternalError(e.toString(), e); + } + } + + /** + * Returns a formatted string describing the parameters. + * + * @return a formatted string describing the parameters + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("CollectionCertStoreParameters: [\n"); + sb.append(" collection: " + coll + "\n"); + sb.append("]"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/Extension.java b/sources/net.sf.j2s.java.core/src/java/security/cert/Extension.java new file mode 100644 index 000000000..98e827c59 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/Extension.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2007, 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 java.security.cert; + +import java.io.IOException; +import java.io.OutputStream; +import java.io.Serializable; + +/** + * This interface represents an X.509 extension. + * + *

+ * Extensions provide a means of associating additional attributes with users + * or public keys and for managing a certification hierarchy. The extension + * format also allows communities to define private extensions to carry + * information unique to those communities. + * + *

+ * Each extension contains an object identifier, a criticality setting + * indicating whether it is a critical or a non-critical extension, and + * and an ASN.1 DER-encoded value. Its ASN.1 definition is: + * + *

+ *
+ *     Extension ::= SEQUENCE {
+ *         extnId        OBJECT IDENTIFIER,
+ *         critical      BOOLEAN DEFAULT FALSE,
+ *         extnValue     OCTET STRING
+ *                 -- contains a DER encoding of a value
+ *                 -- of the type registered for use with
+ *                 -- the extnId object identifier value
+ *     }
+ *
+ * 
+ * + *

+ * This interface is designed to provide access to a single extension, + * unlike {@link java.security.cert.X509Extension} which is more suitable + * for accessing a set of extensions. + * + * @since 1.7 + */ +public interface Extension { + + /** + * Gets the extensions's object identifier. + * + * @return the object identifier as a String + */ + String getId(); + + /** + * Gets the extension's criticality setting. + * + * @return true if this is a critical extension. + */ + boolean isCritical(); + + /** + * Gets the extensions's DER-encoded value. Note, this is the bytes + * that are encoded as an OCTET STRING. It does not include the OCTET + * STRING tag and length. + * + * @return a copy of the extension's value, or {@code null} if no + * extension value is present. + */ + byte[] getValue(); + + /** + * Generates the extension's DER encoding and writes it to the output + * stream. + * + * @param out the output stream + * @exception IOException on encoding or output error. + * @exception NullPointerException if {@code out} is {@code null}. + */ + void encode(OutputStream out) throws IOException; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/LDAPCertStoreParameters.java b/sources/net.sf.j2s.java.core/src/java/security/cert/LDAPCertStoreParameters.java new file mode 100644 index 000000000..96fe9cd09 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/LDAPCertStoreParameters.java @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +/** + * Parameters used as input for the LDAP {@code CertStore} algorithm. + *

+ * This class is used to provide necessary configuration parameters (server + * name and port number) to implementations of the LDAP {@code CertStore} + * algorithm. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @since 1.4 + * @author Steve Hanna + * @see CertStore + */ +public class LDAPCertStoreParameters implements CertStoreParameters { + + private static final int LDAP_DEFAULT_PORT = 389; + + /** + * the port number of the LDAP server + */ + private int port; + + /** + * the DNS name of the LDAP server + */ + private String serverName; + + /** + * Creates an instance of {@code LDAPCertStoreParameters} with the + * specified parameter values. + * + * @param serverName the DNS name of the LDAP server + * @param port the port number of the LDAP server + * @exception NullPointerException if {@code serverName} is + * {@code null} + */ + public LDAPCertStoreParameters(String serverName, int port) { + if (serverName == null) + throw new NullPointerException(); + this.serverName = serverName; + this.port = port; + } + + /** + * Creates an instance of {@code LDAPCertStoreParameters} with the + * specified server name and a default port of 389. + * + * @param serverName the DNS name of the LDAP server + * @exception NullPointerException if {@code serverName} is + * {@code null} + */ + public LDAPCertStoreParameters(String serverName) { + this(serverName, LDAP_DEFAULT_PORT); + } + + /** + * Creates an instance of {@code LDAPCertStoreParameters} with the + * default parameter values (server name "localhost", port 389). + */ + public LDAPCertStoreParameters() { + this("localhost", LDAP_DEFAULT_PORT); + } + + /** + * Returns the DNS name of the LDAP server. + * + * @return the name (not {@code null}) + */ + public String getServerName() { + return serverName; + } + + /** + * Returns the port number of the LDAP server. + * + * @return the port number + */ + public int getPort() { + return port; + } + + /** + * Returns a copy of this object. Changes to the copy will not affect + * the original and vice versa. + *

+ * Note: this method currently performs a shallow copy of the object + * (simply calls {@code Object.clone()}). This may be changed in a + * future revision to perform a deep copy if new parameters are added + * that should not be shared. + * + * @return the copy + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + /* Cannot happen */ + throw new InternalError(e.toString(), e); + } + } + + /** + * Returns a formatted string describing the parameters. + * + * @return a formatted string describing the parameters + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("LDAPCertStoreParameters: [\n"); + + sb.append(" serverName: " + serverName + "\n"); + sb.append(" port: " + port + "\n"); + sb.append("]"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXBuilderParameters.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXBuilderParameters.java new file mode 100644 index 000000000..b33e1f8c1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXBuilderParameters.java @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.InvalidAlgorithmParameterException; +import java.security.InvalidParameterException; +import java.util.Set; + +/** + * Parameters used as input for the PKIX {@code CertPathBuilder} + * algorithm. + *

+ * A PKIX {@code CertPathBuilder} uses these parameters to {@link + * CertPathBuilder#build build} a {@code CertPath} which has been + * validated according to the PKIX certification path validation algorithm. + * + *

To instantiate a {@code PKIXBuilderParameters} object, an + * application must specify one or more most-trusted CAs as defined by + * the PKIX certification path validation algorithm. The most-trusted CA + * can be specified using one of two constructors. An application + * can call {@link #PKIXBuilderParameters(Set, CertSelector) + * PKIXBuilderParameters(Set, CertSelector)}, specifying a + * {@code Set} of {@code TrustAnchor} objects, each of which + * identifies a most-trusted CA. Alternatively, an application can call + * {@link #PKIXBuilderParameters(KeyStore, CertSelector) + * PKIXBuilderParameters(KeyStore, CertSelector)}, specifying a + * {@code KeyStore} instance containing trusted certificate entries, each + * of which will be considered as a most-trusted CA. + * + *

In addition, an application must specify constraints on the target + * certificate that the {@code CertPathBuilder} will attempt + * to build a path to. The constraints are specified as a + * {@code CertSelector} object. These constraints should provide the + * {@code CertPathBuilder} with enough search criteria to find the target + * certificate. Minimal criteria for an {@code X509Certificate} usually + * include the subject name and/or one or more subject alternative names. + * If enough criteria is not specified, the {@code CertPathBuilder} + * may throw a {@code CertPathBuilderException}. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathBuilder + * + * @since 1.4 + * @author Sean Mullan + */ +public class PKIXBuilderParameters extends PKIXParameters { + + private int maxPathLength = 5; + + /** + * Creates an instance of {@code PKIXBuilderParameters} with + * the specified {@code Set} of most-trusted CAs. + * Each element of the set is a {@link TrustAnchor TrustAnchor}. + * + *

Note that the {@code Set} is copied to protect against + * subsequent modifications. + * + * @param trustAnchors a {@code Set} of {@code TrustAnchor}s + * @param targetConstraints a {@code CertSelector} specifying the + * constraints on the target certificate + * @throws InvalidAlgorithmParameterException if {@code trustAnchors} + * is empty {@code (trustAnchors.isEmpty() == true)} + * @throws NullPointerException if {@code trustAnchors} is + * {@code null} + * @throws ClassCastException if any of the elements of + * {@code trustAnchors} are not of type + * {@code java.security.cert.TrustAnchor} + */ + public PKIXBuilderParameters(Set trustAnchors, CertSelector + targetConstraints) throws InvalidAlgorithmParameterException + { + super(trustAnchors); + setTargetCertConstraints(targetConstraints); + } + + /** + * Creates an instance of {@code PKIXBuilderParameters} that + * populates the set of most-trusted CAs from the trusted + * certificate entries contained in the specified {@code KeyStore}. + * Only keystore entries that contain trusted {@code X509Certificate}s + * are considered; all other certificate types are ignored. + * + * @param keystore a {@code KeyStore} from which the set of + * most-trusted CAs will be populated + * @param targetConstraints a {@code CertSelector} specifying the + * constraints on the target certificate + * @throws KeyStoreException if {@code keystore} has not been + * initialized + * @throws InvalidAlgorithmParameterException if {@code keystore} does + * not contain at least one trusted certificate entry + * @throws NullPointerException if {@code keystore} is + * {@code null} + */ + public PKIXBuilderParameters(KeyStore keystore, + CertSelector targetConstraints) + throws KeyStoreException, InvalidAlgorithmParameterException + { + super(keystore); + setTargetCertConstraints(targetConstraints); + } + + /** + * Sets the value of the maximum number of non-self-issued intermediate + * certificates that may exist in a certification path. A certificate + * is self-issued if the DNs that appear in the subject and issuer + * fields are identical and are not empty. Note that the last certificate + * in a certification path is not an intermediate certificate, and is not + * included in this limit. Usually the last certificate is an end entity + * certificate, but it can be a CA certificate. A PKIX + * {@code CertPathBuilder} instance must not build + * paths longer than the length specified. + * + *

A value of 0 implies that the path can only contain + * a single certificate. A value of -1 implies that the + * path length is unconstrained (i.e. there is no maximum). + * The default maximum path length, if not specified, is 5. + * Setting a value less than -1 will cause an exception to be thrown. + * + *

If any of the CA certificates contain the + * {@code BasicConstraintsExtension}, the value of the + * {@code pathLenConstraint} field of the extension overrides + * the maximum path length parameter whenever the result is a + * certification path of smaller length. + * + * @param maxPathLength the maximum number of non-self-issued intermediate + * certificates that may exist in a certification path + * @throws InvalidParameterException if {@code maxPathLength} is set + * to a value less than -1 + * + * @see #getMaxPathLength + */ + public void setMaxPathLength(int maxPathLength) { + if (maxPathLength < -1) { + throw new InvalidParameterException("the maximum path " + + "length parameter can not be less than -1"); + } + this.maxPathLength = maxPathLength; + } + + /** + * Returns the value of the maximum number of intermediate non-self-issued + * certificates that may exist in a certification path. See + * the {@link #setMaxPathLength} method for more details. + * + * @return the maximum number of non-self-issued intermediate certificates + * that may exist in a certification path, or -1 if there is no limit + * + * @see #setMaxPathLength + */ + public int getMaxPathLength() { + return maxPathLength; + } + + /** + * Returns a formatted string describing the parameters. + * + * @return a formatted string describing the parameters + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("[\n"); + sb.append(super.toString()); + sb.append(" Maximum Path Length: " + maxPathLength + "\n"); + sb.append("]\n"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathBuilderResult.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathBuilderResult.java new file mode 100644 index 000000000..3255a3bbd --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathBuilderResult.java @@ -0,0 +1,119 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.PublicKey; + +/** + * This class represents the successful result of the PKIX certification + * path builder algorithm. All certification paths that are built and + * returned using this algorithm are also validated according to the PKIX + * certification path validation algorithm. + * + *

Instances of {@code PKIXCertPathBuilderResult} are returned by + * the {@code build} method of {@code CertPathBuilder} + * objects implementing the PKIX algorithm. + * + *

All {@code PKIXCertPathBuilderResult} objects contain the + * certification path constructed by the build algorithm, the + * valid policy tree and subject public key resulting from the build + * algorithm, and a {@code TrustAnchor} describing the certification + * authority (CA) that served as a trust anchor for the certification path. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathBuilderResult + * + * @since 1.4 + * @author Anne Anderson + */ +public class PKIXCertPathBuilderResult extends PKIXCertPathValidatorResult + implements CertPathBuilderResult { + + private CertPath certPath; + + /** + * Creates an instance of {@code PKIXCertPathBuilderResult} + * containing the specified parameters. + * + * @param certPath the validated {@code CertPath} + * @param trustAnchor a {@code TrustAnchor} describing the CA that + * served as a trust anchor for the certification path + * @param policyTree the immutable valid policy tree, or {@code null} + * if there are no valid policies + * @param subjectPublicKey the public key of the subject + * @throws NullPointerException if the {@code certPath}, + * {@code trustAnchor} or {@code subjectPublicKey} parameters + * are {@code null} + */ + public PKIXCertPathBuilderResult(CertPath certPath, + TrustAnchor trustAnchor, PolicyNode policyTree, + PublicKey subjectPublicKey) + { + super(trustAnchor, policyTree, subjectPublicKey); + if (certPath == null) + throw new NullPointerException("certPath must be non-null"); + this.certPath = certPath; + } + + /** + * Returns the built and validated certification path. The + * {@code CertPath} object does not include the trust anchor. + * Instead, use the {@link #getTrustAnchor() getTrustAnchor()} method to + * obtain the {@code TrustAnchor} that served as the trust anchor + * for the certification path. + * + * @return the built and validated {@code CertPath} (never + * {@code null}) + */ + public CertPath getCertPath() { + return certPath; + } + + /** + * Return a printable representation of this + * {@code PKIXCertPathBuilderResult}. + * + * @return a {@code String} describing the contents of this + * {@code PKIXCertPathBuilderResult} + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("PKIXCertPathBuilderResult: [\n"); + sb.append(" Certification Path: " + certPath + "\n"); + sb.append(" Trust Anchor: " + getTrustAnchor().toString() + "\n"); + sb.append(" Policy Tree: " + String.valueOf(getPolicyTree()) + "\n"); + sb.append(" Subject Public Key: " + getPublicKey() + "\n"); + sb.append("]"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathChecker.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathChecker.java new file mode 100644 index 000000000..21e01bf51 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathChecker.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.util.Collection; +import java.util.Set; + +/** + * An abstract class that performs one or more checks on an + * {@code X509Certificate}. + * + *

A concrete implementation of the {@code PKIXCertPathChecker} class + * can be created to extend the PKIX certification path validation algorithm. + * For example, an implementation may check for and process a critical private + * extension of each certificate in a certification path. + * + *

Instances of {@code PKIXCertPathChecker} are passed as parameters + * using the {@link PKIXParameters#setCertPathCheckers setCertPathCheckers} + * or {@link PKIXParameters#addCertPathChecker addCertPathChecker} methods + * of the {@code PKIXParameters} and {@code PKIXBuilderParameters} + * class. Each of the {@code PKIXCertPathChecker}s {@link #check check} + * methods will be called, in turn, for each certificate processed by a PKIX + * {@code CertPathValidator} or {@code CertPathBuilder} + * implementation. + * + *

A {@code PKIXCertPathChecker} may be called multiple times on + * successive certificates in a certification path. Concrete subclasses + * are expected to maintain any internal state that may be necessary to + * check successive certificates. The {@link #init init} method is used + * to initialize the internal state of the checker so that the certificates + * of a new certification path may be checked. A stateful implementation + * must override the {@link #clone clone} method if necessary in + * order to allow a PKIX {@code CertPathBuilder} to efficiently + * backtrack and try other paths. In these situations, the + * {@code CertPathBuilder} is able to restore prior path validation + * states by restoring the cloned {@code PKIXCertPathChecker}s. + * + *

The order in which the certificates are presented to the + * {@code PKIXCertPathChecker} may be either in the forward direction + * (from target to most-trusted CA) or in the reverse direction (from + * most-trusted CA to target). A {@code PKIXCertPathChecker} implementation + * must support reverse checking (the ability to perform its checks when + * it is presented with certificates in the reverse direction) and may + * support forward checking (the ability to perform its checks when it is + * presented with certificates in the forward direction). The + * {@link #isForwardCheckingSupported isForwardCheckingSupported} method + * indicates whether forward checking is supported. + *

+ * Additional input parameters required for executing the check may be + * specified through constructors of concrete implementations of this class. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see PKIXParameters + * @see PKIXBuilderParameters + * + * @since 1.4 + * @author Yassir Elley + * @author Sean Mullan + */ +public abstract class PKIXCertPathChecker + implements CertPathChecker, Cloneable { + + /** + * Default constructor. + */ + protected PKIXCertPathChecker() {} + + /** + * Initializes the internal state of this {@code PKIXCertPathChecker}. + *

+ * The {@code forward} flag specifies the order that + * certificates will be passed to the {@link #check check} method + * (forward or reverse). A {@code PKIXCertPathChecker} must + * support reverse checking and may support forward checking. + * + * @param forward the order that certificates are presented to + * the {@code check} method. If {@code true}, certificates + * are presented from target to most-trusted CA (forward); if + * {@code false}, from most-trusted CA to target (reverse). + * @throws CertPathValidatorException if this + * {@code PKIXCertPathChecker} is unable to check certificates in + * the specified order; it should never be thrown if the forward flag + * is false since reverse checking must be supported + */ + @Override + public abstract void init(boolean forward) + throws CertPathValidatorException; + + /** + * Indicates if forward checking is supported. Forward checking refers + * to the ability of the {@code PKIXCertPathChecker} to perform + * its checks when certificates are presented to the {@code check} + * method in the forward direction (from target to most-trusted CA). + * + * @return {@code true} if forward checking is supported, + * {@code false} otherwise + */ + @Override + public abstract boolean isForwardCheckingSupported(); + + /** + * Returns an immutable {@code Set} of X.509 certificate extensions + * that this {@code PKIXCertPathChecker} supports (i.e. recognizes, is + * able to process), or {@code null} if no extensions are supported. + *

+ * Each element of the set is a {@code String} representing the + * Object Identifier (OID) of the X.509 extension that is supported. + * The OID is represented by a set of nonnegative integers separated by + * periods. + *

+ * All X.509 certificate extensions that a {@code PKIXCertPathChecker} + * might possibly be able to process should be included in the set. + * + * @return an immutable {@code Set} of X.509 extension OIDs (in + * {@code String} format) supported by this + * {@code PKIXCertPathChecker}, or {@code null} if no + * extensions are supported + */ + public abstract Set getSupportedExtensions(); + + /** + * Performs the check(s) on the specified certificate using its internal + * state and removes any critical extensions that it processes from the + * specified collection of OID strings that represent the unresolved + * critical extensions. The certificates are presented in the order + * specified by the {@code init} method. + * + * @param cert the {@code Certificate} to be checked + * @param unresolvedCritExts a {@code Collection} of OID strings + * representing the current set of unresolved critical extensions + * @exception CertPathValidatorException if the specified certificate does + * not pass the check + */ + public abstract void check(Certificate cert, + Collection unresolvedCritExts) + throws CertPathValidatorException; + + /** + * {@inheritDoc} + * + *

This implementation calls + * {@code check(cert, java.util.Collections.emptySet())}. + */ + @Override + public void check(Certificate cert) throws CertPathValidatorException { + check(cert, java.util.Collections.emptySet()); + } + + /** + * Returns a clone of this object. Calls the {@code Object.clone()} + * method. + * All subclasses which maintain state must support and + * override this method, if necessary. + * + * @return a copy of this {@code PKIXCertPathChecker} + */ + @Override + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + /* Cannot happen */ + throw new InternalError(e.toString(), e); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathValidatorResult.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathValidatorResult.java new file mode 100644 index 000000000..b40cd393c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXCertPathValidatorResult.java @@ -0,0 +1,159 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.PublicKey; + +/** + * This class represents the successful result of the PKIX certification + * path validation algorithm. + * + *

Instances of {@code PKIXCertPathValidatorResult} are returned by the + * {@link CertPathValidator#validate validate} method of + * {@code CertPathValidator} objects implementing the PKIX algorithm. + * + *

All {@code PKIXCertPathValidatorResult} objects contain the + * valid policy tree and subject public key resulting from the + * validation algorithm, as well as a {@code TrustAnchor} describing + * the certification authority (CA) that served as a trust anchor for the + * certification path. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathValidatorResult + * + * @since 1.4 + * @author Yassir Elley + * @author Sean Mullan + */ +public class PKIXCertPathValidatorResult implements CertPathValidatorResult { + + private TrustAnchor trustAnchor; + private PolicyNode policyTree; + private PublicKey subjectPublicKey; + + /** + * Creates an instance of {@code PKIXCertPathValidatorResult} + * containing the specified parameters. + * + * @param trustAnchor a {@code TrustAnchor} describing the CA that + * served as a trust anchor for the certification path + * @param policyTree the immutable valid policy tree, or {@code null} + * if there are no valid policies + * @param subjectPublicKey the public key of the subject + * @throws NullPointerException if the {@code subjectPublicKey} or + * {@code trustAnchor} parameters are {@code null} + */ + public PKIXCertPathValidatorResult(TrustAnchor trustAnchor, + PolicyNode policyTree, PublicKey subjectPublicKey) + { + if (subjectPublicKey == null) + throw new NullPointerException("subjectPublicKey must be non-null"); + if (trustAnchor == null) + throw new NullPointerException("trustAnchor must be non-null"); + this.trustAnchor = trustAnchor; + this.policyTree = policyTree; + this.subjectPublicKey = subjectPublicKey; + } + + /** + * Returns the {@code TrustAnchor} describing the CA that served + * as a trust anchor for the certification path. + * + * @return the {@code TrustAnchor} (never {@code null}) + */ + public TrustAnchor getTrustAnchor() { + return trustAnchor; + } + + /** + * Returns the root node of the valid policy tree resulting from the + * PKIX certification path validation algorithm. The + * {@code PolicyNode} object that is returned and any objects that + * it returns through public methods are immutable. + * + *

Most applications will not need to examine the valid policy tree. + * They can achieve their policy processing goals by setting the + * policy-related parameters in {@code PKIXParameters}. However, more + * sophisticated applications, especially those that process policy + * qualifiers, may need to traverse the valid policy tree using the + * {@link PolicyNode#getParent PolicyNode.getParent} and + * {@link PolicyNode#getChildren PolicyNode.getChildren} methods. + * + * @return the root node of the valid policy tree, or {@code null} + * if there are no valid policies + */ + public PolicyNode getPolicyTree() { + return policyTree; + } + + /** + * Returns the public key of the subject (target) of the certification + * path, including any inherited public key parameters if applicable. + * + * @return the public key of the subject (never {@code null}) + */ + public PublicKey getPublicKey() { + return subjectPublicKey; + } + + /** + * Returns a copy of this object. + * + * @return the copy + */ + public Object clone() { + try { + return super.clone(); + } catch (CloneNotSupportedException e) { + /* Cannot happen */ + throw new InternalError(e.toString(), e); + } + } + + /** + * Return a printable representation of this + * {@code PKIXCertPathValidatorResult}. + * + * @return a {@code String} describing the contents of this + * {@code PKIXCertPathValidatorResult} + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("PKIXCertPathValidatorResult: [\n"); + sb.append(" Trust Anchor: " + trustAnchor.toString() + "\n"); + sb.append(" Policy Tree: " + String.valueOf(policyTree) + "\n"); + sb.append(" Subject Public Key: " + subjectPublicKey + "\n"); + sb.append("]"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXParameters.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXParameters.java new file mode 100644 index 000000000..4d8a34453 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXParameters.java @@ -0,0 +1,736 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.security.InvalidAlgorithmParameterException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Date; +import java.util.Enumeration; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +/** + * Parameters used as input for the PKIX {@code CertPathValidator} + * algorithm. + *

+ * A PKIX {@code CertPathValidator} uses these parameters to + * validate a {@code CertPath} according to the PKIX certification path + * validation algorithm. + * + *

To instantiate a {@code PKIXParameters} object, an + * application must specify one or more most-trusted CAs as defined by + * the PKIX certification path validation algorithm. The most-trusted CAs + * can be specified using one of two constructors. An application + * can call {@link #PKIXParameters(Set) PKIXParameters(Set)}, + * specifying a {@code Set} of {@code TrustAnchor} objects, each + * of which identify a most-trusted CA. Alternatively, an application can call + * {@link #PKIXParameters(KeyStore) PKIXParameters(KeyStore)}, specifying a + * {@code KeyStore} instance containing trusted certificate entries, each + * of which will be considered as a most-trusted CA. + *

+ * Once a {@code PKIXParameters} object has been created, other parameters + * can be specified (by calling {@link #setInitialPolicies setInitialPolicies} + * or {@link #setDate setDate}, for instance) and then the + * {@code PKIXParameters} is passed along with the {@code CertPath} + * to be validated to {@link CertPathValidator#validate + * CertPathValidator.validate}. + *

+ * Any parameter that is not set (or is set to {@code null}) will + * be set to the default value for that parameter. The default value for the + * {@code date} parameter is {@code null}, which indicates + * the current time when the path is validated. The default for the + * remaining parameters is the least constrained. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertPathValidator + * + * @since 1.4 + * @author Sean Mullan + * @author Yassir Elley + */ +public class PKIXParameters implements CertPathParameters { + + private Set unmodTrustAnchors; + private Date date; + private List certPathCheckers; + private String sigProvider; + private boolean revocationEnabled = true; + private Set unmodInitialPolicies; + private boolean explicitPolicyRequired = false; + private boolean policyMappingInhibited = false; + private boolean anyPolicyInhibited = false; + private boolean policyQualifiersRejected = true; + private List certStores; + private CertSelector certSelector; + + /** + * Creates an instance of {@code PKIXParameters} with the specified + * {@code Set} of most-trusted CAs. Each element of the + * set is a {@link TrustAnchor TrustAnchor}. + *

+ * Note that the {@code Set} is copied to protect against + * subsequent modifications. + * + * @param trustAnchors a {@code Set} of {@code TrustAnchor}s + * @throws InvalidAlgorithmParameterException if the specified + * {@code Set} is empty {@code (trustAnchors.isEmpty() == true)} + * @throws NullPointerException if the specified {@code Set} is + * {@code null} + * @throws ClassCastException if any of the elements in the {@code Set} + * are not of type {@code java.security.cert.TrustAnchor} + */ + public PKIXParameters(Set trustAnchors) + throws InvalidAlgorithmParameterException + { + setTrustAnchors(trustAnchors); + + this.unmodInitialPolicies = Collections.emptySet(); + this.certPathCheckers = new ArrayList(); + this.certStores = new ArrayList(); + } + + /** + * Creates an instance of {@code PKIXParameters} that + * populates the set of most-trusted CAs from the trusted + * certificate entries contained in the specified {@code KeyStore}. + * Only keystore entries that contain trusted {@code X509Certificates} + * are considered; all other certificate types are ignored. + * + * @param keystore a {@code KeyStore} from which the set of + * most-trusted CAs will be populated + * @throws KeyStoreException if the keystore has not been initialized + * @throws InvalidAlgorithmParameterException if the keystore does + * not contain at least one trusted certificate entry + * @throws NullPointerException if the keystore is {@code null} + */ + public PKIXParameters(KeyStore keystore) + throws KeyStoreException, InvalidAlgorithmParameterException + { + if (keystore == null) + throw new NullPointerException("the keystore parameter must be " + + "non-null"); + Set hashSet = new HashSet(); + Enumeration aliases = keystore.aliases(); + while (aliases.hasMoreElements()) { + String alias = aliases.nextElement(); + if (keystore.isCertificateEntry(alias)) { + Certificate cert = keystore.getCertificate(alias); + if (cert instanceof X509Certificate) + hashSet.add(new TrustAnchor((X509Certificate)cert, null)); + } + } + setTrustAnchors(hashSet); + this.unmodInitialPolicies = Collections.emptySet(); + this.certPathCheckers = new ArrayList(); + this.certStores = new ArrayList(); + } + + /** + * Returns an immutable {@code Set} of the most-trusted + * CAs. + * + * @return an immutable {@code Set} of {@code TrustAnchor}s + * (never {@code null}) + * + * @see #setTrustAnchors + */ + public Set getTrustAnchors() { + return this.unmodTrustAnchors; + } + + /** + * Sets the {@code Set} of most-trusted CAs. + *

+ * Note that the {@code Set} is copied to protect against + * subsequent modifications. + * + * @param trustAnchors a {@code Set} of {@code TrustAnchor}s + * @throws InvalidAlgorithmParameterException if the specified + * {@code Set} is empty {@code (trustAnchors.isEmpty() == true)} + * @throws NullPointerException if the specified {@code Set} is + * {@code null} + * @throws ClassCastException if any of the elements in the set + * are not of type {@code java.security.cert.TrustAnchor} + * + * @see #getTrustAnchors + */ + public void setTrustAnchors(Set trustAnchors) + throws InvalidAlgorithmParameterException + { + if (trustAnchors == null) { + throw new NullPointerException("the trustAnchors parameters must" + + " be non-null"); + } + if (trustAnchors.isEmpty()) { + throw new InvalidAlgorithmParameterException("the trustAnchors " + + "parameter must be non-empty"); + } + for (Iterator i = trustAnchors.iterator(); i.hasNext(); ) { + if (!(i.next() instanceof TrustAnchor)) { + throw new ClassCastException("all elements of set must be " + + "of type java.security.cert.TrustAnchor"); + } + } + this.unmodTrustAnchors = Collections.unmodifiableSet + (new HashSet(trustAnchors)); + } + + /** + * Returns an immutable {@code Set} of initial + * policy identifiers (OID strings), indicating that any one of these + * policies would be acceptable to the certificate user for the purposes of + * certification path processing. The default return value is an empty + * {@code Set}, which is interpreted as meaning that any policy would + * be acceptable. + * + * @return an immutable {@code Set} of initial policy OIDs in + * {@code String} format, or an empty {@code Set} (implying any + * policy is acceptable). Never returns {@code null}. + * + * @see #setInitialPolicies + */ + public Set getInitialPolicies() { + return this.unmodInitialPolicies; + } + + /** + * Sets the {@code Set} of initial policy identifiers + * (OID strings), indicating that any one of these + * policies would be acceptable to the certificate user for the purposes of + * certification path processing. By default, any policy is acceptable + * (i.e. all policies), so a user that wants to allow any policy as + * acceptable does not need to call this method, or can call it + * with an empty {@code Set} (or {@code null}). + *

+ * Note that the {@code Set} is copied to protect against + * subsequent modifications. + * + * @param initialPolicies a {@code Set} of initial policy + * OIDs in {@code String} format (or {@code null}) + * @throws ClassCastException if any of the elements in the set are + * not of type {@code String} + * + * @see #getInitialPolicies + */ + public void setInitialPolicies(Set initialPolicies) { + if (initialPolicies != null) { + for (Iterator i = initialPolicies.iterator(); + i.hasNext();) { + if (!(i.next() instanceof String)) + throw new ClassCastException("all elements of set must be " + + "of type java.lang.String"); + } + this.unmodInitialPolicies = + Collections.unmodifiableSet(new HashSet(initialPolicies)); + } else + this.unmodInitialPolicies = Collections.emptySet(); + } + + /** + * Sets the list of {@code CertStore}s to be used in finding + * certificates and CRLs. May be {@code null}, in which case + * no {@code CertStore}s will be used. The first + * {@code CertStore}s in the list may be preferred to those that + * appear later. + *

+ * Note that the {@code List} is copied to protect against + * subsequent modifications. + * + * @param stores a {@code List} of {@code CertStore}s (or + * {@code null}) + * @throws ClassCastException if any of the elements in the list are + * not of type {@code java.security.cert.CertStore} + * + * @see #getCertStores + */ + public void setCertStores(List stores) { + if (stores == null) { + this.certStores = new ArrayList(); + } else { + for (Iterator i = stores.iterator(); i.hasNext();) { + if (!(i.next() instanceof CertStore)) { + throw new ClassCastException("all elements of list must be " + + "of type java.security.cert.CertStore"); + } + } + this.certStores = new ArrayList(stores); + } + } + + /** + * Adds a {@code CertStore} to the end of the list of + * {@code CertStore}s used in finding certificates and CRLs. + * + * @param store the {@code CertStore} to add. If {@code null}, + * the store is ignored (not added to list). + */ + public void addCertStore(CertStore store) { + if (store != null) { + this.certStores.add(store); + } + } + + /** + * Returns an immutable {@code List} of {@code CertStore}s that + * are used to find certificates and CRLs. + * + * @return an immutable {@code List} of {@code CertStore}s + * (may be empty, but never {@code null}) + * + * @see #setCertStores + */ + public List getCertStores() { + return Collections.unmodifiableList + (new ArrayList(this.certStores)); + } + + /** + * Sets the RevocationEnabled flag. If this flag is true, the default + * revocation checking mechanism of the underlying PKIX service provider + * will be used. If this flag is false, the default revocation checking + * mechanism will be disabled (not used). + *

+ * When a {@code PKIXParameters} object is created, this flag is set + * to true. This setting reflects the most common strategy for checking + * revocation, since each service provider must support revocation + * checking to be PKIX compliant. Sophisticated applications should set + * this flag to false when it is not practical to use a PKIX service + * provider's default revocation checking mechanism or when an alternative + * revocation checking mechanism is to be substituted (by also calling the + * {@link #addCertPathChecker addCertPathChecker} or {@link + * #setCertPathCheckers setCertPathCheckers} methods). + * + * @param val the new value of the RevocationEnabled flag + */ + public void setRevocationEnabled(boolean val) { + revocationEnabled = val; + } + + /** + * Checks the RevocationEnabled flag. If this flag is true, the default + * revocation checking mechanism of the underlying PKIX service provider + * will be used. If this flag is false, the default revocation checking + * mechanism will be disabled (not used). See the {@link + * #setRevocationEnabled setRevocationEnabled} method for more details on + * setting the value of this flag. + * + * @return the current value of the RevocationEnabled flag + */ + public boolean isRevocationEnabled() { + return revocationEnabled; + } + + /** + * Sets the ExplicitPolicyRequired flag. If this flag is true, an + * acceptable policy needs to be explicitly identified in every certificate. + * By default, the ExplicitPolicyRequired flag is false. + * + * @param val {@code true} if explicit policy is to be required, + * {@code false} otherwise + */ + public void setExplicitPolicyRequired(boolean val) { + explicitPolicyRequired = val; + } + + /** + * Checks if explicit policy is required. If this flag is true, an + * acceptable policy needs to be explicitly identified in every certificate. + * By default, the ExplicitPolicyRequired flag is false. + * + * @return {@code true} if explicit policy is required, + * {@code false} otherwise + */ + public boolean isExplicitPolicyRequired() { + return explicitPolicyRequired; + } + + /** + * Sets the PolicyMappingInhibited flag. If this flag is true, policy + * mapping is inhibited. By default, policy mapping is not inhibited (the + * flag is false). + * + * @param val {@code true} if policy mapping is to be inhibited, + * {@code false} otherwise + */ + public void setPolicyMappingInhibited(boolean val) { + policyMappingInhibited = val; + } + + /** + * Checks if policy mapping is inhibited. If this flag is true, policy + * mapping is inhibited. By default, policy mapping is not inhibited (the + * flag is false). + * + * @return true if policy mapping is inhibited, false otherwise + */ + public boolean isPolicyMappingInhibited() { + return policyMappingInhibited; + } + + /** + * Sets state to determine if the any policy OID should be processed + * if it is included in a certificate. By default, the any policy OID + * is not inhibited ({@link #isAnyPolicyInhibited isAnyPolicyInhibited()} + * returns {@code false}). + * + * @param val {@code true} if the any policy OID is to be + * inhibited, {@code false} otherwise + */ + public void setAnyPolicyInhibited(boolean val) { + anyPolicyInhibited = val; + } + + /** + * Checks whether the any policy OID should be processed if it + * is included in a certificate. + * + * @return {@code true} if the any policy OID is inhibited, + * {@code false} otherwise + */ + public boolean isAnyPolicyInhibited() { + return anyPolicyInhibited; + } + + /** + * Sets the PolicyQualifiersRejected flag. If this flag is true, + * certificates that include policy qualifiers in a certificate + * policies extension that is marked critical are rejected. + * If the flag is false, certificates are not rejected on this basis. + * + *

When a {@code PKIXParameters} object is created, this flag is + * set to true. This setting reflects the most common (and simplest) + * strategy for processing policy qualifiers. Applications that want to use + * a more sophisticated policy must set this flag to false. + *

+ * Note that the PKIX certification path validation algorithm specifies + * that any policy qualifier in a certificate policies extension that is + * marked critical must be processed and validated. Otherwise the + * certification path must be rejected. If the policyQualifiersRejected flag + * is set to false, it is up to the application to validate all policy + * qualifiers in this manner in order to be PKIX compliant. + * + * @param qualifiersRejected the new value of the PolicyQualifiersRejected + * flag + * @see #getPolicyQualifiersRejected + * @see PolicyQualifierInfo + */ + public void setPolicyQualifiersRejected(boolean qualifiersRejected) { + policyQualifiersRejected = qualifiersRejected; + } + + /** + * Gets the PolicyQualifiersRejected flag. If this flag is true, + * certificates that include policy qualifiers in a certificate policies + * extension that is marked critical are rejected. + * If the flag is false, certificates are not rejected on this basis. + * + *

When a {@code PKIXParameters} object is created, this flag is + * set to true. This setting reflects the most common (and simplest) + * strategy for processing policy qualifiers. Applications that want to use + * a more sophisticated policy must set this flag to false. + * + * @return the current value of the PolicyQualifiersRejected flag + * @see #setPolicyQualifiersRejected + */ + public boolean getPolicyQualifiersRejected() { + return policyQualifiersRejected; + } + + /** + * Returns the time for which the validity of the certification path + * should be determined. If {@code null}, the current time is used. + *

+ * Note that the {@code Date} returned is copied to protect against + * subsequent modifications. + * + * @return the {@code Date}, or {@code null} if not set + * @see #setDate + */ + public Date getDate() { + if (date == null) + return null; + else + return (Date) this.date.clone(); + } + + /** + * Sets the time for which the validity of the certification path + * should be determined. If {@code null}, the current time is used. + *

+ * Note that the {@code Date} supplied here is copied to protect + * against subsequent modifications. + * + * @param date the {@code Date}, or {@code null} for the + * current time + * @see #getDate + */ + public void setDate(Date date) { + if (date != null) + this.date = (Date) date.clone(); + else + date = null; + } + + /** + * Sets a {@code List} of additional certification path checkers. If + * the specified {@code List} contains an object that is not a + * {@code PKIXCertPathChecker}, it is ignored. + *

+ * Each {@code PKIXCertPathChecker} specified implements + * additional checks on a certificate. Typically, these are checks to + * process and verify private extensions contained in certificates. + * Each {@code PKIXCertPathChecker} should be instantiated with any + * initialization parameters needed to execute the check. + *

+ * This method allows sophisticated applications to extend a PKIX + * {@code CertPathValidator} or {@code CertPathBuilder}. + * Each of the specified {@code PKIXCertPathChecker}s will be called, + * in turn, by a PKIX {@code CertPathValidator} or + * {@code CertPathBuilder} for each certificate processed or + * validated. + *

+ * Regardless of whether these additional {@code PKIXCertPathChecker}s + * are set, a PKIX {@code CertPathValidator} or + * {@code CertPathBuilder} must perform all of the required PKIX + * checks on each certificate. The one exception to this rule is if the + * RevocationEnabled flag is set to false (see the {@link + * #setRevocationEnabled setRevocationEnabled} method). + *

+ * Note that the {@code List} supplied here is copied and each + * {@code PKIXCertPathChecker} in the list is cloned to protect + * against subsequent modifications. + * + * @param checkers a {@code List} of {@code PKIXCertPathChecker}s. + * May be {@code null}, in which case no additional checkers will be + * used. + * @throws ClassCastException if any of the elements in the list + * are not of type {@code java.security.cert.PKIXCertPathChecker} + * @see #getCertPathCheckers + */ + public void setCertPathCheckers(List checkers) { + if (checkers != null) { + List tmpList = + new ArrayList(); + for (PKIXCertPathChecker checker : checkers) { + tmpList.add((PKIXCertPathChecker)checker.clone()); + } + this.certPathCheckers = tmpList; + } else { + this.certPathCheckers = new ArrayList(); + } + } + + /** + * Returns the {@code List} of certification path checkers. + * The returned {@code List} is immutable, and each + * {@code PKIXCertPathChecker} in the {@code List} is cloned + * to protect against subsequent modifications. + * + * @return an immutable {@code List} of + * {@code PKIXCertPathChecker}s (may be empty, but not + * {@code null}) + * @see #setCertPathCheckers + */ + public List getCertPathCheckers() { + List tmpList = new ArrayList(); + for (PKIXCertPathChecker ck : certPathCheckers) { + tmpList.add((PKIXCertPathChecker)ck.clone()); + } + return Collections.unmodifiableList(tmpList); + } + + /** + * Adds a {@code PKIXCertPathChecker} to the list of certification + * path checkers. See the {@link #setCertPathCheckers setCertPathCheckers} + * method for more details. + *

+ * Note that the {@code PKIXCertPathChecker} is cloned to protect + * against subsequent modifications. + * + * @param checker a {@code PKIXCertPathChecker} to add to the list of + * checks. If {@code null}, the checker is ignored (not added to list). + */ + public void addCertPathChecker(PKIXCertPathChecker checker) { + if (checker != null) { + certPathCheckers.add((PKIXCertPathChecker)checker.clone()); + } + } + + /** + * Returns the signature provider's name, or {@code null} + * if not set. + * + * @return the signature provider's name (or {@code null}) + * @see #setSigProvider + */ + public String getSigProvider() { + return this.sigProvider; + } + + /** + * Sets the signature provider's name. The specified provider will be + * preferred when creating {@link java.security.Signature Signature} + * objects. If {@code null} or not set, the first provider found + * supporting the algorithm will be used. + * + * @param sigProvider the signature provider's name (or {@code null}) + * @see #getSigProvider + */ + public void setSigProvider(String sigProvider) { + this.sigProvider = sigProvider; + } + + /** + * Returns the required constraints on the target certificate. + * The constraints are returned as an instance of {@code CertSelector}. + * If {@code null}, no constraints are defined. + * + *

Note that the {@code CertSelector} returned is cloned + * to protect against subsequent modifications. + * + * @return a {@code CertSelector} specifying the constraints + * on the target certificate (or {@code null}) + * @see #setTargetCertConstraints + */ + public CertSelector getTargetCertConstraints() { + if (certSelector != null) { + return (CertSelector) certSelector.clone(); + } else { + return null; + } + } + + /** + * Sets the required constraints on the target certificate. + * The constraints are specified as an instance of + * {@code CertSelector}. If {@code null}, no constraints are + * defined. + * + *

Note that the {@code CertSelector} specified is cloned + * to protect against subsequent modifications. + * + * @param selector a {@code CertSelector} specifying the constraints + * on the target certificate (or {@code null}) + * @see #getTargetCertConstraints + */ + public void setTargetCertConstraints(CertSelector selector) { + if (selector != null) + certSelector = (CertSelector) selector.clone(); + else + certSelector = null; + } + + /** + * Makes a copy of this {@code PKIXParameters} object. Changes + * to the copy will not affect the original and vice versa. + * + * @return a copy of this {@code PKIXParameters} object + */ + public Object clone() { + try { + PKIXParameters copy = (PKIXParameters)super.clone(); + + // must clone these because addCertStore, et al. modify them + if (certStores != null) { + copy.certStores = new ArrayList(certStores); + } + if (certPathCheckers != null) { + copy.certPathCheckers = + new ArrayList(certPathCheckers.size()); + for (PKIXCertPathChecker checker : certPathCheckers) { + copy.certPathCheckers.add( + (PKIXCertPathChecker)checker.clone()); + } + } + + // other class fields are immutable to public, don't bother + // to clone the read-only fields. + return copy; + } catch (CloneNotSupportedException e) { + /* Cannot happen */ + throw new InternalError(e.toString(), e); + } + } + + /** + * Returns a formatted string describing the parameters. + * + * @return a formatted string describing the parameters. + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("[\n"); + + /* start with trusted anchor info */ + if (unmodTrustAnchors != null) { + sb.append(" Trust Anchors: " + unmodTrustAnchors.toString() + + "\n"); + } + + /* now, append initial state information */ + if (unmodInitialPolicies != null) { + if (unmodInitialPolicies.isEmpty()) { + sb.append(" Initial Policy OIDs: any\n"); + } else { + sb.append(" Initial Policy OIDs: [" + + unmodInitialPolicies.toString() + "]\n"); + } + } + + /* now, append constraints on all certificates in the path */ + sb.append(" Validity Date: " + String.valueOf(date) + "\n"); + sb.append(" Signature Provider: " + String.valueOf(sigProvider) + "\n"); + sb.append(" Default Revocation Enabled: " + revocationEnabled + "\n"); + sb.append(" Explicit Policy Required: " + explicitPolicyRequired + "\n"); + sb.append(" Policy Mapping Inhibited: " + policyMappingInhibited + "\n"); + sb.append(" Any Policy Inhibited: " + anyPolicyInhibited + "\n"); + sb.append(" Policy Qualifiers Rejected: " + policyQualifiersRejected + "\n"); + + /* now, append target cert requirements */ + sb.append(" Target Cert Constraints: " + String.valueOf(certSelector) + "\n"); + + /* finally, append miscellaneous parameters */ + if (certPathCheckers != null) + sb.append(" Certification Path Checkers: [" + + certPathCheckers.toString() + "]\n"); + if (certStores != null) + sb.append(" CertStores: [" + certStores.toString() + "]\n"); + sb.append("]"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXReason.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXReason.java new file mode 100644 index 000000000..d58ded975 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXReason.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008, 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 java.security.cert; + +/** + * The {@code PKIXReason} enumerates the potential PKIX-specific reasons + * that an X.509 certification path may be invalid according to the PKIX + * (RFC 3280) standard. These reasons are in addition to those of the + * {@code CertPathValidatorException.BasicReason} enumeration. + * + * @since 1.7 + */ +public enum PKIXReason implements CertPathValidatorException.Reason { + /** + * The certificate does not chain correctly. + */ + NAME_CHAINING, + + /** + * The certificate's key usage is invalid. + */ + INVALID_KEY_USAGE, + + /** + * The policy constraints have been violated. + */ + INVALID_POLICY, + + /** + * No acceptable trust anchor found. + */ + NO_TRUST_ANCHOR, + + /** + * The certificate contains one or more unrecognized critical + * extensions. + */ + UNRECOGNIZED_CRIT_EXT, + + /** + * The certificate is not a CA certificate. + */ + NOT_CA_CERT, + + /** + * The path length constraint has been violated. + */ + PATH_TOO_LONG, + + /** + * The name constraints have been violated. + */ + INVALID_NAME +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXRevocationChecker.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXRevocationChecker.java new file mode 100644 index 000000000..a345c96ca --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PKIXRevocationChecker.java @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2012, 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 java.security.cert; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; + +/** + * A {@code PKIXCertPathChecker} for checking the revocation status of + * certificates with the PKIX algorithm. + * + *

A {@code PKIXRevocationChecker} checks the revocation status of + * certificates with the Online Certificate Status Protocol (OCSP) or + * Certificate Revocation Lists (CRLs). OCSP is described in RFC 2560 and + * is a network protocol for determining the status of a certificate. A CRL + * is a time-stamped list identifying revoked certificates, and RFC 5280 + * describes an algorithm for determining the revocation status of certificates + * using CRLs. + * + *

Each {@code PKIXRevocationChecker} must be able to check the revocation + * status of certificates with OCSP and CRLs. By default, OCSP is the + * preferred mechanism for checking revocation status, with CRLs as the + * fallback mechanism. However, this preference can be switched to CRLs with + * the {@link Option#PREFER_CRLS PREFER_CRLS} option. In addition, the fallback + * mechanism can be disabled with the {@link Option#NO_FALLBACK NO_FALLBACK} + * option. + * + *

A {@code PKIXRevocationChecker} is obtained by calling the + * {@link CertPathValidator#getRevocationChecker getRevocationChecker} method + * of a PKIX {@code CertPathValidator}. Additional parameters and options + * specific to revocation can be set (by calling the + * {@link #setOcspResponder setOcspResponder} method for instance). The + * {@code PKIXRevocationChecker} is added to a {@code PKIXParameters} object + * using the {@link PKIXParameters#addCertPathChecker addCertPathChecker} + * or {@link PKIXParameters#setCertPathCheckers setCertPathCheckers} method, + * and then the {@code PKIXParameters} is passed along with the {@code CertPath} + * to be validated to the {@link CertPathValidator#validate validate} method + * of a PKIX {@code CertPathValidator}. When supplying a revocation checker in + * this manner, it will be used to check revocation irrespective of the setting + * of the {@link PKIXParameters#isRevocationEnabled RevocationEnabled} flag. + * Similarly, a {@code PKIXRevocationChecker} may be added to a + * {@code PKIXBuilderParameters} object for use with a PKIX + * {@code CertPathBuilder}. + * + *

Note that when a {@code PKIXRevocationChecker} is added to + * {@code PKIXParameters}, it clones the {@code PKIXRevocationChecker}; + * thus any subsequent modifications to the {@code PKIXRevocationChecker} + * have no effect. + * + *

Any parameter that is not set (or is set to {@code null}) will be set to + * the default value for that parameter. + * + *

Concurrent Access + * + *

Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single object + * concurrently should synchronize amongst themselves and provide the + * necessary locking. Multiple threads each manipulating separate objects + * need not synchronize. + * + * @since 1.8 + * + * @see RFC 2560: X.509 + * Internet Public Key Infrastructure Online Certificate Status Protocol - + * OCSP,
RFC 5280: Internet X.509 + * Public Key Infrastructure Certificate and Certificate Revocation List (CRL) + * Profile + */ +public abstract class PKIXRevocationChecker extends PKIXCertPathChecker { + private URI ocspResponder; + private X509Certificate ocspResponderCert; + private List ocspExtensions = Collections.emptyList(); + private Map ocspResponses = Collections.emptyMap(); + private Set

+ * An implementation of {@code PKIXRevocationChecker} is responsible for + * adding the ignored exceptions to the list. + * + * @return an unmodifiable list containing the ignored exceptions. The list + * is empty if no exceptions have been ignored. + */ + public abstract List getSoftFailExceptions(); + + @Override + public PKIXRevocationChecker clone() { + PKIXRevocationChecker copy = (PKIXRevocationChecker)super.clone(); + copy.ocspExtensions = new ArrayList<>(ocspExtensions); + copy.ocspResponses = new HashMap<>(ocspResponses); + // deep-copy the encoded responses, since they are mutable + for (Map.Entry entry : + copy.ocspResponses.entrySet()) + { + byte[] encoded = entry.getValue(); + entry.setValue(encoded.clone()); + } + copy.options = new HashSet<>(options); + return copy; + } + + /** + * Various revocation options that can be specified for the revocation + * checking mechanism. + */ + public enum Option { + /** + * Only check the revocation status of end-entity certificates. + */ + ONLY_END_ENTITY, + /** + * Prefer CRLs to OSCP. The default behavior is to prefer OCSP. Each + * PKIX implementation should document further details of their + * specific preference rules and fallback policies. + */ + PREFER_CRLS, + /** + * Disable the fallback mechanism. + */ + NO_FALLBACK, + /** + * Allow revocation check to succeed if the revocation status cannot be + * determined for one of the following reasons: + *

    + *
  • The CRL or OCSP response cannot be obtained because of a + * network error. + *
  • The OCSP responder returns one of the following errors + * specified in section 2.3 of RFC 2560: internalError or tryLater. + *

+ * Note that these conditions apply to both OCSP and CRLs, and unless + * the {@code NO_FALLBACK} option is set, the revocation check is + * allowed to succeed only if both mechanisms fail under one of the + * conditions as stated above. + * Exceptions that cause the network errors are ignored but can be + * later retrieved by calling the + * {@link #getSoftFailExceptions getSoftFailExceptions} method. + */ + SOFT_FAIL + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PolicyNode.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PolicyNode.java new file mode 100644 index 000000000..1633dcb83 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PolicyNode.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.util.Iterator; +import java.util.Set; + +/** + * An immutable valid policy tree node as defined by the PKIX certification + * path validation algorithm. + * + *

One of the outputs of the PKIX certification path validation + * algorithm is a valid policy tree, which includes the policies that + * were determined to be valid, how this determination was reached, + * and any policy qualifiers encountered. This tree is of depth + * n, where n is the length of the certification + * path that has been validated. + * + *

Most applications will not need to examine the valid policy tree. + * They can achieve their policy processing goals by setting the + * policy-related parameters in {@code PKIXParameters}. However, + * the valid policy tree is available for more sophisticated applications, + * especially those that process policy qualifiers. + * + *

{@link PKIXCertPathValidatorResult#getPolicyTree() + * PKIXCertPathValidatorResult.getPolicyTree} returns the root node of the + * valid policy tree. The tree can be traversed using the + * {@link #getChildren getChildren} and {@link #getParent getParent} methods. + * Data about a particular node can be retrieved using other methods of + * {@code PolicyNode}. + * + *

Concurrent Access + *

All {@code PolicyNode} objects must be immutable and + * thread-safe. Multiple threads may concurrently invoke the methods defined + * in this class on a single {@code PolicyNode} object (or more than one) + * with no ill effects. This stipulation applies to all public fields and + * methods of this class and any added or overridden by subclasses. + * + * @since 1.4 + * @author Sean Mullan + */ +public interface PolicyNode { + + /** + * Returns the parent of this node, or {@code null} if this is the + * root node. + * + * @return the parent of this node, or {@code null} if this is the + * root node + */ + PolicyNode getParent(); + + /** + * Returns an iterator over the children of this node. Any attempts to + * modify the children of this node through the + * {@code Iterator}'s remove method must throw an + * {@code UnsupportedOperationException}. + * + * @return an iterator over the children of this node + */ + Iterator getChildren(); + + /** + * Returns the depth of this node in the valid policy tree. + * + * @return the depth of this node (0 for the root node, 1 for its + * children, and so on) + */ + int getDepth(); + + /** + * Returns the valid policy represented by this node. + * + * @return the {@code String} OID of the valid policy + * represented by this node. For the root node, this method always returns + * the special anyPolicy OID: "2.5.29.32.0". + */ + String getValidPolicy(); + + /** + * Returns the set of policy qualifiers associated with the + * valid policy represented by this node. + * + * @return an immutable {@code Set} of + * {@code PolicyQualifierInfo}s. For the root node, this + * is always an empty {@code Set}. + */ + Set getPolicyQualifiers(); + + /** + * Returns the set of expected policies that would satisfy this + * node's valid policy in the next certificate to be processed. + * + * @return an immutable {@code Set} of expected policy + * {@code String} OIDs. For the root node, this method + * always returns a {@code Set} with one element, the + * special anyPolicy OID: "2.5.29.32.0". + */ + Set getExpectedPolicies(); + + /** + * Returns the criticality indicator of the certificate policy extension + * in the most recently processed certificate. + * + * @return {@code true} if extension marked critical, + * {@code false} otherwise. For the root node, {@code false} + * is always returned. + */ + boolean isCritical(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/PolicyQualifierInfo.java b/sources/net.sf.j2s.java.core/src/java/security/cert/PolicyQualifierInfo.java new file mode 100644 index 000000000..ec06a88ae --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/PolicyQualifierInfo.java @@ -0,0 +1,173 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.io.IOException; + +import sun.misc.HexDumpEncoder; +import sun.security.util.DerValue; + +/** + * An immutable policy qualifier represented by the ASN.1 PolicyQualifierInfo + * structure. + * + *

The ASN.1 definition is as follows: + *

+ *   PolicyQualifierInfo ::= SEQUENCE {
+ *        policyQualifierId       PolicyQualifierId,
+ *        qualifier               ANY DEFINED BY policyQualifierId }
+ * 
+ *

+ * A certificate policies extension, if present in an X.509 version 3 + * certificate, contains a sequence of one or more policy information terms, + * each of which consists of an object identifier (OID) and optional + * qualifiers. In an end-entity certificate, these policy information terms + * indicate the policy under which the certificate has been issued and the + * purposes for which the certificate may be used. In a CA certificate, these + * policy information terms limit the set of policies for certification paths + * which include this certificate. + *

+ * A {@code Set} of {@code PolicyQualifierInfo} objects are returned + * by the {@link PolicyNode#getPolicyQualifiers PolicyNode.getPolicyQualifiers} + * method. This allows applications with specific policy requirements to + * process and validate each policy qualifier. Applications that need to + * process policy qualifiers should explicitly set the + * {@code policyQualifiersRejected} flag to false (by calling the + * {@link PKIXParameters#setPolicyQualifiersRejected + * PKIXParameters.setPolicyQualifiersRejected} method) before validating + * a certification path. + * + *

Note that the PKIX certification path validation algorithm specifies + * that any policy qualifier in a certificate policies extension that is + * marked critical must be processed and validated. Otherwise the + * certification path must be rejected. If the + * {@code policyQualifiersRejected} flag is set to false, it is up to + * the application to validate all policy qualifiers in this manner in order + * to be PKIX compliant. + * + *

Concurrent Access + * + *

All {@code PolicyQualifierInfo} objects must be immutable and + * thread-safe. That is, multiple threads may concurrently invoke the + * methods defined in this class on a single {@code PolicyQualifierInfo} + * object (or more than one) with no ill effects. Requiring + * {@code PolicyQualifierInfo} objects to be immutable and thread-safe + * allows them to be passed around to various pieces of code without + * worrying about coordinating access. + * + * @author seth proctor + * @author Sean Mullan + * @since 1.4 + */ +public class PolicyQualifierInfo { + + private byte [] mEncoded; + private String mId; + private byte [] mData; + private String pqiString; + + /** + * Creates an instance of {@code PolicyQualifierInfo} from the + * encoded bytes. The encoded byte array is copied on construction. + * + * @param encoded a byte array containing the qualifier in DER encoding + * @exception IOException thrown if the byte array does not represent a + * valid and parsable policy qualifier + */ + public PolicyQualifierInfo(byte[] encoded) throws IOException { + mEncoded = encoded.clone(); + + DerValue val = new DerValue(mEncoded); + if (val.tag != DerValue.tag_Sequence) + throw new IOException("Invalid encoding for PolicyQualifierInfo"); + + mId = (val.data.getDerValue()).getOID().toString(); + byte [] tmp = val.data.toByteArray(); + if (tmp == null) { + mData = null; + } else { + mData = new byte[tmp.length]; + System.arraycopy(tmp, 0, mData, 0, tmp.length); + } + } + + /** + * Returns the {@code policyQualifierId} field of this + * {@code PolicyQualifierInfo}. The {@code policyQualifierId} + * is an Object Identifier (OID) represented by a set of nonnegative + * integers separated by periods. + * + * @return the OID (never {@code null}) + */ + public final String getPolicyQualifierId() { + return mId; + } + + /** + * Returns the ASN.1 DER encoded form of this + * {@code PolicyQualifierInfo}. + * + * @return the ASN.1 DER encoded bytes (never {@code null}). + * Note that a copy is returned, so the data is cloned each time + * this method is called. + */ + public final byte[] getEncoded() { + return mEncoded.clone(); + } + + /** + * Returns the ASN.1 DER encoded form of the {@code qualifier} + * field of this {@code PolicyQualifierInfo}. + * + * @return the ASN.1 DER encoded bytes of the {@code qualifier} + * field. Note that a copy is returned, so the data is cloned each + * time this method is called. + */ + public final byte[] getPolicyQualifier() { + return (mData == null ? null : mData.clone()); + } + + /** + * Return a printable representation of this + * {@code PolicyQualifierInfo}. + * + * @return a {@code String} describing the contents of this + * {@code PolicyQualifierInfo} + */ + public String toString() { + if (pqiString != null) + return pqiString; + HexDumpEncoder enc = new HexDumpEncoder(); + StringBuffer sb = new StringBuffer(); + sb.append("PolicyQualifierInfo: [\n"); + sb.append(" qualifierID: " + mId + "\n"); + sb.append(" qualifier: " + + (mData == null ? "null" : enc.encodeBuffer(mData)) + "\n"); + sb.append("]"); + pqiString = sb.toString(); + return pqiString; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/TrustAnchor.java b/sources/net.sf.j2s.java.core/src/java/security/cert/TrustAnchor.java new file mode 100644 index 000000000..c98bf814c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/TrustAnchor.java @@ -0,0 +1,333 @@ +/* + * Copyright (c) 2001, 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 java.security.cert; + +import java.io.IOException; +import java.security.PublicKey; + +import javax.security.auth.x500.X500Principal; + +import sun.security.x509.NameConstraintsExtension; +import sun.security.x509.X500Name; + +/** + * A trust anchor or most-trusted Certification Authority (CA). + *

+ * This class represents a "most-trusted CA", which is used as a trust anchor + * for validating X.509 certification paths. A most-trusted CA includes the + * public key of the CA, the CA's name, and any constraints upon the set of + * paths which may be validated using this key. These parameters can be + * specified in the form of a trusted {@code X509Certificate} or as + * individual parameters. + *

+ * Concurrent Access + *

All {@code TrustAnchor} objects must be immutable and + * thread-safe. That is, multiple threads may concurrently invoke the + * methods defined in this class on a single {@code TrustAnchor} + * object (or more than one) with no ill effects. Requiring + * {@code TrustAnchor} objects to be immutable and thread-safe + * allows them to be passed around to various pieces of code without + * worrying about coordinating access. This stipulation applies to all + * public fields and methods of this class and any added or overridden + * by subclasses. + * + * @see PKIXParameters#PKIXParameters(Set) + * @see PKIXBuilderParameters#PKIXBuilderParameters(Set, CertSelector) + * + * @since 1.4 + * @author Sean Mullan + */ +public class TrustAnchor { + + private final PublicKey pubKey; + private final String caName; + private final X500Principal caPrincipal; + private final X509Certificate trustedCert; + private byte[] ncBytes; + private NameConstraintsExtension nc; + + /** + * Creates an instance of {@code TrustAnchor} with the specified + * {@code X509Certificate} and optional name constraints, which + * are intended to be used as additional constraints when validating + * an X.509 certification path. + *

+ * The name constraints are specified as a byte array. This byte array + * should contain the DER encoded form of the name constraints, as they + * would appear in the NameConstraints structure defined in + * RFC 3280 + * and X.509. The ASN.1 definition of this structure appears below. + * + *

{@code
+     *  NameConstraints ::= SEQUENCE {
+     *       permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+     *       excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+     *
+     *  GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+     *
+     *  GeneralSubtree ::= SEQUENCE {
+     *       base                    GeneralName,
+     *       minimum         [0]     BaseDistance DEFAULT 0,
+     *       maximum         [1]     BaseDistance OPTIONAL }
+     *
+     *  BaseDistance ::= INTEGER (0..MAX)
+     *
+     *  GeneralName ::= CHOICE {
+     *       otherName                       [0]     OtherName,
+     *       rfc822Name                      [1]     IA5String,
+     *       dNSName                         [2]     IA5String,
+     *       x400Address                     [3]     ORAddress,
+     *       directoryName                   [4]     Name,
+     *       ediPartyName                    [5]     EDIPartyName,
+     *       uniformResourceIdentifier       [6]     IA5String,
+     *       iPAddress                       [7]     OCTET STRING,
+     *       registeredID                    [8]     OBJECT IDENTIFIER}
+     * }
+ *

+ * Note that the name constraints byte array supplied is cloned to protect + * against subsequent modifications. + * + * @param trustedCert a trusted {@code X509Certificate} + * @param nameConstraints a byte array containing the ASN.1 DER encoding of + * a NameConstraints extension to be used for checking name constraints. + * Only the value of the extension is included, not the OID or criticality + * flag. Specify {@code null} to omit the parameter. + * @throws IllegalArgumentException if the name constraints cannot be + * decoded + * @throws NullPointerException if the specified + * {@code X509Certificate} is {@code null} + */ + public TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) + { + if (trustedCert == null) + throw new NullPointerException("the trustedCert parameter must " + + "be non-null"); + this.trustedCert = trustedCert; + this.pubKey = null; + this.caName = null; + this.caPrincipal = null; + setNameConstraints(nameConstraints); + } + + /** + * Creates an instance of {@code TrustAnchor} where the + * most-trusted CA is specified as an X500Principal and public key. + * Name constraints are an optional parameter, and are intended to be used + * as additional constraints when validating an X.509 certification path. + *

+ * The name constraints are specified as a byte array. This byte array + * contains the DER encoded form of the name constraints, as they + * would appear in the NameConstraints structure defined in RFC 3280 + * and X.509. The ASN.1 notation for this structure is supplied in the + * documentation for + * {@link #TrustAnchor(X509Certificate, byte[]) + * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }. + *

+ * Note that the name constraints byte array supplied here is cloned to + * protect against subsequent modifications. + * + * @param caPrincipal the name of the most-trusted CA as X500Principal + * @param pubKey the public key of the most-trusted CA + * @param nameConstraints a byte array containing the ASN.1 DER encoding of + * a NameConstraints extension to be used for checking name constraints. + * Only the value of the extension is included, not the OID or criticality + * flag. Specify {@code null} to omit the parameter. + * @throws NullPointerException if the specified {@code caPrincipal} or + * {@code pubKey} parameter is {@code null} + * @since 1.5 + */ + public TrustAnchor(X500Principal caPrincipal, PublicKey pubKey, + byte[] nameConstraints) { + if ((caPrincipal == null) || (pubKey == null)) { + throw new NullPointerException(); + } + this.trustedCert = null; + this.caPrincipal = caPrincipal; + this.caName = caPrincipal.getName(); + this.pubKey = pubKey; + setNameConstraints(nameConstraints); + } + + /** + * Creates an instance of {@code TrustAnchor} where the + * most-trusted CA is specified as a distinguished name and public key. + * Name constraints are an optional parameter, and are intended to be used + * as additional constraints when validating an X.509 certification path. + *

+ * The name constraints are specified as a byte array. This byte array + * contains the DER encoded form of the name constraints, as they + * would appear in the NameConstraints structure defined in RFC 3280 + * and X.509. The ASN.1 notation for this structure is supplied in the + * documentation for + * {@link #TrustAnchor(X509Certificate, byte[]) + * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }. + *

+ * Note that the name constraints byte array supplied here is cloned to + * protect against subsequent modifications. + * + * @param caName the X.500 distinguished name of the most-trusted CA in + * RFC 2253 + * {@code String} format + * @param pubKey the public key of the most-trusted CA + * @param nameConstraints a byte array containing the ASN.1 DER encoding of + * a NameConstraints extension to be used for checking name constraints. + * Only the value of the extension is included, not the OID or criticality + * flag. Specify {@code null} to omit the parameter. + * @throws IllegalArgumentException if the specified + * {@code caName} parameter is empty {@code (caName.length() == 0)} + * or incorrectly formatted or the name constraints cannot be decoded + * @throws NullPointerException if the specified {@code caName} or + * {@code pubKey} parameter is {@code null} + */ + public TrustAnchor(String caName, PublicKey pubKey, byte[] nameConstraints) + { + if (pubKey == null) + throw new NullPointerException("the pubKey parameter must be " + + "non-null"); + if (caName == null) + throw new NullPointerException("the caName parameter must be " + + "non-null"); + if (caName.length() == 0) + throw new IllegalArgumentException("the caName " + + "parameter must be a non-empty String"); + // check if caName is formatted correctly + this.caPrincipal = new X500Principal(caName); + this.pubKey = pubKey; + this.caName = caName; + this.trustedCert = null; + setNameConstraints(nameConstraints); + } + + /** + * Returns the most-trusted CA certificate. + * + * @return a trusted {@code X509Certificate} or {@code null} + * if the trust anchor was not specified as a trusted certificate + */ + public final X509Certificate getTrustedCert() { + return this.trustedCert; + } + + /** + * Returns the name of the most-trusted CA as an X500Principal. + * + * @return the X.500 distinguished name of the most-trusted CA, or + * {@code null} if the trust anchor was not specified as a trusted + * public key and name or X500Principal pair + * @since 1.5 + */ + public final X500Principal getCA() { + return this.caPrincipal; + } + + /** + * Returns the name of the most-trusted CA in RFC 2253 {@code String} + * format. + * + * @return the X.500 distinguished name of the most-trusted CA, or + * {@code null} if the trust anchor was not specified as a trusted + * public key and name or X500Principal pair + */ + public final String getCAName() { + return this.caName; + } + + /** + * Returns the public key of the most-trusted CA. + * + * @return the public key of the most-trusted CA, or {@code null} + * if the trust anchor was not specified as a trusted public key and name + * or X500Principal pair + */ + public final PublicKey getCAPublicKey() { + return this.pubKey; + } + + /** + * Decode the name constraints and clone them if not null. + */ + private void setNameConstraints(byte[] bytes) { + if (bytes == null) { + ncBytes = null; + nc = null; + } else { + ncBytes = bytes.clone(); + // validate DER encoding + try { + nc = new NameConstraintsExtension(Boolean.FALSE, bytes); + } catch (IOException ioe) { + IllegalArgumentException iae = + new IllegalArgumentException(ioe.getMessage()); + iae.initCause(ioe); + throw iae; + } + } + } + + /** + * Returns the name constraints parameter. The specified name constraints + * are associated with this trust anchor and are intended to be used + * as additional constraints when validating an X.509 certification path. + *

+ * The name constraints are returned as a byte array. This byte array + * contains the DER encoded form of the name constraints, as they + * would appear in the NameConstraints structure defined in RFC 3280 + * and X.509. The ASN.1 notation for this structure is supplied in the + * documentation for + * {@link #TrustAnchor(X509Certificate, byte[]) + * TrustAnchor(X509Certificate trustedCert, byte[] nameConstraints) }. + *

+ * Note that the byte array returned is cloned to protect against + * subsequent modifications. + * + * @return a byte array containing the ASN.1 DER encoding of + * a NameConstraints extension used for checking name constraints, + * or {@code null} if not set. + */ + public final byte [] getNameConstraints() { + return ncBytes == null ? null : ncBytes.clone(); + } + + /** + * Returns a formatted string describing the {@code TrustAnchor}. + * + * @return a formatted string describing the {@code TrustAnchor} + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("[\n"); + if (pubKey != null) { + sb.append(" Trusted CA Public Key: " + pubKey.toString() + "\n"); + sb.append(" Trusted CA Issuer Name: " + + String.valueOf(caName) + "\n"); + } else { + sb.append(" Trusted CA cert: " + trustedCert.toString() + "\n"); + } + if (nc != null) + sb.append(" Name Constraints: " + nc.toString() + "\n"); + return sb.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRL.java b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRL.java new file mode 100644 index 000000000..5ce84847f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRL.java @@ -0,0 +1,468 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +import java.security.NoSuchAlgorithmException; +import java.security.NoSuchProviderException; +import java.security.InvalidKeyException; +import java.security.SignatureException; +import java.security.Principal; +import java.security.Provider; +import java.security.PublicKey; +import javax.security.auth.x500.X500Principal; + +import java.math.BigInteger; +import java.util.Date; +import java.util.Set; +import java.util.Arrays; + +import sun.security.x509.X509CRLImpl; + +/** + *

+ * Abstract class for an X.509 Certificate Revocation List (CRL). + * A CRL is a time-stamped list identifying revoked certificates. + * It is signed by a Certificate Authority (CA) and made freely + * available in a public repository. + * + *

Each revoked certificate is + * identified in a CRL by its certificate serial number. When a + * certificate-using system uses a certificate (e.g., for verifying a + * remote user's digital signature), that system not only checks the + * certificate signature and validity but also acquires a suitably- + * recent CRL and checks that the certificate serial number is not on + * that CRL. The meaning of "suitably-recent" may vary with local + * policy, but it usually means the most recently-issued CRL. A CA + * issues a new CRL on a regular periodic basis (e.g., hourly, daily, or + * weekly). Entries are added to CRLs as revocations occur, and an + * entry may be removed when the certificate expiration date is reached. + *

+ * The X.509 v2 CRL format is described below in ASN.1: + *

+ * CertificateList  ::=  SEQUENCE  {
+ *     tbsCertList          TBSCertList,
+ *     signatureAlgorithm   AlgorithmIdentifier,
+ *     signature            BIT STRING  }
+ * 
+ *

+ * More information can be found in + * RFC 3280: Internet X.509 + * Public Key Infrastructure Certificate and CRL Profile. + *

+ * The ASN.1 definition of {@code tbsCertList} is: + *

+ * TBSCertList  ::=  SEQUENCE  {
+ *     version                 Version OPTIONAL,
+ *                             -- if present, must be v2
+ *     signature               AlgorithmIdentifier,
+ *     issuer                  Name,
+ *     thisUpdate              ChoiceOfTime,
+ *     nextUpdate              ChoiceOfTime OPTIONAL,
+ *     revokedCertificates     SEQUENCE OF SEQUENCE  {
+ *         userCertificate         CertificateSerialNumber,
+ *         revocationDate          ChoiceOfTime,
+ *         crlEntryExtensions      Extensions OPTIONAL
+ *                                 -- if present, must be v2
+ *         }  OPTIONAL,
+ *     crlExtensions           [0]  EXPLICIT Extensions OPTIONAL
+ *                                  -- if present, must be v2
+ *     }
+ * 
+ *

+ * CRLs are instantiated using a certificate factory. The following is an + * example of how to instantiate an X.509 CRL: + *

{@code
+ * try (InputStream inStream = new FileInputStream("fileName-of-crl")) {
+ *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ *     X509CRL crl = (X509CRL)cf.generateCRL(inStream);
+ * }
+ * }
+ * + * @author Hemma Prafullchandra + * + * + * @see CRL + * @see CertificateFactory + * @see X509Extension + */ + +public abstract class X509CRL extends CRL implements X509Extension { + + private transient X500Principal issuerPrincipal; + + /** + * Constructor for X.509 CRLs. + */ + protected X509CRL() { + super("X.509"); + } + + /** + * Compares this CRL for equality with the given + * object. If the {@code other} object is an + * {@code instanceof} {@code X509CRL}, then + * its encoded form is retrieved and compared with the + * encoded form of this CRL. + * + * @param other the object to test for equality with this CRL. + * + * @return true iff the encoded forms of the two CRLs + * match, false otherwise. + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (!(other instanceof X509CRL)) { + return false; + } + try { + byte[] thisCRL = X509CRLImpl.getEncodedInternal(this); + byte[] otherCRL = X509CRLImpl.getEncodedInternal((X509CRL)other); + + return Arrays.equals(thisCRL, otherCRL); + } catch (CRLException e) { + return false; + } + } + + /** + * Returns a hashcode value for this CRL from its + * encoded form. + * + * @return the hashcode value. + */ + public int hashCode() { + int retval = 0; + try { + byte[] crlData = X509CRLImpl.getEncodedInternal(this); + for (int i = 1; i < crlData.length; i++) { + retval += crlData[i] * i; + } + return retval; + } catch (CRLException e) { + return retval; + } + } + + /** + * Returns the ASN.1 DER-encoded form of this CRL. + * + * @return the encoded form of this certificate + * @exception CRLException if an encoding error occurs. + */ + public abstract byte[] getEncoded() + throws CRLException; + + /** + * Verifies that this CRL was signed using the + * private key that corresponds to the given public key. + * + * @param key the PublicKey used to carry out the verification. + * + * @exception NoSuchAlgorithmException on unsupported signature + * algorithms. + * @exception InvalidKeyException on incorrect key. + * @exception NoSuchProviderException if there's no default provider. + * @exception SignatureException on signature errors. + * @exception CRLException on encoding errors. + */ + public abstract void verify(PublicKey key) + throws CRLException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, + SignatureException; + + /** + * Verifies that this CRL was signed using the + * private key that corresponds to the given public key. + * This method uses the signature verification engine + * supplied by the given provider. + * + * @param key the PublicKey used to carry out the verification. + * @param sigProvider the name of the signature provider. + * + * @exception NoSuchAlgorithmException on unsupported signature + * algorithms. + * @exception InvalidKeyException on incorrect key. + * @exception NoSuchProviderException on incorrect provider. + * @exception SignatureException on signature errors. + * @exception CRLException on encoding errors. + */ + public abstract void verify(PublicKey key, String sigProvider) + throws CRLException, NoSuchAlgorithmException, + InvalidKeyException, NoSuchProviderException, + SignatureException; + + /** + * Verifies that this CRL was signed using the + * private key that corresponds to the given public key. + * This method uses the signature verification engine + * supplied by the given provider. Note that the specified Provider object + * does not have to be registered in the provider list. + * + * This method was added to version 1.8 of the Java Platform Standard + * Edition. In order to maintain backwards compatibility with existing + * service providers, this method is not {@code abstract} + * and it provides a default implementation. + * + * @param key the PublicKey used to carry out the verification. + * @param sigProvider the signature provider. + * + * @exception NoSuchAlgorithmException on unsupported signature + * algorithms. + * @exception InvalidKeyException on incorrect key. + * @exception SignatureException on signature errors. + * @exception CRLException on encoding errors. + * @since 1.8 + */ + public void verify(PublicKey key, Provider sigProvider) + throws CRLException, NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + X509CRLImpl.verify(this, key, sigProvider); + } + + /** + * Gets the {@code version} (version number) value from the CRL. + * The ASN.1 definition for this is: + *
+     * version    Version OPTIONAL,
+     *             -- if present, must be v2
+     *
+     * Version  ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+     *             -- v3 does not apply to CRLs but appears for consistency
+     *             -- with definition of Version for certs
+     * 
+ * + * @return the version number, i.e. 1 or 2. + */ + public abstract int getVersion(); + + /** + * Denigrated, replaced by {@linkplain + * #getIssuerX500Principal()}. This method returns the {@code issuer} + * as an implementation specific Principal object, which should not be + * relied upon by portable code. + * + *

+ * Gets the {@code issuer} (issuer distinguished name) value from + * the CRL. The issuer name identifies the entity that signed (and + * issued) the CRL. + * + *

The issuer name field contains an + * X.500 distinguished name (DN). + * The ASN.1 definition for this is: + *

+     * issuer    Name
+     *
+     * Name ::= CHOICE { RDNSequence }
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     * RelativeDistinguishedName ::=
+     *     SET OF AttributeValueAssertion
+     *
+     * AttributeValueAssertion ::= SEQUENCE {
+     *                               AttributeType,
+     *                               AttributeValue }
+     * AttributeType ::= OBJECT IDENTIFIER
+     * AttributeValue ::= ANY
+     * 
+ * The {@code Name} describes a hierarchical name composed of + * attributes, + * such as country name, and corresponding values, such as US. + * The type of the {@code AttributeValue} component is determined by + * the {@code AttributeType}; in general it will be a + * {@code directoryString}. A {@code directoryString} is usually + * one of {@code PrintableString}, + * {@code TeletexString} or {@code UniversalString}. + * + * @return a Principal whose name is the issuer distinguished name. + */ + public abstract Principal getIssuerDN(); + + /** + * Returns the issuer (issuer distinguished name) value from the + * CRL as an {@code X500Principal}. + *

+ * It is recommended that subclasses override this method. + * + * @return an {@code X500Principal} representing the issuer + * distinguished name + * @since 1.4 + */ + public X500Principal getIssuerX500Principal() { + if (issuerPrincipal == null) { + issuerPrincipal = X509CRLImpl.getIssuerX500Principal(this); + } + return issuerPrincipal; + } + + /** + * Gets the {@code thisUpdate} date from the CRL. + * The ASN.1 definition for this is: + *

+     * thisUpdate   ChoiceOfTime
+     * ChoiceOfTime ::= CHOICE {
+     *     utcTime        UTCTime,
+     *     generalTime    GeneralizedTime }
+     * 
+ * + * @return the {@code thisUpdate} date from the CRL. + */ + public abstract Date getThisUpdate(); + + /** + * Gets the {@code nextUpdate} date from the CRL. + * + * @return the {@code nextUpdate} date from the CRL, or null if + * not present. + */ + public abstract Date getNextUpdate(); + + /** + * Gets the CRL entry, if any, with the given certificate serialNumber. + * + * @param serialNumber the serial number of the certificate for which a CRL entry + * is to be looked up + * @return the entry with the given serial number, or null if no such entry + * exists in this CRL. + * @see X509CRLEntry + */ + public abstract X509CRLEntry + getRevokedCertificate(BigInteger serialNumber); + + /** + * Get the CRL entry, if any, for the given certificate. + * + *

This method can be used to lookup CRL entries in indirect CRLs, + * that means CRLs that contain entries from issuers other than the CRL + * issuer. The default implementation will only return entries for + * certificates issued by the CRL issuer. Subclasses that wish to + * support indirect CRLs should override this method. + * + * @param certificate the certificate for which a CRL entry is to be looked + * up + * @return the entry for the given certificate, or null if no such entry + * exists in this CRL. + * @exception NullPointerException if certificate is null + * + * @since 1.5 + */ + public X509CRLEntry getRevokedCertificate(X509Certificate certificate) { + X500Principal certIssuer = certificate.getIssuerX500Principal(); + X500Principal crlIssuer = getIssuerX500Principal(); + if (certIssuer.equals(crlIssuer) == false) { + return null; + } + return getRevokedCertificate(certificate.getSerialNumber()); + } + + /** + * Gets all the entries from this CRL. + * This returns a Set of X509CRLEntry objects. + * + * @return all the entries or null if there are none present. + * @see X509CRLEntry + */ + public abstract Set getRevokedCertificates(); + + /** + * Gets the DER-encoded CRL information, the + * {@code tbsCertList} from this CRL. + * This can be used to verify the signature independently. + * + * @return the DER-encoded CRL information. + * @exception CRLException if an encoding error occurs. + */ + public abstract byte[] getTBSCertList() throws CRLException; + + /** + * Gets the {@code signature} value (the raw signature bits) from + * the CRL. + * The ASN.1 definition for this is: + *

+     * signature     BIT STRING
+     * 
+ * + * @return the signature. + */ + public abstract byte[] getSignature(); + + /** + * Gets the signature algorithm name for the CRL + * signature algorithm. An example is the string "SHA256withRSA". + * The ASN.1 definition for this is: + *
+     * signatureAlgorithm   AlgorithmIdentifier
+     *
+     * AlgorithmIdentifier  ::=  SEQUENCE  {
+     *     algorithm               OBJECT IDENTIFIER,
+     *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
+     *                             -- contains a value of the type
+     *                             -- registered for use with the
+     *                             -- algorithm object identifier value
+     * 
+ * + *

The algorithm name is determined from the {@code algorithm} + * OID string. + * + * @return the signature algorithm name. + */ + public abstract String getSigAlgName(); + + /** + * Gets the signature algorithm OID string from the CRL. + * An OID is represented by a set of nonnegative whole numbers separated + * by periods. + * For example, the string "1.2.840.10040.4.3" identifies the SHA-1 + * with DSA signature algorithm defined in + * RFC 3279: Algorithms and + * Identifiers for the Internet X.509 Public Key Infrastructure Certificate + * and CRL Profile. + * + *

See {@link #getSigAlgName() getSigAlgName} for + * relevant ASN.1 definitions. + * + * @return the signature algorithm OID string. + */ + public abstract String getSigAlgOID(); + + /** + * Gets the DER-encoded signature algorithm parameters from this + * CRL's signature algorithm. In most cases, the signature + * algorithm parameters are null; the parameters are usually + * supplied with the public key. + * If access to individual parameter values is needed then use + * {@link java.security.AlgorithmParameters AlgorithmParameters} + * and instantiate with the name returned by + * {@link #getSigAlgName() getSigAlgName}. + * + *

See {@link #getSigAlgName() getSigAlgName} for + * relevant ASN.1 definitions. + * + * @return the DER-encoded signature algorithm parameters, or + * null if no parameters are present. + */ + public abstract byte[] getSigAlgParams(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRLEntry.java b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRLEntry.java new file mode 100644 index 000000000..268fa8195 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRLEntry.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +import java.math.BigInteger; +import java.util.Date; +import javax.security.auth.x500.X500Principal; + +import sun.security.x509.X509CRLEntryImpl; + +/** + *

Abstract class for a revoked certificate in a CRL (Certificate + * Revocation List). + * + * The ASN.1 definition for revokedCertificates is: + *

+ * revokedCertificates    SEQUENCE OF SEQUENCE  {
+ *     userCertificate    CertificateSerialNumber,
+ *     revocationDate     ChoiceOfTime,
+ *     crlEntryExtensions Extensions OPTIONAL
+ *                        -- if present, must be v2
+ * }  OPTIONAL
+ *
+ * CertificateSerialNumber  ::=  INTEGER
+ *
+ * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension  ::=  SEQUENCE  {
+ *     extnId        OBJECT IDENTIFIER,
+ *     critical      BOOLEAN DEFAULT FALSE,
+ *     extnValue     OCTET STRING
+ *                   -- contains a DER encoding of a value
+ *                   -- of the type registered for use with
+ *                   -- the extnId object identifier value
+ * }
+ * 
+ * + * @see X509CRL + * @see X509Extension + * + * @author Hemma Prafullchandra + */ + +public abstract class X509CRLEntry implements X509Extension { + + /** + * Compares this CRL entry for equality with the given + * object. If the {@code other} object is an + * {@code instanceof} {@code X509CRLEntry}, then + * its encoded form (the inner SEQUENCE) is retrieved and compared + * with the encoded form of this CRL entry. + * + * @param other the object to test for equality with this CRL entry. + * @return true iff the encoded forms of the two CRL entries + * match, false otherwise. + */ + public boolean equals(Object other) { + if (this == other) + return true; + if (!(other instanceof X509CRLEntry)) + return false; + try { + byte[] thisCRLEntry = this.getEncoded(); + byte[] otherCRLEntry = ((X509CRLEntry)other).getEncoded(); + + if (thisCRLEntry.length != otherCRLEntry.length) + return false; + for (int i = 0; i < thisCRLEntry.length; i++) + if (thisCRLEntry[i] != otherCRLEntry[i]) + return false; + } catch (CRLException ce) { + return false; + } + return true; + } + + /** + * Returns a hashcode value for this CRL entry from its + * encoded form. + * + * @return the hashcode value. + */ + public int hashCode() { + int retval = 0; + try { + byte[] entryData = this.getEncoded(); + for (int i = 1; i < entryData.length; i++) + retval += entryData[i] * i; + + } catch (CRLException ce) { + return(retval); + } + return(retval); + } + + /** + * Returns the ASN.1 DER-encoded form of this CRL Entry, + * that is the inner SEQUENCE. + * + * @return the encoded form of this certificate + * @exception CRLException if an encoding error occurs. + */ + public abstract byte[] getEncoded() throws CRLException; + + /** + * Gets the serial number from this X509CRLEntry, + * the userCertificate. + * + * @return the serial number. + */ + public abstract BigInteger getSerialNumber(); + + /** + * Get the issuer of the X509Certificate described by this entry. If + * the certificate issuer is also the CRL issuer, this method returns + * null. + * + *

This method is used with indirect CRLs. The default implementation + * always returns null. Subclasses that wish to support indirect CRLs + * should override it. + * + * @return the issuer of the X509Certificate described by this entry + * or null if it is issued by the CRL issuer. + * + * @since 1.5 + */ + public X500Principal getCertificateIssuer() { + return null; + } + + /** + * Gets the revocation date from this X509CRLEntry, + * the revocationDate. + * + * @return the revocation date. + */ + public abstract Date getRevocationDate(); + + /** + * Returns true if this CRL entry has extensions. + * + * @return true if this entry has extensions, false otherwise. + */ + public abstract boolean hasExtensions(); + + /** + * Returns a string representation of this CRL entry. + * + * @return a string representation of this CRL entry. + */ + public abstract String toString(); + + /** + * Returns the reason the certificate has been revoked, as specified + * in the Reason Code extension of this CRL entry. + * + * @return the reason the certificate has been revoked, or + * {@code null} if this CRL entry does not have + * a Reason Code extension + * @since 1.7 + */ + public CRLReason getRevocationReason() { + if (!hasExtensions()) { + return null; + } + return X509CRLEntryImpl.getRevocationReason(this); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRLSelector.java b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRLSelector.java new file mode 100644 index 000000000..0580ee36b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CRLSelector.java @@ -0,0 +1,714 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.io.IOException; +import java.math.BigInteger; +import java.util.*; + +import javax.security.auth.x500.X500Principal; + +import sun.security.util.Debug; +import sun.security.util.DerInputStream; +import sun.security.x509.CRLNumberExtension; +import sun.security.x509.X500Name; + +/** + * A {@code CRLSelector} that selects {@code X509CRLs} that + * match all specified criteria. This class is particularly useful when + * selecting CRLs from a {@code CertStore} to check revocation status + * of a particular certificate. + *

+ * When first constructed, an {@code X509CRLSelector} has no criteria + * enabled and each of the {@code get} methods return a default + * value ({@code null}). Therefore, the {@link #match match} method + * would return {@code true} for any {@code X509CRL}. Typically, + * several criteria are enabled (by calling {@link #setIssuers setIssuers} + * or {@link #setDateAndTime setDateAndTime}, for instance) and then the + * {@code X509CRLSelector} is passed to + * {@link CertStore#getCRLs CertStore.getCRLs} or some similar + * method. + *

+ * Please refer to RFC 3280: + * Internet X.509 Public Key Infrastructure Certificate and CRL Profile + * for definitions of the X.509 CRL fields and extensions mentioned below. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CRLSelector + * @see X509CRL + * + * @since 1.4 + * @author Steve Hanna + */ +public class X509CRLSelector implements CRLSelector { + + static { + CertPathHelperImpl.initialize(); + } + + private static final Debug debug = Debug.getInstance("certpath"); + private HashSet issuerNames; + private HashSet issuerX500Principals; + private BigInteger minCRL; + private BigInteger maxCRL; + private Date dateAndTime; + private X509Certificate certChecking; + private long skew = 0; + + /** + * Creates an {@code X509CRLSelector}. Initially, no criteria are set + * so any {@code X509CRL} will match. + */ + public X509CRLSelector() {} + + /** + * Sets the issuerNames criterion. The issuer distinguished name in the + * {@code X509CRL} must match at least one of the specified + * distinguished names. If {@code null}, any issuer distinguished name + * will do. + *

+ * This method allows the caller to specify, with a single method call, + * the complete set of issuer names which {@code X509CRLs} may contain. + * The specified value replaces the previous value for the issuerNames + * criterion. + *

+ * The {@code names} parameter (if not {@code null}) is a + * {@code Collection} of {@code X500Principal}s. + *

+ * Note that the {@code names} parameter can contain duplicate + * distinguished names, but they may be removed from the + * {@code Collection} of names returned by the + * {@link #getIssuers getIssuers} method. + *

+ * Note that a copy is performed on the {@code Collection} to + * protect against subsequent modifications. + * + * @param issuers a {@code Collection} of X500Principals + * (or {@code null}) + * @see #getIssuers + * @since 1.5 + */ + public void setIssuers(Collection issuers) { + if ((issuers == null) || issuers.isEmpty()) { + issuerNames = null; + issuerX500Principals = null; + } else { + // clone + issuerX500Principals = new HashSet(issuers); + issuerNames = new HashSet(); + for (X500Principal p : issuerX500Principals) { + issuerNames.add(p.getEncoded()); + } + } + } + + /** + * Note: use {@linkplain #setIssuers(Collection)} instead + * or only specify the byte array form of distinguished names when using + * this method. See {@link #addIssuerName(String)} for more information. + *

+ * Sets the issuerNames criterion. The issuer distinguished name in the + * {@code X509CRL} must match at least one of the specified + * distinguished names. If {@code null}, any issuer distinguished name + * will do. + *

+ * This method allows the caller to specify, with a single method call, + * the complete set of issuer names which {@code X509CRLs} may contain. + * The specified value replaces the previous value for the issuerNames + * criterion. + *

+ * The {@code names} parameter (if not {@code null}) is a + * {@code Collection} of names. Each name is a {@code String} + * or a byte array representing a distinguished name (in + * RFC 2253 or + * ASN.1 DER encoded form, respectively). If {@code null} is supplied + * as the value for this argument, no issuerNames check will be performed. + *

+ * Note that the {@code names} parameter can contain duplicate + * distinguished names, but they may be removed from the + * {@code Collection} of names returned by the + * {@link #getIssuerNames getIssuerNames} method. + *

+ * If a name is specified as a byte array, it should contain a single DER + * encoded distinguished name, as defined in X.501. The ASN.1 notation for + * this structure is as follows. + *

{@code
+     * Name ::= CHOICE {
+     *   RDNSequence }
+     *
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     *
+     * RelativeDistinguishedName ::=
+     *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+     *
+     * AttributeTypeAndValue ::= SEQUENCE {
+     *   type     AttributeType,
+     *   value    AttributeValue }
+     *
+     * AttributeType ::= OBJECT IDENTIFIER
+     *
+     * AttributeValue ::= ANY DEFINED BY AttributeType
+     * ....
+     * DirectoryString ::= CHOICE {
+     *       teletexString           TeletexString (SIZE (1..MAX)),
+     *       printableString         PrintableString (SIZE (1..MAX)),
+     *       universalString         UniversalString (SIZE (1..MAX)),
+     *       utf8String              UTF8String (SIZE (1.. MAX)),
+     *       bmpString               BMPString (SIZE (1..MAX)) }
+     * }
+ *

+ * Note that a deep copy is performed on the {@code Collection} to + * protect against subsequent modifications. + * + * @param names a {@code Collection} of names (or {@code null}) + * @throws IOException if a parsing error occurs + * @see #getIssuerNames + */ + public void setIssuerNames(Collection names) throws IOException { + if (names == null || names.size() == 0) { + issuerNames = null; + issuerX500Principals = null; + } else { + HashSet tempNames = cloneAndCheckIssuerNames(names); + // Ensure that we either set both of these or neither + issuerX500Principals = parseIssuerNames(tempNames); + issuerNames = tempNames; + } + } + + /** + * Adds a name to the issuerNames criterion. The issuer distinguished + * name in the {@code X509CRL} must match at least one of the specified + * distinguished names. + *

+ * This method allows the caller to add a name to the set of issuer names + * which {@code X509CRLs} may contain. The specified name is added to + * any previous value for the issuerNames criterion. + * If the specified name is a duplicate, it may be ignored. + * + * @param issuer the issuer as X500Principal + * @since 1.5 + */ + public void addIssuer(X500Principal issuer) { + addIssuerNameInternal(issuer.getEncoded(), issuer); + } + + /** + * Denigrated, use + * {@linkplain #addIssuer(X500Principal)} or + * {@linkplain #addIssuerName(byte[])} instead. This method should not be + * relied on as it can fail to match some CRLs because of a loss of + * encoding information in the RFC 2253 String form of some distinguished + * names. + *

+ * Adds a name to the issuerNames criterion. The issuer distinguished + * name in the {@code X509CRL} must match at least one of the specified + * distinguished names. + *

+ * This method allows the caller to add a name to the set of issuer names + * which {@code X509CRLs} may contain. The specified name is added to + * any previous value for the issuerNames criterion. + * If the specified name is a duplicate, it may be ignored. + * + * @param name the name in RFC 2253 form + * @throws IOException if a parsing error occurs + */ + public void addIssuerName(String name) throws IOException { + addIssuerNameInternal(name, new X500Name(name).asX500Principal()); + } + + /** + * Adds a name to the issuerNames criterion. The issuer distinguished + * name in the {@code X509CRL} must match at least one of the specified + * distinguished names. + *

+ * This method allows the caller to add a name to the set of issuer names + * which {@code X509CRLs} may contain. The specified name is added to + * any previous value for the issuerNames criterion. If the specified name + * is a duplicate, it may be ignored. + * If a name is specified as a byte array, it should contain a single DER + * encoded distinguished name, as defined in X.501. The ASN.1 notation for + * this structure is as follows. + *

+ * The name is provided as a byte array. This byte array should contain + * a single DER encoded distinguished name, as defined in X.501. The ASN.1 + * notation for this structure appears in the documentation for + * {@link #setIssuerNames setIssuerNames(Collection names)}. + *

+ * Note that the byte array supplied here is cloned to protect against + * subsequent modifications. + * + * @param name a byte array containing the name in ASN.1 DER encoded form + * @throws IOException if a parsing error occurs + */ + public void addIssuerName(byte[] name) throws IOException { + // clone because byte arrays are modifiable + addIssuerNameInternal(name.clone(), new X500Name(name).asX500Principal()); + } + + /** + * A private method that adds a name (String or byte array) to the + * issuerNames criterion. The issuer distinguished + * name in the {@code X509CRL} must match at least one of the specified + * distinguished names. + * + * @param name the name in string or byte array form + * @param principal the name in X500Principal form + * @throws IOException if a parsing error occurs + */ + private void addIssuerNameInternal(Object name, X500Principal principal) { + if (issuerNames == null) { + issuerNames = new HashSet(); + } + if (issuerX500Principals == null) { + issuerX500Principals = new HashSet(); + } + issuerNames.add(name); + issuerX500Principals.add(principal); + } + + /** + * Clone and check an argument of the form passed to + * setIssuerNames. Throw an IOException if the argument is malformed. + * + * @param names a {@code Collection} of names. Each entry is a + * String or a byte array (the name, in string or ASN.1 + * DER encoded form, respectively). {@code null} is + * not an acceptable value. + * @return a deep copy of the specified {@code Collection} + * @throws IOException if a parsing error occurs + */ + private static HashSet cloneAndCheckIssuerNames(Collection names) + throws IOException + { + HashSet namesCopy = new HashSet(); + Iterator i = names.iterator(); + while (i.hasNext()) { + Object nameObject = i.next(); + if (!(nameObject instanceof byte []) && + !(nameObject instanceof String)) + throw new IOException("name not byte array or String"); + if (nameObject instanceof byte []) + namesCopy.add(((byte []) nameObject).clone()); + else + namesCopy.add(nameObject); + } + return(namesCopy); + } + + /** + * Clone an argument of the form passed to setIssuerNames. + * Throw a RuntimeException if the argument is malformed. + *

+ * This method wraps cloneAndCheckIssuerNames, changing any IOException + * into a RuntimeException. This method should be used when the object being + * cloned has already been checked, so there should never be any exceptions. + * + * @param names a {@code Collection} of names. Each entry is a + * String or a byte array (the name, in string or ASN.1 + * DER encoded form, respectively). {@code null} is + * not an acceptable value. + * @return a deep copy of the specified {@code Collection} + * @throws RuntimeException if a parsing error occurs + */ + private static HashSet cloneIssuerNames(Collection names) { + try { + return cloneAndCheckIssuerNames(names); + } catch (IOException ioe) { + throw new RuntimeException(ioe); + } + } + + /** + * Parse an argument of the form passed to setIssuerNames, + * returning a Collection of issuerX500Principals. + * Throw an IOException if the argument is malformed. + * + * @param names a {@code Collection} of names. Each entry is a + * String or a byte array (the name, in string or ASN.1 + * DER encoded form, respectively). Null is + * not an acceptable value. + * @return a HashSet of issuerX500Principals + * @throws IOException if a parsing error occurs + */ + private static HashSet parseIssuerNames(Collection names) + throws IOException { + HashSet x500Principals = new HashSet(); + for (Iterator t = names.iterator(); t.hasNext(); ) { + Object nameObject = t.next(); + if (nameObject instanceof String) { + x500Principals.add(new X500Name((String)nameObject).asX500Principal()); + } else { + try { + x500Principals.add(new X500Principal((byte[])nameObject)); + } catch (IllegalArgumentException e) { + throw (IOException)new IOException("Invalid name").initCause(e); + } + } + } + return x500Principals; + } + + /** + * Sets the minCRLNumber criterion. The {@code X509CRL} must have a + * CRL number extension whose value is greater than or equal to the + * specified value. If {@code null}, no minCRLNumber check will be + * done. + * + * @param minCRL the minimum CRL number accepted (or {@code null}) + */ + public void setMinCRLNumber(BigInteger minCRL) { + this.minCRL = minCRL; + } + + /** + * Sets the maxCRLNumber criterion. The {@code X509CRL} must have a + * CRL number extension whose value is less than or equal to the + * specified value. If {@code null}, no maxCRLNumber check will be + * done. + * + * @param maxCRL the maximum CRL number accepted (or {@code null}) + */ + public void setMaxCRLNumber(BigInteger maxCRL) { + this.maxCRL = maxCRL; + } + + /** + * Sets the dateAndTime criterion. The specified date must be + * equal to or later than the value of the thisUpdate component + * of the {@code X509CRL} and earlier than the value of the + * nextUpdate component. There is no match if the {@code X509CRL} + * does not contain a nextUpdate component. + * If {@code null}, no dateAndTime check will be done. + *

+ * Note that the {@code Date} supplied here is cloned to protect + * against subsequent modifications. + * + * @param dateAndTime the {@code Date} to match against + * (or {@code null}) + * @see #getDateAndTime + */ + public void setDateAndTime(Date dateAndTime) { + if (dateAndTime == null) + this.dateAndTime = null; + else + this.dateAndTime = new Date(dateAndTime.getTime()); + this.skew = 0; + } + + /** + * Sets the dateAndTime criterion and allows for the specified clock skew + * (in milliseconds) when checking against the validity period of the CRL. + */ + void setDateAndTime(Date dateAndTime, long skew) { + this.dateAndTime = + (dateAndTime == null ? null : new Date(dateAndTime.getTime())); + this.skew = skew; + } + + /** + * Sets the certificate being checked. This is not a criterion. Rather, + * it is optional information that may help a {@code CertStore} + * find CRLs that would be relevant when checking revocation for the + * specified certificate. If {@code null} is specified, then no + * such optional information is provided. + * + * @param cert the {@code X509Certificate} being checked + * (or {@code null}) + * @see #getCertificateChecking + */ + public void setCertificateChecking(X509Certificate cert) { + certChecking = cert; + } + + /** + * Returns the issuerNames criterion. The issuer distinguished + * name in the {@code X509CRL} must match at least one of the specified + * distinguished names. If the value returned is {@code null}, any + * issuer distinguished name will do. + *

+ * If the value returned is not {@code null}, it is a + * unmodifiable {@code Collection} of {@code X500Principal}s. + * + * @return an unmodifiable {@code Collection} of names + * (or {@code null}) + * @see #setIssuers + * @since 1.5 + */ + public Collection getIssuers() { + if (issuerX500Principals == null) { + return null; + } + return Collections.unmodifiableCollection(issuerX500Principals); + } + + /** + * Returns a copy of the issuerNames criterion. The issuer distinguished + * name in the {@code X509CRL} must match at least one of the specified + * distinguished names. If the value returned is {@code null}, any + * issuer distinguished name will do. + *

+ * If the value returned is not {@code null}, it is a + * {@code Collection} of names. Each name is a {@code String} + * or a byte array representing a distinguished name (in RFC 2253 or + * ASN.1 DER encoded form, respectively). Note that the + * {@code Collection} returned may contain duplicate names. + *

+ * If a name is specified as a byte array, it should contain a single DER + * encoded distinguished name, as defined in X.501. The ASN.1 notation for + * this structure is given in the documentation for + * {@link #setIssuerNames setIssuerNames(Collection names)}. + *

+ * Note that a deep copy is performed on the {@code Collection} to + * protect against subsequent modifications. + * + * @return a {@code Collection} of names (or {@code null}) + * @see #setIssuerNames + */ + public Collection getIssuerNames() { + if (issuerNames == null) { + return null; + } + return cloneIssuerNames(issuerNames); + } + + /** + * Returns the minCRLNumber criterion. The {@code X509CRL} must have a + * CRL number extension whose value is greater than or equal to the + * specified value. If {@code null}, no minCRLNumber check will be done. + * + * @return the minimum CRL number accepted (or {@code null}) + */ + public BigInteger getMinCRL() { + return minCRL; + } + + /** + * Returns the maxCRLNumber criterion. The {@code X509CRL} must have a + * CRL number extension whose value is less than or equal to the + * specified value. If {@code null}, no maxCRLNumber check will be + * done. + * + * @return the maximum CRL number accepted (or {@code null}) + */ + public BigInteger getMaxCRL() { + return maxCRL; + } + + /** + * Returns the dateAndTime criterion. The specified date must be + * equal to or later than the value of the thisUpdate component + * of the {@code X509CRL} and earlier than the value of the + * nextUpdate component. There is no match if the + * {@code X509CRL} does not contain a nextUpdate component. + * If {@code null}, no dateAndTime check will be done. + *

+ * Note that the {@code Date} returned is cloned to protect against + * subsequent modifications. + * + * @return the {@code Date} to match against (or {@code null}) + * @see #setDateAndTime + */ + public Date getDateAndTime() { + if (dateAndTime == null) + return null; + return (Date) dateAndTime.clone(); + } + + /** + * Returns the certificate being checked. This is not a criterion. Rather, + * it is optional information that may help a {@code CertStore} + * find CRLs that would be relevant when checking revocation for the + * specified certificate. If the value returned is {@code null}, then + * no such optional information is provided. + * + * @return the certificate being checked (or {@code null}) + * @see #setCertificateChecking + */ + public X509Certificate getCertificateChecking() { + return certChecking; + } + + /** + * Returns a printable representation of the {@code X509CRLSelector}. + * + * @return a {@code String} describing the contents of the + * {@code X509CRLSelector}. + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("X509CRLSelector: [\n"); + if (issuerNames != null) { + sb.append(" IssuerNames:\n"); + Iterator i = issuerNames.iterator(); + while (i.hasNext()) + sb.append(" " + i.next() + "\n"); + } + if (minCRL != null) + sb.append(" minCRLNumber: " + minCRL + "\n"); + if (maxCRL != null) + sb.append(" maxCRLNumber: " + maxCRL + "\n"); + if (dateAndTime != null) + sb.append(" dateAndTime: " + dateAndTime + "\n"); + if (certChecking != null) + sb.append(" Certificate being checked: " + certChecking + "\n"); + sb.append("]"); + return sb.toString(); + } + + /** + * Decides whether a {@code CRL} should be selected. + * + * @param crl the {@code CRL} to be checked + * @return {@code true} if the {@code CRL} should be selected, + * {@code false} otherwise + */ + public boolean match(CRL crl) { + if (!(crl instanceof X509CRL)) { + return false; + } + X509CRL xcrl = (X509CRL)crl; + + /* match on issuer name */ + if (issuerNames != null) { + X500Principal issuer = xcrl.getIssuerX500Principal(); + Iterator i = issuerX500Principals.iterator(); + boolean found = false; + while (!found && i.hasNext()) { + if (i.next().equals(issuer)) { + found = true; + } + } + if (!found) { + if (debug != null) { + debug.println("X509CRLSelector.match: issuer DNs " + + "don't match"); + } + return false; + } + } + + if ((minCRL != null) || (maxCRL != null)) { + /* Get CRL number extension from CRL */ + byte[] crlNumExtVal = xcrl.getExtensionValue("2.5.29.20"); + if (crlNumExtVal == null) { + if (debug != null) { + debug.println("X509CRLSelector.match: no CRLNumber"); + } + } + BigInteger crlNum; + try { + DerInputStream in = new DerInputStream(crlNumExtVal); + byte[] encoded = in.getOctetString(); + CRLNumberExtension crlNumExt = + new CRLNumberExtension(Boolean.FALSE, encoded); + crlNum = crlNumExt.get(CRLNumberExtension.NUMBER); + } catch (IOException ex) { + if (debug != null) { + debug.println("X509CRLSelector.match: exception in " + + "decoding CRL number"); + } + return false; + } + + /* match on minCRLNumber */ + if (minCRL != null) { + if (crlNum.compareTo(minCRL) < 0) { + if (debug != null) { + debug.println("X509CRLSelector.match: CRLNumber too small"); + } + return false; + } + } + + /* match on maxCRLNumber */ + if (maxCRL != null) { + if (crlNum.compareTo(maxCRL) > 0) { + if (debug != null) { + debug.println("X509CRLSelector.match: CRLNumber too large"); + } + return false; + } + } + } + + + /* match on dateAndTime */ + if (dateAndTime != null) { + Date crlThisUpdate = xcrl.getThisUpdate(); + Date nextUpdate = xcrl.getNextUpdate(); + if (nextUpdate == null) { + if (debug != null) { + debug.println("X509CRLSelector.match: nextUpdate null"); + } + return false; + } + Date nowPlusSkew = dateAndTime; + Date nowMinusSkew = dateAndTime; + if (skew > 0) { + nowPlusSkew = new Date(dateAndTime.getTime() + skew); + nowMinusSkew = new Date(dateAndTime.getTime() - skew); + } + if (nowMinusSkew.after(nextUpdate) + || nowPlusSkew.before(crlThisUpdate)) { + if (debug != null) { + debug.println("X509CRLSelector.match: update out of range"); + } + return false; + } + } + + return true; + } + + /** + * Returns a copy of this object. + * + * @return the copy + */ + public Object clone() { + try { + X509CRLSelector copy = (X509CRLSelector)super.clone(); + if (issuerNames != null) { + copy.issuerNames = + new HashSet(issuerNames); + copy.issuerX500Principals = + new HashSet(issuerX500Principals); + } + return copy; + } catch (CloneNotSupportedException e) { + /* Cannot happen */ + throw new InternalError(e.toString(), e); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/X509CertSelector.java b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CertSelector.java new file mode 100644 index 000000000..4a1ff7ef5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/X509CertSelector.java @@ -0,0 +1,2623 @@ +/* + * Copyright (c) 2000, 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 java.security.cert; + +import java.io.IOException; +import java.math.BigInteger; +import java.security.PublicKey; +import java.util.*; +import javax.security.auth.x500.X500Principal; + +import sun.misc.HexDumpEncoder; +import sun.security.util.Debug; +import sun.security.util.DerInputStream; +import sun.security.util.DerValue; +import sun.security.util.ObjectIdentifier; +import sun.security.x509.*; + +/** + * A {@code CertSelector} that selects {@code X509Certificates} that + * match all specified criteria. This class is particularly useful when + * selecting certificates from a {@code CertStore} to build a + * PKIX-compliant certification path. + *

+ * When first constructed, an {@code X509CertSelector} has no criteria + * enabled and each of the {@code get} methods return a default value + * ({@code null}, or {@code -1} for the {@link #getBasicConstraints + * getBasicConstraints} method). Therefore, the {@link #match match} + * method would return {@code true} for any {@code X509Certificate}. + * Typically, several criteria are enabled (by calling + * {@link #setIssuer setIssuer} or + * {@link #setKeyUsage setKeyUsage}, for instance) and then the + * {@code X509CertSelector} is passed to + * {@link CertStore#getCertificates CertStore.getCertificates} or some similar + * method. + *

+ * Several criteria can be enabled (by calling {@link #setIssuer setIssuer} + * and {@link #setSerialNumber setSerialNumber}, + * for example) such that the {@code match} method + * usually uniquely matches a single {@code X509Certificate}. We say + * usually, since it is possible for two issuing CAs to have the same + * distinguished name and each issue a certificate with the same serial + * number. Other unique combinations include the issuer, subject, + * subjectKeyIdentifier and/or the subjectPublicKey criteria. + *

+ * Please refer to RFC 3280: + * Internet X.509 Public Key Infrastructure Certificate and CRL Profile for + * definitions of the X.509 certificate extensions mentioned below. + *

+ * Concurrent Access + *

+ * Unless otherwise specified, the methods defined in this class are not + * thread-safe. Multiple threads that need to access a single + * object concurrently should synchronize amongst themselves and + * provide the necessary locking. Multiple threads each manipulating + * separate objects need not synchronize. + * + * @see CertSelector + * @see X509Certificate + * + * @since 1.4 + * @author Steve Hanna + */ +public class X509CertSelector implements CertSelector { + + private static final Debug debug = Debug.getInstance("certpath"); + + private final static ObjectIdentifier ANY_EXTENDED_KEY_USAGE = + ObjectIdentifier.newInternal(new int[] {2, 5, 29, 37, 0}); + + static { + CertPathHelperImpl.initialize(); + } + + private BigInteger serialNumber; + private X500Principal issuer; + private X500Principal subject; + private byte[] subjectKeyID; + private byte[] authorityKeyID; + private Date certificateValid; + private Date privateKeyValid; + private ObjectIdentifier subjectPublicKeyAlgID; + private PublicKey subjectPublicKey; + private byte[] subjectPublicKeyBytes; + private boolean[] keyUsage; + private Set keyPurposeSet; + private Set keyPurposeOIDSet; + private Set> subjectAlternativeNames; + private Set subjectAlternativeGeneralNames; + private CertificatePolicySet policy; + private Set policySet; + private Set> pathToNames; + private Set pathToGeneralNames; + private NameConstraintsExtension nc; + private byte[] ncBytes; + private int basicConstraints = -1; + private X509Certificate x509Cert; + private boolean matchAllSubjectAltNames = true; + + private static final Boolean FALSE = Boolean.FALSE; + + private static final int PRIVATE_KEY_USAGE_ID = 0; + private static final int SUBJECT_ALT_NAME_ID = 1; + private static final int NAME_CONSTRAINTS_ID = 2; + private static final int CERT_POLICIES_ID = 3; + private static final int EXTENDED_KEY_USAGE_ID = 4; + private static final int NUM_OF_EXTENSIONS = 5; + private static final String[] EXTENSION_OIDS = new String[NUM_OF_EXTENSIONS]; + + static { + EXTENSION_OIDS[PRIVATE_KEY_USAGE_ID] = "2.5.29.16"; + EXTENSION_OIDS[SUBJECT_ALT_NAME_ID] = "2.5.29.17"; + EXTENSION_OIDS[NAME_CONSTRAINTS_ID] = "2.5.29.30"; + EXTENSION_OIDS[CERT_POLICIES_ID] = "2.5.29.32"; + EXTENSION_OIDS[EXTENDED_KEY_USAGE_ID] = "2.5.29.37"; + }; + + /* Constants representing the GeneralName types */ + static final int NAME_ANY = 0; + static final int NAME_RFC822 = 1; + static final int NAME_DNS = 2; + static final int NAME_X400 = 3; + static final int NAME_DIRECTORY = 4; + static final int NAME_EDI = 5; + static final int NAME_URI = 6; + static final int NAME_IP = 7; + static final int NAME_OID = 8; + + /** + * Creates an {@code X509CertSelector}. Initially, no criteria are set + * so any {@code X509Certificate} will match. + */ + public X509CertSelector() { + // empty + } + + /** + * Sets the certificateEquals criterion. The specified + * {@code X509Certificate} must be equal to the + * {@code X509Certificate} passed to the {@code match} method. + * If {@code null}, then this check is not applied. + * + *

This method is particularly useful when it is necessary to + * match a single certificate. Although other criteria can be specified + * in conjunction with the certificateEquals criterion, it is usually not + * practical or necessary. + * + * @param cert the {@code X509Certificate} to match (or + * {@code null}) + * @see #getCertificate + */ + public void setCertificate(X509Certificate cert) { + x509Cert = cert; + } + + /** + * Sets the serialNumber criterion. The specified serial number + * must match the certificate serial number in the + * {@code X509Certificate}. If {@code null}, any certificate + * serial number will do. + * + * @param serial the certificate serial number to match + * (or {@code null}) + * @see #getSerialNumber + */ + public void setSerialNumber(BigInteger serial) { + serialNumber = serial; + } + + /** + * Sets the issuer criterion. The specified distinguished name + * must match the issuer distinguished name in the + * {@code X509Certificate}. If {@code null}, any issuer + * distinguished name will do. + * + * @param issuer a distinguished name as X500Principal + * (or {@code null}) + * @since 1.5 + */ + public void setIssuer(X500Principal issuer) { + this.issuer = issuer; + } + + /** + * Denigrated, use {@linkplain #setIssuer(X500Principal)} + * or {@linkplain #setIssuer(byte[])} instead. This method should not be + * relied on as it can fail to match some certificates because of a loss of + * encoding information in the + * RFC 2253 String form + * of some distinguished names. + *

+ * Sets the issuer criterion. The specified distinguished name + * must match the issuer distinguished name in the + * {@code X509Certificate}. If {@code null}, any issuer + * distinguished name will do. + *

+ * If {@code issuerDN} is not {@code null}, it should contain a + * distinguished name, in RFC 2253 format. + * + * @param issuerDN a distinguished name in RFC 2253 format + * (or {@code null}) + * @throws IOException if a parsing error occurs (incorrect form for DN) + */ + public void setIssuer(String issuerDN) throws IOException { + if (issuerDN == null) { + issuer = null; + } else { + issuer = new X500Name(issuerDN).asX500Principal(); + } + } + + /** + * Sets the issuer criterion. The specified distinguished name + * must match the issuer distinguished name in the + * {@code X509Certificate}. If {@code null} is specified, + * the issuer criterion is disabled and any issuer distinguished name will + * do. + *

+ * If {@code issuerDN} is not {@code null}, it should contain a + * single DER encoded distinguished name, as defined in X.501. The ASN.1 + * notation for this structure is as follows. + *

{@code
+     * Name ::= CHOICE {
+     *   RDNSequence }
+     *
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     *
+     * RelativeDistinguishedName ::=
+     *   SET SIZE (1 .. MAX) OF AttributeTypeAndValue
+     *
+     * AttributeTypeAndValue ::= SEQUENCE {
+     *   type     AttributeType,
+     *   value    AttributeValue }
+     *
+     * AttributeType ::= OBJECT IDENTIFIER
+     *
+     * AttributeValue ::= ANY DEFINED BY AttributeType
+     * ....
+     * DirectoryString ::= CHOICE {
+     *       teletexString           TeletexString (SIZE (1..MAX)),
+     *       printableString         PrintableString (SIZE (1..MAX)),
+     *       universalString         UniversalString (SIZE (1..MAX)),
+     *       utf8String              UTF8String (SIZE (1.. MAX)),
+     *       bmpString               BMPString (SIZE (1..MAX)) }
+     * }
+ *

+ * Note that the byte array specified here is cloned to protect against + * subsequent modifications. + * + * @param issuerDN a byte array containing the distinguished name + * in ASN.1 DER encoded form (or {@code null}) + * @throws IOException if an encoding error occurs (incorrect form for DN) + */ + public void setIssuer(byte[] issuerDN) throws IOException { + try { + issuer = (issuerDN == null ? null : new X500Principal(issuerDN)); + } catch (IllegalArgumentException e) { + throw new IOException("Invalid name", e); + } + } + + /** + * Sets the subject criterion. The specified distinguished name + * must match the subject distinguished name in the + * {@code X509Certificate}. If {@code null}, any subject + * distinguished name will do. + * + * @param subject a distinguished name as X500Principal + * (or {@code null}) + * @since 1.5 + */ + public void setSubject(X500Principal subject) { + this.subject = subject; + } + + /** + * Denigrated, use {@linkplain #setSubject(X500Principal)} + * or {@linkplain #setSubject(byte[])} instead. This method should not be + * relied on as it can fail to match some certificates because of a loss of + * encoding information in the RFC 2253 String form of some distinguished + * names. + *

+ * Sets the subject criterion. The specified distinguished name + * must match the subject distinguished name in the + * {@code X509Certificate}. If {@code null}, any subject + * distinguished name will do. + *

+ * If {@code subjectDN} is not {@code null}, it should contain a + * distinguished name, in RFC 2253 format. + * + * @param subjectDN a distinguished name in RFC 2253 format + * (or {@code null}) + * @throws IOException if a parsing error occurs (incorrect form for DN) + */ + public void setSubject(String subjectDN) throws IOException { + if (subjectDN == null) { + subject = null; + } else { + subject = new X500Name(subjectDN).asX500Principal(); + } + } + + /** + * Sets the subject criterion. The specified distinguished name + * must match the subject distinguished name in the + * {@code X509Certificate}. If {@code null}, any subject + * distinguished name will do. + *

+ * If {@code subjectDN} is not {@code null}, it should contain a + * single DER encoded distinguished name, as defined in X.501. For the ASN.1 + * notation for this structure, see + * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}. + * + * @param subjectDN a byte array containing the distinguished name in + * ASN.1 DER format (or {@code null}) + * @throws IOException if an encoding error occurs (incorrect form for DN) + */ + public void setSubject(byte[] subjectDN) throws IOException { + try { + subject = (subjectDN == null ? null : new X500Principal(subjectDN)); + } catch (IllegalArgumentException e) { + throw new IOException("Invalid name", e); + } + } + + /** + * Sets the subjectKeyIdentifier criterion. The + * {@code X509Certificate} must contain a SubjectKeyIdentifier + * extension for which the contents of the extension + * matches the specified criterion value. + * If the criterion value is {@code null}, no + * subjectKeyIdentifier check will be done. + *

+ * If {@code subjectKeyID} is not {@code null}, it + * should contain a single DER encoded value corresponding to the contents + * of the extension value (not including the object identifier, + * criticality setting, and encapsulating OCTET STRING) + * for a SubjectKeyIdentifier extension. + * The ASN.1 notation for this structure follows. + * + *

{@code
+     * SubjectKeyIdentifier ::= KeyIdentifier
+     *
+     * KeyIdentifier ::= OCTET STRING
+     * }
+ *

+ * Since the format of subject key identifiers is not mandated by + * any standard, subject key identifiers are not parsed by the + * {@code X509CertSelector}. Instead, the values are compared using + * a byte-by-byte comparison. + *

+ * Note that the byte array supplied here is cloned to protect against + * subsequent modifications. + * + * @param subjectKeyID the subject key identifier (or {@code null}) + * @see #getSubjectKeyIdentifier + */ + public void setSubjectKeyIdentifier(byte[] subjectKeyID) { + if (subjectKeyID == null) { + this.subjectKeyID = null; + } else { + this.subjectKeyID = subjectKeyID.clone(); + } + } + + /** + * Sets the authorityKeyIdentifier criterion. The + * {@code X509Certificate} must contain an + * AuthorityKeyIdentifier extension for which the contents of the + * extension value matches the specified criterion value. + * If the criterion value is {@code null}, no + * authorityKeyIdentifier check will be done. + *

+ * If {@code authorityKeyID} is not {@code null}, it + * should contain a single DER encoded value corresponding to the contents + * of the extension value (not including the object identifier, + * criticality setting, and encapsulating OCTET STRING) + * for an AuthorityKeyIdentifier extension. + * The ASN.1 notation for this structure follows. + * + *

{@code
+     * AuthorityKeyIdentifier ::= SEQUENCE {
+     *    keyIdentifier             [0] KeyIdentifier           OPTIONAL,
+     *    authorityCertIssuer       [1] GeneralNames            OPTIONAL,
+     *    authorityCertSerialNumber [2] CertificateSerialNumber OPTIONAL  }
+     *
+     * KeyIdentifier ::= OCTET STRING
+     * }
+ *

+ * Authority key identifiers are not parsed by the + * {@code X509CertSelector}. Instead, the values are + * compared using a byte-by-byte comparison. + *

+ * When the {@code keyIdentifier} field of + * {@code AuthorityKeyIdentifier} is populated, the value is + * usually taken from the {@code SubjectKeyIdentifier} extension + * in the issuer's certificate. Note, however, that the result of + * {@code X509Certificate.getExtensionValue()} on the issuer's certificate may NOT be used + * directly as the input to {@code setAuthorityKeyIdentifier}. + * This is because the SubjectKeyIdentifier contains + * only a KeyIdentifier OCTET STRING, and not a SEQUENCE of + * KeyIdentifier, GeneralNames, and CertificateSerialNumber. + * In order to use the extension value of the issuer certificate's + * {@code SubjectKeyIdentifier} + * extension, it will be necessary to extract the value of the embedded + * {@code KeyIdentifier} OCTET STRING, then DER encode this OCTET + * STRING inside a SEQUENCE. + * For more details on SubjectKeyIdentifier, see + * {@link #setSubjectKeyIdentifier(byte[] subjectKeyID)}. + *

+ * Note also that the byte array supplied here is cloned to protect against + * subsequent modifications. + * + * @param authorityKeyID the authority key identifier + * (or {@code null}) + * @see #getAuthorityKeyIdentifier + */ + public void setAuthorityKeyIdentifier(byte[] authorityKeyID) { + if (authorityKeyID == null) { + this.authorityKeyID = null; + } else { + this.authorityKeyID = authorityKeyID.clone(); + } + } + + /** + * Sets the certificateValid criterion. The specified date must fall + * within the certificate validity period for the + * {@code X509Certificate}. If {@code null}, no certificateValid + * check will be done. + *

+ * Note that the {@code Date} supplied here is cloned to protect + * against subsequent modifications. + * + * @param certValid the {@code Date} to check (or {@code null}) + * @see #getCertificateValid + */ + public void setCertificateValid(Date certValid) { + if (certValid == null) { + certificateValid = null; + } else { + certificateValid = (Date)certValid.clone(); + } + } + + /** + * Sets the privateKeyValid criterion. The specified date must fall + * within the private key validity period for the + * {@code X509Certificate}. If {@code null}, no privateKeyValid + * check will be done. + *

+ * Note that the {@code Date} supplied here is cloned to protect + * against subsequent modifications. + * + * @param privateKeyValid the {@code Date} to check (or + * {@code null}) + * @see #getPrivateKeyValid + */ + public void setPrivateKeyValid(Date privateKeyValid) { + if (privateKeyValid == null) { + this.privateKeyValid = null; + } else { + this.privateKeyValid = (Date)privateKeyValid.clone(); + } + } + + /** + * Sets the subjectPublicKeyAlgID criterion. The + * {@code X509Certificate} must contain a subject public key + * with the specified algorithm. If {@code null}, no + * subjectPublicKeyAlgID check will be done. + * + * @param oid The object identifier (OID) of the algorithm to check + * for (or {@code null}). An OID is represented by a + * set of nonnegative integers separated by periods. + * @throws IOException if the OID is invalid, such as + * the first component being not 0, 1 or 2 or the second component + * being greater than 39. + * + * @see #getSubjectPublicKeyAlgID + */ + public void setSubjectPublicKeyAlgID(String oid) throws IOException { + if (oid == null) { + subjectPublicKeyAlgID = null; + } else { + subjectPublicKeyAlgID = new ObjectIdentifier(oid); + } + } + + /** + * Sets the subjectPublicKey criterion. The + * {@code X509Certificate} must contain the specified subject public + * key. If {@code null}, no subjectPublicKey check will be done. + * + * @param key the subject public key to check for (or {@code null}) + * @see #getSubjectPublicKey + */ + public void setSubjectPublicKey(PublicKey key) { + if (key == null) { + subjectPublicKey = null; + subjectPublicKeyBytes = null; + } else { + subjectPublicKey = key; + subjectPublicKeyBytes = key.getEncoded(); + } + } + + /** + * Sets the subjectPublicKey criterion. The {@code X509Certificate} + * must contain the specified subject public key. If {@code null}, + * no subjectPublicKey check will be done. + *

+ * Because this method allows the public key to be specified as a byte + * array, it may be used for unknown key types. + *

+ * If {@code key} is not {@code null}, it should contain a + * single DER encoded SubjectPublicKeyInfo structure, as defined in X.509. + * The ASN.1 notation for this structure is as follows. + *

{@code
+     * SubjectPublicKeyInfo  ::=  SEQUENCE  {
+     *   algorithm            AlgorithmIdentifier,
+     *   subjectPublicKey     BIT STRING  }
+     *
+     * AlgorithmIdentifier  ::=  SEQUENCE  {
+     *   algorithm               OBJECT IDENTIFIER,
+     *   parameters              ANY DEFINED BY algorithm OPTIONAL  }
+     *                              -- contains a value of the type
+     *                              -- registered for use with the
+     *                              -- algorithm object identifier value
+     * }
+ *

+ * Note that the byte array supplied here is cloned to protect against + * subsequent modifications. + * + * @param key a byte array containing the subject public key in ASN.1 DER + * form (or {@code null}) + * @throws IOException if an encoding error occurs (incorrect form for + * subject public key) + * @see #getSubjectPublicKey + */ + public void setSubjectPublicKey(byte[] key) throws IOException { + if (key == null) { + subjectPublicKey = null; + subjectPublicKeyBytes = null; + } else { + subjectPublicKeyBytes = key.clone(); + subjectPublicKey = X509Key.parse(new DerValue(subjectPublicKeyBytes)); + } + } + + /** + * Sets the keyUsage criterion. The {@code X509Certificate} + * must allow the specified keyUsage values. If {@code null}, no + * keyUsage check will be done. Note that an {@code X509Certificate} + * that has no keyUsage extension implicitly allows all keyUsage values. + *

+ * Note that the boolean array supplied here is cloned to protect against + * subsequent modifications. + * + * @param keyUsage a boolean array in the same format as the boolean + * array returned by + * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. + * Or {@code null}. + * @see #getKeyUsage + */ + public void setKeyUsage(boolean[] keyUsage) { + if (keyUsage == null) { + this.keyUsage = null; + } else { + this.keyUsage = keyUsage.clone(); + } + } + + /** + * Sets the extendedKeyUsage criterion. The {@code X509Certificate} + * must allow the specified key purposes in its extended key usage + * extension. If {@code keyPurposeSet} is empty or {@code null}, + * no extendedKeyUsage check will be done. Note that an + * {@code X509Certificate} that has no extendedKeyUsage extension + * implicitly allows all key purposes. + *

+ * Note that the {@code Set} is cloned to protect against + * subsequent modifications. + * + * @param keyPurposeSet a {@code Set} of key purpose OIDs in string + * format (or {@code null}). Each OID is represented by a set of + * nonnegative integers separated by periods. + * @throws IOException if the OID is invalid, such as + * the first component being not 0, 1 or 2 or the second component + * being greater than 39. + * @see #getExtendedKeyUsage + */ + public void setExtendedKeyUsage(Set keyPurposeSet) throws IOException { + if ((keyPurposeSet == null) || keyPurposeSet.isEmpty()) { + this.keyPurposeSet = null; + keyPurposeOIDSet = null; + } else { + this.keyPurposeSet = + Collections.unmodifiableSet(new HashSet(keyPurposeSet)); + keyPurposeOIDSet = new HashSet(); + for (String s : this.keyPurposeSet) { + keyPurposeOIDSet.add(new ObjectIdentifier(s)); + } + } + } + + /** + * Enables/disables matching all of the subjectAlternativeNames + * specified in the {@link #setSubjectAlternativeNames + * setSubjectAlternativeNames} or {@link #addSubjectAlternativeName + * addSubjectAlternativeName} methods. If enabled, + * the {@code X509Certificate} must contain all of the + * specified subject alternative names. If disabled, the + * {@code X509Certificate} must contain at least one of the + * specified subject alternative names. + * + *

The matchAllNames flag is {@code true} by default. + * + * @param matchAllNames if {@code true}, the flag is enabled; + * if {@code false}, the flag is disabled. + * @see #getMatchAllSubjectAltNames + */ + public void setMatchAllSubjectAltNames(boolean matchAllNames) { + this.matchAllSubjectAltNames = matchAllNames; + } + + /** + * Sets the subjectAlternativeNames criterion. The + * {@code X509Certificate} must contain all or at least one of the + * specified subjectAlternativeNames, depending on the value of + * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames + * setMatchAllSubjectAltNames}). + *

+ * This method allows the caller to specify, with a single method call, + * the complete set of subject alternative names for the + * subjectAlternativeNames criterion. The specified value replaces + * the previous value for the subjectAlternativeNames criterion. + *

+ * The {@code names} parameter (if not {@code null}) is a + * {@code Collection} with one + * entry for each name to be included in the subject alternative name + * criterion. Each entry is a {@code List} whose first entry is an + * {@code Integer} (the name type, 0-8) and whose second + * entry is a {@code String} or a byte array (the name, in + * string or ASN.1 DER encoded form, respectively). + * There can be multiple names of the same type. If {@code null} + * is supplied as the value for this argument, no + * subjectAlternativeNames check will be performed. + *

+ * Each subject alternative name in the {@code Collection} + * may be specified either as a {@code String} or as an ASN.1 encoded + * byte array. For more details about the formats used, see + * {@link #addSubjectAlternativeName(int type, String name) + * addSubjectAlternativeName(int type, String name)} and + * {@link #addSubjectAlternativeName(int type, byte [] name) + * addSubjectAlternativeName(int type, byte [] name)}. + *

+ * Note: for distinguished names, specify the byte + * array form instead of the String form. See the note in + * {@link #addSubjectAlternativeName(int, String)} for more information. + *

+ * Note that the {@code names} parameter can contain duplicate + * names (same name and name type), but they may be removed from the + * {@code Collection} of names returned by the + * {@link #getSubjectAlternativeNames getSubjectAlternativeNames} method. + *

+ * Note that a deep copy is performed on the {@code Collection} to + * protect against subsequent modifications. + * + * @param names a {@code Collection} of names (or {@code null}) + * @throws IOException if a parsing error occurs + * @see #getSubjectAlternativeNames + */ + public void setSubjectAlternativeNames(Collection> names) + throws IOException { + if (names == null) { + subjectAlternativeNames = null; + subjectAlternativeGeneralNames = null; + } else { + if (names.isEmpty()) { + subjectAlternativeNames = null; + subjectAlternativeGeneralNames = null; + return; + } + Set> tempNames = cloneAndCheckNames(names); + // Ensure that we either set both of these or neither + subjectAlternativeGeneralNames = parseNames(tempNames); + subjectAlternativeNames = tempNames; + } + } + + /** + * Adds a name to the subjectAlternativeNames criterion. The + * {@code X509Certificate} must contain all or at least one + * of the specified subjectAlternativeNames, depending on the value of + * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames + * setMatchAllSubjectAltNames}). + *

+ * This method allows the caller to add a name to the set of subject + * alternative names. + * The specified name is added to any previous value for the + * subjectAlternativeNames criterion. If the specified name is a + * duplicate, it may be ignored. + *

+ * The name is provided in string format. + * RFC 822, DNS, and URI + * names use the well-established string formats for those types (subject to + * the restrictions included in RFC 3280). IPv4 address names are + * supplied using dotted quad notation. OID address names are represented + * as a series of nonnegative integers separated by periods. And + * directory names (distinguished names) are supplied in RFC 2253 format. + * No standard string format is defined for otherNames, X.400 names, + * EDI party names, IPv6 address names, or any other type of names. They + * should be specified using the + * {@link #addSubjectAlternativeName(int type, byte [] name) + * addSubjectAlternativeName(int type, byte [] name)} + * method. + *

+ * Note: for distinguished names, use + * {@linkplain #addSubjectAlternativeName(int, byte[])} instead. + * This method should not be relied on as it can fail to match some + * certificates because of a loss of encoding information in the RFC 2253 + * String form of some distinguished names. + * + * @param type the name type (0-8, as specified in + * RFC 3280, section 4.2.1.7) + * @param name the name in string form (not {@code null}) + * @throws IOException if a parsing error occurs + */ + public void addSubjectAlternativeName(int type, String name) + throws IOException { + addSubjectAlternativeNameInternal(type, name); + } + + /** + * Adds a name to the subjectAlternativeNames criterion. The + * {@code X509Certificate} must contain all or at least one + * of the specified subjectAlternativeNames, depending on the value of + * the matchAllNames flag (see {@link #setMatchAllSubjectAltNames + * setMatchAllSubjectAltNames}). + *

+ * This method allows the caller to add a name to the set of subject + * alternative names. + * The specified name is added to any previous value for the + * subjectAlternativeNames criterion. If the specified name is a + * duplicate, it may be ignored. + *

+ * The name is provided as a byte array. This byte array should contain + * the DER encoded name, as it would appear in the GeneralName structure + * defined in RFC 3280 and X.509. The encoded byte array should only contain + * the encoded value of the name, and should not include the tag associated + * with the name in the GeneralName structure. The ASN.1 definition of this + * structure appears below. + *

{@code
+     *  GeneralName ::= CHOICE {
+     *       otherName                       [0]     OtherName,
+     *       rfc822Name                      [1]     IA5String,
+     *       dNSName                         [2]     IA5String,
+     *       x400Address                     [3]     ORAddress,
+     *       directoryName                   [4]     Name,
+     *       ediPartyName                    [5]     EDIPartyName,
+     *       uniformResourceIdentifier       [6]     IA5String,
+     *       iPAddress                       [7]     OCTET STRING,
+     *       registeredID                    [8]     OBJECT IDENTIFIER}
+     * }
+ *

+ * Note that the byte array supplied here is cloned to protect against + * subsequent modifications. + * + * @param type the name type (0-8, as listed above) + * @param name a byte array containing the name in ASN.1 DER encoded form + * @throws IOException if a parsing error occurs + */ + public void addSubjectAlternativeName(int type, byte[] name) + throws IOException { + // clone because byte arrays are modifiable + addSubjectAlternativeNameInternal(type, name.clone()); + } + + /** + * A private method that adds a name (String or byte array) to the + * subjectAlternativeNames criterion. The {@code X509Certificate} + * must contain the specified subjectAlternativeName. + * + * @param type the name type (0-8, as specified in + * RFC 3280, section 4.2.1.7) + * @param name the name in string or byte array form + * @throws IOException if a parsing error occurs + */ + private void addSubjectAlternativeNameInternal(int type, Object name) + throws IOException { + // First, ensure that the name parses + GeneralNameInterface tempName = makeGeneralNameInterface(type, name); + if (subjectAlternativeNames == null) { + subjectAlternativeNames = new HashSet>(); + } + if (subjectAlternativeGeneralNames == null) { + subjectAlternativeGeneralNames = new HashSet(); + } + List list = new ArrayList(2); + list.add(Integer.valueOf(type)); + list.add(name); + subjectAlternativeNames.add(list); + subjectAlternativeGeneralNames.add(tempName); + } + + /** + * Parse an argument of the form passed to setSubjectAlternativeNames, + * returning a {@code Collection} of + * {@code GeneralNameInterface}s. + * Throw an IllegalArgumentException or a ClassCastException + * if the argument is malformed. + * + * @param names a Collection with one entry per name. + * Each entry is a {@code List} whose first entry + * is an Integer (the name type, 0-8) and whose second + * entry is a String or a byte array (the name, in + * string or ASN.1 DER encoded form, respectively). + * There can be multiple names of the same type. Null is + * not an acceptable value. + * @return a Set of {@code GeneralNameInterface}s + * @throws IOException if a parsing error occurs + */ + private static Set parseNames(Collection> names) throws IOException { + Set genNames = new HashSet(); + for (List nameList : names) { + if (nameList.size() != 2) { + throw new IOException("name list size not 2"); + } + Object o = nameList.get(0); + if (!(o instanceof Integer)) { + throw new IOException("expected an Integer"); + } + int nameType = ((Integer)o).intValue(); + o = nameList.get(1); + genNames.add(makeGeneralNameInterface(nameType, o)); + } + + return genNames; + } + + /** + * Compare for equality two objects of the form passed to + * setSubjectAlternativeNames (or X509CRLSelector.setIssuerNames). + * Throw an {@code IllegalArgumentException} or a + * {@code ClassCastException} if one of the objects is malformed. + * + * @param object1 a Collection containing the first object to compare + * @param object2 a Collection containing the second object to compare + * @return true if the objects are equal, false otherwise + */ + static boolean equalNames(Collection object1, Collection object2) { + if ((object1 == null) || (object2 == null)) { + return object1 == object2; + } + return object1.equals(object2); + } + + /** + * Make a {@code GeneralNameInterface} out of a name type (0-8) and an + * Object that may be a byte array holding the ASN.1 DER encoded + * name or a String form of the name. Except for X.509 + * Distinguished Names, the String form of the name must not be the + * result from calling toString on an existing GeneralNameInterface + * implementing class. The output of toString is not compatible + * with the String constructors for names other than Distinguished + * Names. + * + * @param type name type (0-8) + * @param name name as ASN.1 Der-encoded byte array or String + * @return a GeneralNameInterface name + * @throws IOException if a parsing error occurs + */ + static GeneralNameInterface makeGeneralNameInterface(int type, Object name) + throws IOException { + GeneralNameInterface result; + if (debug != null) { + debug.println("X509CertSelector.makeGeneralNameInterface(" + + type + ")..."); + } + + if (name instanceof String) { + if (debug != null) { + debug.println("X509CertSelector.makeGeneralNameInterface() " + + "name is String: " + name); + } + switch (type) { + case NAME_RFC822: + result = new RFC822Name((String)name); + break; + case NAME_DNS: + result = new DNSName((String)name); + break; + case NAME_DIRECTORY: + result = new X500Name((String)name); + break; + case NAME_URI: + result = new URIName((String)name); + break; + case NAME_IP: + result = new IPAddressName((String)name); + break; + case NAME_OID: + result = new OIDName((String)name); + break; + default: + throw new IOException("unable to parse String names of type " + + type); + } + if (debug != null) { + debug.println("X509CertSelector.makeGeneralNameInterface() " + + "result: " + result.toString()); + } + } else if (name instanceof byte[]) { + DerValue val = new DerValue((byte[]) name); + if (debug != null) { + debug.println + ("X509CertSelector.makeGeneralNameInterface() is byte[]"); + } + + switch (type) { + case NAME_ANY: + result = new OtherName(val); + break; + case NAME_RFC822: + result = new RFC822Name(val); + break; + case NAME_DNS: + result = new DNSName(val); + break; + case NAME_X400: + result = new X400Address(val); + break; + case NAME_DIRECTORY: + result = new X500Name(val); + break; + case NAME_EDI: + result = new EDIPartyName(val); + break; + case NAME_URI: + result = new URIName(val); + break; + case NAME_IP: + result = new IPAddressName(val); + break; + case NAME_OID: + result = new OIDName(val); + break; + default: + throw new IOException("unable to parse byte array names of " + + "type " + type); + } + if (debug != null) { + debug.println("X509CertSelector.makeGeneralNameInterface() result: " + + result.toString()); + } + } else { + if (debug != null) { + debug.println("X509CertSelector.makeGeneralName() input name " + + "not String or byte array"); + } + throw new IOException("name not String or byte array"); + } + return result; + } + + + /** + * Sets the name constraints criterion. The {@code X509Certificate} + * must have subject and subject alternative names that + * meet the specified name constraints. + *

+ * The name constraints are specified as a byte array. This byte array + * should contain the DER encoded form of the name constraints, as they + * would appear in the NameConstraints structure defined in RFC 3280 + * and X.509. The ASN.1 definition of this structure appears below. + * + *

{@code
+     *  NameConstraints ::= SEQUENCE {
+     *       permittedSubtrees       [0]     GeneralSubtrees OPTIONAL,
+     *       excludedSubtrees        [1]     GeneralSubtrees OPTIONAL }
+     *
+     *  GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
+     *
+     *  GeneralSubtree ::= SEQUENCE {
+     *       base                    GeneralName,
+     *       minimum         [0]     BaseDistance DEFAULT 0,
+     *       maximum         [1]     BaseDistance OPTIONAL }
+     *
+     *  BaseDistance ::= INTEGER (0..MAX)
+     *
+     *  GeneralName ::= CHOICE {
+     *       otherName                       [0]     OtherName,
+     *       rfc822Name                      [1]     IA5String,
+     *       dNSName                         [2]     IA5String,
+     *       x400Address                     [3]     ORAddress,
+     *       directoryName                   [4]     Name,
+     *       ediPartyName                    [5]     EDIPartyName,
+     *       uniformResourceIdentifier       [6]     IA5String,
+     *       iPAddress                       [7]     OCTET STRING,
+     *       registeredID                    [8]     OBJECT IDENTIFIER}
+     * }
+ *

+ * Note that the byte array supplied here is cloned to protect against + * subsequent modifications. + * + * @param bytes a byte array containing the ASN.1 DER encoding of + * a NameConstraints extension to be used for checking + * name constraints. Only the value of the extension is + * included, not the OID or criticality flag. Can be + * {@code null}, + * in which case no name constraints check will be performed. + * @throws IOException if a parsing error occurs + * @see #getNameConstraints + */ + public void setNameConstraints(byte[] bytes) throws IOException { + if (bytes == null) { + ncBytes = null; + nc = null; + } else { + ncBytes = bytes.clone(); + nc = new NameConstraintsExtension(FALSE, bytes); + } + } + + /** + * Sets the basic constraints constraint. If the value is greater than or + * equal to zero, {@code X509Certificates} must include a + * basicConstraints extension with + * a pathLen of at least this value. If the value is -2, only end-entity + * certificates are accepted. If the value is -1, no check is done. + *

+ * This constraint is useful when building a certification path forward + * (from the target toward the trust anchor. If a partial path has been + * built, any candidate certificate must have a maxPathLen value greater + * than or equal to the number of certificates in the partial path. + * + * @param minMaxPathLen the value for the basic constraints constraint + * @throws IllegalArgumentException if the value is less than -2 + * @see #getBasicConstraints + */ + public void setBasicConstraints(int minMaxPathLen) { + if (minMaxPathLen < -2) { + throw new IllegalArgumentException("basic constraints less than -2"); + } + basicConstraints = minMaxPathLen; + } + + /** + * Sets the policy constraint. The {@code X509Certificate} must + * include at least one of the specified policies in its certificate + * policies extension. If {@code certPolicySet} is empty, then the + * {@code X509Certificate} must include at least some specified policy + * in its certificate policies extension. If {@code certPolicySet} is + * {@code null}, no policy check will be performed. + *

+ * Note that the {@code Set} is cloned to protect against + * subsequent modifications. + * + * @param certPolicySet a {@code Set} of certificate policy OIDs in + * string format (or {@code null}). Each OID is + * represented by a set of nonnegative integers + * separated by periods. + * @throws IOException if a parsing error occurs on the OID such as + * the first component is not 0, 1 or 2 or the second component is + * greater than 39. + * @see #getPolicy + */ + public void setPolicy(Set certPolicySet) throws IOException { + if (certPolicySet == null) { + policySet = null; + policy = null; + } else { + // Snapshot set and parse it + Set tempSet = Collections.unmodifiableSet + (new HashSet(certPolicySet)); + /* Convert to Vector of ObjectIdentifiers */ + Iterator i = tempSet.iterator(); + Vector polIdVector = new Vector(); + while (i.hasNext()) { + Object o = i.next(); + if (!(o instanceof String)) { + throw new IOException("non String in certPolicySet"); + } + polIdVector.add(new CertificatePolicyId(new ObjectIdentifier( + (String)o))); + } + // If everything went OK, make the changes + policySet = tempSet; + policy = new CertificatePolicySet(polIdVector); + } + } + + /** + * Sets the pathToNames criterion. The {@code X509Certificate} must + * not include name constraints that would prohibit building a + * path to the specified names. + *

+ * This method allows the caller to specify, with a single method call, + * the complete set of names which the {@code X509Certificates}'s + * name constraints must permit. The specified value replaces + * the previous value for the pathToNames criterion. + *

+ * This constraint is useful when building a certification path forward + * (from the target toward the trust anchor. If a partial path has been + * built, any candidate certificate must not include name constraints that + * would prohibit building a path to any of the names in the partial path. + *

+ * The {@code names} parameter (if not {@code null}) is a + * {@code Collection} with one + * entry for each name to be included in the pathToNames + * criterion. Each entry is a {@code List} whose first entry is an + * {@code Integer} (the name type, 0-8) and whose second + * entry is a {@code String} or a byte array (the name, in + * string or ASN.1 DER encoded form, respectively). + * There can be multiple names of the same type. If {@code null} + * is supplied as the value for this argument, no + * pathToNames check will be performed. + *

+ * Each name in the {@code Collection} + * may be specified either as a {@code String} or as an ASN.1 encoded + * byte array. For more details about the formats used, see + * {@link #addPathToName(int type, String name) + * addPathToName(int type, String name)} and + * {@link #addPathToName(int type, byte [] name) + * addPathToName(int type, byte [] name)}. + *

+ * Note: for distinguished names, specify the byte + * array form instead of the String form. See the note in + * {@link #addPathToName(int, String)} for more information. + *

+ * Note that the {@code names} parameter can contain duplicate + * names (same name and name type), but they may be removed from the + * {@code Collection} of names returned by the + * {@link #getPathToNames getPathToNames} method. + *

+ * Note that a deep copy is performed on the {@code Collection} to + * protect against subsequent modifications. + * + * @param names a {@code Collection} with one entry per name + * (or {@code null}) + * @throws IOException if a parsing error occurs + * @see #getPathToNames + */ + public void setPathToNames(Collection> names) throws IOException { + if ((names == null) || names.isEmpty()) { + pathToNames = null; + pathToGeneralNames = null; + } else { + Set> tempNames = cloneAndCheckNames(names); + pathToGeneralNames = parseNames(tempNames); + // Ensure that we either set both of these or neither + pathToNames = tempNames; + } + } + + // called from CertPathHelper + void setPathToNamesInternal(Set names) { + // set names to non-null dummy value + // this breaks getPathToNames() + pathToNames = Collections.>emptySet(); + pathToGeneralNames = names; + } + + /** + * Adds a name to the pathToNames criterion. The {@code X509Certificate} + * must not include name constraints that would prohibit building a + * path to the specified name. + *

+ * This method allows the caller to add a name to the set of names which + * the {@code X509Certificates}'s name constraints must permit. + * The specified name is added to any previous value for the + * pathToNames criterion. If the name is a duplicate, it may be ignored. + *

+ * The name is provided in string format. RFC 822, DNS, and URI names + * use the well-established string formats for those types (subject to + * the restrictions included in RFC 3280). IPv4 address names are + * supplied using dotted quad notation. OID address names are represented + * as a series of nonnegative integers separated by periods. And + * directory names (distinguished names) are supplied in RFC 2253 format. + * No standard string format is defined for otherNames, X.400 names, + * EDI party names, IPv6 address names, or any other type of names. They + * should be specified using the + * {@link #addPathToName(int type, byte [] name) + * addPathToName(int type, byte [] name)} method. + *

+ * Note: for distinguished names, use + * {@linkplain #addPathToName(int, byte[])} instead. + * This method should not be relied on as it can fail to match some + * certificates because of a loss of encoding information in the RFC 2253 + * String form of some distinguished names. + * + * @param type the name type (0-8, as specified in + * RFC 3280, section 4.2.1.7) + * @param name the name in string form + * @throws IOException if a parsing error occurs + */ + public void addPathToName(int type, String name) throws IOException { + addPathToNameInternal(type, name); + } + + /** + * Adds a name to the pathToNames criterion. The {@code X509Certificate} + * must not include name constraints that would prohibit building a + * path to the specified name. + *

+ * This method allows the caller to add a name to the set of names which + * the {@code X509Certificates}'s name constraints must permit. + * The specified name is added to any previous value for the + * pathToNames criterion. If the name is a duplicate, it may be ignored. + *

+ * The name is provided as a byte array. This byte array should contain + * the DER encoded name, as it would appear in the GeneralName structure + * defined in RFC 3280 and X.509. The ASN.1 definition of this structure + * appears in the documentation for + * {@link #addSubjectAlternativeName(int type, byte [] name) + * addSubjectAlternativeName(int type, byte [] name)}. + *

+ * Note that the byte array supplied here is cloned to protect against + * subsequent modifications. + * + * @param type the name type (0-8, as specified in + * RFC 3280, section 4.2.1.7) + * @param name a byte array containing the name in ASN.1 DER encoded form + * @throws IOException if a parsing error occurs + */ + public void addPathToName(int type, byte [] name) throws IOException { + // clone because byte arrays are modifiable + addPathToNameInternal(type, name.clone()); + } + + /** + * A private method that adds a name (String or byte array) to the + * pathToNames criterion. The {@code X509Certificate} must contain + * the specified pathToName. + * + * @param type the name type (0-8, as specified in + * RFC 3280, section 4.2.1.7) + * @param name the name in string or byte array form + * @throws IOException if an encoding error occurs (incorrect form for DN) + */ + private void addPathToNameInternal(int type, Object name) + throws IOException { + // First, ensure that the name parses + GeneralNameInterface tempName = makeGeneralNameInterface(type, name); + if (pathToGeneralNames == null) { + pathToNames = new HashSet>(); + pathToGeneralNames = new HashSet(); + } + List list = new ArrayList(2); + list.add(Integer.valueOf(type)); + list.add(name); + pathToNames.add(list); + pathToGeneralNames.add(tempName); + } + + /** + * Returns the certificateEquals criterion. The specified + * {@code X509Certificate} must be equal to the + * {@code X509Certificate} passed to the {@code match} method. + * If {@code null}, this check is not applied. + * + * @return the {@code X509Certificate} to match (or {@code null}) + * @see #setCertificate + */ + public X509Certificate getCertificate() { + return x509Cert; + } + + /** + * Returns the serialNumber criterion. The specified serial number + * must match the certificate serial number in the + * {@code X509Certificate}. If {@code null}, any certificate + * serial number will do. + * + * @return the certificate serial number to match + * (or {@code null}) + * @see #setSerialNumber + */ + public BigInteger getSerialNumber() { + return serialNumber; + } + + /** + * Returns the issuer criterion as an {@code X500Principal}. This + * distinguished name must match the issuer distinguished name in the + * {@code X509Certificate}. If {@code null}, the issuer criterion + * is disabled and any issuer distinguished name will do. + * + * @return the required issuer distinguished name as X500Principal + * (or {@code null}) + * @since 1.5 + */ + public X500Principal getIssuer() { + return issuer; + } + + /** + * Denigrated, use {@linkplain #getIssuer()} or + * {@linkplain #getIssuerAsBytes()} instead. This method should not be + * relied on as it can fail to match some certificates because of a loss of + * encoding information in the RFC 2253 String form of some distinguished + * names. + *

+ * Returns the issuer criterion as a {@code String}. This + * distinguished name must match the issuer distinguished name in the + * {@code X509Certificate}. If {@code null}, the issuer criterion + * is disabled and any issuer distinguished name will do. + *

+ * If the value returned is not {@code null}, it is a + * distinguished name, in RFC 2253 format. + * + * @return the required issuer distinguished name in RFC 2253 format + * (or {@code null}) + */ + public String getIssuerAsString() { + return (issuer == null ? null : issuer.getName()); + } + + /** + * Returns the issuer criterion as a byte array. This distinguished name + * must match the issuer distinguished name in the + * {@code X509Certificate}. If {@code null}, the issuer criterion + * is disabled and any issuer distinguished name will do. + *

+ * If the value returned is not {@code null}, it is a byte + * array containing a single DER encoded distinguished name, as defined in + * X.501. The ASN.1 notation for this structure is supplied in the + * documentation for + * {@link #setIssuer(byte [] issuerDN) setIssuer(byte [] issuerDN)}. + *

+ * Note that the byte array returned is cloned to protect against + * subsequent modifications. + * + * @return a byte array containing the required issuer distinguished name + * in ASN.1 DER format (or {@code null}) + * @throws IOException if an encoding error occurs + */ + public byte[] getIssuerAsBytes() throws IOException { + return (issuer == null ? null: issuer.getEncoded()); + } + + /** + * Returns the subject criterion as an {@code X500Principal}. This + * distinguished name must match the subject distinguished name in the + * {@code X509Certificate}. If {@code null}, the subject criterion + * is disabled and any subject distinguished name will do. + * + * @return the required subject distinguished name as X500Principal + * (or {@code null}) + * @since 1.5 + */ + public X500Principal getSubject() { + return subject; + } + + /** + * Denigrated, use {@linkplain #getSubject()} or + * {@linkplain #getSubjectAsBytes()} instead. This method should not be + * relied on as it can fail to match some certificates because of a loss of + * encoding information in the RFC 2253 String form of some distinguished + * names. + *

+ * Returns the subject criterion as a {@code String}. This + * distinguished name must match the subject distinguished name in the + * {@code X509Certificate}. If {@code null}, the subject criterion + * is disabled and any subject distinguished name will do. + *

+ * If the value returned is not {@code null}, it is a + * distinguished name, in RFC 2253 format. + * + * @return the required subject distinguished name in RFC 2253 format + * (or {@code null}) + */ + public String getSubjectAsString() { + return (subject == null ? null : subject.getName()); + } + + /** + * Returns the subject criterion as a byte array. This distinguished name + * must match the subject distinguished name in the + * {@code X509Certificate}. If {@code null}, the subject criterion + * is disabled and any subject distinguished name will do. + *

+ * If the value returned is not {@code null}, it is a byte + * array containing a single DER encoded distinguished name, as defined in + * X.501. The ASN.1 notation for this structure is supplied in the + * documentation for + * {@link #setSubject(byte [] subjectDN) setSubject(byte [] subjectDN)}. + *

+ * Note that the byte array returned is cloned to protect against + * subsequent modifications. + * + * @return a byte array containing the required subject distinguished name + * in ASN.1 DER format (or {@code null}) + * @throws IOException if an encoding error occurs + */ + public byte[] getSubjectAsBytes() throws IOException { + return (subject == null ? null : subject.getEncoded()); + } + + /** + * Returns the subjectKeyIdentifier criterion. The + * {@code X509Certificate} must contain a SubjectKeyIdentifier + * extension with the specified value. If {@code null}, no + * subjectKeyIdentifier check will be done. + *

+ * Note that the byte array returned is cloned to protect against + * subsequent modifications. + * + * @return the key identifier (or {@code null}) + * @see #setSubjectKeyIdentifier + */ + public byte[] getSubjectKeyIdentifier() { + if (subjectKeyID == null) { + return null; + } + return subjectKeyID.clone(); + } + + /** + * Returns the authorityKeyIdentifier criterion. The + * {@code X509Certificate} must contain a AuthorityKeyIdentifier + * extension with the specified value. If {@code null}, no + * authorityKeyIdentifier check will be done. + *

+ * Note that the byte array returned is cloned to protect against + * subsequent modifications. + * + * @return the key identifier (or {@code null}) + * @see #setAuthorityKeyIdentifier + */ + public byte[] getAuthorityKeyIdentifier() { + if (authorityKeyID == null) { + return null; + } + return authorityKeyID.clone(); + } + + /** + * Returns the certificateValid criterion. The specified date must fall + * within the certificate validity period for the + * {@code X509Certificate}. If {@code null}, no certificateValid + * check will be done. + *

+ * Note that the {@code Date} returned is cloned to protect against + * subsequent modifications. + * + * @return the {@code Date} to check (or {@code null}) + * @see #setCertificateValid + */ + public Date getCertificateValid() { + if (certificateValid == null) { + return null; + } + return (Date)certificateValid.clone(); + } + + /** + * Returns the privateKeyValid criterion. The specified date must fall + * within the private key validity period for the + * {@code X509Certificate}. If {@code null}, no privateKeyValid + * check will be done. + *

+ * Note that the {@code Date} returned is cloned to protect against + * subsequent modifications. + * + * @return the {@code Date} to check (or {@code null}) + * @see #setPrivateKeyValid + */ + public Date getPrivateKeyValid() { + if (privateKeyValid == null) { + return null; + } + return (Date)privateKeyValid.clone(); + } + + /** + * Returns the subjectPublicKeyAlgID criterion. The + * {@code X509Certificate} must contain a subject public key + * with the specified algorithm. If {@code null}, no + * subjectPublicKeyAlgID check will be done. + * + * @return the object identifier (OID) of the signature algorithm to check + * for (or {@code null}). An OID is represented by a set of + * nonnegative integers separated by periods. + * @see #setSubjectPublicKeyAlgID + */ + public String getSubjectPublicKeyAlgID() { + if (subjectPublicKeyAlgID == null) { + return null; + } + return subjectPublicKeyAlgID.toString(); + } + + /** + * Returns the subjectPublicKey criterion. The + * {@code X509Certificate} must contain the specified subject + * public key. If {@code null}, no subjectPublicKey check will be done. + * + * @return the subject public key to check for (or {@code null}) + * @see #setSubjectPublicKey + */ + public PublicKey getSubjectPublicKey() { + return subjectPublicKey; + } + + /** + * Returns the keyUsage criterion. The {@code X509Certificate} + * must allow the specified keyUsage values. If null, no keyUsage + * check will be done. + *

+ * Note that the boolean array returned is cloned to protect against + * subsequent modifications. + * + * @return a boolean array in the same format as the boolean + * array returned by + * {@link X509Certificate#getKeyUsage() X509Certificate.getKeyUsage()}. + * Or {@code null}. + * @see #setKeyUsage + */ + public boolean[] getKeyUsage() { + if (keyUsage == null) { + return null; + } + return keyUsage.clone(); + } + + /** + * Returns the extendedKeyUsage criterion. The {@code X509Certificate} + * must allow the specified key purposes in its extended key usage + * extension. If the {@code keyPurposeSet} returned is empty or + * {@code null}, no extendedKeyUsage check will be done. Note that an + * {@code X509Certificate} that has no extendedKeyUsage extension + * implicitly allows all key purposes. + * + * @return an immutable {@code Set} of key purpose OIDs in string + * format (or {@code null}) + * @see #setExtendedKeyUsage + */ + public Set getExtendedKeyUsage() { + return keyPurposeSet; + } + + /** + * Indicates if the {@code X509Certificate} must contain all + * or at least one of the subjectAlternativeNames + * specified in the {@link #setSubjectAlternativeNames + * setSubjectAlternativeNames} or {@link #addSubjectAlternativeName + * addSubjectAlternativeName} methods. If {@code true}, + * the {@code X509Certificate} must contain all of the + * specified subject alternative names. If {@code false}, the + * {@code X509Certificate} must contain at least one of the + * specified subject alternative names. + * + * @return {@code true} if the flag is enabled; + * {@code false} if the flag is disabled. The flag is + * {@code true} by default. + * @see #setMatchAllSubjectAltNames + */ + public boolean getMatchAllSubjectAltNames() { + return matchAllSubjectAltNames; + } + + /** + * Returns a copy of the subjectAlternativeNames criterion. + * The {@code X509Certificate} must contain all or at least one + * of the specified subjectAlternativeNames, depending on the value + * of the matchAllNames flag (see {@link #getMatchAllSubjectAltNames + * getMatchAllSubjectAltNames}). If the value returned is + * {@code null}, no subjectAlternativeNames check will be performed. + *

+ * If the value returned is not {@code null}, it is a + * {@code Collection} with + * one entry for each name to be included in the subject alternative name + * criterion. Each entry is a {@code List} whose first entry is an + * {@code Integer} (the name type, 0-8) and whose second + * entry is a {@code String} or a byte array (the name, in + * string or ASN.1 DER encoded form, respectively). + * There can be multiple names of the same type. Note that the + * {@code Collection} returned may contain duplicate names (same name + * and name type). + *

+ * Each subject alternative name in the {@code Collection} + * may be specified either as a {@code String} or as an ASN.1 encoded + * byte array. For more details about the formats used, see + * {@link #addSubjectAlternativeName(int type, String name) + * addSubjectAlternativeName(int type, String name)} and + * {@link #addSubjectAlternativeName(int type, byte [] name) + * addSubjectAlternativeName(int type, byte [] name)}. + *

+ * Note that a deep copy is performed on the {@code Collection} to + * protect against subsequent modifications. + * + * @return a {@code Collection} of names (or {@code null}) + * @see #setSubjectAlternativeNames + */ + public Collection> getSubjectAlternativeNames() { + if (subjectAlternativeNames == null) { + return null; + } + return cloneNames(subjectAlternativeNames); + } + + /** + * Clone an object of the form passed to + * setSubjectAlternativeNames and setPathToNames. + * Throw a {@code RuntimeException} if the argument is malformed. + *

+ * This method wraps cloneAndCheckNames, changing any + * {@code IOException} into a {@code RuntimeException}. This + * method should be used when the object being + * cloned has already been checked, so there should never be any exceptions. + * + * @param names a {@code Collection} with one entry per name. + * Each entry is a {@code List} whose first entry + * is an Integer (the name type, 0-8) and whose second + * entry is a String or a byte array (the name, in + * string or ASN.1 DER encoded form, respectively). + * There can be multiple names of the same type. Null + * is not an acceptable value. + * @return a deep copy of the specified {@code Collection} + * @throws RuntimeException if a parsing error occurs + */ + private static Set> cloneNames(Collection> names) { + try { + return cloneAndCheckNames(names); + } catch (IOException e) { + throw new RuntimeException("cloneNames encountered IOException: " + + e.getMessage()); + } + } + + /** + * Clone and check an argument of the form passed to + * setSubjectAlternativeNames and setPathToNames. + * Throw an {@code IOException} if the argument is malformed. + * + * @param names a {@code Collection} with one entry per name. + * Each entry is a {@code List} whose first entry + * is an Integer (the name type, 0-8) and whose second + * entry is a String or a byte array (the name, in + * string or ASN.1 DER encoded form, respectively). + * There can be multiple names of the same type. + * {@code null} is not an acceptable value. + * @return a deep copy of the specified {@code Collection} + * @throws IOException if a parsing error occurs + */ + private static Set> cloneAndCheckNames(Collection> names) throws IOException { + // Copy the Lists and Collection + Set> namesCopy = new HashSet>(); + for (List o : names) + { + namesCopy.add(new ArrayList(o)); + } + + // Check the contents of the Lists and clone any byte arrays + for (List list : namesCopy) { + @SuppressWarnings("unchecked") // See javadoc for parameter "names". + List nameList = (List)list; + if (nameList.size() != 2) { + throw new IOException("name list size not 2"); + } + Object o = nameList.get(0); + if (!(o instanceof Integer)) { + throw new IOException("expected an Integer"); + } + int nameType = ((Integer)o).intValue(); + if ((nameType < 0) || (nameType > 8)) { + throw new IOException("name type not 0-8"); + } + Object nameObject = nameList.get(1); + if (!(nameObject instanceof byte[]) && + !(nameObject instanceof String)) { + if (debug != null) { + debug.println("X509CertSelector.cloneAndCheckNames() " + + "name not byte array"); + } + throw new IOException("name not byte array or String"); + } + if (nameObject instanceof byte[]) { + nameList.set(1, ((byte[]) nameObject).clone()); + } + } + return namesCopy; + } + + /** + * Returns the name constraints criterion. The {@code X509Certificate} + * must have subject and subject alternative names that + * meet the specified name constraints. + *

+ * The name constraints are returned as a byte array. This byte array + * contains the DER encoded form of the name constraints, as they + * would appear in the NameConstraints structure defined in RFC 3280 + * and X.509. The ASN.1 notation for this structure is supplied in the + * documentation for + * {@link #setNameConstraints(byte [] bytes) setNameConstraints(byte [] bytes)}. + *

+ * Note that the byte array returned is cloned to protect against + * subsequent modifications. + * + * @return a byte array containing the ASN.1 DER encoding of + * a NameConstraints extension used for checking name constraints. + * {@code null} if no name constraints check will be performed. + * @see #setNameConstraints + */ + public byte[] getNameConstraints() { + if (ncBytes == null) { + return null; + } else { + return ncBytes.clone(); + } + } + + /** + * Returns the basic constraints constraint. If the value is greater than + * or equal to zero, the {@code X509Certificates} must include a + * basicConstraints extension with a pathLen of at least this value. + * If the value is -2, only end-entity certificates are accepted. If + * the value is -1, no basicConstraints check is done. + * + * @return the value for the basic constraints constraint + * @see #setBasicConstraints + */ + public int getBasicConstraints() { + return basicConstraints; + } + + /** + * Returns the policy criterion. The {@code X509Certificate} must + * include at least one of the specified policies in its certificate policies + * extension. If the {@code Set} returned is empty, then the + * {@code X509Certificate} must include at least some specified policy + * in its certificate policies extension. If the {@code Set} returned is + * {@code null}, no policy check will be performed. + * + * @return an immutable {@code Set} of certificate policy OIDs in + * string format (or {@code null}) + * @see #setPolicy + */ + public Set getPolicy() { + return policySet; + } + + /** + * Returns a copy of the pathToNames criterion. The + * {@code X509Certificate} must not include name constraints that would + * prohibit building a path to the specified names. If the value + * returned is {@code null}, no pathToNames check will be performed. + *

+ * If the value returned is not {@code null}, it is a + * {@code Collection} with one + * entry for each name to be included in the pathToNames + * criterion. Each entry is a {@code List} whose first entry is an + * {@code Integer} (the name type, 0-8) and whose second + * entry is a {@code String} or a byte array (the name, in + * string or ASN.1 DER encoded form, respectively). + * There can be multiple names of the same type. Note that the + * {@code Collection} returned may contain duplicate names (same + * name and name type). + *

+ * Each name in the {@code Collection} + * may be specified either as a {@code String} or as an ASN.1 encoded + * byte array. For more details about the formats used, see + * {@link #addPathToName(int type, String name) + * addPathToName(int type, String name)} and + * {@link #addPathToName(int type, byte [] name) + * addPathToName(int type, byte [] name)}. + *

+ * Note that a deep copy is performed on the {@code Collection} to + * protect against subsequent modifications. + * + * @return a {@code Collection} of names (or {@code null}) + * @see #setPathToNames + */ + public Collection> getPathToNames() { + if (pathToNames == null) { + return null; + } + return cloneNames(pathToNames); + } + + /** + * Return a printable representation of the {@code CertSelector}. + * + * @return a {@code String} describing the contents of the + * {@code CertSelector} + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append("X509CertSelector: [\n"); + if (x509Cert != null) { + sb.append(" Certificate: " + x509Cert.toString() + "\n"); + } + if (serialNumber != null) { + sb.append(" Serial Number: " + serialNumber.toString() + "\n"); + } + if (issuer != null) { + sb.append(" Issuer: " + getIssuerAsString() + "\n"); + } + if (subject != null) { + sb.append(" Subject: " + getSubjectAsString() + "\n"); + } + sb.append(" matchAllSubjectAltNames flag: " + + String.valueOf(matchAllSubjectAltNames) + "\n"); + if (subjectAlternativeNames != null) { + sb.append(" SubjectAlternativeNames:\n"); + Iterator> i = subjectAlternativeNames.iterator(); + while (i.hasNext()) { + List list = i.next(); + sb.append(" type " + list.get(0) + + ", name " + list.get(1) + "\n"); + } + } + if (subjectKeyID != null) { + HexDumpEncoder enc = new HexDumpEncoder(); + sb.append(" Subject Key Identifier: " + + enc.encodeBuffer(subjectKeyID) + "\n"); + } + if (authorityKeyID != null) { + HexDumpEncoder enc = new HexDumpEncoder(); + sb.append(" Authority Key Identifier: " + + enc.encodeBuffer(authorityKeyID) + "\n"); + } + if (certificateValid != null) { + sb.append(" Certificate Valid: " + + certificateValid.toString() + "\n"); + } + if (privateKeyValid != null) { + sb.append(" Private Key Valid: " + + privateKeyValid.toString() + "\n"); + } + if (subjectPublicKeyAlgID != null) { + sb.append(" Subject Public Key AlgID: " + + subjectPublicKeyAlgID.toString() + "\n"); + } + if (subjectPublicKey != null) { + sb.append(" Subject Public Key: " + + subjectPublicKey.toString() + "\n"); + } + if (keyUsage != null) { + sb.append(" Key Usage: " + keyUsageToString(keyUsage) + "\n"); + } + if (keyPurposeSet != null) { + sb.append(" Extended Key Usage: " + + keyPurposeSet.toString() + "\n"); + } + if (policy != null) { + sb.append(" Policy: " + policy.toString() + "\n"); + } + if (pathToGeneralNames != null) { + sb.append(" Path to names:\n"); + Iterator i = pathToGeneralNames.iterator(); + while (i.hasNext()) { + sb.append(" " + i.next() + "\n"); + } + } + sb.append("]"); + return sb.toString(); + } + + // Copied from sun.security.x509.KeyUsageExtension + // (without calling the superclass) + /** + * Returns a printable representation of the KeyUsage. + */ + private static String keyUsageToString(boolean[] k) { + String s = "KeyUsage [\n"; + try { + if (k[0]) { + s += " DigitalSignature\n"; + } + if (k[1]) { + s += " Non_repudiation\n"; + } + if (k[2]) { + s += " Key_Encipherment\n"; + } + if (k[3]) { + s += " Data_Encipherment\n"; + } + if (k[4]) { + s += " Key_Agreement\n"; + } + if (k[5]) { + s += " Key_CertSign\n"; + } + if (k[6]) { + s += " Crl_Sign\n"; + } + if (k[7]) { + s += " Encipher_Only\n"; + } + if (k[8]) { + s += " Decipher_Only\n"; + } + } catch (ArrayIndexOutOfBoundsException ex) {} + + s += "]\n"; + + return (s); + } + + /** + * Returns an Extension object given any X509Certificate and extension oid. + * Throw an {@code IOException} if the extension byte value is + * malformed. + * + * @param cert a {@code X509Certificate} + * @param extId an {@code integer} which specifies the extension index. + * Currently, the supported extensions are as follows: + * index 0 - PrivateKeyUsageExtension + * index 1 - SubjectAlternativeNameExtension + * index 2 - NameConstraintsExtension + * index 3 - CertificatePoliciesExtension + * index 4 - ExtendedKeyUsageExtension + * @return an {@code Extension} object whose real type is as specified + * by the extension oid. + * @throws IOException if cannot construct the {@code Extension} + * object with the extension encoding retrieved from the passed in + * {@code X509Certificate}. + */ + private static Extension getExtensionObject(X509Certificate cert, int extId) + throws IOException { + if (cert instanceof X509CertImpl) { + X509CertImpl impl = (X509CertImpl)cert; + switch (extId) { + case PRIVATE_KEY_USAGE_ID: + return impl.getPrivateKeyUsageExtension(); + case SUBJECT_ALT_NAME_ID: + return impl.getSubjectAlternativeNameExtension(); + case NAME_CONSTRAINTS_ID: + return impl.getNameConstraintsExtension(); + case CERT_POLICIES_ID: + return impl.getCertificatePoliciesExtension(); + case EXTENDED_KEY_USAGE_ID: + return impl.getExtendedKeyUsageExtension(); + default: + return null; + } + } + byte[] rawExtVal = cert.getExtensionValue(EXTENSION_OIDS[extId]); + if (rawExtVal == null) { + return null; + } + DerInputStream in = new DerInputStream(rawExtVal); + byte[] encoded = in.getOctetString(); + switch (extId) { + case PRIVATE_KEY_USAGE_ID: + try { + return new PrivateKeyUsageExtension(FALSE, encoded); + } catch (CertificateException ex) { + throw new IOException(ex.getMessage()); + } + case SUBJECT_ALT_NAME_ID: + return new SubjectAlternativeNameExtension(FALSE, encoded); + case NAME_CONSTRAINTS_ID: + return new NameConstraintsExtension(FALSE, encoded); + case CERT_POLICIES_ID: + return new CertificatePoliciesExtension(FALSE, encoded); + case EXTENDED_KEY_USAGE_ID: + return new ExtendedKeyUsageExtension(FALSE, encoded); + default: + return null; + } + } + + /** + * Decides whether a {@code Certificate} should be selected. + * + * @param cert the {@code Certificate} to be checked + * @return {@code true} if the {@code Certificate} should be + * selected, {@code false} otherwise + */ + public boolean match(Certificate cert) { + if (!(cert instanceof X509Certificate)) { + return false; + } + X509Certificate xcert = (X509Certificate)cert; + + if (debug != null) { + debug.println("X509CertSelector.match(SN: " + + (xcert.getSerialNumber()).toString(16) + "\n Issuer: " + + xcert.getIssuerDN() + "\n Subject: " + xcert.getSubjectDN() + + ")"); + } + + /* match on X509Certificate */ + if (x509Cert != null) { + if (!x509Cert.equals(xcert)) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "certs don't match"); + } + return false; + } + } + + /* match on serial number */ + if (serialNumber != null) { + if (!serialNumber.equals(xcert.getSerialNumber())) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "serial numbers don't match"); + } + return false; + } + } + + /* match on issuer name */ + if (issuer != null) { + if (!issuer.equals(xcert.getIssuerX500Principal())) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "issuer DNs don't match"); + } + return false; + } + } + + /* match on subject name */ + if (subject != null) { + if (!subject.equals(xcert.getSubjectX500Principal())) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "subject DNs don't match"); + } + return false; + } + } + + /* match on certificate validity range */ + if (certificateValid != null) { + try { + xcert.checkValidity(certificateValid); + } catch (CertificateException e) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "certificate not within validity period"); + } + return false; + } + } + + /* match on subject public key */ + if (subjectPublicKeyBytes != null) { + byte[] certKey = xcert.getPublicKey().getEncoded(); + if (!Arrays.equals(subjectPublicKeyBytes, certKey)) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "subject public keys don't match"); + } + return false; + } + } + + boolean result = matchBasicConstraints(xcert) + && matchKeyUsage(xcert) + && matchExtendedKeyUsage(xcert) + && matchSubjectKeyID(xcert) + && matchAuthorityKeyID(xcert) + && matchPrivateKeyValid(xcert) + && matchSubjectPublicKeyAlgID(xcert) + && matchPolicy(xcert) + && matchSubjectAlternativeNames(xcert) + && matchPathToNames(xcert) + && matchNameConstraints(xcert); + + if (result && (debug != null)) { + debug.println("X509CertSelector.match returning: true"); + } + return result; + } + + /* match on subject key identifier extension value */ + private boolean matchSubjectKeyID(X509Certificate xcert) { + if (subjectKeyID == null) { + return true; + } + try { + byte[] extVal = xcert.getExtensionValue("2.5.29.14"); + if (extVal == null) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "no subject key ID extension"); + } + return false; + } + DerInputStream in = new DerInputStream(extVal); + byte[] certSubjectKeyID = in.getOctetString(); + if (certSubjectKeyID == null || + !Arrays.equals(subjectKeyID, certSubjectKeyID)) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "subject key IDs don't match"); + } + return false; + } + } catch (IOException ex) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "exception in subject key ID check"); + } + return false; + } + return true; + } + + /* match on authority key identifier extension value */ + private boolean matchAuthorityKeyID(X509Certificate xcert) { + if (authorityKeyID == null) { + return true; + } + try { + byte[] extVal = xcert.getExtensionValue("2.5.29.35"); + if (extVal == null) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "no authority key ID extension"); + } + return false; + } + DerInputStream in = new DerInputStream(extVal); + byte[] certAuthKeyID = in.getOctetString(); + if (certAuthKeyID == null || + !Arrays.equals(authorityKeyID, certAuthKeyID)) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "authority key IDs don't match"); + } + return false; + } + } catch (IOException ex) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "exception in authority key ID check"); + } + return false; + } + return true; + } + + /* match on private key usage range */ + private boolean matchPrivateKeyValid(X509Certificate xcert) { + if (privateKeyValid == null) { + return true; + } + PrivateKeyUsageExtension ext = null; + try { + ext = (PrivateKeyUsageExtension) + getExtensionObject(xcert, PRIVATE_KEY_USAGE_ID); + if (ext != null) { + ext.valid(privateKeyValid); + } + } catch (CertificateExpiredException e1) { + if (debug != null) { + String time = "n/a"; + try { + Date notAfter = ext.get(PrivateKeyUsageExtension.NOT_AFTER); + time = notAfter.toString(); + } catch (CertificateException ex) { + // not able to retrieve notAfter value + } + debug.println("X509CertSelector.match: private key usage not " + + "within validity date; ext.NOT_After: " + + time + "; X509CertSelector: " + + this.toString()); + e1.printStackTrace(); + } + return false; + } catch (CertificateNotYetValidException e2) { + if (debug != null) { + String time = "n/a"; + try { + Date notBefore = ext.get(PrivateKeyUsageExtension.NOT_BEFORE); + time = notBefore.toString(); + } catch (CertificateException ex) { + // not able to retrieve notBefore value + } + debug.println("X509CertSelector.match: private key usage not " + + "within validity date; ext.NOT_BEFORE: " + + time + "; X509CertSelector: " + + this.toString()); + e2.printStackTrace(); + } + return false; + } catch (IOException e4) { + if (debug != null) { + debug.println("X509CertSelector.match: IOException in " + + "private key usage check; X509CertSelector: " + + this.toString()); + e4.printStackTrace(); + } + return false; + } + return true; + } + + /* match on subject public key algorithm OID */ + private boolean matchSubjectPublicKeyAlgID(X509Certificate xcert) { + if (subjectPublicKeyAlgID == null) { + return true; + } + try { + byte[] encodedKey = xcert.getPublicKey().getEncoded(); + DerValue val = new DerValue(encodedKey); + if (val.tag != DerValue.tag_Sequence) { + throw new IOException("invalid key format"); + } + + AlgorithmId algID = AlgorithmId.parse(val.data.getDerValue()); + if (debug != null) { + debug.println("X509CertSelector.match: subjectPublicKeyAlgID = " + + subjectPublicKeyAlgID + ", xcert subjectPublicKeyAlgID = " + + algID.getOID()); + } + if (!subjectPublicKeyAlgID.equals((Object)algID.getOID())) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "subject public key alg IDs don't match"); + } + return false; + } + } catch (IOException e5) { + if (debug != null) { + debug.println("X509CertSelector.match: IOException in subject " + + "public key algorithm OID check"); + } + return false; + } + return true; + } + + /* match on key usage extension value */ + private boolean matchKeyUsage(X509Certificate xcert) { + if (keyUsage == null) { + return true; + } + boolean[] certKeyUsage = xcert.getKeyUsage(); + if (certKeyUsage != null) { + for (int keyBit = 0; keyBit < keyUsage.length; keyBit++) { + if (keyUsage[keyBit] && + ((keyBit >= certKeyUsage.length) || !certKeyUsage[keyBit])) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "key usage bits don't match"); + } + return false; + } + } + } + return true; + } + + /* match on extended key usage purpose OIDs */ + private boolean matchExtendedKeyUsage(X509Certificate xcert) { + if ((keyPurposeSet == null) || keyPurposeSet.isEmpty()) { + return true; + } + try { + ExtendedKeyUsageExtension ext = + (ExtendedKeyUsageExtension)getExtensionObject(xcert, + EXTENDED_KEY_USAGE_ID); + if (ext != null) { + Vector certKeyPurposeVector = + ext.get(ExtendedKeyUsageExtension.USAGES); + if (!certKeyPurposeVector.contains(ANY_EXTENDED_KEY_USAGE) + && !certKeyPurposeVector.containsAll(keyPurposeOIDSet)) { + if (debug != null) { + debug.println("X509CertSelector.match: cert failed " + + "extendedKeyUsage criterion"); + } + return false; + } + } + } catch (IOException ex) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "IOException in extended key usage check"); + } + return false; + } + return true; + } + + /* match on subject alternative name extension names */ + private boolean matchSubjectAlternativeNames(X509Certificate xcert) { + if ((subjectAlternativeNames == null) || subjectAlternativeNames.isEmpty()) { + return true; + } + try { + SubjectAlternativeNameExtension sanExt = + (SubjectAlternativeNameExtension) getExtensionObject(xcert, + SUBJECT_ALT_NAME_ID); + if (sanExt == null) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "no subject alternative name extension"); + } + return false; + } + GeneralNames certNames = + sanExt.get(SubjectAlternativeNameExtension.SUBJECT_NAME); + Iterator i = + subjectAlternativeGeneralNames.iterator(); + while (i.hasNext()) { + GeneralNameInterface matchName = i.next(); + boolean found = false; + for (Iterator t = certNames.iterator(); + t.hasNext() && !found; ) { + GeneralNameInterface certName = (t.next()).getName(); + found = certName.equals(matchName); + } + if (!found && (matchAllSubjectAltNames || !i.hasNext())) { + if (debug != null) { + debug.println("X509CertSelector.match: subject alternative " + + "name " + matchName + " not found"); + } + return false; + } else if (found && !matchAllSubjectAltNames) { + break; + } + } + } catch (IOException ex) { + if (debug != null) + debug.println("X509CertSelector.match: IOException in subject " + + "alternative name check"); + return false; + } + return true; + } + + /* match on name constraints */ + private boolean matchNameConstraints(X509Certificate xcert) { + if (nc == null) { + return true; + } + try { + if (!nc.verify(xcert)) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "name constraints not satisfied"); + } + return false; + } + } catch (IOException e) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "IOException in name constraints check"); + } + return false; + } + return true; + } + + /* match on policy OIDs */ + private boolean matchPolicy(X509Certificate xcert) { + if (policy == null) { + return true; + } + try { + CertificatePoliciesExtension ext = (CertificatePoliciesExtension) + getExtensionObject(xcert, CERT_POLICIES_ID); + if (ext == null) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "no certificate policy extension"); + } + return false; + } + List policies = ext.get(CertificatePoliciesExtension.POLICIES); + /* + * Convert the Vector of PolicyInformation to a Vector + * of CertificatePolicyIds for easier comparison. + */ + List policyIDs = new ArrayList(policies.size()); + for (PolicyInformation info : policies) { + policyIDs.add(info.getPolicyIdentifier()); + } + if (policy != null) { + boolean foundOne = false; + /* + * if the user passes in an empty policy Set, then + * we just want to make sure that the candidate certificate + * has some policy OID in its CertPoliciesExtension + */ + if (policy.getCertPolicyIds().isEmpty()) { + if (policyIDs.isEmpty()) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "cert failed policyAny criterion"); + } + return false; + } + } else { + for (CertificatePolicyId id : policy.getCertPolicyIds()) { + if (policyIDs.contains(id)) { + foundOne = true; + break; + } + } + if (!foundOne) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "cert failed policyAny criterion"); + } + return false; + } + } + } + } catch (IOException ex) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "IOException in certificate policy ID check"); + } + return false; + } + return true; + } + + /* match on pathToNames */ + private boolean matchPathToNames(X509Certificate xcert) { + if (pathToGeneralNames == null) { + return true; + } + try { + NameConstraintsExtension ext = (NameConstraintsExtension) + getExtensionObject(xcert, NAME_CONSTRAINTS_ID); + if (ext == null) { + return true; + } + if ((debug != null) && Debug.isOn("certpath")) { + debug.println("X509CertSelector.match pathToNames:\n"); + Iterator i = + pathToGeneralNames.iterator(); + while (i.hasNext()) { + debug.println(" " + i.next() + "\n"); + } + } + + GeneralSubtrees permitted = + ext.get(NameConstraintsExtension.PERMITTED_SUBTREES); + GeneralSubtrees excluded = + ext.get(NameConstraintsExtension.EXCLUDED_SUBTREES); + if (excluded != null) { + if (matchExcluded(excluded) == false) { + return false; + } + } + if (permitted != null) { + if (matchPermitted(permitted) == false) { + return false; + } + } + } catch (IOException ex) { + if (debug != null) { + debug.println("X509CertSelector.match: " + + "IOException in name constraints check"); + } + return false; + } + return true; + } + + private boolean matchExcluded(GeneralSubtrees excluded) { + /* + * Enumerate through excluded and compare each entry + * to all pathToNames. If any pathToName is within any of the + * subtrees listed in excluded, return false. + */ + for (Iterator t = excluded.iterator(); t.hasNext(); ) { + GeneralSubtree tree = t.next(); + GeneralNameInterface excludedName = tree.getName().getName(); + Iterator i = pathToGeneralNames.iterator(); + while (i.hasNext()) { + GeneralNameInterface pathToName = i.next(); + if (excludedName.getType() == pathToName.getType()) { + switch (pathToName.constrains(excludedName)) { + case GeneralNameInterface.NAME_WIDENS: + case GeneralNameInterface.NAME_MATCH: + if (debug != null) { + debug.println("X509CertSelector.match: name constraints " + + "inhibit path to specified name"); + debug.println("X509CertSelector.match: excluded name: " + + pathToName); + } + return false; + default: + } + } + } + } + return true; + } + + private boolean matchPermitted(GeneralSubtrees permitted) { + /* + * Enumerate through pathToNames, checking that each pathToName + * is in at least one of the subtrees listed in permitted. + * If not, return false. However, if no subtrees of a given type + * are listed, all names of that type are permitted. + */ + Iterator i = pathToGeneralNames.iterator(); + while (i.hasNext()) { + GeneralNameInterface pathToName = i.next(); + Iterator t = permitted.iterator(); + boolean permittedNameFound = false; + boolean nameTypeFound = false; + String names = ""; + while (t.hasNext() && !permittedNameFound) { + GeneralSubtree tree = t.next(); + GeneralNameInterface permittedName = tree.getName().getName(); + if (permittedName.getType() == pathToName.getType()) { + nameTypeFound = true; + names = names + " " + permittedName; + switch (pathToName.constrains(permittedName)) { + case GeneralNameInterface.NAME_WIDENS: + case GeneralNameInterface.NAME_MATCH: + permittedNameFound = true; + break; + default: + } + } + } + if (!permittedNameFound && nameTypeFound) { + if (debug != null) + debug.println("X509CertSelector.match: " + + "name constraints inhibit path to specified name; " + + "permitted names of type " + pathToName.getType() + + ": " + names); + return false; + } + } + return true; + } + + /* match on basic constraints */ + private boolean matchBasicConstraints(X509Certificate xcert) { + if (basicConstraints == -1) { + return true; + } + int maxPathLen = xcert.getBasicConstraints(); + if (basicConstraints == -2) { + if (maxPathLen != -1) { + if (debug != null) { + debug.println("X509CertSelector.match: not an EE cert"); + } + return false; + } + } else { + if (maxPathLen < basicConstraints) { + if (debug != null) { + debug.println("X509CertSelector.match: cert's maxPathLen " + + "is less than the min maxPathLen set by " + + "basicConstraints. " + + "(" + maxPathLen + " < " + basicConstraints + ")"); + } + return false; + } + } + return true; + } + + @SuppressWarnings("unchecked") // Safe casts assuming clone() works correctly + private static Set cloneSet(Set set) { + if (set instanceof HashSet) { + Object clone = ((HashSet)set).clone(); + return (Set)clone; + } else { + return new HashSet(set); + } + } + + /** + * Returns a copy of this object. + * + * @return the copy + */ + public Object clone() { + try { + X509CertSelector copy = (X509CertSelector)super.clone(); + // Must clone these because addPathToName et al. modify them + if (subjectAlternativeNames != null) { + copy.subjectAlternativeNames = + cloneSet(subjectAlternativeNames); + copy.subjectAlternativeGeneralNames = + cloneSet(subjectAlternativeGeneralNames); + } + if (pathToGeneralNames != null) { + copy.pathToNames = cloneSet(pathToNames); + copy.pathToGeneralNames = cloneSet(pathToGeneralNames); + } + return copy; + } catch (CloneNotSupportedException e) { + /* Cannot happen */ + throw new InternalError(e.toString(), e); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/X509Certificate.java b/sources/net.sf.j2s.java.core/src/java/security/cert/X509Certificate.java new file mode 100644 index 000000000..0aba5da60 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/X509Certificate.java @@ -0,0 +1,678 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +import java.math.BigInteger; +import java.security.*; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import javax.security.auth.x500.X500Principal; + +import sun.security.x509.X509CertImpl; + +/** + *

+ * Abstract class for X.509 certificates. This provides a standard + * way to access all the attributes of an X.509 certificate. + *

+ * In June of 1996, the basic X.509 v3 format was completed by + * ISO/IEC and ANSI X9, which is described below in ASN.1: + *

+ * Certificate  ::=  SEQUENCE  {
+ *     tbsCertificate       TBSCertificate,
+ *     signatureAlgorithm   AlgorithmIdentifier,
+ *     signature            BIT STRING  }
+ * 
+ *

+ * These certificates are widely used to support authentication and + * other functionality in Internet security systems. Common applications + * include Privacy Enhanced Mail (PEM), Transport Layer Security (SSL), + * code signing for trusted software distribution, and Secure Electronic + * Transactions (SET). + *

+ * These certificates are managed and vouched for by Certificate + * Authorities (CAs). CAs are services which create certificates by + * placing data in the X.509 standard format and then digitally signing + * that data. CAs act as trusted third parties, making introductions + * between principals who have no direct knowledge of each other. + * CA certificates are either signed by themselves, or by some other + * CA such as a "root" CA. + *

+ * More information can be found in + * RFC 3280: Internet X.509 + * Public Key Infrastructure Certificate and CRL Profile. + *

+ * The ASN.1 definition of {@code tbsCertificate} is: + *

+ * TBSCertificate  ::=  SEQUENCE  {
+ *     version         [0]  EXPLICIT Version DEFAULT v1,
+ *     serialNumber         CertificateSerialNumber,
+ *     signature            AlgorithmIdentifier,
+ *     issuer               Name,
+ *     validity             Validity,
+ *     subject              Name,
+ *     subjectPublicKeyInfo SubjectPublicKeyInfo,
+ *     issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
+ *                          -- If present, version must be v2 or v3
+ *     subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
+ *                          -- If present, version must be v2 or v3
+ *     extensions      [3]  EXPLICIT Extensions OPTIONAL
+ *                          -- If present, version must be v3
+ *     }
+ * 
+ *

+ * Certificates are instantiated using a certificate factory. The following is + * an example of how to instantiate an X.509 certificate: + *

+ * try (InputStream inStream = new FileInputStream("fileName-of-cert")) {
+ *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
+ *     X509Certificate cert = (X509Certificate)cf.generateCertificate(inStream);
+ * }
+ * 
+ * + * @author Hemma Prafullchandra + * + * + * @see Certificate + * @see CertificateFactory + * @see X509Extension + */ + +public abstract class X509Certificate extends Certificate +implements X509Extension { + + private static final long serialVersionUID = -2491127588187038216L; + + private transient X500Principal subjectX500Principal, issuerX500Principal; + + /** + * Constructor for X.509 certificates. + */ + protected X509Certificate() { + super("X.509"); + } + + /** + * Checks that the certificate is currently valid. It is if + * the current date and time are within the validity period given in the + * certificate. + *

+ * The validity period consists of two date/time values: + * the first and last dates (and times) on which the certificate + * is valid. It is defined in + * ASN.1 as: + *

+     * validity             Validity
+     *
+     * Validity ::= SEQUENCE {
+     *     notBefore      CertificateValidityDate,
+     *     notAfter       CertificateValidityDate }
+     *
+     * CertificateValidityDate ::= CHOICE {
+     *     utcTime        UTCTime,
+     *     generalTime    GeneralizedTime }
+     * 
+ * + * @exception CertificateExpiredException if the certificate has expired. + * @exception CertificateNotYetValidException if the certificate is not + * yet valid. + */ + public abstract void checkValidity() + throws CertificateExpiredException, CertificateNotYetValidException; + + /** + * Checks that the given date is within the certificate's + * validity period. In other words, this determines whether the + * certificate would be valid at the given date/time. + * + * @param date the Date to check against to see if this certificate + * is valid at that date/time. + * + * @exception CertificateExpiredException if the certificate has expired + * with respect to the {@code date} supplied. + * @exception CertificateNotYetValidException if the certificate is not + * yet valid with respect to the {@code date} supplied. + * + * @see #checkValidity() + */ + public abstract void checkValidity(Date date) + throws CertificateExpiredException, CertificateNotYetValidException; + + /** + * Gets the {@code version} (version number) value from the + * certificate. + * The ASN.1 definition for this is: + *
+     * version  [0] EXPLICIT Version DEFAULT v1
+     *
+     * Version ::=  INTEGER  {  v1(0), v2(1), v3(2)  }
+     * 
+ * @return the version number, i.e. 1, 2 or 3. + */ + public abstract int getVersion(); + + /** + * Gets the {@code serialNumber} value from the certificate. + * The serial number is an integer assigned by the certification + * authority to each certificate. It must be unique for each + * certificate issued by a given CA (i.e., the issuer name and + * serial number identify a unique certificate). + * The ASN.1 definition for this is: + *
+     * serialNumber     CertificateSerialNumber
+     *
+     * CertificateSerialNumber  ::=  INTEGER
+     * 
+ * + * @return the serial number. + */ + public abstract BigInteger getSerialNumber(); + + /** + * Denigrated, replaced by {@linkplain + * #getIssuerX500Principal()}. This method returns the {@code issuer} + * as an implementation specific Principal object, which should not be + * relied upon by portable code. + * + *

+ * Gets the {@code issuer} (issuer distinguished name) value from + * the certificate. The issuer name identifies the entity that signed (and + * issued) the certificate. + * + *

The issuer name field contains an + * X.500 distinguished name (DN). + * The ASN.1 definition for this is: + *

+     * issuer    Name
+     *
+     * Name ::= CHOICE { RDNSequence }
+     * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
+     * RelativeDistinguishedName ::=
+     *     SET OF AttributeValueAssertion
+     *
+     * AttributeValueAssertion ::= SEQUENCE {
+     *                               AttributeType,
+     *                               AttributeValue }
+     * AttributeType ::= OBJECT IDENTIFIER
+     * AttributeValue ::= ANY
+     * 
+ * The {@code Name} describes a hierarchical name composed of + * attributes, + * such as country name, and corresponding values, such as US. + * The type of the {@code AttributeValue} component is determined by + * the {@code AttributeType}; in general it will be a + * {@code directoryString}. A {@code directoryString} is usually + * one of {@code PrintableString}, + * {@code TeletexString} or {@code UniversalString}. + * + * @return a Principal whose name is the issuer distinguished name. + */ + public abstract Principal getIssuerDN(); + + /** + * Returns the issuer (issuer distinguished name) value from the + * certificate as an {@code X500Principal}. + *

+ * It is recommended that subclasses override this method. + * + * @return an {@code X500Principal} representing the issuer + * distinguished name + * @since 1.4 + */ + public X500Principal getIssuerX500Principal() { + if (issuerX500Principal == null) { + issuerX500Principal = X509CertImpl.getIssuerX500Principal(this); + } + return issuerX500Principal; + } + + /** + * Denigrated, replaced by {@linkplain + * #getSubjectX500Principal()}. This method returns the {@code subject} + * as an implementation specific Principal object, which should not be + * relied upon by portable code. + * + *

+ * Gets the {@code subject} (subject distinguished name) value + * from the certificate. If the {@code subject} value is empty, + * then the {@code getName()} method of the returned + * {@code Principal} object returns an empty string (""). + * + *

The ASN.1 definition for this is: + *

+     * subject    Name
+     * 
+ * + *

See {@link #getIssuerDN() getIssuerDN} for {@code Name} + * and other relevant definitions. + * + * @return a Principal whose name is the subject name. + */ + public abstract Principal getSubjectDN(); + + /** + * Returns the subject (subject distinguished name) value from the + * certificate as an {@code X500Principal}. If the subject value + * is empty, then the {@code getName()} method of the returned + * {@code X500Principal} object returns an empty string (""). + *

+ * It is recommended that subclasses override this method. + * + * @return an {@code X500Principal} representing the subject + * distinguished name + * @since 1.4 + */ + public X500Principal getSubjectX500Principal() { + if (subjectX500Principal == null) { + subjectX500Principal = X509CertImpl.getSubjectX500Principal(this); + } + return subjectX500Principal; + } + + /** + * Gets the {@code notBefore} date from the validity period of + * the certificate. + * The relevant ASN.1 definitions are: + *

+     * validity             Validity
+     *
+     * Validity ::= SEQUENCE {
+     *     notBefore      CertificateValidityDate,
+     *     notAfter       CertificateValidityDate }
+     *
+     * CertificateValidityDate ::= CHOICE {
+     *     utcTime        UTCTime,
+     *     generalTime    GeneralizedTime }
+     * 
+ * + * @return the start date of the validity period. + * @see #checkValidity + */ + public abstract Date getNotBefore(); + + /** + * Gets the {@code notAfter} date from the validity period of + * the certificate. See {@link #getNotBefore() getNotBefore} + * for relevant ASN.1 definitions. + * + * @return the end date of the validity period. + * @see #checkValidity + */ + public abstract Date getNotAfter(); + + /** + * Gets the DER-encoded certificate information, the + * {@code tbsCertificate} from this certificate. + * This can be used to verify the signature independently. + * + * @return the DER-encoded certificate information. + * @exception CertificateEncodingException if an encoding error occurs. + */ + public abstract byte[] getTBSCertificate() + throws CertificateEncodingException; + + /** + * Gets the {@code signature} value (the raw signature bits) from + * the certificate. + * The ASN.1 definition for this is: + *
+     * signature     BIT STRING
+     * 
+ * + * @return the signature. + */ + public abstract byte[] getSignature(); + + /** + * Gets the signature algorithm name for the certificate + * signature algorithm. An example is the string "SHA256withRSA". + * The ASN.1 definition for this is: + *
+     * signatureAlgorithm   AlgorithmIdentifier
+     *
+     * AlgorithmIdentifier  ::=  SEQUENCE  {
+     *     algorithm               OBJECT IDENTIFIER,
+     *     parameters              ANY DEFINED BY algorithm OPTIONAL  }
+     *                             -- contains a value of the type
+     *                             -- registered for use with the
+     *                             -- algorithm object identifier value
+     * 
+ * + *

The algorithm name is determined from the {@code algorithm} + * OID string. + * + * @return the signature algorithm name. + */ + public abstract String getSigAlgName(); + + /** + * Gets the signature algorithm OID string from the certificate. + * An OID is represented by a set of nonnegative whole numbers separated + * by periods. + * For example, the string "1.2.840.10040.4.3" identifies the SHA-1 + * with DSA signature algorithm defined in + * RFC 3279: Algorithms and + * Identifiers for the Internet X.509 Public Key Infrastructure Certificate + * and CRL Profile. + * + *

See {@link #getSigAlgName() getSigAlgName} for + * relevant ASN.1 definitions. + * + * @return the signature algorithm OID string. + */ + public abstract String getSigAlgOID(); + + /** + * Gets the DER-encoded signature algorithm parameters from this + * certificate's signature algorithm. In most cases, the signature + * algorithm parameters are null; the parameters are usually + * supplied with the certificate's public key. + * If access to individual parameter values is needed then use + * {@link java.security.AlgorithmParameters AlgorithmParameters} + * and instantiate with the name returned by + * {@link #getSigAlgName() getSigAlgName}. + * + *

See {@link #getSigAlgName() getSigAlgName} for + * relevant ASN.1 definitions. + * + * @return the DER-encoded signature algorithm parameters, or + * null if no parameters are present. + */ + public abstract byte[] getSigAlgParams(); + + /** + * Gets the {@code issuerUniqueID} value from the certificate. + * The issuer unique identifier is present in the certificate + * to handle the possibility of reuse of issuer names over time. + * RFC 3280 recommends that names not be reused and that + * conforming certificates not make use of unique identifiers. + * Applications conforming to that profile should be capable of + * parsing unique identifiers and making comparisons. + * + *

The ASN.1 definition for this is: + *

+     * issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL
+     *
+     * UniqueIdentifier  ::=  BIT STRING
+     * 
+ * + * @return the issuer unique identifier or null if it is not + * present in the certificate. + */ + public abstract boolean[] getIssuerUniqueID(); + + /** + * Gets the {@code subjectUniqueID} value from the certificate. + * + *

The ASN.1 definition for this is: + *

+     * subjectUniqueID  [2]  IMPLICIT UniqueIdentifier OPTIONAL
+     *
+     * UniqueIdentifier  ::=  BIT STRING
+     * 
+ * + * @return the subject unique identifier or null if it is not + * present in the certificate. + */ + public abstract boolean[] getSubjectUniqueID(); + + /** + * Gets a boolean array representing bits of + * the {@code KeyUsage} extension, (OID = 2.5.29.15). + * The key usage extension defines the purpose (e.g., encipherment, + * signature, certificate signing) of the key contained in the + * certificate. + * The ASN.1 definition for this is: + *
+     * KeyUsage ::= BIT STRING {
+     *     digitalSignature        (0),
+     *     nonRepudiation          (1),
+     *     keyEncipherment         (2),
+     *     dataEncipherment        (3),
+     *     keyAgreement            (4),
+     *     keyCertSign             (5),
+     *     cRLSign                 (6),
+     *     encipherOnly            (7),
+     *     decipherOnly            (8) }
+     * 
+ * RFC 3280 recommends that when used, this be marked + * as a critical extension. + * + * @return the KeyUsage extension of this certificate, represented as + * an array of booleans. The order of KeyUsage values in the array is + * the same as in the above ASN.1 definition. The array will contain a + * value for each KeyUsage defined above. If the KeyUsage list encoded + * in the certificate is longer than the above list, it will not be + * truncated. Returns null if this certificate does not + * contain a KeyUsage extension. + */ + public abstract boolean[] getKeyUsage(); + + /** + * Gets an unmodifiable list of Strings representing the OBJECT + * IDENTIFIERs of the {@code ExtKeyUsageSyntax} field of the + * extended key usage extension, (OID = 2.5.29.37). It indicates + * one or more purposes for which the certified public key may be + * used, in addition to or in place of the basic purposes + * indicated in the key usage extension field. The ASN.1 + * definition for this is: + *
+     * ExtKeyUsageSyntax ::= SEQUENCE SIZE (1..MAX) OF KeyPurposeId
+     *
+     * KeyPurposeId ::= OBJECT IDENTIFIER
+     * 
+ * + * Key purposes may be defined by any organization with a + * need. Object identifiers used to identify key purposes shall be + * assigned in accordance with IANA or ITU-T Rec. X.660 | + * ISO/IEC/ITU 9834-1. + *

+ * This method was added to version 1.4 of the Java 2 Platform Standard + * Edition. In order to maintain backwards compatibility with existing + * service providers, this method is not {@code abstract} + * and it provides a default implementation. Subclasses + * should override this method with a correct implementation. + * + * @return the ExtendedKeyUsage extension of this certificate, + * as an unmodifiable list of object identifiers represented + * as Strings. Returns null if this certificate does not + * contain an ExtendedKeyUsage extension. + * @throws CertificateParsingException if the extension cannot be decoded + * @since 1.4 + */ + public List getExtendedKeyUsage() throws CertificateParsingException { + return X509CertImpl.getExtendedKeyUsage(this); + } + + /** + * Gets the certificate constraints path length from the + * critical {@code BasicConstraints} extension, (OID = 2.5.29.19). + *

+ * The basic constraints extension identifies whether the subject + * of the certificate is a Certificate Authority (CA) and + * how deep a certification path may exist through that CA. The + * {@code pathLenConstraint} field (see below) is meaningful + * only if {@code cA} is set to TRUE. In this case, it gives the + * maximum number of CA certificates that may follow this certificate in a + * certification path. A value of zero indicates that only an end-entity + * certificate may follow in the path. + *

+ * The ASN.1 definition for this is: + *

+     * BasicConstraints ::= SEQUENCE {
+     *     cA                  BOOLEAN DEFAULT FALSE,
+     *     pathLenConstraint   INTEGER (0..MAX) OPTIONAL }
+     * 
+ * + * @return the value of {@code pathLenConstraint} if the + * BasicConstraints extension is present in the certificate and the + * subject of the certificate is a CA, otherwise -1. + * If the subject of the certificate is a CA and + * {@code pathLenConstraint} does not appear, + * {@code Integer.MAX_VALUE} is returned to indicate that there is no + * limit to the allowed length of the certification path. + */ + public abstract int getBasicConstraints(); + + /** + * Gets an immutable collection of subject alternative names from the + * {@code SubjectAltName} extension, (OID = 2.5.29.17). + *

+ * The ASN.1 definition of the {@code SubjectAltName} extension is: + *

+     * SubjectAltName ::= GeneralNames
+     *
+     * GeneralNames :: = SEQUENCE SIZE (1..MAX) OF GeneralName
+     *
+     * GeneralName ::= CHOICE {
+     *      otherName                       [0]     OtherName,
+     *      rfc822Name                      [1]     IA5String,
+     *      dNSName                         [2]     IA5String,
+     *      x400Address                     [3]     ORAddress,
+     *      directoryName                   [4]     Name,
+     *      ediPartyName                    [5]     EDIPartyName,
+     *      uniformResourceIdentifier       [6]     IA5String,
+     *      iPAddress                       [7]     OCTET STRING,
+     *      registeredID                    [8]     OBJECT IDENTIFIER}
+     * 
+ *

+ * If this certificate does not contain a {@code SubjectAltName} + * extension, {@code null} is returned. Otherwise, a + * {@code Collection} is returned with an entry representing each + * {@code GeneralName} included in the extension. Each entry is a + * {@code List} whose first entry is an {@code Integer} + * (the name type, 0-8) and whose second entry is a {@code String} + * or a byte array (the name, in string or ASN.1 DER encoded form, + * respectively). + *

+ * RFC 822, DNS, and URI + * names are returned as {@code String}s, + * using the well-established string formats for those types (subject to + * the restrictions included in RFC 3280). IPv4 address names are + * returned using dotted quad notation. IPv6 address names are returned + * in the form "a1:a2:...:a8", where a1-a8 are hexadecimal values + * representing the eight 16-bit pieces of the address. OID names are + * returned as {@code String}s represented as a series of nonnegative + * integers separated by periods. And directory names (distinguished names) + * are returned in + * RFC 2253 string format. No standard string format is + * defined for otherNames, X.400 names, EDI party names, or any + * other type of names. They are returned as byte arrays + * containing the ASN.1 DER encoded form of the name. + *

+ * Note that the {@code Collection} returned may contain more + * than one name of the same type. Also, note that the returned + * {@code Collection} is immutable and any entries containing byte + * arrays are cloned to protect against subsequent modifications. + *

+ * This method was added to version 1.4 of the Java 2 Platform Standard + * Edition. In order to maintain backwards compatibility with existing + * service providers, this method is not {@code abstract} + * and it provides a default implementation. Subclasses + * should override this method with a correct implementation. + * + * @return an immutable {@code Collection} of subject alternative + * names (or {@code null}) + * @throws CertificateParsingException if the extension cannot be decoded + * @since 1.4 + */ + public Collection> getSubjectAlternativeNames() + throws CertificateParsingException { + return X509CertImpl.getSubjectAlternativeNames(this); + } + + /** + * Gets an immutable collection of issuer alternative names from the + * {@code IssuerAltName} extension, (OID = 2.5.29.18). + *

+ * The ASN.1 definition of the {@code IssuerAltName} extension is: + *

+     * IssuerAltName ::= GeneralNames
+     * 
+ * The ASN.1 definition of {@code GeneralNames} is defined + * in {@link #getSubjectAlternativeNames getSubjectAlternativeNames}. + *

+ * If this certificate does not contain an {@code IssuerAltName} + * extension, {@code null} is returned. Otherwise, a + * {@code Collection} is returned with an entry representing each + * {@code GeneralName} included in the extension. Each entry is a + * {@code List} whose first entry is an {@code Integer} + * (the name type, 0-8) and whose second entry is a {@code String} + * or a byte array (the name, in string or ASN.1 DER encoded form, + * respectively). For more details about the formats used for each + * name type, see the {@code getSubjectAlternativeNames} method. + *

+ * Note that the {@code Collection} returned may contain more + * than one name of the same type. Also, note that the returned + * {@code Collection} is immutable and any entries containing byte + * arrays are cloned to protect against subsequent modifications. + *

+ * This method was added to version 1.4 of the Java 2 Platform Standard + * Edition. In order to maintain backwards compatibility with existing + * service providers, this method is not {@code abstract} + * and it provides a default implementation. Subclasses + * should override this method with a correct implementation. + * + * @return an immutable {@code Collection} of issuer alternative + * names (or {@code null}) + * @throws CertificateParsingException if the extension cannot be decoded + * @since 1.4 + */ + public Collection> getIssuerAlternativeNames() + throws CertificateParsingException { + return X509CertImpl.getIssuerAlternativeNames(this); + } + + /** + * Verifies that this certificate was signed using the + * private key that corresponds to the specified public key. + * This method uses the signature verification engine + * supplied by the specified provider. Note that the specified + * Provider object does not have to be registered in the provider list. + * + * This method was added to version 1.8 of the Java Platform Standard + * Edition. In order to maintain backwards compatibility with existing + * service providers, this method is not {@code abstract} + * and it provides a default implementation. + * + * @param key the PublicKey used to carry out the verification. + * @param sigProvider the signature provider. + * + * @exception NoSuchAlgorithmException on unsupported signature + * algorithms. + * @exception InvalidKeyException on incorrect key. + * @exception SignatureException on signature errors. + * @exception CertificateException on encoding errors. + * @exception UnsupportedOperationException if the method is not supported + * @since 1.8 + */ + public void verify(PublicKey key, Provider sigProvider) + throws CertificateException, NoSuchAlgorithmException, + InvalidKeyException, SignatureException { + X509CertImpl.verify(this, key, sigProvider); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/X509Extension.java b/sources/net.sf.j2s.java.core/src/java/security/cert/X509Extension.java new file mode 100644 index 000000000..03469606e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/X509Extension.java @@ -0,0 +1,186 @@ +/* + * Copyright (c) 1997, 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 java.security.cert; + +import java.util.Set; + +/** + * Interface for an X.509 extension. + * + *

The extensions defined for X.509 v3 + * {@link X509Certificate Certificates} and v2 + * {@link X509CRL CRLs} (Certificate Revocation + * Lists) provide methods + * for associating additional attributes with users or public keys, + * for managing the certification hierarchy, and for managing CRL + * distribution. The X.509 extensions format also allows communities + * to define private extensions to carry information unique to those + * communities. + * + *

Each extension in a certificate/CRL may be designated as + * critical or non-critical. A certificate/CRL-using system (an application + * validating a certificate/CRL) must reject the certificate/CRL if it + * encounters a critical extension it does not recognize. A non-critical + * extension may be ignored if it is not recognized. + *

+ * The ASN.1 definition for this is: + *

+ * Extensions  ::=  SEQUENCE SIZE (1..MAX) OF Extension
+ *
+ * Extension  ::=  SEQUENCE  {
+ *     extnId        OBJECT IDENTIFIER,
+ *     critical      BOOLEAN DEFAULT FALSE,
+ *     extnValue     OCTET STRING
+ *                   -- contains a DER encoding of a value
+ *                   -- of the type registered for use with
+ *                   -- the extnId object identifier value
+ * }
+ * 
+ * Since not all extensions are known, the {@code getExtensionValue} + * method returns the DER-encoded OCTET STRING of the + * extension value (i.e., the {@code extnValue}). This can then + * be handled by a Class that understands the extension. + * + * @author Hemma Prafullchandra + */ + +public interface X509Extension { + + /** + * Check if there is a critical extension that is not supported. + * + * @return {@code true} if a critical extension is found that is + * not supported, otherwise {@code false}. + */ + public boolean hasUnsupportedCriticalExtension(); + + /** + * Gets a Set of the OID strings for the extension(s) marked + * CRITICAL in the certificate/CRL managed by the object + * implementing this interface. + * + * Here is sample code to get a Set of critical extensions from an + * X509Certificate and print the OIDs: + *
{@code
+     * X509Certificate cert = null;
+     * try (InputStream inStrm = new FileInputStream("DER-encoded-Cert")) {
+     *     CertificateFactory cf = CertificateFactory.getInstance("X.509");
+     *     cert = (X509Certificate)cf.generateCertificate(inStrm);
+     * }
+     *
+     * Set critSet = cert.getCriticalExtensionOIDs();
+     * if (critSet != null && !critSet.isEmpty()) {
+     *     System.out.println("Set of critical extensions:");
+     *     for (String oid : critSet) {
+     *         System.out.println(oid);
+     *     }
+     * }
+     * }
+ * @return a Set (or an empty Set if none are marked critical) of + * the extension OID strings for extensions that are marked critical. + * If there are no extensions present at all, then this method returns + * null. + */ + public Set getCriticalExtensionOIDs(); + + /** + * Gets a Set of the OID strings for the extension(s) marked + * NON-CRITICAL in the certificate/CRL managed by the object + * implementing this interface. + * + * Here is sample code to get a Set of non-critical extensions from an + * X509CRL revoked certificate entry and print the OIDs: + *
{@code
+     * CertificateFactory cf = null;
+     * X509CRL crl = null;
+     * try (InputStream inStrm = new FileInputStream("DER-encoded-CRL")) {
+     *     cf = CertificateFactory.getInstance("X.509");
+     *     crl = (X509CRL)cf.generateCRL(inStrm);
+     * }
+     *
+     * byte[] certData = 
+     * ByteArrayInputStream bais = new ByteArrayInputStream(certData);
+     * X509Certificate cert = (X509Certificate)cf.generateCertificate(bais);
+     * X509CRLEntry badCert =
+     *              crl.getRevokedCertificate(cert.getSerialNumber());
+     *
+     * if (badCert != null) {
+     *     Set nonCritSet = badCert.getNonCriticalExtensionOIDs();
+     *     if (nonCritSet != null)
+     *         for (String oid : nonCritSet) {
+     *             System.out.println(oid);
+     *         }
+     * }
+     * }
+ * + * @return a Set (or an empty Set if none are marked non-critical) of + * the extension OID strings for extensions that are marked non-critical. + * If there are no extensions present at all, then this method returns + * null. + */ + public Set getNonCriticalExtensionOIDs(); + + /** + * Gets the DER-encoded OCTET string for the extension value + * (extnValue) identified by the passed-in {@code oid} + * String. + * The {@code oid} string is + * represented by a set of nonnegative whole numbers separated + * by periods. + * + *

For example:
+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
OID (Object Identifier)Extension Name
2.5.29.14SubjectKeyIdentifier
2.5.29.15KeyUsage
2.5.29.16PrivateKeyUsage
2.5.29.17SubjectAlternativeName
2.5.29.18IssuerAlternativeName
2.5.29.19BasicConstraints
2.5.29.30NameConstraints
2.5.29.33PolicyMappings
2.5.29.35AuthorityKeyIdentifier
2.5.29.36PolicyConstraints
+ * + * @param oid the Object Identifier value for the extension. + * @return the DER-encoded octet string of the extension value or + * null if it is not present. + */ + public byte[] getExtensionValue(String oid); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/cert/package-info.java b/sources/net.sf.j2s.java.core/src/java/security/cert/package-info.java new file mode 100644 index 000000000..58f5fb77e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/cert/package-info.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 1998, 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. + */ + +/** + * Provides classes and interfaces for parsing and managing + * certificates, certificate revocation lists (CRLs), and + * certification paths. It contains support for X.509 v3 + * certificates and X.509 v2 CRLs. + * + *

Package Specification

+ * + * + * + *

Related Documentation

+ * + * For information about X.509 certificates and CRLs, please see: + * + * + * @since 1.2 + */ +package java.security.cert; diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAKey.java new file mode 100644 index 000000000..d78b3e198 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAKey.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 1996, 1998, 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 java.security.interfaces; + +/** + * The interface to a DSA public or private key. DSA (Digital Signature + * Algorithm) is defined in NIST's FIPS-186. + * + * @see DSAParams + * @see java.security.Key + * @see java.security.Signature + * + * @author Benjamin Renaud + * @author Josh Bloch + */ +public interface DSAKey { + + /** + * Returns the DSA-specific key parameters. These parameters are + * never secret. + * + * @return the DSA-specific key parameters. + * + * @see DSAParams + */ + public DSAParams getParams(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAKeyPairGenerator.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAKeyPairGenerator.java new file mode 100644 index 000000000..e50cfd24c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAKeyPairGenerator.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 1997, 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 java.security.interfaces; + +import java.security.*; + +/** + * An interface to an object capable of generating DSA key pairs. + * + *

The {@code initialize} methods may each be called any number + * of times. If no {@code initialize} method is called on a + * DSAKeyPairGenerator, the default is to generate 1024-bit keys, using + * precomputed p, q and g parameters and an instance of SecureRandom as + * the random bit source. + * + *

Users wishing to indicate DSA-specific parameters, and to generate a key + * pair suitable for use with the DSA algorithm typically + * + *

    + * + *
  1. Get a key pair generator for the DSA algorithm by calling the + * KeyPairGenerator {@code getInstance} method with "DSA" + * as its argument. + * + *
  2. Initialize the generator by casting the result to a DSAKeyPairGenerator + * and calling one of the + * {@code initialize} methods from this DSAKeyPairGenerator interface. + * + *
  3. Generate a key pair by calling the {@code generateKeyPair} + * method from the KeyPairGenerator class. + * + *
+ * + *

Note: it is not always necessary to do do algorithm-specific + * initialization for a DSA key pair generator. That is, it is not always + * necessary to call an {@code initialize} method in this interface. + * Algorithm-independent initialization using the {@code initialize} method + * in the KeyPairGenerator + * interface is all that is needed when you accept defaults for algorithm-specific + * parameters. + * + *

Note: Some earlier implementations of this interface may not support + * larger sizes of DSA parameters such as 2048 and 3072-bit. + * + * @see java.security.KeyPairGenerator + */ +public interface DSAKeyPairGenerator { + + /** + * Initializes the key pair generator using the DSA family parameters + * (p,q and g) and an optional SecureRandom bit source. If a + * SecureRandom bit source is needed but not supplied, i.e. null, a + * default SecureRandom instance will be used. + * + * @param params the parameters to use to generate the keys. + * + * @param random the random bit source to use to generate key bits; + * can be null. + * + * @exception InvalidParameterException if the {@code params} + * value is invalid, null, or unsupported. + */ + public void initialize(DSAParams params, SecureRandom random) + throws InvalidParameterException; + + /** + * Initializes the key pair generator for a given modulus length + * (instead of parameters), and an optional SecureRandom bit source. + * If a SecureRandom bit source is needed but not supplied, i.e. + * null, a default SecureRandom instance will be used. + * + *

If {@code genParams} is true, this method generates new + * p, q and g parameters. If it is false, the method uses precomputed + * parameters for the modulus length requested. If there are no + * precomputed parameters for that modulus length, an exception will be + * thrown. It is guaranteed that there will always be + * default parameters for modulus lengths of 512 and 1024 bits. + * + * @param modlen the modulus length in bits. Valid values are any + * multiple of 64 between 512 and 1024, inclusive, 2048, and 3072. + * + * @param random the random bit source to use to generate key bits; + * can be null. + * + * @param genParams whether or not to generate new parameters for + * the modulus length requested. + * + * @exception InvalidParameterException if {@code modlen} is + * invalid, or unsupported, or if {@code genParams} is false and there + * are no precomputed parameters for the requested modulus length. + */ + public void initialize(int modlen, boolean genParams, SecureRandom random) + throws InvalidParameterException; +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAParams.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAParams.java new file mode 100644 index 000000000..8c46ed57e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAParams.java @@ -0,0 +1,64 @@ +/* + * Copyright (c) 1996, 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 java.security.interfaces; + +import java.math.BigInteger; + +/** + * Interface to a DSA-specific set of key parameters, which defines a + * DSA key family. DSA (Digital Signature Algorithm) is defined + * in NIST's FIPS-186. + * + * @see DSAKey + * @see java.security.Key + * @see java.security.Signature + * + * @author Benjamin Renaud + * @author Josh Bloch + */ +public interface DSAParams { + + /** + * Returns the prime, {@code p}. + * + * @return the prime, {@code p}. + */ + public BigInteger getP(); + + /** + * Returns the subprime, {@code q}. + * + * @return the subprime, {@code q}. + */ + public BigInteger getQ(); + + /** + * Returns the base, {@code g}. + * + * @return the base, {@code g}. + */ + public BigInteger getG(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAPrivateKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAPrivateKey.java new file mode 100644 index 000000000..81ab3586f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAPrivateKey.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1997, 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 java.security.interfaces; + +import java.math.BigInteger; + +/** + * The standard interface to a DSA private key. DSA (Digital Signature + * Algorithm) is defined in NIST's FIPS-186. + * + * @see java.security.Key + * @see java.security.Signature + * @see DSAKey + * @see DSAPublicKey + * + * @author Benjamin Renaud + */ +public interface DSAPrivateKey extends DSAKey, java.security.PrivateKey { + + // Declare serialVersionUID to be compatible with JDK1.1 + + /** + * The class fingerprint that is set to indicate + * serialization compatibility with a previous + * version of the class. + */ + static final long serialVersionUID = 7776497482533790279L; + + /** + * Returns the value of the private key, {@code x}. + * + * @return the value of the private key, {@code x}. + */ + public BigInteger getX(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAPublicKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAPublicKey.java new file mode 100644 index 000000000..e56b795ae --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/DSAPublicKey.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 1996, 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 java.security.interfaces; + +import java.math.BigInteger; + +/** + * The interface to a DSA public key. DSA (Digital Signature Algorithm) + * is defined in NIST's FIPS-186. + * + * @see java.security.Key + * @see java.security.Signature + * @see DSAKey + * @see DSAPrivateKey + * + * @author Benjamin Renaud + */ +public interface DSAPublicKey extends DSAKey, java.security.PublicKey { + + // Declare serialVersionUID to be compatible with JDK1.1 + + /** + * The class fingerprint that is set to indicate + * serialization compatibility with a previous + * version of the class. + */ + static final long serialVersionUID = 1234526332779022332L; + + /** + * Returns the value of the public key, {@code y}. + * + * @return the value of the public key, {@code y}. + */ + public BigInteger getY(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECKey.java new file mode 100644 index 000000000..dd4b9d19b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECKey.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2003, 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 java.security.interfaces; + +import java.security.spec.ECParameterSpec; + +/** + * The interface to an elliptic curve (EC) key. + * + * @author Valerie Peng + * + * @since 1.5 + */ +public interface ECKey { + /** + * Returns the domain parameters associated + * with this key. The domain parameters are + * either explicitly specified or implicitly + * created during key generation. + * @return the associated domain parameters. + */ + ECParameterSpec getParams(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECPrivateKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECPrivateKey.java new file mode 100644 index 000000000..0ccdc2d5c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECPrivateKey.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003, 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 java.security.interfaces; + +import java.math.BigInteger; +import java.security.PrivateKey; + +/** + * The interface to an elliptic curve (EC) private key. + * + * @author Valerie Peng + * + * + * @see PrivateKey + * @see ECKey + * + * @since 1.5 + */ +public interface ECPrivateKey extends PrivateKey, ECKey { + /** + * The class fingerprint that is set to indicate + * serialization compatibility. + */ + static final long serialVersionUID = -7896394956925609184L; + + /** + * Returns the private value S. + * @return the private value S. + */ + BigInteger getS(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECPublicKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECPublicKey.java new file mode 100644 index 000000000..6d16157e2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/ECPublicKey.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2003, 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 java.security.interfaces; + +import java.security.PublicKey; +import java.security.spec.ECPoint; + +/** + * The interface to an elliptic curve (EC) public key. + * + * @author Valerie Peng + * + * + * @see PublicKey + * @see ECKey + * @see java.security.spec.ECPoint + * + * @since 1.5 + */ +public interface ECPublicKey extends PublicKey, ECKey { + + /** + * The class fingerprint that is set to indicate + * serialization compatibility. + */ + static final long serialVersionUID = -3314988629879632826L; + + /** + * Returns the public point W. + * @return the public point W. + */ + ECPoint getW(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAKey.java new file mode 100644 index 000000000..67fbe2bf8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAKey.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 1999, 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 java.security.interfaces; + +import java.math.BigInteger; + +/** + * The interface to an RSA public or private key. + * + * @author Jan Luehe + * + * @see RSAPublicKey + * @see RSAPrivateKey + * + * @since 1.3 + */ + +public interface RSAKey { + + /** + * Returns the modulus. + * + * @return the modulus + */ + public BigInteger getModulus(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java new file mode 100644 index 000000000..f85d96a76 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAMultiPrimePrivateCrtKey.java @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2001, 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 java.security.interfaces; + +import java.math.BigInteger; +import java.security.spec.RSAOtherPrimeInfo; + +/** + * The interface to an RSA multi-prime private key, as defined in the + * PKCS#1 v2.1, using the Chinese Remainder Theorem + * (CRT) information values. + * + * @author Valerie Peng + * + * + * @see java.security.spec.RSAPrivateKeySpec + * @see java.security.spec.RSAMultiPrimePrivateCrtKeySpec + * @see RSAPrivateKey + * @see RSAPrivateCrtKey + * + * @since 1.4 + */ + +public interface RSAMultiPrimePrivateCrtKey extends RSAPrivateKey { + + /** + * The type fingerprint that is set to indicate + * serialization compatibility with a previous + * version of the type. + */ + static final long serialVersionUID = 618058533534628008L; + + /** + * Returns the public exponent. + * + * @return the public exponent. + */ + public BigInteger getPublicExponent(); + + /** + * Returns the primeP. + * + * @return the primeP. + */ + public BigInteger getPrimeP(); + + /** + * Returns the primeQ. + * + * @return the primeQ. + */ + public BigInteger getPrimeQ(); + + /** + * Returns the primeExponentP. + * + * @return the primeExponentP. + */ + public BigInteger getPrimeExponentP(); + + /** + * Returns the primeExponentQ. + * + * @return the primeExponentQ. + */ + public BigInteger getPrimeExponentQ(); + + /** + * Returns the crtCoefficient. + * + * @return the crtCoefficient. + */ + public BigInteger getCrtCoefficient(); + + /** + * Returns the otherPrimeInfo or null if there are only + * two prime factors (p and q). + * + * @return the otherPrimeInfo. + */ + public RSAOtherPrimeInfo[] getOtherPrimeInfo(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPrivateCrtKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPrivateCrtKey.java new file mode 100644 index 000000000..0408feabb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPrivateCrtKey.java @@ -0,0 +1,90 @@ +/* + * Copyright (c) 1998, 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 java.security.interfaces; + +import java.math.BigInteger; + +/** + * The interface to an RSA private key, as defined in the PKCS#1 standard, + * using the Chinese Remainder Theorem (CRT) information values. + * + * @author Jan Luehe + * + * + * @see RSAPrivateKey + */ + +public interface RSAPrivateCrtKey extends RSAPrivateKey { + + /** + * The type fingerprint that is set to indicate + * serialization compatibility with a previous + * version of the type. + */ + static final long serialVersionUID = -5682214253527700368L; + + /** + * Returns the public exponent. + * + * @return the public exponent + */ + public BigInteger getPublicExponent(); + + /** + * Returns the primeP. + + * @return the primeP + */ + public BigInteger getPrimeP(); + + /** + * Returns the primeQ. + * + * @return the primeQ + */ + public BigInteger getPrimeQ(); + + /** + * Returns the primeExponentP. + * + * @return the primeExponentP + */ + public BigInteger getPrimeExponentP(); + + /** + * Returns the primeExponentQ. + * + * @return the primeExponentQ + */ + public BigInteger getPrimeExponentQ(); + + /** + * Returns the crtCoefficient. + * + * @return the crtCoefficient + */ + public BigInteger getCrtCoefficient(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPrivateKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPrivateKey.java new file mode 100644 index 000000000..5d69ad683 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPrivateKey.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 1998, 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 java.security.interfaces; + +import java.math.BigInteger; + +/** + * The interface to an RSA private key. + * + * @author Jan Luehe + * + * + * @see RSAPrivateCrtKey + */ + +public interface RSAPrivateKey extends java.security.PrivateKey, RSAKey +{ + + /** + * The type fingerprint that is set to indicate + * serialization compatibility with a previous + * version of the type. + */ + static final long serialVersionUID = 5187144804936595022L; + + /** + * Returns the private exponent. + * + * @return the private exponent + */ + public BigInteger getPrivateExponent(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPublicKey.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPublicKey.java new file mode 100644 index 000000000..a698c05f7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/RSAPublicKey.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 1998, 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 java.security.interfaces; + +import java.math.BigInteger; + +/** + * The interface to an RSA public key. + * + * @author Jan Luehe + * + */ + +public interface RSAPublicKey extends java.security.PublicKey, RSAKey +{ + /** + * The type fingerprint that is set to indicate + * serialization compatibility with a previous + * version of the type. + */ + static final long serialVersionUID = -8727434096241101194L; + + /** + * Returns the public exponent. + * + * @return the public exponent + */ + public BigInteger getPublicExponent(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/interfaces/package-info.java b/sources/net.sf.j2s.java.core/src/java/security/interfaces/package-info.java new file mode 100644 index 000000000..54c9397e6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/interfaces/package-info.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 1998, 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. + */ + +/** + * Provides interfaces for generating RSA (Rivest, Shamir and + * Adleman AsymmetricCipher algorithm) + * keys as defined in the RSA Laboratory Technical Note + * PKCS#1, and DSA (Digital Signature + * Algorithm) keys as defined in NIST's FIPS-186. + *

+ * Note that these interfaces are intended only for key + * implementations whose key material is accessible and + * available. These interfaces are not intended for key + * implementations whose key material resides in + * inaccessible, protected storage (such as in a + * hardware device). + *

+ * For more developer information on how to use these + * interfaces, including information on how to design + * {@code Key} classes for hardware devices, please refer + * to these cryptographic provider developer guides: + *

+ * + *

Package Specification

+ * + *
    + *
  • PKCS #1: RSA Encryption Standard, Version 1.5, November 1993
  • + *
  • Federal Information Processing Standards Publication (FIPS PUB) 186: + * Digital Signature Standard (DSS)
  • + *
+ * + *

Related Documentation

+ * + * For further documentation, please see: + * + * + * @since JDK1.1 + */ +package java.security.interfaces; diff --git a/sources/net.sf.j2s.java.core/src/java/security/package-info.java b/sources/net.sf.j2s.java.core/src/java/security/package-info.java new file mode 100644 index 000000000..2c8205b09 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/package-info.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1998, 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. + */ + +/** + * Provides the classes and interfaces for the security framework. + * This includes classes that implement an easily configurable, + * fine-grained access control security architecture. + * This package also supports + * the generation and storage of cryptographic public key pairs, + * as well as a number of exportable cryptographic operations + * including those for message digest and signature generation. Finally, + * this package provides classes that support signed/guarded objects + * and secure random number generation. + * + * Many of the classes provided in this package (the cryptographic + * and secure random number generator classes in particular) are + * provider-based. The class itself defines a programming interface + * to which applications may write. The implementations themselves may + * then be written by independent third-party vendors and plugged + * in seamlessly as needed. Therefore application developers may + * take advantage of any number of provider-based implementations + * without having to add or rewrite code. + * + *

Package Specification

+ * + * + * + *

Related Documentation

+ * + * For further documentation, please see: + * + * + * @since 1.1 + */ +package java.security; diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/AlgorithmParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/AlgorithmParameterSpec.java new file mode 100644 index 000000000..7714c3021 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/AlgorithmParameterSpec.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 1997, 1999, 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 java.security.spec; + +/** + * A (transparent) specification of cryptographic parameters. + * + *

This interface contains no methods or constants. Its only purpose + * is to group (and provide type safety for) all parameter specifications. + * All parameter specifications must implement this interface. + * + * @author Jan Luehe + * + * + * @see java.security.AlgorithmParameters + * @see DSAParameterSpec + * + * @since 1.2 + */ + +public interface AlgorithmParameterSpec { } diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/DSAGenParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAGenParameterSpec.java new file mode 100644 index 000000000..932a9f05c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAGenParameterSpec.java @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2012, 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 java.security.spec; + +/** + * This immutable class specifies the set of parameters used for + * generating DSA parameters as specified in + * FIPS 186-3 Digital Signature Standard (DSS). + * + * @see AlgorithmParameterSpec + * + * @since 8 + */ +public final class DSAGenParameterSpec implements AlgorithmParameterSpec { + + private final int pLen; + private final int qLen; + private final int seedLen; + + /** + * Creates a domain parameter specification for DSA parameter + * generation using {@code primePLen} and {@code subprimeQLen}. + * The value of {@code subprimeQLen} is also used as the default + * length of the domain parameter seed in bits. + * @param primePLen the desired length of the prime P in bits. + * @param subprimeQLen the desired length of the sub-prime Q in bits. + * @exception IllegalArgumentException if {@code primePLen} + * or {@code subprimeQLen} is illegal per the specification of + * FIPS 186-3. + */ + public DSAGenParameterSpec(int primePLen, int subprimeQLen) { + this(primePLen, subprimeQLen, subprimeQLen); + } + + /** + * Creates a domain parameter specification for DSA parameter + * generation using {@code primePLen}, {@code subprimeQLen}, + * and {@code seedLen}. + * @param primePLen the desired length of the prime P in bits. + * @param subprimeQLen the desired length of the sub-prime Q in bits. + * @param seedLen the desired length of the domain parameter seed in bits, + * shall be equal to or greater than {@code subprimeQLen}. + * @exception IllegalArgumentException if {@code primePLenLen}, + * {@code subprimeQLen}, or {@code seedLen} is illegal per the + * specification of FIPS 186-3. + */ + public DSAGenParameterSpec(int primePLen, int subprimeQLen, int seedLen) { + switch (primePLen) { + case 1024: + if (subprimeQLen != 160) { + throw new IllegalArgumentException + ("subprimeQLen must be 160 when primePLen=1024"); + } + break; + case 2048: + if (subprimeQLen != 224 && subprimeQLen != 256) { + throw new IllegalArgumentException + ("subprimeQLen must be 224 or 256 when primePLen=2048"); + } + break; + case 3072: + if (subprimeQLen != 256) { + throw new IllegalArgumentException + ("subprimeQLen must be 256 when primePLen=3072"); + } + break; + default: + throw new IllegalArgumentException + ("primePLen must be 1024, 2048, or 3072"); + } + if (seedLen < subprimeQLen) { + throw new IllegalArgumentException + ("seedLen must be equal to or greater than subprimeQLen"); + } + this.pLen = primePLen; + this.qLen = subprimeQLen; + this.seedLen = seedLen; + } + + /** + * Returns the desired length of the prime P of the + * to-be-generated DSA domain parameters in bits. + * @return the length of the prime P. + */ + public int getPrimePLength() { + return pLen; + } + + /** + * Returns the desired length of the sub-prime Q of the + * to-be-generated DSA domain parameters in bits. + * @return the length of the sub-prime Q. + */ + public int getSubprimeQLength() { + return qLen; + } + + /** + * Returns the desired length of the domain parameter seed in bits. + * @return the length of the domain parameter seed. + */ + public int getSeedLength() { + return seedLen; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/DSAParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAParameterSpec.java new file mode 100644 index 000000000..eed6bdcae --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAParameterSpec.java @@ -0,0 +1,89 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class specifies the set of parameters used with the DSA algorithm. + * + * @author Jan Luehe + * + * + * @see AlgorithmParameterSpec + * + * @since 1.2 + */ + +public class DSAParameterSpec implements AlgorithmParameterSpec, +java.security.interfaces.DSAParams { + + BigInteger p; + BigInteger q; + BigInteger g; + + /** + * Creates a new DSAParameterSpec with the specified parameter values. + * + * @param p the prime. + * + * @param q the sub-prime. + * + * @param g the base. + */ + public DSAParameterSpec(BigInteger p, BigInteger q, BigInteger g) { + this.p = p; + this.q = q; + this.g = g; + } + + /** + * Returns the prime {@code p}. + * + * @return the prime {@code p}. + */ + public BigInteger getP() { + return this.p; + } + + /** + * Returns the sub-prime {@code q}. + * + * @return the sub-prime {@code q}. + */ + public BigInteger getQ() { + return this.q; + } + + /** + * Returns the base {@code g}. + * + * @return the base {@code g}. + */ + public BigInteger getG() { + return this.g; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/DSAPrivateKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAPrivateKeySpec.java new file mode 100644 index 000000000..a004de75d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAPrivateKeySpec.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class specifies a DSA private key with its associated parameters. + * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see DSAPublicKeySpec + * @see PKCS8EncodedKeySpec + * + * @since 1.2 + */ + +public class DSAPrivateKeySpec implements KeySpec { + + private BigInteger x; + private BigInteger p; + private BigInteger q; + private BigInteger g; + + /** + * Creates a new DSAPrivateKeySpec with the specified parameter values. + * + * @param x the private key. + * + * @param p the prime. + * + * @param q the sub-prime. + * + * @param g the base. + */ + public DSAPrivateKeySpec(BigInteger x, BigInteger p, BigInteger q, + BigInteger g) { + this.x = x; + this.p = p; + this.q = q; + this.g = g; + } + + /** + * Returns the private key {@code x}. + * + * @return the private key {@code x}. + */ + public BigInteger getX() { + return this.x; + } + + /** + * Returns the prime {@code p}. + * + * @return the prime {@code p}. + */ + public BigInteger getP() { + return this.p; + } + + /** + * Returns the sub-prime {@code q}. + * + * @return the sub-prime {@code q}. + */ + public BigInteger getQ() { + return this.q; + } + + /** + * Returns the base {@code g}. + * + * @return the base {@code g}. + */ + public BigInteger getG() { + return this.g; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/DSAPublicKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAPublicKeySpec.java new file mode 100644 index 000000000..a56e6f9c0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/DSAPublicKeySpec.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class specifies a DSA public key with its associated parameters. + * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see DSAPrivateKeySpec + * @see X509EncodedKeySpec + * + * @since 1.2 + */ + +public class DSAPublicKeySpec implements KeySpec { + + private BigInteger y; + private BigInteger p; + private BigInteger q; + private BigInteger g; + + /** + * Creates a new DSAPublicKeySpec with the specified parameter values. + * + * @param y the public key. + * + * @param p the prime. + * + * @param q the sub-prime. + * + * @param g the base. + */ + public DSAPublicKeySpec(BigInteger y, BigInteger p, BigInteger q, + BigInteger g) { + this.y = y; + this.p = p; + this.q = q; + this.g = g; + } + + /** + * Returns the public key {@code y}. + * + * @return the public key {@code y}. + */ + public BigInteger getY() { + return this.y; + } + + /** + * Returns the prime {@code p}. + * + * @return the prime {@code p}. + */ + public BigInteger getP() { + return this.p; + } + + /** + * Returns the sub-prime {@code q}. + * + * @return the sub-prime {@code q}. + */ + public BigInteger getQ() { + return this.q; + } + + /** + * Returns the base {@code g}. + * + * @return the base {@code g}. + */ + public BigInteger getG() { + return this.g; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECField.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECField.java new file mode 100644 index 000000000..6a42521be --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECField.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * This interface represents an elliptic curve (EC) finite field. + * All specialized EC fields must implements this interface. + * + * @see ECFieldFp + * @see ECFieldF2m + * + * @author Valerie Peng + * + * @since 1.5 + */ +public interface ECField { + /** + * Returns the field size in bits. Note: For prime finite + * field ECFieldFp, size of prime p in bits is returned. + * For characteristic 2 finite field ECFieldF2m, m is returned. + * @return the field size in bits. + */ + int getFieldSize(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECFieldF2m.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECFieldF2m.java new file mode 100644 index 000000000..4076fa6a3 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECFieldF2m.java @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * This immutable class defines an elliptic curve (EC) + * characteristic 2 finite field. + * + * @see ECField + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class ECFieldF2m implements ECField { + + private int m; + private int[] ks; + private BigInteger rp; + + /** + * Creates an elliptic curve characteristic 2 finite + * field which has 2^{@code m} elements with normal basis. + * @param m with 2^{@code m} being the number of elements. + * @exception IllegalArgumentException if {@code m} + * is not positive. + */ + public ECFieldF2m(int m) { + if (m <= 0) { + throw new IllegalArgumentException("m is not positive"); + } + this.m = m; + this.ks = null; + this.rp = null; + } + + /** + * Creates an elliptic curve characteristic 2 finite + * field which has 2^{@code m} elements with + * polynomial basis. + * The reduction polynomial for this field is based + * on {@code rp} whose i-th bit corresponds to + * the i-th coefficient of the reduction polynomial.

+ * Note: A valid reduction polynomial is either a + * trinomial (X^{@code m} + X^{@code k} + 1 + * with {@code m} > {@code k} >= 1) or a + * pentanomial (X^{@code m} + X^{@code k3} + * + X^{@code k2} + X^{@code k1} + 1 with + * {@code m} > {@code k3} > {@code k2} + * > {@code k1} >= 1). + * @param m with 2^{@code m} being the number of elements. + * @param rp the BigInteger whose i-th bit corresponds to + * the i-th coefficient of the reduction polynomial. + * @exception NullPointerException if {@code rp} is null. + * @exception IllegalArgumentException if {@code m} + * is not positive, or {@code rp} does not represent + * a valid reduction polynomial. + */ + public ECFieldF2m(int m, BigInteger rp) { + // check m and rp + this.m = m; + this.rp = rp; + if (m <= 0) { + throw new IllegalArgumentException("m is not positive"); + } + int bitCount = this.rp.bitCount(); + if (!this.rp.testBit(0) || !this.rp.testBit(m) || + ((bitCount != 3) && (bitCount != 5))) { + throw new IllegalArgumentException + ("rp does not represent a valid reduction polynomial"); + } + // convert rp into ks + BigInteger temp = this.rp.clearBit(0).clearBit(m); + this.ks = new int[bitCount-2]; + for (int i = this.ks.length-1; i >= 0; i--) { + int index = temp.getLowestSetBit(); + this.ks[i] = index; + temp = temp.clearBit(index); + } + } + + /** + * Creates an elliptic curve characteristic 2 finite + * field which has 2^{@code m} elements with + * polynomial basis. The reduction polynomial for this + * field is based on {@code ks} whose content + * contains the order of the middle term(s) of the + * reduction polynomial. + * Note: A valid reduction polynomial is either a + * trinomial (X^{@code m} + X^{@code k} + 1 + * with {@code m} > {@code k} >= 1) or a + * pentanomial (X^{@code m} + X^{@code k3} + * + X^{@code k2} + X^{@code k1} + 1 with + * {@code m} > {@code k3} > {@code k2} + * > {@code k1} >= 1), so {@code ks} should + * have length 1 or 3. + * @param m with 2^{@code m} being the number of elements. + * @param ks the order of the middle term(s) of the + * reduction polynomial. Contents of this array are copied + * to protect against subsequent modification. + * @exception NullPointerException if {@code ks} is null. + * @exception IllegalArgumentException if{@code m} + * is not positive, or the length of {@code ks} + * is neither 1 nor 3, or values in {@code ks} + * are not between {@code m}-1 and 1 (inclusive) + * and in descending order. + */ + public ECFieldF2m(int m, int[] ks) { + // check m and ks + this.m = m; + this.ks = ks.clone(); + if (m <= 0) { + throw new IllegalArgumentException("m is not positive"); + } + if ((this.ks.length != 1) && (this.ks.length != 3)) { + throw new IllegalArgumentException + ("length of ks is neither 1 nor 3"); + } + for (int i = 0; i < this.ks.length; i++) { + if ((this.ks[i] < 1) || (this.ks[i] > m-1)) { + throw new IllegalArgumentException + ("ks["+ i + "] is out of range"); + } + if ((i != 0) && (this.ks[i] >= this.ks[i-1])) { + throw new IllegalArgumentException + ("values in ks are not in descending order"); + } + } + // convert ks into rp + this.rp = BigInteger.ONE; + this.rp = rp.setBit(m); + for (int j = 0; j < this.ks.length; j++) { + rp = rp.setBit(this.ks[j]); + } + } + + /** + * Returns the field size in bits which is {@code m} + * for this characteristic 2 finite field. + * @return the field size in bits. + */ + public int getFieldSize() { + return m; + } + + /** + * Returns the value {@code m} of this characteristic + * 2 finite field. + * @return {@code m} with 2^{@code m} being the + * number of elements. + */ + public int getM() { + return m; + } + + /** + * Returns a BigInteger whose i-th bit corresponds to the + * i-th coefficient of the reduction polynomial for polynomial + * basis or null for normal basis. + * @return a BigInteger whose i-th bit corresponds to the + * i-th coefficient of the reduction polynomial for polynomial + * basis or null for normal basis. + */ + public BigInteger getReductionPolynomial() { + return rp; + } + + /** + * Returns an integer array which contains the order of the + * middle term(s) of the reduction polynomial for polynomial + * basis or null for normal basis. + * @return an integer array which contains the order of the + * middle term(s) of the reduction polynomial for polynomial + * basis or null for normal basis. A new array is returned + * each time this method is called. + */ + public int[] getMidTermsOfReductionPolynomial() { + if (ks == null) { + return null; + } else { + return ks.clone(); + } + } + + /** + * Compares this finite field for equality with the + * specified object. + * @param obj the object to be compared. + * @return true if {@code obj} is an instance + * of ECFieldF2m and both {@code m} and the reduction + * polynomial match, false otherwise. + */ + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj instanceof ECFieldF2m) { + // no need to compare rp here since ks and rp + // should be equivalent + return ((m == ((ECFieldF2m)obj).m) && + (Arrays.equals(ks, ((ECFieldF2m) obj).ks))); + } + return false; + } + + /** + * Returns a hash code value for this characteristic 2 + * finite field. + * @return a hash code value. + */ + public int hashCode() { + int value = m << 5; + value += (rp==null? 0:rp.hashCode()); + // no need to involve ks here since ks and rp + // should be equivalent. + return value; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECFieldFp.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECFieldFp.java new file mode 100644 index 000000000..c578962d3 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECFieldFp.java @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * This immutable class defines an elliptic curve (EC) prime + * finite field. + * + * @see ECField + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class ECFieldFp implements ECField { + + private BigInteger p; + + /** + * Creates an elliptic curve prime finite field + * with the specified prime {@code p}. + * @param p the prime. + * @exception NullPointerException if {@code p} is null. + * @exception IllegalArgumentException if {@code p} + * is not positive. + */ + public ECFieldFp(BigInteger p) { + if (p.signum() != 1) { + throw new IllegalArgumentException("p is not positive"); + } + this.p = p; + } + + /** + * Returns the field size in bits which is size of prime p + * for this prime finite field. + * @return the field size in bits. + */ + public int getFieldSize() { + return p.bitLength(); + }; + + /** + * Returns the prime {@code p} of this prime finite field. + * @return the prime. + */ + public BigInteger getP() { + return p; + } + + /** + * Compares this prime finite field for equality with the + * specified object. + * @param obj the object to be compared. + * @return true if {@code obj} is an instance + * of ECFieldFp and the prime value match, false otherwise. + */ + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj instanceof ECFieldFp) { + return (p.equals(((ECFieldFp)obj).p)); + } + return false; + } + + /** + * Returns a hash code value for this prime finite field. + * @return a hash code value. + */ + public int hashCode() { + return p.hashCode(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECGenParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECGenParameterSpec.java new file mode 100644 index 000000000..4f3f63b87 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECGenParameterSpec.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +/** + * This immutable class specifies the set of parameters used for + * generating elliptic curve (EC) domain parameters. + * + * @see AlgorithmParameterSpec + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class ECGenParameterSpec implements AlgorithmParameterSpec { + + private String name; + + /** + * Creates a parameter specification for EC parameter + * generation using a standard (or predefined) name + * {@code stdName} in order to generate the corresponding + * (precomputed) elliptic curve domain parameters. For the + * list of supported names, please consult the documentation + * of provider whose implementation will be used. + * @param stdName the standard name of the to-be-generated EC + * domain parameters. + * @exception NullPointerException if {@code stdName} + * is null. + */ + public ECGenParameterSpec(String stdName) { + if (stdName == null) { + throw new NullPointerException("stdName is null"); + } + this.name = stdName; + } + + /** + * Returns the standard or predefined name of the + * to-be-generated EC domain parameters. + * @return the standard or predefined name. + */ + public String getName() { + return name; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECParameterSpec.java new file mode 100644 index 000000000..3f7cae3b8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECParameterSpec.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This immutable class specifies the set of domain parameters + * used with elliptic curve cryptography (ECC). + * + * @see AlgorithmParameterSpec + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class ECParameterSpec implements AlgorithmParameterSpec { + + private final EllipticCurve curve; + private final ECPoint g; + private final BigInteger n; + private final int h; + + /** + * Creates elliptic curve domain parameters based on the + * specified values. + * @param curve the elliptic curve which this parameter + * defines. + * @param g the generator which is also known as the base point. + * @param n the order of the generator {@code g}. + * @param h the cofactor. + * @exception NullPointerException if {@code curve}, + * {@code g}, or {@code n} is null. + * @exception IllegalArgumentException if {@code n} + * or {@code h} is not positive. + */ + public ECParameterSpec(EllipticCurve curve, ECPoint g, + BigInteger n, int h) { + if (curve == null) { + throw new NullPointerException("curve is null"); + } + if (g == null) { + throw new NullPointerException("g is null"); + } + if (n == null) { + throw new NullPointerException("n is null"); + } + if (n.signum() != 1) { + throw new IllegalArgumentException("n is not positive"); + } + if (h <= 0) { + throw new IllegalArgumentException("h is not positive"); + } + this.curve = curve; + this.g = g; + this.n = n; + this.h = h; + } + + /** + * Returns the elliptic curve that this parameter defines. + * @return the elliptic curve that this parameter defines. + */ + public EllipticCurve getCurve() { + return curve; + } + + /** + * Returns the generator which is also known as the base point. + * @return the generator which is also known as the base point. + */ + public ECPoint getGenerator() { + return g; + } + + /** + * Returns the order of the generator. + * @return the order of the generator. + */ + public BigInteger getOrder() { + return n; + } + + /** + * Returns the cofactor. + * @return the cofactor. + */ + public int getCofactor() { + return h; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECPoint.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECPoint.java new file mode 100644 index 000000000..1b051c71a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECPoint.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This immutable class represents a point on an elliptic curve (EC) + * in affine coordinates. Other coordinate systems can + * extend this class to represent this point in other + * coordinates. + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class ECPoint { + + private final BigInteger x; + private final BigInteger y; + + /** + * This defines the point at infinity. + */ + public static final ECPoint POINT_INFINITY = new ECPoint(); + + // private constructor for constructing point at infinity + private ECPoint() { + this.x = null; + this.y = null; + } + + /** + * Creates an ECPoint from the specified affine x-coordinate + * {@code x} and affine y-coordinate {@code y}. + * @param x the affine x-coordinate. + * @param y the affine y-coordinate. + * @exception NullPointerException if {@code x} or + * {@code y} is null. + */ + public ECPoint(BigInteger x, BigInteger y) { + if ((x==null) || (y==null)) { + throw new NullPointerException("affine coordinate x or y is null"); + } + this.x = x; + this.y = y; + } + + /** + * Returns the affine x-coordinate {@code x}. + * Note: POINT_INFINITY has a null affine x-coordinate. + * @return the affine x-coordinate. + */ + public BigInteger getAffineX() { + return x; + } + + /** + * Returns the affine y-coordinate {@code y}. + * Note: POINT_INFINITY has a null affine y-coordinate. + * @return the affine y-coordinate. + */ + public BigInteger getAffineY() { + return y; + } + + /** + * Compares this elliptic curve point for equality with + * the specified object. + * @param obj the object to be compared. + * @return true if {@code obj} is an instance of + * ECPoint and the affine coordinates match, false otherwise. + */ + public boolean equals(Object obj) { + if (this == obj) return true; + if (this == POINT_INFINITY) return false; + if (obj instanceof ECPoint) { + return ((x.equals(((ECPoint)obj).x)) && + (y.equals(((ECPoint)obj).y))); + } + return false; + } + + /** + * Returns a hash code value for this elliptic curve point. + * @return a hash code value. + */ + public int hashCode() { + if (this == POINT_INFINITY) return 0; + return x.hashCode() << 5 + y.hashCode(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECPrivateKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECPrivateKeySpec.java new file mode 100644 index 000000000..7f03cfd49 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECPrivateKeySpec.java @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This immutable class specifies an elliptic curve private key with + * its associated parameters. + * + * @see KeySpec + * @see ECParameterSpec + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class ECPrivateKeySpec implements KeySpec { + + private BigInteger s; + private ECParameterSpec params; + + /** + * Creates a new ECPrivateKeySpec with the specified + * parameter values. + * @param s the private value. + * @param params the associated elliptic curve domain + * parameters. + * @exception NullPointerException if {@code s} + * or {@code params} is null. + */ + public ECPrivateKeySpec(BigInteger s, ECParameterSpec params) { + if (s == null) { + throw new NullPointerException("s is null"); + } + if (params == null) { + throw new NullPointerException("params is null"); + } + this.s = s; + this.params = params; + } + + /** + * Returns the private value S. + * @return the private value S. + */ + public BigInteger getS() { + return s; + } + + /** + * Returns the associated elliptic curve domain + * parameters. + * @return the EC domain parameters. + */ + public ECParameterSpec getParams() { + return params; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/ECPublicKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/ECPublicKeySpec.java new file mode 100644 index 000000000..e0cfb777c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/ECPublicKeySpec.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +/** + * This immutable class specifies an elliptic curve public key with + * its associated parameters. + * + * @see KeySpec + * @see ECPoint + * @see ECParameterSpec + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class ECPublicKeySpec implements KeySpec { + + private ECPoint w; + private ECParameterSpec params; + + /** + * Creates a new ECPublicKeySpec with the specified + * parameter values. + * @param w the public point. + * @param params the associated elliptic curve domain + * parameters. + * @exception NullPointerException if {@code w} + * or {@code params} is null. + * @exception IllegalArgumentException if {@code w} + * is point at infinity, i.e. ECPoint.POINT_INFINITY + */ + public ECPublicKeySpec(ECPoint w, ECParameterSpec params) { + if (w == null) { + throw new NullPointerException("w is null"); + } + if (params == null) { + throw new NullPointerException("params is null"); + } + if (w == ECPoint.POINT_INFINITY) { + throw new IllegalArgumentException("w is ECPoint.POINT_INFINITY"); + } + this.w = w; + this.params = params; + } + + /** + * Returns the public point W. + * @return the public point W. + */ + public ECPoint getW() { + return w; + } + + /** + * Returns the associated elliptic curve domain + * parameters. + * @return the EC domain parameters. + */ + public ECParameterSpec getParams() { + return params; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/EllipticCurve.java b/sources/net.sf.j2s.java.core/src/java/security/spec/EllipticCurve.java new file mode 100644 index 000000000..8ec97b05e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/EllipticCurve.java @@ -0,0 +1,196 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.math.BigInteger; +import java.util.Arrays; + +/** + * This immutable class holds the necessary values needed to represent + * an elliptic curve. + * + * @see ECField + * @see ECFieldFp + * @see ECFieldF2m + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class EllipticCurve { + + private final ECField field; + private final BigInteger a; + private final BigInteger b; + private final byte[] seed; + + // Check coefficient c is a valid element in ECField field. + private static void checkValidity(ECField field, BigInteger c, + String cName) { + // can only perform check if field is ECFieldFp or ECFieldF2m. + if (field instanceof ECFieldFp) { + BigInteger p = ((ECFieldFp)field).getP(); + if (p.compareTo(c) != 1) { + throw new IllegalArgumentException(cName + " is too large"); + } else if (c.signum() < 0) { + throw new IllegalArgumentException(cName + " is negative"); + } + } else if (field instanceof ECFieldF2m) { + int m = ((ECFieldF2m)field).getM(); + if (c.bitLength() > m) { + throw new IllegalArgumentException(cName + " is too large"); + } + } + } + + /** + * Creates an elliptic curve with the specified elliptic field + * {@code field} and the coefficients {@code a} and + * {@code b}. + * @param field the finite field that this elliptic curve is over. + * @param a the first coefficient of this elliptic curve. + * @param b the second coefficient of this elliptic curve. + * @exception NullPointerException if {@code field}, + * {@code a}, or {@code b} is null. + * @exception IllegalArgumentException if {@code a} + * or {@code b} is not null and not in {@code field}. + */ + public EllipticCurve(ECField field, BigInteger a, + BigInteger b) { + this(field, a, b, null); + } + + /** + * Creates an elliptic curve with the specified elliptic field + * {@code field}, the coefficients {@code a} and + * {@code b}, and the {@code seed} used for curve generation. + * @param field the finite field that this elliptic curve is over. + * @param a the first coefficient of this elliptic curve. + * @param b the second coefficient of this elliptic curve. + * @param seed the bytes used during curve generation for later + * validation. Contents of this array are copied to protect against + * subsequent modification. + * @exception NullPointerException if {@code field}, + * {@code a}, or {@code b} is null. + * @exception IllegalArgumentException if {@code a} + * or {@code b} is not null and not in {@code field}. + */ + public EllipticCurve(ECField field, BigInteger a, + BigInteger b, byte[] seed) { + if (field == null) { + throw new NullPointerException("field is null"); + } + if (a == null) { + throw new NullPointerException("first coefficient is null"); + } + if (b == null) { + throw new NullPointerException("second coefficient is null"); + } + checkValidity(field, a, "first coefficient"); + checkValidity(field, b, "second coefficient"); + this.field = field; + this.a = a; + this.b = b; + if (seed != null) { + this.seed = seed.clone(); + } else { + this.seed = null; + } + } + + /** + * Returns the finite field {@code field} that this + * elliptic curve is over. + * @return the field {@code field} that this curve + * is over. + */ + public ECField getField() { + return field; + } + + /** + * Returns the first coefficient {@code a} of the + * elliptic curve. + * @return the first coefficient {@code a}. + */ + public BigInteger getA() { + return a; + } + + /** + * Returns the second coefficient {@code b} of the + * elliptic curve. + * @return the second coefficient {@code b}. + */ + public BigInteger getB() { + return b; + } + + /** + * Returns the seeding bytes {@code seed} used + * during curve generation. May be null if not specified. + * @return the seeding bytes {@code seed}. A new + * array is returned each time this method is called. + */ + public byte[] getSeed() { + if (seed == null) return null; + else return seed.clone(); + } + + /** + * Compares this elliptic curve for equality with the + * specified object. + * @param obj the object to be compared. + * @return true if {@code obj} is an instance of + * EllipticCurve and the field, A, and B match, false otherwise. + */ + public boolean equals(Object obj) { + if (this == obj) return true; + if (obj instanceof EllipticCurve) { + EllipticCurve curve = (EllipticCurve) obj; + if ((field.equals(curve.field)) && + (a.equals(curve.a)) && + (b.equals(curve.b))) { + return true; + } + } + return false; + } + + /** + * Returns a hash code value for this elliptic curve. + * @return a hash code value computed from the hash codes of the field, A, + * and B, as follows: + *

{@code
+     *     (field.hashCode() << 6) + (a.hashCode() << 4) + (b.hashCode() << 2)
+     * }
+ */ + public int hashCode() { + return (field.hashCode() << 6 + + (a.hashCode() << 4) + + (b.hashCode() << 2)); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/EncodedKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/EncodedKeySpec.java new file mode 100644 index 000000000..cc3b81e6a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/EncodedKeySpec.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +/** + * This class represents a public or private key in encoded format. + * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see X509EncodedKeySpec + * @see PKCS8EncodedKeySpec + * + * @since 1.2 + */ + +public abstract class EncodedKeySpec implements KeySpec { + + private byte[] encodedKey; + + /** + * Creates a new EncodedKeySpec with the given encoded key. + * + * @param encodedKey the encoded key. The contents of the + * array are copied to protect against subsequent modification. + * @exception NullPointerException if {@code encodedKey} + * is null. + */ + public EncodedKeySpec(byte[] encodedKey) { + this.encodedKey = encodedKey.clone(); + } + + /** + * Returns the encoded key. + * + * @return the encoded key. Returns a new array each time + * this method is called. + */ + public byte[] getEncoded() { + return this.encodedKey.clone(); + } + + /** + * Returns the name of the encoding format associated with this + * key specification. + * + *

If the opaque representation of a key + * (see {@link java.security.Key Key}) can be transformed + * (see {@link java.security.KeyFactory KeyFactory}) + * into this key specification (or a subclass of it), + * {@code getFormat} called + * on the opaque key returns the same value as the + * {@code getFormat} method + * of this key specification. + * + * @return a string representation of the encoding format. + */ + public abstract String getFormat(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/InvalidKeySpecException.java b/sources/net.sf.j2s.java.core/src/java/security/spec/InvalidKeySpecException.java new file mode 100644 index 000000000..4655c4abe --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/InvalidKeySpecException.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +import java.security.GeneralSecurityException; + +/** + * This is the exception for invalid key specifications. + * + * @author Jan Luehe + * + * + * @see KeySpec + * + * @since 1.2 + */ + +public class InvalidKeySpecException extends GeneralSecurityException { + + private static final long serialVersionUID = 3546139293998810778L; + + /** + * Constructs an InvalidKeySpecException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public InvalidKeySpecException() { + super(); + } + + /** + * Constructs an InvalidKeySpecException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public InvalidKeySpecException(String msg) { + super(msg); + } + + /** + * Creates a {@code InvalidKeySpecException} with the specified + * detail message and cause. + * + * @param message the detail message (which is saved for later retrieval + * by the {@link #getMessage()} method). + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public InvalidKeySpecException(String message, Throwable cause) { + super(message, cause); + } + + /** + * Creates a {@code InvalidKeySpecException} with the specified cause + * and a detail message of {@code (cause==null ? null : cause.toString())} + * (which typically contains the class and detail message of + * {@code cause}). + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A {@code null} value is permitted, + * and indicates that the cause is nonexistent or unknown.) + * @since 1.5 + */ + public InvalidKeySpecException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/InvalidParameterSpecException.java b/sources/net.sf.j2s.java.core/src/java/security/spec/InvalidParameterSpecException.java new file mode 100644 index 000000000..3059c77b5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/InvalidParameterSpecException.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 1997, 2003, 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 java.security.spec; + +import java.security.GeneralSecurityException; + +/** + * This is the exception for invalid parameter specifications. + * + * @author Jan Luehe + * + * + * @see java.security.AlgorithmParameters + * @see AlgorithmParameterSpec + * @see DSAParameterSpec + * + * @since 1.2 + */ + +public class InvalidParameterSpecException extends GeneralSecurityException { + + private static final long serialVersionUID = -970468769593399342L; + + /** + * Constructs an InvalidParameterSpecException with no detail message. A + * detail message is a String that describes this particular + * exception. + */ + public InvalidParameterSpecException() { + super(); + } + + /** + * Constructs an InvalidParameterSpecException with the specified detail + * message. A detail message is a String that describes this + * particular exception. + * + * @param msg the detail message. + */ + public InvalidParameterSpecException(String msg) { + super(msg); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/KeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/KeySpec.java new file mode 100644 index 000000000..34fec5d31 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/KeySpec.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +/** + * A (transparent) specification of the key material + * that constitutes a cryptographic key. + * + *

If the key is stored on a hardware device, its + * specification may contain information that helps identify the key on the + * device. + * + *

A key may be specified in an algorithm-specific way, or in an + * algorithm-independent encoding format (such as ASN.1). + * For example, a DSA private key may be specified by its components + * {@code x}, {@code p}, {@code q}, and {@code g} + * (see {@link DSAPrivateKeySpec}), or it may be + * specified using its DER encoding + * (see {@link PKCS8EncodedKeySpec}). + * + *

This interface contains no methods or constants. Its only purpose + * is to group (and provide type safety for) all key specifications. + * All key specifications must implement this interface. + * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see EncodedKeySpec + * @see X509EncodedKeySpec + * @see PKCS8EncodedKeySpec + * @see DSAPrivateKeySpec + * @see DSAPublicKeySpec + * + * @since 1.2 + */ + +public interface KeySpec { } diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/MGF1ParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/MGF1ParameterSpec.java new file mode 100644 index 000000000..1be267f0c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/MGF1ParameterSpec.java @@ -0,0 +1,113 @@ +/* + * Copyright (c) 2003, 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 java.security.spec; + +import java.security.spec.AlgorithmParameterSpec; + +/** + * This class specifies the set of parameters used with mask generation + * function MGF1 in OAEP Padding and RSA-PSS signature scheme, as + * defined in the + * PKCS #1 v2.1 + * standard. + * + *

Its ASN.1 definition in PKCS#1 standard is described below: + *

+ * MGF1Parameters ::= OAEP-PSSDigestAlgorthms
+ * 
+ * where + *
+ * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+ *   { OID id-sha1 PARAMETERS NULL   }|
+ *   { OID id-sha224 PARAMETERS NULL   }|
+ *   { OID id-sha256 PARAMETERS NULL }|
+ *   { OID id-sha384 PARAMETERS NULL }|
+ *   { OID id-sha512 PARAMETERS NULL },
+ *   ...  -- Allows for future expansion --
+ * }
+ * 
+ * @see PSSParameterSpec + * @see javax.crypto.spec.OAEPParameterSpec + * + * @author Valerie Peng + * + * @since 1.5 + */ +public class MGF1ParameterSpec implements AlgorithmParameterSpec { + + /** + * The MGF1ParameterSpec which uses "SHA-1" message digest. + */ + public static final MGF1ParameterSpec SHA1 = + new MGF1ParameterSpec("SHA-1"); + /** + * The MGF1ParameterSpec which uses "SHA-224" message digest. + */ + public static final MGF1ParameterSpec SHA224 = + new MGF1ParameterSpec("SHA-224"); + /** + * The MGF1ParameterSpec which uses "SHA-256" message digest. + */ + public static final MGF1ParameterSpec SHA256 = + new MGF1ParameterSpec("SHA-256"); + /** + * The MGF1ParameterSpec which uses "SHA-384" message digest. + */ + public static final MGF1ParameterSpec SHA384 = + new MGF1ParameterSpec("SHA-384"); + /** + * The MGF1ParameterSpec which uses SHA-512 message digest. + */ + public static final MGF1ParameterSpec SHA512 = + new MGF1ParameterSpec("SHA-512"); + + private String mdName; + + /** + * Constructs a parameter set for mask generation function MGF1 + * as defined in the PKCS #1 standard. + * + * @param mdName the algorithm name for the message digest + * used in this mask generation function MGF1. + * @exception NullPointerException if {@code mdName} is null. + */ + public MGF1ParameterSpec(String mdName) { + if (mdName == null) { + throw new NullPointerException("digest algorithm is null"); + } + this.mdName = mdName; + } + + /** + * Returns the algorithm name of the message digest used by the mask + * generation function. + * + * @return the algorithm name of the message digest. + */ + public String getDigestAlgorithm() { + return mdName; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/PKCS8EncodedKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/PKCS8EncodedKeySpec.java new file mode 100644 index 000000000..060f266fc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/PKCS8EncodedKeySpec.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +/** + * This class represents the ASN.1 encoding of a private key, + * encoded according to the ASN.1 type {@code PrivateKeyInfo}. + * The {@code PrivateKeyInfo} syntax is defined in the PKCS#8 standard + * as follows: + * + *
+ * PrivateKeyInfo ::= SEQUENCE {
+ *   version Version,
+ *   privateKeyAlgorithm PrivateKeyAlgorithmIdentifier,
+ *   privateKey PrivateKey,
+ *   attributes [0] IMPLICIT Attributes OPTIONAL }
+ *
+ * Version ::= INTEGER
+ *
+ * PrivateKeyAlgorithmIdentifier ::= AlgorithmIdentifier
+ *
+ * PrivateKey ::= OCTET STRING
+ *
+ * Attributes ::= SET OF Attribute
+ * 
+ * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see EncodedKeySpec + * @see X509EncodedKeySpec + * + * @since 1.2 + */ + +public class PKCS8EncodedKeySpec extends EncodedKeySpec { + + /** + * Creates a new PKCS8EncodedKeySpec with the given encoded key. + * + * @param encodedKey the key, which is assumed to be + * encoded according to the PKCS #8 standard. The contents of + * the array are copied to protect against subsequent modification. + * @exception NullPointerException if {@code encodedKey} + * is null. + */ + public PKCS8EncodedKeySpec(byte[] encodedKey) { + super(encodedKey); + } + + /** + * Returns the key bytes, encoded according to the PKCS #8 standard. + * + * @return the PKCS #8 encoding of the key. Returns a new array + * each time this method is called. + */ + public byte[] getEncoded() { + return super.getEncoded(); + } + + /** + * Returns the name of the encoding format associated with this + * key specification. + * + * @return the string {@code "PKCS#8"}. + */ + public final String getFormat() { + return "PKCS#8"; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/PSSParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/PSSParameterSpec.java new file mode 100644 index 000000000..a9b82d8e4 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/PSSParameterSpec.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2001, 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 java.security.spec; + +import java.math.BigInteger; +import java.security.spec.MGF1ParameterSpec; + +/** + * This class specifies a parameter spec for RSA-PSS signature scheme, + * as defined in the + * PKCS#1 v2.1 + * standard. + * + *

Its ASN.1 definition in PKCS#1 standard is described below: + *

+ * RSASSA-PSS-params ::= SEQUENCE {
+ *   hashAlgorithm      [0] OAEP-PSSDigestAlgorithms  DEFAULT sha1,
+ *   maskGenAlgorithm   [1] PKCS1MGFAlgorithms  DEFAULT mgf1SHA1,
+ *   saltLength         [2] INTEGER  DEFAULT 20,
+ *   trailerField       [3] INTEGER  DEFAULT 1
+ * }
+ * 
+ * where + *
+ * OAEP-PSSDigestAlgorithms    ALGORITHM-IDENTIFIER ::= {
+ *   { OID id-sha1 PARAMETERS NULL   }|
+ *   { OID id-sha224 PARAMETERS NULL   }|
+ *   { OID id-sha256 PARAMETERS NULL }|
+ *   { OID id-sha384 PARAMETERS NULL }|
+ *   { OID id-sha512 PARAMETERS NULL },
+ *   ...  -- Allows for future expansion --
+ * }
+ *
+ * PKCS1MGFAlgorithms    ALGORITHM-IDENTIFIER ::= {
+ *   { OID id-mgf1 PARAMETERS OAEP-PSSDigestAlgorithms },
+ *   ...  -- Allows for future expansion --
+ * }
+ * 
+ *

Note: the PSSParameterSpec.DEFAULT uses the following: + * message digest -- "SHA-1" + * mask generation function (mgf) -- "MGF1" + * parameters for mgf -- MGF1ParameterSpec.SHA1 + * SaltLength -- 20 + * TrailerField -- 1 + * + * @see MGF1ParameterSpec + * @see AlgorithmParameterSpec + * @see java.security.Signature + * + * @author Valerie Peng + * + * + * @since 1.4 + */ + +public class PSSParameterSpec implements AlgorithmParameterSpec { + + private String mdName = "SHA-1"; + private String mgfName = "MGF1"; + private AlgorithmParameterSpec mgfSpec = MGF1ParameterSpec.SHA1; + private int saltLen = 20; + private int trailerField = 1; + + /** + * The PSS parameter set with all default values. + * @since 1.5 + */ + public static final PSSParameterSpec DEFAULT = new PSSParameterSpec(); + + /** + * Constructs a new {@code PSSParameterSpec} as defined in + * the PKCS #1 standard using the default values. + */ + private PSSParameterSpec() { + } + + /** + * Creates a new {@code PSSParameterSpec} as defined in + * the PKCS #1 standard using the specified message digest, + * mask generation function, parameters for mask generation + * function, salt length, and trailer field values. + * + * @param mdName the algorithm name of the hash function. + * @param mgfName the algorithm name of the mask generation + * function. + * @param mgfSpec the parameters for the mask generation + * function. If null is specified, null will be returned by + * getMGFParameters(). + * @param saltLen the length of salt. + * @param trailerField the value of the trailer field. + * @exception NullPointerException if {@code mdName}, + * or {@code mgfName} is null. + * @exception IllegalArgumentException if {@code saltLen} + * or {@code trailerField} is less than 0. + * @since 1.5 + */ + public PSSParameterSpec(String mdName, String mgfName, + AlgorithmParameterSpec mgfSpec, + int saltLen, int trailerField) { + if (mdName == null) { + throw new NullPointerException("digest algorithm is null"); + } + if (mgfName == null) { + throw new NullPointerException("mask generation function " + + "algorithm is null"); + } + if (saltLen < 0) { + throw new IllegalArgumentException("negative saltLen value: " + + saltLen); + } + if (trailerField < 0) { + throw new IllegalArgumentException("negative trailerField: " + + trailerField); + } + this.mdName = mdName; + this.mgfName = mgfName; + this.mgfSpec = mgfSpec; + this.saltLen = saltLen; + this.trailerField = trailerField; + } + + /** + * Creates a new {@code PSSParameterSpec} + * using the specified salt length and other default values as + * defined in PKCS#1. + * + * @param saltLen the length of salt in bits to be used in PKCS#1 + * PSS encoding. + * @exception IllegalArgumentException if {@code saltLen} is + * less than 0. + */ + public PSSParameterSpec(int saltLen) { + if (saltLen < 0) { + throw new IllegalArgumentException("negative saltLen value: " + + saltLen); + } + this.saltLen = saltLen; + } + + /** + * Returns the message digest algorithm name. + * + * @return the message digest algorithm name. + * @since 1.5 + */ + public String getDigestAlgorithm() { + return mdName; + } + + /** + * Returns the mask generation function algorithm name. + * + * @return the mask generation function algorithm name. + * + * @since 1.5 + */ + public String getMGFAlgorithm() { + return mgfName; + } + + /** + * Returns the parameters for the mask generation function. + * + * @return the parameters for the mask generation function. + * @since 1.5 + */ + public AlgorithmParameterSpec getMGFParameters() { + return mgfSpec; + } + + /** + * Returns the salt length in bits. + * + * @return the salt length. + */ + public int getSaltLength() { + return saltLen; + } + + /** + * Returns the value for the trailer field, i.e. bc in PKCS#1 v2.1. + * + * @return the value for the trailer field, i.e. bc in PKCS#1 v2.1. + * @since 1.5 + */ + public int getTrailerField() { + return trailerField; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/RSAKeyGenParameterSpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAKeyGenParameterSpec.java new file mode 100644 index 000000000..a73c6cd46 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAKeyGenParameterSpec.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 1999, 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 java.security.spec; + +import java.math.BigInteger; +import java.security.spec.AlgorithmParameterSpec; + +/** + * This class specifies the set of parameters used to generate an RSA + * key pair. + * + * @author Jan Luehe + * + * @see java.security.KeyPairGenerator#initialize(java.security.spec.AlgorithmParameterSpec) + * + * @since 1.3 + */ + +public class RSAKeyGenParameterSpec implements AlgorithmParameterSpec { + + private int keysize; + private BigInteger publicExponent; + + /** + * The public-exponent value F0 = 3. + */ + public static final BigInteger F0 = BigInteger.valueOf(3); + + /** + * The public exponent-value F4 = 65537. + */ + public static final BigInteger F4 = BigInteger.valueOf(65537); + + /** + * Constructs a new {@code RSAParameterSpec} object from the + * given keysize and public-exponent value. + * + * @param keysize the modulus size (specified in number of bits) + * @param publicExponent the public exponent + */ + public RSAKeyGenParameterSpec(int keysize, BigInteger publicExponent) { + this.keysize = keysize; + this.publicExponent = publicExponent; + } + + /** + * Returns the keysize. + * + * @return the keysize. + */ + public int getKeysize() { + return keysize; + } + + /** + * Returns the public-exponent value. + * + * @return the public-exponent value. + */ + public BigInteger getPublicExponent() { + return publicExponent; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java new file mode 100644 index 000000000..a198e43a2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAMultiPrimePrivateCrtKeySpec.java @@ -0,0 +1,212 @@ +/* + * Copyright (c) 2001, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class specifies an RSA multi-prime private key, as defined in the + * PKCS#1 v2.1, using the Chinese Remainder Theorem (CRT) information + * values for efficiency. + * + * @author Valerie Peng + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see PKCS8EncodedKeySpec + * @see RSAPrivateKeySpec + * @see RSAPublicKeySpec + * @see RSAOtherPrimeInfo + * + * @since 1.4 + */ + +public class RSAMultiPrimePrivateCrtKeySpec extends RSAPrivateKeySpec { + + private final BigInteger publicExponent; + private final BigInteger primeP; + private final BigInteger primeQ; + private final BigInteger primeExponentP; + private final BigInteger primeExponentQ; + private final BigInteger crtCoefficient; + private final RSAOtherPrimeInfo otherPrimeInfo[]; + + /** + * Creates a new {@code RSAMultiPrimePrivateCrtKeySpec} + * given the modulus, publicExponent, privateExponent, + * primeP, primeQ, primeExponentP, primeExponentQ, + * crtCoefficient, and otherPrimeInfo as defined in PKCS#1 v2.1. + * + *

Note that the contents of {@code otherPrimeInfo} + * are copied to protect against subsequent modification when + * constructing this object. + * + * @param modulus the modulus n. + * @param publicExponent the public exponent e. + * @param privateExponent the private exponent d. + * @param primeP the prime factor p of n. + * @param primeQ the prime factor q of n. + * @param primeExponentP this is d mod (p-1). + * @param primeExponentQ this is d mod (q-1). + * @param crtCoefficient the Chinese Remainder Theorem + * coefficient q-1 mod p. + * @param otherPrimeInfo triplets of the rest of primes, null can be + * specified if there are only two prime factors (p and q). + * @exception NullPointerException if any of the parameters, i.e. + * {@code modulus}, + * {@code publicExponent}, {@code privateExponent}, + * {@code primeP}, {@code primeQ}, + * {@code primeExponentP}, {@code primeExponentQ}, + * {@code crtCoefficient}, is null. + * @exception IllegalArgumentException if an empty, i.e. 0-length, + * {@code otherPrimeInfo} is specified. + */ + public RSAMultiPrimePrivateCrtKeySpec(BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger primeP, + BigInteger primeQ, + BigInteger primeExponentP, + BigInteger primeExponentQ, + BigInteger crtCoefficient, + RSAOtherPrimeInfo[] otherPrimeInfo) { + super(modulus, privateExponent); + if (modulus == null) { + throw new NullPointerException("the modulus parameter must be " + + "non-null"); + } + if (publicExponent == null) { + throw new NullPointerException("the publicExponent parameter " + + "must be non-null"); + } + if (privateExponent == null) { + throw new NullPointerException("the privateExponent parameter " + + "must be non-null"); + } + if (primeP == null) { + throw new NullPointerException("the primeP parameter " + + "must be non-null"); + } + if (primeQ == null) { + throw new NullPointerException("the primeQ parameter " + + "must be non-null"); + } + if (primeExponentP == null) { + throw new NullPointerException("the primeExponentP parameter " + + "must be non-null"); + } + if (primeExponentQ == null) { + throw new NullPointerException("the primeExponentQ parameter " + + "must be non-null"); + } + if (crtCoefficient == null) { + throw new NullPointerException("the crtCoefficient parameter " + + "must be non-null"); + } + this.publicExponent = publicExponent; + this.primeP = primeP; + this.primeQ = primeQ; + this.primeExponentP = primeExponentP; + this.primeExponentQ = primeExponentQ; + this.crtCoefficient = crtCoefficient; + if (otherPrimeInfo == null) { + this.otherPrimeInfo = null; + } else if (otherPrimeInfo.length == 0) { + throw new IllegalArgumentException("the otherPrimeInfo " + + "parameter must not be empty"); + } else { + this.otherPrimeInfo = otherPrimeInfo.clone(); + } + } + + /** + * Returns the public exponent. + * + * @return the public exponent. + */ + public BigInteger getPublicExponent() { + return this.publicExponent; + } + + /** + * Returns the primeP. + * + * @return the primeP. + */ + public BigInteger getPrimeP() { + return this.primeP; + } + + /** + * Returns the primeQ. + * + * @return the primeQ. + */ + public BigInteger getPrimeQ() { + return this.primeQ; + } + + /** + * Returns the primeExponentP. + * + * @return the primeExponentP. + */ + public BigInteger getPrimeExponentP() { + return this.primeExponentP; + } + + /** + * Returns the primeExponentQ. + * + * @return the primeExponentQ. + */ + public BigInteger getPrimeExponentQ() { + return this.primeExponentQ; + } + + /** + * Returns the crtCoefficient. + * + * @return the crtCoefficient. + */ + public BigInteger getCrtCoefficient() { + return this.crtCoefficient; + } + + /** + * Returns a copy of the otherPrimeInfo or null if there are + * only two prime factors (p and q). + * + * @return the otherPrimeInfo. Returns a new array each + * time this method is called. + */ + public RSAOtherPrimeInfo[] getOtherPrimeInfo() { + if (otherPrimeInfo == null) return null; + return otherPrimeInfo.clone(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/RSAOtherPrimeInfo.java b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAOtherPrimeInfo.java new file mode 100644 index 000000000..10d847176 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAOtherPrimeInfo.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 2001, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class represents the triplet (prime, exponent, and coefficient) + * inside RSA's OtherPrimeInfo structure, as defined in the PKCS#1 v2.1. + * The ASN.1 syntax of RSA's OtherPrimeInfo is as follows: + * + *

+ * OtherPrimeInfo ::= SEQUENCE {
+ *   prime INTEGER,
+ *   exponent INTEGER,
+ *   coefficient INTEGER
+ *   }
+ *
+ * 
+ * + * @author Valerie Peng + * + * + * @see RSAPrivateCrtKeySpec + * @see java.security.interfaces.RSAMultiPrimePrivateCrtKey + * + * @since 1.4 + */ + +public class RSAOtherPrimeInfo { + + private BigInteger prime; + private BigInteger primeExponent; + private BigInteger crtCoefficient; + + + /** + * Creates a new {@code RSAOtherPrimeInfo} + * given the prime, primeExponent, and + * crtCoefficient as defined in PKCS#1. + * + * @param prime the prime factor of n. + * @param primeExponent the exponent. + * @param crtCoefficient the Chinese Remainder Theorem + * coefficient. + * @exception NullPointerException if any of the parameters, i.e. + * {@code prime}, {@code primeExponent}, + * {@code crtCoefficient}, is null. + * + */ + public RSAOtherPrimeInfo(BigInteger prime, + BigInteger primeExponent, + BigInteger crtCoefficient) { + if (prime == null) { + throw new NullPointerException("the prime parameter must be " + + "non-null"); + } + if (primeExponent == null) { + throw new NullPointerException("the primeExponent parameter " + + "must be non-null"); + } + if (crtCoefficient == null) { + throw new NullPointerException("the crtCoefficient parameter " + + "must be non-null"); + } + this.prime = prime; + this.primeExponent = primeExponent; + this.crtCoefficient = crtCoefficient; + } + + /** + * Returns the prime. + * + * @return the prime. + */ + public final BigInteger getPrime() { + return this.prime; + } + + /** + * Returns the prime's exponent. + * + * @return the primeExponent. + */ + public final BigInteger getExponent() { + return this.primeExponent; + } + + /** + * Returns the prime's crtCoefficient. + * + * @return the crtCoefficient. + */ + public final BigInteger getCrtCoefficient() { + return this.crtCoefficient; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPrivateCrtKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPrivateCrtKeySpec.java new file mode 100644 index 000000000..d0ba70be4 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPrivateCrtKeySpec.java @@ -0,0 +1,143 @@ +/* + * Copyright (c) 1998, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class specifies an RSA private key, as defined in the PKCS#1 + * standard, using the Chinese Remainder Theorem (CRT) information values for + * efficiency. + * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see PKCS8EncodedKeySpec + * @see RSAPrivateKeySpec + * @see RSAPublicKeySpec + */ + +public class RSAPrivateCrtKeySpec extends RSAPrivateKeySpec { + + private final BigInteger publicExponent; + private final BigInteger primeP; + private final BigInteger primeQ; + private final BigInteger primeExponentP; + private final BigInteger primeExponentQ; + private final BigInteger crtCoefficient; + + + + /** + * Creates a new {@code RSAPrivateCrtKeySpec} + * given the modulus, publicExponent, privateExponent, + * primeP, primeQ, primeExponentP, primeExponentQ, and + * crtCoefficient as defined in PKCS#1. + * + * @param modulus the modulus n + * @param publicExponent the public exponent e + * @param privateExponent the private exponent d + * @param primeP the prime factor p of n + * @param primeQ the prime factor q of n + * @param primeExponentP this is d mod (p-1) + * @param primeExponentQ this is d mod (q-1) + * @param crtCoefficient the Chinese Remainder Theorem + * coefficient q-1 mod p + */ + public RSAPrivateCrtKeySpec(BigInteger modulus, + BigInteger publicExponent, + BigInteger privateExponent, + BigInteger primeP, + BigInteger primeQ, + BigInteger primeExponentP, + BigInteger primeExponentQ, + BigInteger crtCoefficient) { + super(modulus, privateExponent); + this.publicExponent = publicExponent; + this.primeP = primeP; + this.primeQ = primeQ; + this.primeExponentP = primeExponentP; + this.primeExponentQ = primeExponentQ; + this.crtCoefficient = crtCoefficient; + } + + /** + * Returns the public exponent. + * + * @return the public exponent + */ + public BigInteger getPublicExponent() { + return this.publicExponent; + } + + /** + * Returns the primeP. + + * @return the primeP + */ + public BigInteger getPrimeP() { + return this.primeP; + } + + /** + * Returns the primeQ. + * + * @return the primeQ + */ + public BigInteger getPrimeQ() { + return this.primeQ; + } + + /** + * Returns the primeExponentP. + * + * @return the primeExponentP + */ + public BigInteger getPrimeExponentP() { + return this.primeExponentP; + } + + /** + * Returns the primeExponentQ. + * + * @return the primeExponentQ + */ + public BigInteger getPrimeExponentQ() { + return this.primeExponentQ; + } + + /** + * Returns the crtCoefficient. + * + * @return the crtCoefficient + */ + public BigInteger getCrtCoefficient() { + return this.crtCoefficient; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPrivateKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPrivateKeySpec.java new file mode 100644 index 000000000..e74914616 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPrivateKeySpec.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1998, 2001, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class specifies an RSA private key. + * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see PKCS8EncodedKeySpec + * @see RSAPublicKeySpec + * @see RSAPrivateCrtKeySpec + */ + +public class RSAPrivateKeySpec implements KeySpec { + + private BigInteger modulus; + private BigInteger privateExponent; + + /** + * Creates a new RSAPrivateKeySpec. + * + * @param modulus the modulus + * @param privateExponent the private exponent + */ + public RSAPrivateKeySpec(BigInteger modulus, BigInteger privateExponent) { + this.modulus = modulus; + this.privateExponent = privateExponent; + } + + /** + * Returns the modulus. + * + * @return the modulus + */ + public BigInteger getModulus() { + return this.modulus; + } + + /** + * Returns the private exponent. + * + * @return the private exponent + */ + public BigInteger getPrivateExponent() { + return this.privateExponent; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPublicKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPublicKeySpec.java new file mode 100644 index 000000000..9a944f962 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/RSAPublicKeySpec.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 1998, 2001, 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 java.security.spec; + +import java.math.BigInteger; + +/** + * This class specifies an RSA public key. + * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see X509EncodedKeySpec + * @see RSAPrivateKeySpec + * @see RSAPrivateCrtKeySpec + */ + +public class RSAPublicKeySpec implements KeySpec { + + private BigInteger modulus; + private BigInteger publicExponent; + + /** + * Creates a new RSAPublicKeySpec. + * + * @param modulus the modulus + * @param publicExponent the public exponent + */ + public RSAPublicKeySpec(BigInteger modulus, BigInteger publicExponent) { + this.modulus = modulus; + this.publicExponent = publicExponent; + } + + /** + * Returns the modulus. + * + * @return the modulus + */ + public BigInteger getModulus() { + return this.modulus; + } + + /** + * Returns the public exponent. + * + * @return the public exponent + */ + public BigInteger getPublicExponent() { + return this.publicExponent; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/X509EncodedKeySpec.java b/sources/net.sf.j2s.java.core/src/java/security/spec/X509EncodedKeySpec.java new file mode 100644 index 000000000..b9984de87 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/X509EncodedKeySpec.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 1997, 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 java.security.spec; + +/** + * This class represents the ASN.1 encoding of a public key, + * encoded according to the ASN.1 type {@code SubjectPublicKeyInfo}. + * The {@code SubjectPublicKeyInfo} syntax is defined in the X.509 + * standard as follows: + * + *
+ * SubjectPublicKeyInfo ::= SEQUENCE {
+ *   algorithm AlgorithmIdentifier,
+ *   subjectPublicKey BIT STRING }
+ * 
+ * + * @author Jan Luehe + * + * + * @see java.security.Key + * @see java.security.KeyFactory + * @see KeySpec + * @see EncodedKeySpec + * @see PKCS8EncodedKeySpec + * + * @since 1.2 + */ + +public class X509EncodedKeySpec extends EncodedKeySpec { + + /** + * Creates a new X509EncodedKeySpec with the given encoded key. + * + * @param encodedKey the key, which is assumed to be + * encoded according to the X.509 standard. The contents of the + * array are copied to protect against subsequent modification. + * @exception NullPointerException if {@code encodedKey} + * is null. + */ + public X509EncodedKeySpec(byte[] encodedKey) { + super(encodedKey); + } + + /** + * Returns the key bytes, encoded according to the X.509 standard. + * + * @return the X.509 encoding of the key. Returns a new array + * each time this method is called. + */ + public byte[] getEncoded() { + return super.getEncoded(); + } + + /** + * Returns the name of the encoding format associated with this + * key specification. + * + * @return the string {@code "X.509"}. + */ + public final String getFormat() { + return "X.509"; + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/security/spec/package-info.java b/sources/net.sf.j2s.java.core/src/java/security/spec/package-info.java new file mode 100644 index 000000000..cb393088e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/security/spec/package-info.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 1998, 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. + */ + +/** + * Provides classes and interfaces for key specifications and algorithm + * parameter specifications. + * + *

A key specification is a transparent representation of the key material + * that constitutes a key. A key may be specified in an algorithm-specific + * way, or in an algorithm-independent encoding format (such as ASN.1). + * This package contains key specifications for DSA public and private keys, + * RSA public and private keys, PKCS #8 private keys in DER-encoded format, + * and X.509 public and private keys in DER-encoded format. + * + *

An algorithm parameter specification is a transparent representation + * of the sets of parameters used with an algorithm. This package contains + * an algorithm parameter specification for parameters used with the + * DSA algorithm. + * + *

Package Specification

+ * + *
    + *
  • PKCS #1: RSA Encryption Standard, Version 1.5, November 1993
  • + *
  • PKCS #8: Private-Key Information Syntax Standard, + * Version 1.2, November 1993
  • + *
  • Federal Information Processing Standards Publication (FIPS PUB) 186: + * Digital Signature Standard (DSS)
  • + *
+ * + *

Related Documentation

+ * + * For documentation that includes information about algorithm parameter + * and key specifications, please see: + * + * + * @since 1.2 + */ +package java.security.spec; diff --git a/sources/net.sf.j2s.java.core/src/java/text/BreakIterator.java b/sources/net.sf.j2s.java.core/src/java/text/BreakIterator.java index f5e53c4d4..e8f1424a2 100644 --- a/sources/net.sf.j2s.java.core/src/java/text/BreakIterator.java +++ b/sources/net.sf.j2s.java.core/src/java/text/BreakIterator.java @@ -40,7 +40,7 @@ package java.text; -import java.lang.ref.SoftReference; +//import java.lang.ref.SoftReference; import java.text.spi.BreakIteratorProvider; import java.util.Locale; import sun.util.locale.provider.LocaleProviderAdapter; @@ -433,7 +433,7 @@ public void setText(String newText) private static final int SENTENCE_INDEX = 3; @SuppressWarnings("unchecked") - private static final SoftReference[] iterCache = (SoftReference[]) new SoftReference[4]; + private static final BreakIteratorCache[] iterCache = new BreakIteratorCache[4]; /** * Returns a new BreakIterator instance @@ -533,7 +533,7 @@ public static BreakIterator getSentenceInstance(Locale locale) private static BreakIterator getBreakInstance(Locale locale, int type) { if (iterCache[type] != null) { - BreakIteratorCache cache = iterCache[type].get(); + BreakIteratorCache cache = iterCache[type]; if (cache != null) { if (cache.getLocale().equals(locale)) { return cache.createBreakInstance(); @@ -543,7 +543,7 @@ private static BreakIterator getBreakInstance(Locale locale, int type) { BreakIterator result = createBreakInstance(locale, type); BreakIteratorCache cache = new BreakIteratorCache(locale, result); - iterCache[type] = new SoftReference<>(cache); + iterCache[type] = cache; return result; } diff --git a/sources/net.sf.j2s.java.core/src/java/util/Properties.java b/sources/net.sf.j2s.java.core/src/java/util/Properties.java index 551ecae9b..51b9cf098 100644 --- a/sources/net.sf.j2s.java.core/src/java/util/Properties.java +++ b/sources/net.sf.j2s.java.core/src/java/util/Properties.java @@ -1,8 +1,5 @@ /* - * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017 - * for use in SwingJS via transpilation into JavaScript using Java2Script. - * - * Copyright (c) 1995, 2006, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1995, 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 @@ -29,15 +26,22 @@ package java.util; import java.io.IOException; +import java.io.PrintStream; +import java.io.PrintWriter; import java.io.InputStream; +import java.io.OutputStream; import java.io.Reader; -import java.util.Enumeration; -import java.util.Hashtable; -import java.util.Set; +import java.io.Writer; +import java.io.OutputStreamWriter; +import java.io.BufferedWriter; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import sun.util.spi.XmlPropertiesProvider; /** - * The Properties class represents a persistent set of - * properties. The Properties can be saved to a stream + * The {@code Properties} class represents a persistent set of + * properties. The {@code Properties} can be saved to a stream * or loaded from a stream. Each key and its corresponding value in * the property list is a string. *

@@ -45,17 +49,17 @@ * "defaults"; this second property list is searched if * the property key is not found in the original property list. *

- * Because Properties inherits from Hashtable, the - * put and putAll methods can be applied to a - * Properties object. Their use is strongly discouraged as they + * Because {@code Properties} inherits from {@code Hashtable}, the + * {@code put} and {@code putAll} methods can be applied to a + * {@code Properties} object. Their use is strongly discouraged as they * allow the caller to insert entries whose keys or values are not - * Strings. The setProperty method should be used - * instead. If the store or save method is called - * on a "compromised" Properties object that contains a - * non-String key or value, the call will fail. Similarly, - * the call to the propertyNames or list method - * will fail if it is called on a "compromised" Properties - * object that contains a non-String key. + * {@code Strings}. The {@code setProperty} method should be used + * instead. If the {@code store} or {@code save} method is called + * on a "compromised" {@code Properties} object that contains a + * non-{@code String} key or value, the call will fail. Similarly, + * the call to the {@code propertyNames} or {@code list} method + * will fail if it is called on a "compromised" {@code Properties} + * object that contains a non-{@code String} key. * *

* The {@link #load(java.io.Reader) load(Reader)} / @@ -68,16 +72,18 @@ * methods work the same way as the load(Reader)/store(Writer, String) pair, except * the input/output stream is encoded in ISO 8859-1 character encoding. * Characters that cannot be directly represented in this encoding can be written using - * Unicode escapes - * ; only a single 'u' character is allowed in an escape + * Unicode escapes as defined in section 3.3 of + * The Java™ Language Specification; + * only a single 'u' character is allowed in an escape * sequence. The native2ascii tool can be used to convert property files to and * from other character encodings. * *

The {@link #loadFromXML(InputStream)} and {@link * #storeToXML(OutputStream, String, String)} methods load and store properties * in a simple XML format. By default the UTF-8 character encoding is used, - * however a specific encoding may be specified if required. An XML properties - * document has the following DOCTYPE declaration: + * however a specific encoding may be specified if required. Implementations + * are required to support UTF-8 and UTF-16 and may support other encodings. + * An XML properties document has the following DOCTYPE declaration: * *

  * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
@@ -112,7 +118,6 @@
  * @author  Xueming Shen
  * @since   JDK1.0
  */
-@SuppressWarnings({"rawtypes", "unchecked"})
 public
 class Properties extends Hashtable {
     /**
@@ -145,15 +150,15 @@ public Properties(Properties defaults) {
     }
 
     /**
-     * Calls the Hashtable method put. Provided for
+     * Calls the Hashtable method {@code put}. Provided for
      * parallelism with the getProperty method. Enforces use of
      * strings for property keys and values. The value returned is the
-     * result of the Hashtable call to put.
+     * result of the Hashtable call to {@code put}.
      *
      * @param key the key to be placed into this property list.
      * @param value the value corresponding to key.
      * @return     the previous value of the specified key in this property
-     *             list, or null if it did not have one.
+     *             list, or {@code null} if it did not have one.
      * @see #getProperty
      * @since    1.2
      */
@@ -170,13 +175,13 @@ public synchronized Object setProperty(String key, String value) {
      * kinds of line, natural lines and logical lines.
      * A natural line is defined as a line of
      * characters that is terminated either by a set of line terminator
-     * characters (\n or \r or \r\n)
+     * characters ({@code \n} or {@code \r} or {@code \r\n})
      * or by the end of the stream. A natural line may be either a blank line,
      * a comment line, or hold all or some of a key-element pair. A logical
      * line holds all the data of a key-element pair, which may be spread
      * out across several adjacent natural lines by escaping
      * the line terminator sequence with a backslash character
-     * \.  Note that a comment line cannot be extended
+     * {@code \}.  Note that a comment line cannot be extended
      * in this manner; every natural line that is a comment must have
      * its own comment indicator, as described below. Lines are read from
      * input until the end of the stream is reached.
@@ -184,13 +189,13 @@ public synchronized Object setProperty(String key, String value) {
      * 

* A natural line that contains only white space characters is * considered blank and is ignored. A comment line has an ASCII - * '#' or '!' as its first non-white + * {@code '#'} or {@code '!'} as its first non-white * space character; comment lines are also ignored and do not * encode key-element information. In addition to line * terminators, this format considers the characters space - * (' ', '\u0020'), tab - * ('\t', '\u0009'), and form feed - * ('\f', '\u000C') to be white + * ({@code ' '}, {@code '\u005Cu0020'}), tab + * ({@code '\t'}, {@code '\u005Cu0009'}), and form feed + * ({@code '\f'}, {@code '\u005Cu000C'}) to be white * space. * *

@@ -214,32 +219,31 @@ public synchronized Object setProperty(String key, String value) { *

* The key contains all of the characters in the line starting * with the first non-white space character and up to, but not - * including, the first unescaped '=', - * ':', or white space character other than a line + * including, the first unescaped {@code '='}, + * {@code ':'}, or white space character other than a line * terminator. All of these key termination characters may be * included in the key by escaping them with a preceding backslash * character; for example,

* - * \:\=

+ * {@code \:\=}

* - * would be the two-character key ":=". Line - * terminator characters can be included using \r and - * \n escape sequences. Any white space after the + * would be the two-character key {@code ":="}. Line + * terminator characters can be included using {@code \r} and + * {@code \n} escape sequences. Any white space after the * key is skipped; if the first non-white space character after - * the key is '=' or ':', then it is + * the key is {@code '='} or {@code ':'}, then it is * ignored and any white space characters after it are also * skipped. All remaining characters on the line become part of * the associated element string; if there are no remaining * characters, the element is the empty string - * "". Once the raw character sequences + * {@code ""}. Once the raw character sequences * constituting the key and element are identified, escape * processing is performed as described above. * *

* As an example, each of the following three lines specifies the key - * "Truth" and the associated element value - * "Beauty": - *

+ * {@code "Truth"} and the associated element value + * {@code "Beauty"}: *

      * Truth = Beauty
      *  Truth:Beauty
@@ -247,37 +251,30 @@ public synchronized Object setProperty(String key, String value) {
      * 
* As another example, the following three lines specify a single * property: - *

*

      * fruits                           apple, banana, pear, \
      *                                  cantaloupe, watermelon, \
      *                                  kiwi, mango
      * 
- * The key is "fruits" and the associated element is: - *

+ * The key is {@code "fruits"} and the associated element is: *

"apple, banana, pear, cantaloupe, watermelon, kiwi, mango"
- * Note that a space appears before each \ so that a space - * will appear after each comma in the final result; the \, + * Note that a space appears before each {@code \} so that a space + * will appear after each comma in the final result; the {@code \}, * line terminator, and leading white space on the continuation line are * merely discarded and are not replaced by one or more other * characters. *

* As a third example, the line: - *

*

cheeses
      * 
- * specifies that the key is "cheeses" and the associated - * element is the empty string "".

+ * specifies that the key is {@code "cheeses"} and the associated + * element is the empty string {@code ""}. *

- * * * Characters in keys and elements can be represented in escape * sequences similar to those used for character and string literals - * (see §3.3 - * and §3.10.6 - * of the Java Language Specification). + * (see sections 3.3 and 3.10.6 of + * The Java™ Language Specification). * * The differences from the character escape sequences and Unicode * escapes used for characters and strings are: @@ -285,24 +282,24 @@ public synchronized Object setProperty(String key, String value) { *

    *
  • Octal escapes are not recognized. * - *
  • The character sequence \b does not + *
  • The character sequence {@code \b} does not * represent a backspace character. * *
  • The method does not treat a backslash character, - * \, before a non-valid escape character as an + * {@code \}, before a non-valid escape character as an * error; the backslash is silently dropped. For example, in a - * Java string the sequence "\z" would cause a + * Java string the sequence {@code "\z"} would cause a * compile time error. In contrast, this method silently drops * the backslash. Therefore, this method treats the two character - * sequence "\b" as equivalent to the single - * character 'b'. + * sequence {@code "\b"} as equivalent to the single + * character {@code 'b'}. * *
  • Escapes are not necessary for single and double quotes; * however, by the rule above, single and double quote characters * preceded by a backslash still yield single and double quote * characters, respectively. * - *
  • Only a single 'u' character is allowed in a Uniocde escape + *
  • Only a single 'u' character is allowed in a Unicode escape * sequence. * *
@@ -327,8 +324,9 @@ public synchronized void load(Reader reader) throws IOException { * {@link #load(java.io.Reader) load(Reader)} and is assumed to use * the ISO 8859-1 character encoding; that is each byte is one Latin1 * character. Characters not in Latin1, and certain special characters, - * are represented in keys and elements using - * Unicode escapes. + * are represented in keys and elements using Unicode escapes as defined in + * section 3.3 of + * The Java™ Language Specification. *

* The specified stream remains open after this method returns. * @@ -420,111 +418,119 @@ public LineReader(Reader reader) { InputStream inStream; Reader reader; - int readLine() throws IOException { - int len = 0; - char c = 0; + int readLine() throws IOException { + int len = 0; + char c = 0; - boolean skipWhiteSpace = true; - boolean isCommentLine = false; - boolean isNewLine = true; - boolean appendedLineBegin = false; - boolean precedingBackslash = false; - boolean skipLF = false; + boolean skipWhiteSpace = true; + boolean isCommentLine = false; + boolean isNewLine = true; + boolean appendedLineBegin = false; + boolean precedingBackslash = false; + boolean skipLF = false; - while (true) { - if (inOff >= inLimit) { - inLimit = (inStream == null) ? reader.read(inCharBuf) : inStream - .read(inByteBuf); - inOff = 0; - if (inLimit <= 0) { - if (len == 0 || isCommentLine) { - return -1; - } - return len; - } - } - if (inStream != null) { - // The line below is equivalent to calling a - // ISO8859-1 decoder. - c = (char) (0xff & inByteBuf[inOff++]); - } else { - c = inCharBuf[inOff++]; - } - if (skipLF) { - skipLF = false; - if (c == '\n') { - continue; - } - } - if (skipWhiteSpace) { - if (c == ' ' || c == '\t' || c == '\f') { - continue; - } - if (!appendedLineBegin && (c == '\r' || c == '\n')) { - continue; - } - skipWhiteSpace = false; - appendedLineBegin = false; - } - if (isNewLine) { - isNewLine = false; - if (c == '#' || c == '!') { - isCommentLine = true; - continue; - } - } + while (true) { + if (inOff >= inLimit) { + inLimit = (inStream==null)?reader.read(inCharBuf) + :inStream.read(inByteBuf); + inOff = 0; + if (inLimit <= 0) { + if (len == 0 || isCommentLine) { + return -1; + } + if (precedingBackslash) { + len--; + } + return len; + } + } + if (inStream != null) { + //The line below is equivalent to calling a + //ISO8859-1 decoder. + c = (char) (0xff & inByteBuf[inOff++]); + } else { + c = inCharBuf[inOff++]; + } + if (skipLF) { + skipLF = false; + if (c == '\n') { + continue; + } + } + if (skipWhiteSpace) { + if (c == ' ' || c == '\t' || c == '\f') { + continue; + } + if (!appendedLineBegin && (c == '\r' || c == '\n')) { + continue; + } + skipWhiteSpace = false; + appendedLineBegin = false; + } + if (isNewLine) { + isNewLine = false; + if (c == '#' || c == '!') { + isCommentLine = true; + continue; + } + } - if (c != '\n' && c != '\r') { - lineBuf[len++] = c; - if (len == lineBuf.length) { - int newLength = lineBuf.length * 2; + if (c != '\n' && c != '\r') { + lineBuf[len++] = c; + if (len == lineBuf.length) { + int newLength = lineBuf.length * 2; // if (newLength < 0) { // // in other words, we ran over and went negative // // this will never happen in JavaScript // newLength = 80;// HOLY COW! was Integer.MAX_VALUE; // } - char[] buf = new char[newLength]; - System.arraycopy(lineBuf, 0, buf, 0, lineBuf.length); - lineBuf = buf; - } - // flip the preceding backslash flag - if (c == '\\') { - precedingBackslash = !precedingBackslash; - } else { - precedingBackslash = false; - } - } else { - // reached EOL - if (isCommentLine || len == 0) { - isCommentLine = false; - isNewLine = true; - skipWhiteSpace = true; - len = 0; - continue; - } - if (inOff >= inLimit) { - inLimit = (inStream == null) ? reader.read(inCharBuf) : inStream - .read(inByteBuf); - inOff = 0; - if (inLimit <= 0) { - return len; - } - } - if (precedingBackslash) { - len -= 1; - // skip the leading whitespace characters in following line - skipWhiteSpace = true; - appendedLineBegin = true; - precedingBackslash = false; - if (c == '\r') { - skipLF = true; - } - } else { - return len; - } - } - } - } + char[] buf = new char[newLength]; + System.arraycopy(lineBuf, 0, buf, 0, lineBuf.length); + lineBuf = buf; + } + //flip the preceding backslash flag + if (c == '\\') { + precedingBackslash = !precedingBackslash; + } else { + precedingBackslash = false; + } + } + else { + // reached EOL + if (isCommentLine || len == 0) { + isCommentLine = false; + isNewLine = true; + skipWhiteSpace = true; + len = 0; + continue; + } + if (inOff >= inLimit) { + inLimit = (inStream==null) + ?reader.read(inCharBuf) + :inStream.read(inByteBuf); + inOff = 0; + if (inLimit <= 0) { + if (precedingBackslash) { + len--; + } + return len; + } + } + if (precedingBackslash) { + len -= 1; + //skip the leading whitespace characters in following line + skipWhiteSpace = true; + appendedLineBegin = true; + precedingBackslash = false; + if (c == '\r') { + skipLF = true; + } + } else { + return len; + } + } + } + } } /* @@ -586,360 +592,375 @@ private String loadConvert (char[] in, int off, int len, char[] convtBuf) { return new String (out, 0, outLen); } -// /* -// * Converts unicodes to encoded \uxxxx and escapes -// * special characters with a preceding slash -// */ -// private String saveConvert(String theString, -// boolean escapeSpace, -// boolean escapeUnicode) { -// int len = theString.length(); -// int bufLen = len * 2; -// if (bufLen < 0) { -// bufLen = Integer.MAX_VALUE; -// } -// StringBuffer outBuffer = new StringBuffer(bufLen); -// -// for(int x=0; x 61) && (aChar < 127)) { -// if (aChar == '\\') { -// outBuffer.append('\\'); outBuffer.append('\\'); -// continue; -// } -// outBuffer.append(aChar); -// continue; -// } -// switch(aChar) { -// case ' ': -// if (x == 0 || escapeSpace) -// outBuffer.append('\\'); -// outBuffer.append(' '); -// break; -// case '\t':outBuffer.append('\\'); outBuffer.append('t'); -// break; -// case '\n':outBuffer.append('\\'); outBuffer.append('n'); -// break; -// case '\r':outBuffer.append('\\'); outBuffer.append('r'); -// break; -// case '\f':outBuffer.append('\\'); outBuffer.append('f'); -// break; -// case '=': // Fall through -// case ':': // Fall through -// case '#': // Fall through -// case '!': -// outBuffer.append('\\'); outBuffer.append(aChar); -// break; -// default: -// if (((aChar < 0x0020) || (aChar > 0x007e)) & escapeUnicode ) { -// outBuffer.append('\\'); -// outBuffer.append('u'); -// outBuffer.append(toHex((aChar >> 12) & 0xF)); -// outBuffer.append(toHex((aChar >> 8) & 0xF)); -// outBuffer.append(toHex((aChar >> 4) & 0xF)); -// outBuffer.append(toHex( aChar & 0xF)); -// } else { -// outBuffer.append(aChar); -// } -// } -// } -// return outBuffer.toString(); -// } + /* + * Converts unicodes to encoded \uxxxx and escapes + * special characters with a preceding slash + */ + private String saveConvert(String theString, + boolean escapeSpace, + boolean escapeUnicode) { + int len = theString.length(); + int bufLen = len * 2; + if (bufLen < 0) { + bufLen = Integer.MAX_VALUE; + } + StringBuffer outBuffer = new StringBuffer(bufLen); -// private static void writeComments(BufferedWriter bw, String comments) -// throws IOException { -// bw.write("#"); -// int len = comments.length(); -// int current = 0; -// int last = 0; -// char[] uu = new char[6]; -// uu[0] = '\\'; -// uu[1] = 'u'; -// while (current < len) { -// char c = comments.charAt(current); -// if (c > '\u00ff' || c == '\n' || c == '\r') { -// if (last != current) -// bw.write(comments.substring(last, current)); -// if (c > '\u00ff') { -// uu[2] = toHex((c >> 12) & 0xf); -// uu[3] = toHex((c >> 8) & 0xf); -// uu[4] = toHex((c >> 4) & 0xf); -// uu[5] = toHex( c & 0xf); -// bw.write(new String(uu)); -// } else { -// bw.newLine(); -// if (c == '\r' && -// current != len - 1 && -// comments.charAt(current + 1) == '\n') { -// current++; -// } -// if (current == len - 1 || -// (comments.charAt(current + 1) != '#' && -// comments.charAt(current + 1) != '!')) -// bw.write("#"); -// } -// last = current + 1; -// } -// current++; -// } -// if (last != current) -// bw.write(comments.substring(last, current)); -// bw.newLine(); -// } + for(int x=0; x 61) && (aChar < 127)) { + if (aChar == '\\') { + outBuffer.append('\\'); outBuffer.append('\\'); + continue; + } + outBuffer.append(aChar); + continue; + } + switch(aChar) { + case ' ': + if (x == 0 || escapeSpace) + outBuffer.append('\\'); + outBuffer.append(' '); + break; + case '\t':outBuffer.append('\\'); outBuffer.append('t'); + break; + case '\n':outBuffer.append('\\'); outBuffer.append('n'); + break; + case '\r':outBuffer.append('\\'); outBuffer.append('r'); + break; + case '\f':outBuffer.append('\\'); outBuffer.append('f'); + break; + case '=': // Fall through + case ':': // Fall through + case '#': // Fall through + case '!': + outBuffer.append('\\'); outBuffer.append(aChar); + break; + default: + if (((aChar < 0x0020) || (aChar > 0x007e)) & escapeUnicode ) { + outBuffer.append('\\'); + outBuffer.append('u'); + outBuffer.append(toHex((aChar >> 12) & 0xF)); + outBuffer.append(toHex((aChar >> 8) & 0xF)); + outBuffer.append(toHex((aChar >> 4) & 0xF)); + outBuffer.append(toHex( aChar & 0xF)); + } else { + outBuffer.append(aChar); + } + } + } + return outBuffer.toString(); + } -// /** -// * Calls the store(OutputStream out, String comments) method -// * and suppresses IOExceptions that were thrown. -// * -// * @deprecated This method does not throw an IOException if an I/O error -// * occurs while saving the property list. The preferred way to save a -// * properties list is via the store(OutputStream out, -// * String comments) method or the -// * storeToXML(OutputStream os, String comment) method. -// * -// * @param out an output stream. -// * @param comments a description of the property list. -// * @exception ClassCastException if this Properties object -// * contains any keys or values that are not -// * Strings. -// */ -// @Deprecated -// public synchronized void save(OutputStream out, String comments) { -// try { -// store(out, comments); -// } catch (IOException e) { -// } -// } + private static void writeComments(BufferedWriter bw, String comments) + throws IOException { + bw.write("#"); + int len = comments.length(); + int current = 0; + int last = 0; + char[] uu = new char[6]; + uu[0] = '\\'; + uu[1] = 'u'; + while (current < len) { + char c = comments.charAt(current); + if (c > '\u00ff' || c == '\n' || c == '\r') { + if (last != current) + bw.write(comments.substring(last, current)); + if (c > '\u00ff') { + uu[2] = toHex((c >> 12) & 0xf); + uu[3] = toHex((c >> 8) & 0xf); + uu[4] = toHex((c >> 4) & 0xf); + uu[5] = toHex( c & 0xf); + bw.write(new String(uu)); + } else { + bw.newLine(); + if (c == '\r' && + current != len - 1 && + comments.charAt(current + 1) == '\n') { + current++; + } + if (current == len - 1 || + (comments.charAt(current + 1) != '#' && + comments.charAt(current + 1) != '!')) + bw.write("#"); + } + last = current + 1; + } + current++; + } + if (last != current) + bw.write(comments.substring(last, current)); + bw.newLine(); + } -// /** -// * Writes this property list (key and element pairs) in this -// * Properties table to the output character stream in a -// * format suitable for using the {@link #load(java.io.Reader) load(Reader)} -// * method. -// *

-// * Properties from the defaults table of this Properties -// * table (if any) are not written out by this method. -// *

-// * If the comments argument is not null, then an ASCII # -// * character, the comments string, and a line separator are first written -// * to the output stream. Thus, the comments can serve as an -// * identifying comment. Any one of a line feed ('\n'), a carriage -// * return ('\r'), or a carriage return followed immediately by a line feed -// * in comments is replaced by a line separator generated by the Writer -// * and if the next character in comments is not character # or -// * character ! then an ASCII # is written out -// * after that line separator. -// *

-// * Next, a comment line is always written, consisting of an ASCII -// * # character, the current date and time (as if produced -// * by the toString method of Date for the -// * current time), and a line separator as generated by the Writer. -// *

-// * Then every entry in this Properties table is -// * written out, one per line. For each entry the key string is -// * written, then an ASCII =, then the associated -// * element string. For the key, all space characters are -// * written with a preceding \ character. For the -// * element, leading space characters, but not embedded or trailing -// * space characters, are written with a preceding \ -// * character. The key and element characters #, -// * !, =, and : are written -// * with a preceding backslash to ensure that they are properly loaded. -// *

-// * After the entries have been written, the output stream is flushed. -// * The output stream remains open after this method returns. -// *

-// * -// * @param writer an output character stream writer. -// * @param comments a description of the property list. -// * @exception IOException if writing this property list to the specified -// * output stream throws an IOException. -// * @exception ClassCastException if this Properties object -// * contains any keys or values that are not Strings. -// * @exception NullPointerException if writer is null. -// * @since 1.6 -// */ -// public void store(Writer writer, String comments) -// throws IOException -// { -// store0((writer instanceof BufferedWriter)?(BufferedWriter)writer -// : new BufferedWriter(writer), -// comments, -// false); -// } + /** + * Calls the {@code store(OutputStream out, String comments)} method + * and suppresses IOExceptions that were thrown. + * + * @deprecated This method does not throw an IOException if an I/O error + * occurs while saving the property list. The preferred way to save a + * properties list is via the {@code store(OutputStream out, + * String comments)} method or the + * {@code storeToXML(OutputStream os, String comment)} method. + * + * @param out an output stream. + * @param comments a description of the property list. + * @exception ClassCastException if this {@code Properties} object + * contains any keys or values that are not + * {@code Strings}. + */ + @Deprecated + public void save(OutputStream out, String comments) { + try { + store(out, comments); + } catch (IOException e) { + } + } -// /** -// * Writes this property list (key and element pairs) in this -// * Properties table to the output stream in a format suitable -// * for loading into a Properties table using the -// * {@link #load(InputStream) load(InputStream)} method. -// *

-// * Properties from the defaults table of this Properties -// * table (if any) are not written out by this method. -// *

-// * This method outputs the comments, properties keys and values in -// * the same format as specified in -// * {@link #store(java.io.Writer, java.lang.String) store(Writer)}, -// * with the following differences: -// *

    -// *
  • The stream is written using the ISO 8859-1 character encoding. -// * -// *
  • Characters not in Latin-1 in the comments are written as -// * \uxxxx for their appropriate unicode -// * hexadecimal value xxxx. -// * -// *
  • Characters less than \u0020 and characters greater -// * than \u007E in property keys or values are written -// * as \uxxxx for the appropriate hexadecimal -// * value xxxx. -// *
-// *

-// * After the entries have been written, the output stream is flushed. -// * The output stream remains open after this method returns. -// *

-// * @param out an output stream. -// * @param comments a description of the property list. -// * @exception IOException if writing this property list to the specified -// * output stream throws an IOException. -// * @exception ClassCastException if this Properties object -// * contains any keys or values that are not Strings. -// * @exception NullPointerException if out is null. -// * @since 1.2 -// */ -// public void store(OutputStream out, String comments) -// throws IOException -// { -// store0(new BufferedWriter(new OutputStreamWriter(out, "8859_1")), -// comments, -// true); -// } -// -// private void store0(BufferedWriter bw, String comments, boolean escUnicode) -// throws IOException -// { -// if (comments != null) { -// writeComments(bw, comments); -// } -// bw.write("#" + new Date().toString()); -// bw.newLine(); -// synchronized (this) { -// for (Enumeration e = keys(); e.hasMoreElements();) { -// String key = (String)e.nextElement(); -// String val = (String)get(key); -// key = saveConvert(key, true, escUnicode); -// /* No need to escape embedded and trailing spaces for value, hence -// * pass false to flag. -// */ -// val = saveConvert(val, false, escUnicode); -// bw.write(key + "=" + val); -// bw.newLine(); -// } -// } -// bw.flush(); -// } -// -// /** -// * Loads all of the properties represented by the XML document on the -// * specified input stream into this properties table. -// * -// *

The XML document must have the following DOCTYPE declaration: -// *

-//     * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
-//     * 
-// * Furthermore, the document must satisfy the properties DTD described -// * above. -// * -// *

The specified stream is closed after this method returns. -// * -// * @param in the input stream from which to read the XML document. -// * @throws IOException if reading from the specified input stream -// * results in an IOException. -// * @throws InvalidPropertiesFormatException Data on input stream does not -// * constitute a valid XML document with the mandated document type. -// * @throws NullPointerException if in is null. -// * @see #storeToXML(OutputStream, String, String) -// * @since 1.5 -// */ -// public synchronized void loadFromXML(InputStream in) -// throws IOException, InvalidPropertiesFormatException -// { -// if (in == null) -// throw new NullPointerException(); -// XMLUtils.load(this, in); -// in.close(); -// } + /** + * Writes this property list (key and element pairs) in this + * {@code Properties} table to the output character stream in a + * format suitable for using the {@link #load(java.io.Reader) load(Reader)} + * method. + *

+ * Properties from the defaults table of this {@code Properties} + * table (if any) are not written out by this method. + *

+ * If the comments argument is not null, then an ASCII {@code #} + * character, the comments string, and a line separator are first written + * to the output stream. Thus, the {@code comments} can serve as an + * identifying comment. Any one of a line feed ('\n'), a carriage + * return ('\r'), or a carriage return followed immediately by a line feed + * in comments is replaced by a line separator generated by the {@code Writer} + * and if the next character in comments is not character {@code #} or + * character {@code !} then an ASCII {@code #} is written out + * after that line separator. + *

+ * Next, a comment line is always written, consisting of an ASCII + * {@code #} character, the current date and time (as if produced + * by the {@code toString} method of {@code Date} for the + * current time), and a line separator as generated by the {@code Writer}. + *

+ * Then every entry in this {@code Properties} table is + * written out, one per line. For each entry the key string is + * written, then an ASCII {@code =}, then the associated + * element string. For the key, all space characters are + * written with a preceding {@code \} character. For the + * element, leading space characters, but not embedded or trailing + * space characters, are written with a preceding {@code \} + * character. The key and element characters {@code #}, + * {@code !}, {@code =}, and {@code :} are written + * with a preceding backslash to ensure that they are properly loaded. + *

+ * After the entries have been written, the output stream is flushed. + * The output stream remains open after this method returns. + *

+ * + * @param writer an output character stream writer. + * @param comments a description of the property list. + * @exception IOException if writing this property list to the specified + * output stream throws an IOException. + * @exception ClassCastException if this {@code Properties} object + * contains any keys or values that are not {@code Strings}. + * @exception NullPointerException if {@code writer} is null. + * @since 1.6 + */ + public void store(Writer writer, String comments) + throws IOException + { + store0((writer instanceof BufferedWriter)?(BufferedWriter)writer + : new BufferedWriter(writer), + comments, + false); + } -// /** -// * Emits an XML document representing all of the properties contained -// * in this table. -// * -// *

An invocation of this method of the form props.storeToXML(os, -// * comment) behaves in exactly the same way as the invocation -// * props.storeToXML(os, comment, "UTF-8");. -// * -// * @param os the output stream on which to emit the XML document. -// * @param comment a description of the property list, or null -// * if no comment is desired. -// * @throws IOException if writing to the specified output stream -// * results in an IOException. -// * @throws NullPointerException if os is null. -// * @throws ClassCastException if this Properties object -// * contains any keys or values that are not -// * Strings. -// * @see #loadFromXML(InputStream) -// * @since 1.5 -// */ -// public synchronized void storeToXML(OutputStream os, String comment) -// throws IOException -// { -// if (os == null) -// throw new NullPointerException(); -// storeToXML(os, comment, "UTF-8"); -// } -// -// /** -// * Emits an XML document representing all of the properties contained -// * in this table, using the specified encoding. -// * -// *

The XML document will have the following DOCTYPE declaration: -// *

-//     * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
-//     * 
-// * -// *

If the specified comment is null then no comment -// * will be stored in the document. -// * -// *

The specified stream remains open after this method returns. -// * -// * @param os the output stream on which to emit the XML document. -// * @param comment a description of the property list, or null -// * if no comment is desired. -// * @throws IOException if writing to the specified output stream -// * results in an IOException. -// * @throws NullPointerException if os is null, -// * or if encoding is null. -// * @throws ClassCastException if this Properties object -// * contains any keys or values that are not -// * Strings. -// * @see #loadFromXML(InputStream) -// * @since 1.5 -// */ -// public synchronized void storeToXML(OutputStream os, String comment, -// String encoding) -// throws IOException -// { -// if (os == null) -// throw new NullPointerException(); -// XMLUtils.save(this, os, comment, encoding); -// } + /** + * Writes this property list (key and element pairs) in this + * {@code Properties} table to the output stream in a format suitable + * for loading into a {@code Properties} table using the + * {@link #load(InputStream) load(InputStream)} method. + *

+ * Properties from the defaults table of this {@code Properties} + * table (if any) are not written out by this method. + *

+ * This method outputs the comments, properties keys and values in + * the same format as specified in + * {@link #store(java.io.Writer, java.lang.String) store(Writer)}, + * with the following differences: + *

    + *
  • The stream is written using the ISO 8859-1 character encoding. + * + *
  • Characters not in Latin-1 in the comments are written as + * {@code \u005Cu}xxxx for their appropriate unicode + * hexadecimal value xxxx. + * + *
  • Characters less than {@code \u005Cu0020} and characters greater + * than {@code \u005Cu007E} in property keys or values are written + * as {@code \u005Cu}xxxx for the appropriate hexadecimal + * value xxxx. + *
+ *

+ * After the entries have been written, the output stream is flushed. + * The output stream remains open after this method returns. + *

+ * @param out an output stream. + * @param comments a description of the property list. + * @exception IOException if writing this property list to the specified + * output stream throws an IOException. + * @exception ClassCastException if this {@code Properties} object + * contains any keys or values that are not {@code Strings}. + * @exception NullPointerException if {@code out} is null. + * @since 1.2 + */ + public void store(OutputStream out, String comments) + throws IOException + { + store0(new BufferedWriter(new OutputStreamWriter(out, "8859_1")), + comments, + true); + } + + private void store0(BufferedWriter bw, String comments, boolean escUnicode) + throws IOException + { + if (comments != null) { + writeComments(bw, comments); + } + bw.write("#" + new Date().toString()); + bw.newLine(); + synchronized (this) { + for (Enumeration e = keys(); e.hasMoreElements();) { + String key = (String)e.nextElement(); + String val = (String)get(key); + key = saveConvert(key, true, escUnicode); + /* No need to escape embedded and trailing spaces for value, hence + * pass false to flag. + */ + val = saveConvert(val, false, escUnicode); + bw.write(key + "=" + val); + bw.newLine(); + } + } + bw.flush(); + } + + /** + * Loads all of the properties represented by the XML document on the + * specified input stream into this properties table. + * + *

The XML document must have the following DOCTYPE declaration: + *

+     * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+     * 
+ * Furthermore, the document must satisfy the properties DTD described + * above. + * + *

An implementation is required to read XML documents that use the + * "{@code UTF-8}" or "{@code UTF-16}" encoding. An implementation may + * support additional encodings. + * + *

The specified stream is closed after this method returns. + * + * @param in the input stream from which to read the XML document. + * @throws IOException if reading from the specified input stream + * results in an IOException. + * @throws java.io.UnsupportedEncodingException if the document's encoding + * declaration can be read and it specifies an encoding that is not + * supported + * @throws InvalidPropertiesFormatException Data on input stream does not + * constitute a valid XML document with the mandated document type. + * @throws NullPointerException if {@code in} is null. + * @see #storeToXML(OutputStream, String, String) + * @see Character + * Encoding in Entities + * @since 1.5 + */ + public synchronized void loadFromXML(InputStream in) + throws IOException, InvalidPropertiesFormatException + { + XmlSupport.load(this, Objects.requireNonNull(in)); + in.close(); + } + + /** + * Emits an XML document representing all of the properties contained + * in this table. + * + *

An invocation of this method of the form props.storeToXML(os, + * comment) behaves in exactly the same way as the invocation + * props.storeToXML(os, comment, "UTF-8");. + * + * @param os the output stream on which to emit the XML document. + * @param comment a description of the property list, or {@code null} + * if no comment is desired. + * @throws IOException if writing to the specified output stream + * results in an IOException. + * @throws NullPointerException if {@code os} is null. + * @throws ClassCastException if this {@code Properties} object + * contains any keys or values that are not + * {@code Strings}. + * @see #loadFromXML(InputStream) + * @since 1.5 + */ + public void storeToXML(OutputStream os, String comment) + throws IOException + { + storeToXML(os, comment, "UTF-8"); + } + + /** + * Emits an XML document representing all of the properties contained + * in this table, using the specified encoding. + * + *

The XML document will have the following DOCTYPE declaration: + *

+     * <!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
+     * 
+ * + *

If the specified comment is {@code null} then no comment + * will be stored in the document. + * + *

An implementation is required to support writing of XML documents + * that use the "{@code UTF-8}" or "{@code UTF-16}" encoding. An + * implementation may support additional encodings. + * + *

The specified stream remains open after this method returns. + * + * @param os the output stream on which to emit the XML document. + * @param comment a description of the property list, or {@code null} + * if no comment is desired. + * @param encoding the name of a supported + * + * character encoding + * + * @throws IOException if writing to the specified output stream + * results in an IOException. + * @throws java.io.UnsupportedEncodingException if the encoding is not + * supported by the implementation. + * @throws NullPointerException if {@code os} is {@code null}, + * or if {@code encoding} is {@code null}. + * @throws ClassCastException if this {@code Properties} object + * contains any keys or values that are not + * {@code Strings}. + * @see #loadFromXML(InputStream) + * @see Character + * Encoding in Entities + * @since 1.5 + */ + public void storeToXML(OutputStream os, String comment, String encoding) + throws IOException + { + XmlSupport.save(this, Objects.requireNonNull(os), comment, + Objects.requireNonNull(encoding)); + } /** * Searches for the property with the specified key in this property list. * If the key is not found in this property list, the default property list, * and its defaults, recursively, are then checked. The method returns - * null if the property is not found. + * {@code null} if the property is not found. * * @param key the property key. * @return the value in this property list with the specified key value. @@ -985,7 +1006,7 @@ public String getProperty(String key, String defaultValue) { * @see #stringPropertyNames */ public Enumeration propertyNames() { - Hashtable h = new Hashtable(); + Hashtable h = new Hashtable<>(); enumerate(h); return h.keys(); } @@ -1009,60 +1030,60 @@ public Enumeration propertyNames() { * @since 1.6 */ public Set stringPropertyNames() { - Hashtable h = new Hashtable(); + Hashtable h = new Hashtable<>(); enumerateStringProperties(h); return h.keySet(); } -// /** -// * Prints this property list out to the specified output stream. -// * This method is useful for debugging. -// * -// * @param out an output stream. -// * @throws ClassCastException if any key in this property list -// * is not a string. -// */ -// public void list(PrintStream out) { -// out.println("-- listing properties --"); -// Hashtable h = new Hashtable(); -// enumerate(h); -// for (Enumeration e = h.keys() ; e.hasMoreElements() ;) { -// String key = (String)e.nextElement(); -// String val = (String)h.get(key); -// if (val.length() > 40) { -// val = val.substring(0, 37) + "..."; -// } -// out.println(key + "=" + val); -// } -// } + /** + * Prints this property list out to the specified output stream. + * This method is useful for debugging. + * + * @param out an output stream. + * @throws ClassCastException if any key in this property list + * is not a string. + */ + public void list(PrintStream out) { + out.println("-- listing properties --"); + Hashtable h = new Hashtable<>(); + enumerate(h); + for (Enumeration e = h.keys() ; e.hasMoreElements() ;) { + String key = e.nextElement(); + String val = (String)h.get(key); + if (val.length() > 40) { + val = val.substring(0, 37) + "..."; + } + out.println(key + "=" + val); + } + } -// /** -// * Prints this property list out to the specified output stream. -// * This method is useful for debugging. -// * -// * @param out an output stream. -// * @throws ClassCastException if any key in this property list -// * is not a string. -// * @since JDK1.1 -// */ -// /* -// * Rather than use an anonymous inner class to share common code, this -// * method is duplicated in order to ensure that a non-1.1 compiler can -// * compile this file. -// */ -// public void list(PrintWriter out) { -// out.println("-- listing properties --"); -// Hashtable h = new Hashtable(); -// enumerate(h); -// for (Enumeration e = h.keys() ; e.hasMoreElements() ;) { -// String key = (String)e.nextElement(); -// String val = (String)h.get(key); -// if (val.length() > 40) { -// val = val.substring(0, 37) + "..."; -// } -// out.println(key + "=" + val); -// } -// } + /** + * Prints this property list out to the specified output stream. + * This method is useful for debugging. + * + * @param out an output stream. + * @throws ClassCastException if any key in this property list + * is not a string. + * @since JDK1.1 + */ + /* + * Rather than use an anonymous inner class to share common code, this + * method is duplicated in order to ensure that a non-1.1 compiler can + * compile this file. + */ + public void list(PrintWriter out) { + out.println("-- listing properties --"); + Hashtable h = new Hashtable<>(); + enumerate(h); + for (Enumeration e = h.keys() ; e.hasMoreElements() ;) { + String key = e.nextElement(); + String val = (String)h.get(key); + if (val.length() > 40) { + val = val.substring(0, 37) + "..."; + } + out.println(key + "=" + val); + } + } /** * Enumerates all key/value pairs in the specified hashtable. @@ -1070,11 +1091,11 @@ public Set stringPropertyNames() { * @throws ClassCastException if any of the property keys * is not of String type. */ - private synchronized void enumerate(Hashtable h) { + private synchronized void enumerate(Hashtable h) { if (defaults != null) { defaults.enumerate(h); } - for (Enumeration e = keys() ; e.hasMoreElements() ;) { + for (Enumeration e = keys() ; e.hasMoreElements() ;) { String key = (String)e.nextElement(); h.put(key, get(key)); } @@ -1089,7 +1110,7 @@ private synchronized void enumerateStringProperties(Hashtable h) if (defaults != null) { defaults.enumerateStringProperties(h); } - for (Enumeration e = keys() ; e.hasMoreElements() ;) { + for (Enumeration e = keys() ; e.hasMoreElements() ;) { Object k = e.nextElement(); Object v = get(k); if (k instanceof String && v instanceof String) { @@ -1098,16 +1119,95 @@ private synchronized void enumerateStringProperties(Hashtable h) } } -// /** -// * Convert a nibble to a hex character -// * @param nibble the nibble to convert. -// */ -// private static char toHex(int nibble) { -// return hexDigit[(nibble & 0xF)]; -// } + /** + * Convert a nibble to a hex character + * @param nibble the nibble to convert. + */ + private static char toHex(int nibble) { + return hexDigit[(nibble & 0xF)]; + } + + /** A table of hex digits */ + private static final char[] hexDigit = { + '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' + }; -// /** A table of hex digits */ -// private static final char[] hexDigit = { -// '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' -// }; + /** + * Supporting class for loading/storing properties in XML format. + * + *

The {@code load} and {@code store} methods defined here delegate to a + * system-wide {@code XmlPropertiesProvider}. On first invocation of either + * method then the system-wide provider is located as follows:

+ * + *
    + *
  1. If the system property {@code sun.util.spi.XmlPropertiesProvider} + * is defined then it is taken to be the full-qualified name of a concrete + * provider class. The class is loaded with the system class loader as the + * initiating loader. If it cannot be loaded or instantiated using a zero + * argument constructor then an unspecified error is thrown.
  2. + * + *
  3. If the system property is not defined then the service-provider + * loading facility defined by the {@link ServiceLoader} class is used to + * locate a provider with the system class loader as the initiating + * loader and {@code sun.util.spi.XmlPropertiesProvider} as the service + * type. If this process fails then an unspecified error is thrown. If + * there is more than one service provider installed then it is + * not specified as to which provider will be used.
  4. + * + *
  5. If the provider is not found by the above means then a system + * default provider will be instantiated and used.
  6. + *
+ */ + private static class XmlSupport { + + private static XmlPropertiesProvider loadProviderFromProperty(ClassLoader cl) { + String cn = System.getProperty("sun.util.spi.XmlPropertiesProvider"); + if (cn == null) + return null; + try { + Class c = Class.forName(cn, true, cl); + return (XmlPropertiesProvider)c.newInstance(); + } catch (ClassNotFoundException | + IllegalAccessException | + InstantiationException x) { + throw new ServiceConfigurationError(null, x); + } + } + + private static XmlPropertiesProvider loadProviderAsService(ClassLoader cl) { + Iterator iterator = + ServiceLoader.load(XmlPropertiesProvider.class, cl).iterator(); + return iterator.hasNext() ? iterator.next() : null; + } + + private static XmlPropertiesProvider loadProvider() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public XmlPropertiesProvider run() { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + XmlPropertiesProvider provider = loadProviderFromProperty(cl); + if (provider != null) + return provider; + provider = loadProviderAsService(cl); + if (provider != null) + return provider; + return new jdk.internal.util.xml.BasicXmlPropertiesProvider(); + }}); + } + + private static final XmlPropertiesProvider PROVIDER = loadProvider(); + + static void load(Properties props, InputStream in) + throws IOException, InvalidPropertiesFormatException + { + PROVIDER.load(props, in); + } + + static void save(Properties props, OutputStream os, String comment, + String encoding) + throws IOException + { + PROVIDER.store(props, os, comment, encoding); + } + } } diff --git a/sources/net.sf.j2s.java.core/src/java/util/jar/JarFile.java b/sources/net.sf.j2s.java.core/src/java/util/jar/JarFile.java index a2a27d17b..97893cb52 100644 --- a/sources/net.sf.j2s.java.core/src/java/util/jar/JarFile.java +++ b/sources/net.sf.j2s.java.core/src/java/util/jar/JarFile.java @@ -29,7 +29,7 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; -import java.lang.ref.SoftReference; +//import java.lang.ref.SoftReference; import java.net.URL; import java.security.CodeSource; //import java.security.AccessController; @@ -83,7 +83,7 @@ */ public class JarFile extends ZipFile { - private SoftReference manRef; + private Manifest manRef; private JarEntry manEntry; // private JarVerifier jv; private boolean jvInitialized; @@ -196,7 +196,7 @@ public Manifest getManifest() throws IOException { } private Manifest getManifestFromReference() throws IOException { - Manifest man = manRef != null ? manRef.get() : null; + Manifest man = manRef; if (man == null) { @@ -213,7 +213,7 @@ private Manifest getManifestFromReference() throws IOException { } else { man = new Manifest(super.getInputStream(manEntry)); } - manRef = new SoftReference<>(man); + manRef = man; } } return man; diff --git a/sources/net.sf.j2s.java.core/src/java/util/jar/package.html b/sources/net.sf.j2s.java.core/src/java/util/jar/package.html deleted file mode 100644 index dd9ad7377..000000000 --- a/sources/net.sf.j2s.java.core/src/java/util/jar/package.html +++ /dev/null @@ -1,63 +0,0 @@ - - - - - - - - -Provides classes for reading and writing the JAR (Java ARchive) file -format, which is based on the standard ZIP file format with an -optional manifest file. The manifest stores meta-information about the -JAR file contents and is also used for signing JAR files. - - -

Package Specification

- -The java.util.jar package is based on the following specifications: - - - - -@since 1.2 - - diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/AbstractPreferences.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/AbstractPreferences.java new file mode 100644 index 000000000..31c35d7fa --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/AbstractPreferences.java @@ -0,0 +1,1619 @@ +/* + * Copyright (c) 2000, 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 java.util.prefs; + +import java.util.*; +import java.io.*; +import java.security.AccessController; +import java.security.PrivilegedAction; +// These imports needed only as a workaround for a JavaDoc bug +import java.lang.Integer; +import java.lang.Long; +import java.lang.Float; +import java.lang.Double; + +/** + * This class provides a skeletal implementation of the {@link Preferences} + * class, greatly easing the task of implementing it. + * + *

This class is for Preferences implementers only. + * Normal users of the Preferences facility should have no need to + * consult this documentation. The {@link Preferences} documentation + * should suffice. + * + *

Implementors must override the nine abstract service-provider interface + * (SPI) methods: {@link #getSpi(String)}, {@link #putSpi(String,String)}, + * {@link #removeSpi(String)}, {@link #childSpi(String)}, {@link + * #removeNodeSpi()}, {@link #keysSpi()}, {@link #childrenNamesSpi()}, {@link + * #syncSpi()} and {@link #flushSpi()}. All of the concrete methods specify + * precisely how they are implemented atop these SPI methods. The implementor + * may, at his discretion, override one or more of the concrete methods if the + * default implementation is unsatisfactory for any reason, such as + * performance. + * + *

The SPI methods fall into three groups concerning exception + * behavior. The getSpi method should never throw exceptions, but it + * doesn't really matter, as any exception thrown by this method will be + * intercepted by {@link #get(String,String)}, which will return the specified + * default value to the caller. The removeNodeSpi, keysSpi, + * childrenNamesSpi, syncSpi and flushSpi methods are specified + * to throw {@link BackingStoreException}, and the implementation is required + * to throw this checked exception if it is unable to perform the operation. + * The exception propagates outward, causing the corresponding API method + * to fail. + * + *

The remaining SPI methods {@link #putSpi(String,String)}, {@link + * #removeSpi(String)} and {@link #childSpi(String)} have more complicated + * exception behavior. They are not specified to throw + * BackingStoreException, as they can generally obey their contracts + * even if the backing store is unavailable. This is true because they return + * no information and their effects are not required to become permanent until + * a subsequent call to {@link Preferences#flush()} or + * {@link Preferences#sync()}. Generally speaking, these SPI methods should not + * throw exceptions. In some implementations, there may be circumstances + * under which these calls cannot even enqueue the requested operation for + * later processing. Even under these circumstances it is generally better to + * simply ignore the invocation and return, rather than throwing an + * exception. Under these circumstances, however, all subsequent invocations + * of flush() and sync should return false, as + * returning true would imply that all previous operations had + * successfully been made permanent. + * + *

There is one circumstance under which putSpi, removeSpi and + * childSpi should throw an exception: if the caller lacks + * sufficient privileges on the underlying operating system to perform the + * requested operation. This will, for instance, occur on most systems + * if a non-privileged user attempts to modify system preferences. + * (The required privileges will vary from implementation to + * implementation. On some implementations, they are the right to modify the + * contents of some directory in the file system; on others they are the right + * to modify contents of some key in a registry.) Under any of these + * circumstances, it would generally be undesirable to let the program + * continue executing as if these operations would become permanent at a later + * time. While implementations are not required to throw an exception under + * these circumstances, they are encouraged to do so. A {@link + * SecurityException} would be appropriate. + * + *

Most of the SPI methods require the implementation to read or write + * information at a preferences node. The implementor should beware of the + * fact that another VM may have concurrently deleted this node from the + * backing store. It is the implementation's responsibility to recreate the + * node if it has been deleted. + * + *

Implementation note: In Sun's default Preferences + * implementations, the user's identity is inherited from the underlying + * operating system and does not change for the lifetime of the virtual + * machine. It is recognized that server-side Preferences + * implementations may have the user identity change from request to request, + * implicitly passed to Preferences methods via the use of a + * static {@link ThreadLocal} instance. Authors of such implementations are + * strongly encouraged to determine the user at the time preferences + * are accessed (for example by the {@link #get(String,String)} or {@link + * #put(String,String)} method) rather than permanently associating a user + * with each Preferences instance. The latter behavior conflicts + * with normal Preferences usage and would lead to great confusion. + * + * @author Josh Bloch + * @see Preferences + * @since 1.4 + */ +public abstract class AbstractPreferences extends Preferences { + /** + * Our name relative to parent. + */ + private final String name; + + /** + * Our absolute path name. + */ + private final String absolutePath; + + /** + * Our parent node. + */ + final AbstractPreferences parent; + + /** + * Our root node. + */ + private final AbstractPreferences root; // Relative to this node + + /** + * This field should be true if this node did not exist in the + * backing store prior to the creation of this object. The field + * is initialized to false, but may be set to true by a subclass + * constructor (and should not be modified thereafter). This field + * indicates whether a node change event should be fired when + * creation is complete. + */ + protected boolean newNode = false; + + /** + * All known unremoved children of this node. (This "cache" is consulted + * prior to calling childSpi() or getChild(). + */ + private Map kidCache = new HashMap<>(); + + /** + * This field is used to keep track of whether or not this node has + * been removed. Once it's set to true, it will never be reset to false. + */ + private boolean removed = false; + + /** + * Registered preference change listeners. + */ + private PreferenceChangeListener[] prefListeners = + new PreferenceChangeListener[0]; + + /** + * Registered node change listeners. + */ + private NodeChangeListener[] nodeListeners = new NodeChangeListener[0]; + + /** + * An object whose monitor is used to lock this node. This object + * is used in preference to the node itself to reduce the likelihood of + * intentional or unintentional denial of service due to a locked node. + * To avoid deadlock, a node is never locked by a thread that + * holds a lock on a descendant of that node. + */ + protected final Object lock = new Object(); + + /** + * Creates a preference node with the specified parent and the specified + * name relative to its parent. + * + * @param parent the parent of this preference node, or null if this + * is the root. + * @param name the name of this preference node, relative to its parent, + * or "" if this is the root. + * @throws IllegalArgumentException if name contains a slash + * ('/'), or parent is null and + * name isn't "". + */ + protected AbstractPreferences(AbstractPreferences parent, String name) { + if (parent==null) { + if (!name.equals("")) + throw new IllegalArgumentException("Root name '"+name+ + "' must be \"\""); + this.absolutePath = "/"; + root = this; + } else { + if (name.indexOf('/') != -1) + throw new IllegalArgumentException("Name '" + name + + "' contains '/'"); + if (name.equals("")) + throw new IllegalArgumentException("Illegal name: empty string"); + + root = parent.root; + absolutePath = (parent==root ? "/" + name + : parent.absolutePath() + "/" + name); + } + this.name = name; + this.parent = parent; + } + + /** + * Implements the put method as per the specification in + * {@link Preferences#put(String,String)}. + * + *

This implementation checks that the key and value are legal, + * obtains this preference node's lock, checks that the node + * has not been removed, invokes {@link #putSpi(String,String)}, and if + * there are any preference change listeners, enqueues a notification + * event for processing by the event dispatch thread. + * + * @param key key with which the specified value is to be associated. + * @param value value to be associated with the specified key. + * @throws NullPointerException if key or value is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH or if value.length exceeds + * MAX_VALUE_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void put(String key, String value) { + if (key==null || value==null) + throw new NullPointerException(); + if (key.length() > MAX_KEY_LENGTH) + throw new IllegalArgumentException("Key too long: "+key); + if (value.length() > MAX_VALUE_LENGTH) + throw new IllegalArgumentException("Value too long: "+value); + + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + putSpi(key, value); + enqueuePreferenceChangeEvent(key, value); + } + } + + /** + * Implements the get method as per the specification in + * {@link Preferences#get(String,String)}. + * + *

This implementation first checks to see if key is + * null throwing a NullPointerException if this is + * the case. Then it obtains this preference node's lock, + * checks that the node has not been removed, invokes {@link + * #getSpi(String)}, and returns the result, unless the getSpi + * invocation returns null or throws an exception, in which case + * this invocation returns def. + * + * @param key key whose associated value is to be returned. + * @param def the value to be returned in the event that this + * preference node has no value associated with key. + * @return the value associated with key, or def + * if no value is associated with key. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. (A + * null default is permitted.) + */ + public String get(String key, String def) { + if (key==null) + throw new NullPointerException("Null key"); + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + String result = null; + try { + result = getSpi(key); + } catch (Exception e) { + // Ignoring exception causes default to be returned + } + return (result==null ? def : result); + } + } + + /** + * Implements the remove(String) method as per the specification + * in {@link Preferences#remove(String)}. + * + *

This implementation obtains this preference node's lock, + * checks that the node has not been removed, invokes + * {@link #removeSpi(String)} and if there are any preference + * change listeners, enqueues a notification event for processing by the + * event dispatch thread. + * + * @param key key whose mapping is to be removed from the preference node. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException {@inheritDoc}. + */ + public void remove(String key) { + Objects.requireNonNull(key, "Specified key cannot be null"); + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + removeSpi(key); + enqueuePreferenceChangeEvent(key, null); + } + } + + /** + * Implements the clear method as per the specification in + * {@link Preferences#clear()}. + * + *

This implementation obtains this preference node's lock, + * invokes {@link #keys()} to obtain an array of keys, and + * iterates over the array invoking {@link #remove(String)} on each key. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void clear() throws BackingStoreException { + synchronized(lock) { + String[] keys = keys(); + for (int i=0; iputInt method as per the specification in + * {@link Preferences#putInt(String,int)}. + * + *

This implementation translates value to a string with + * {@link Integer#toString(int)} and invokes {@link #put(String,String)} + * on the result. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void putInt(String key, int value) { + put(key, Integer.toString(value)); + } + + /** + * Implements the getInt method as per the specification in + * {@link Preferences#getInt(String,int)}. + * + *

This implementation invokes {@link #get(String,String) get(key, + * null)}. If the return value is non-null, the implementation + * attempts to translate it to an int with + * {@link Integer#parseInt(String)}. If the attempt succeeds, the return + * value is returned by this method. Otherwise, def is returned. + * + * @param key key whose associated value is to be returned as an int. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as an int. + * @return the int value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * an int. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + */ + public int getInt(String key, int def) { + int result = def; + try { + String value = get(key, null); + if (value != null) + result = Integer.parseInt(value); + } catch (NumberFormatException e) { + // Ignoring exception causes specified default to be returned + } + + return result; + } + + /** + * Implements the putLong method as per the specification in + * {@link Preferences#putLong(String,long)}. + * + *

This implementation translates value to a string with + * {@link Long#toString(long)} and invokes {@link #put(String,String)} + * on the result. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void putLong(String key, long value) { + put(key, Long.toString(value)); + } + + /** + * Implements the getLong method as per the specification in + * {@link Preferences#getLong(String,long)}. + * + *

This implementation invokes {@link #get(String,String) get(key, + * null)}. If the return value is non-null, the implementation + * attempts to translate it to a long with + * {@link Long#parseLong(String)}. If the attempt succeeds, the return + * value is returned by this method. Otherwise, def is returned. + * + * @param key key whose associated value is to be returned as a long. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a long. + * @return the long value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a long. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + */ + public long getLong(String key, long def) { + long result = def; + try { + String value = get(key, null); + if (value != null) + result = Long.parseLong(value); + } catch (NumberFormatException e) { + // Ignoring exception causes specified default to be returned + } + + return result; + } + + /** + * Implements the putBoolean method as per the specification in + * {@link Preferences#putBoolean(String,boolean)}. + * + *

This implementation translates value to a string with + * {@link String#valueOf(boolean)} and invokes {@link #put(String,String)} + * on the result. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void putBoolean(String key, boolean value) { + put(key, String.valueOf(value)); + } + + /** + * Implements the getBoolean method as per the specification in + * {@link Preferences#getBoolean(String,boolean)}. + * + *

This implementation invokes {@link #get(String,String) get(key, + * null)}. If the return value is non-null, it is compared with + * "true" using {@link String#equalsIgnoreCase(String)}. If the + * comparison returns true, this invocation returns + * true. Otherwise, the original return value is compared with + * "false", again using {@link String#equalsIgnoreCase(String)}. + * If the comparison returns true, this invocation returns + * false. Otherwise, this invocation returns def. + * + * @param key key whose associated value is to be returned as a boolean. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a boolean. + * @return the boolean value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a boolean. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + */ + public boolean getBoolean(String key, boolean def) { + boolean result = def; + String value = get(key, null); + if (value != null) { + if (value.equalsIgnoreCase("true")) + result = true; + else if (value.equalsIgnoreCase("false")) + result = false; + } + + return result; + } + + /** + * Implements the putFloat method as per the specification in + * {@link Preferences#putFloat(String,float)}. + * + *

This implementation translates value to a string with + * {@link Float#toString(float)} and invokes {@link #put(String,String)} + * on the result. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void putFloat(String key, float value) { + put(key, Float.toString(value)); + } + + /** + * Implements the getFloat method as per the specification in + * {@link Preferences#getFloat(String,float)}. + * + *

This implementation invokes {@link #get(String,String) get(key, + * null)}. If the return value is non-null, the implementation + * attempts to translate it to an float with + * {@link Float#parseFloat(String)}. If the attempt succeeds, the return + * value is returned by this method. Otherwise, def is returned. + * + * @param key key whose associated value is to be returned as a float. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a float. + * @return the float value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a float. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + */ + public float getFloat(String key, float def) { + float result = def; + try { + String value = get(key, null); + if (value != null) + result = Float.parseFloat(value); + } catch (NumberFormatException e) { + // Ignoring exception causes specified default to be returned + } + + return result; + } + + /** + * Implements the putDouble method as per the specification in + * {@link Preferences#putDouble(String,double)}. + * + *

This implementation translates value to a string with + * {@link Double#toString(double)} and invokes {@link #put(String,String)} + * on the result. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void putDouble(String key, double value) { + put(key, Double.toString(value)); + } + + /** + * Implements the getDouble method as per the specification in + * {@link Preferences#getDouble(String,double)}. + * + *

This implementation invokes {@link #get(String,String) get(key, + * null)}. If the return value is non-null, the implementation + * attempts to translate it to an double with + * {@link Double#parseDouble(String)}. If the attempt succeeds, the return + * value is returned by this method. Otherwise, def is returned. + * + * @param key key whose associated value is to be returned as a double. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a double. + * @return the double value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a double. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + */ + public double getDouble(String key, double def) { + double result = def; + try { + String value = get(key, null); + if (value != null) + result = Double.parseDouble(value); + } catch (NumberFormatException e) { + // Ignoring exception causes specified default to be returned + } + + return result; + } + + /** + * Implements the putByteArray method as per the specification in + * {@link Preferences#putByteArray(String,byte[])}. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key or value is null. + * @throws IllegalArgumentException if key.length() exceeds MAX_KEY_LENGTH + * or if value.length exceeds MAX_VALUE_LENGTH*3/4. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public void putByteArray(String key, byte[] value) { + put(key, Base64.byteArrayToBase64(value)); + } + + /** + * Implements the getByteArray method as per the specification in + * {@link Preferences#getByteArray(String,byte[])}. + * + * @param key key whose associated value is to be returned as a byte array. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a byte array. + * @return the byte array value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a byte array. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. (A + * null value for def is permitted.) + */ + public byte[] getByteArray(String key, byte[] def) { + byte[] result = def; + String value = get(key, null); + try { + if (value != null) + result = Base64.base64ToByteArray(value); + } + catch (RuntimeException e) { + // Ignoring exception causes specified default to be returned + } + + return result; + } + + /** + * Implements the keys method as per the specification in + * {@link Preferences#keys()}. + * + *

This implementation obtains this preference node's lock, checks that + * the node has not been removed and invokes {@link #keysSpi()}. + * + * @return an array of the keys that have an associated value in this + * preference node. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public String[] keys() throws BackingStoreException { + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + return keysSpi(); + } + } + + /** + * Implements the children method as per the specification in + * {@link Preferences#childrenNames()}. + * + *

This implementation obtains this preference node's lock, checks that + * the node has not been removed, constructs a TreeSet initialized + * to the names of children already cached (the children in this node's + * "child-cache"), invokes {@link #childrenNamesSpi()}, and adds all of the + * returned child-names into the set. The elements of the tree set are + * dumped into a String array using the toArray method, + * and this array is returned. + * + * @return the names of the children of this preference node. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #cachedChildren() + */ + public String[] childrenNames() throws BackingStoreException { + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + Set s = new TreeSet<>(kidCache.keySet()); + for (String kid : childrenNamesSpi()) + s.add(kid); + return s.toArray(EMPTY_STRING_ARRAY); + } + } + + private static final String[] EMPTY_STRING_ARRAY = new String[0]; + + /** + * Returns all known unremoved children of this node. + * + * @return all known unremoved children of this node. + */ + protected final AbstractPreferences[] cachedChildren() { + return kidCache.values().toArray(EMPTY_ABSTRACT_PREFS_ARRAY); + } + + private static final AbstractPreferences[] EMPTY_ABSTRACT_PREFS_ARRAY + = new AbstractPreferences[0]; + + /** + * Implements the parent method as per the specification in + * {@link Preferences#parent()}. + * + *

This implementation obtains this preference node's lock, checks that + * the node has not been removed and returns the parent value that was + * passed to this node's constructor. + * + * @return the parent of this preference node. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public Preferences parent() { + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + return parent; + } + } + + /** + * Implements the node method as per the specification in + * {@link Preferences#node(String)}. + * + *

This implementation obtains this preference node's lock and checks + * that the node has not been removed. If path is "", + * this node is returned; if path is "/", this node's + * root is returned. If the first character in path is + * not '/', the implementation breaks path into + * tokens and recursively traverses the path from this node to the + * named node, "consuming" a name and a slash from path at + * each step of the traversal. At each step, the current node is locked + * and the node's child-cache is checked for the named node. If it is + * not found, the name is checked to make sure its length does not + * exceed MAX_NAME_LENGTH. Then the {@link #childSpi(String)} + * method is invoked, and the result stored in this node's child-cache. + * If the newly created Preferences object's {@link #newNode} + * field is true and there are any node change listeners, + * a notification event is enqueued for processing by the event dispatch + * thread. + * + *

When there are no more tokens, the last value found in the + * child-cache or returned by childSpi is returned by this + * method. If during the traversal, two "/" tokens occur + * consecutively, or the final token is "/" (rather than a name), + * an appropriate IllegalArgumentException is thrown. + * + *

If the first character of path is '/' + * (indicating an absolute path name) this preference node's + * lock is dropped prior to breaking path into tokens, and + * this method recursively traverses the path starting from the root + * (rather than starting from this node). The traversal is otherwise + * identical to the one described for relative path names. Dropping + * the lock on this node prior to commencing the traversal at the root + * node is essential to avoid the possibility of deadlock, as per the + * {@link #lock locking invariant}. + * + * @param path the path name of the preference node to return. + * @return the specified preference node. + * @throws IllegalArgumentException if the path name is invalid (i.e., + * it contains multiple consecutive slash characters, or ends + * with a slash character and is more than one character long). + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public Preferences node(String path) { + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + if (path.equals("")) + return this; + if (path.equals("/")) + return root; + if (path.charAt(0) != '/') + return node(new StringTokenizer(path, "/", true)); + } + + // Absolute path. Note that we've dropped our lock to avoid deadlock + return root.node(new StringTokenizer(path.substring(1), "/", true)); + } + + /** + * tokenizer contains {'/' }* + */ + private Preferences node(StringTokenizer path) { + String token = path.nextToken(); + if (token.equals("/")) // Check for consecutive slashes + throw new IllegalArgumentException("Consecutive slashes in path"); + synchronized(lock) { + AbstractPreferences child = kidCache.get(token); + if (child == null) { + if (token.length() > MAX_NAME_LENGTH) + throw new IllegalArgumentException( + "Node name " + token + " too long"); + child = childSpi(token); + if (child.newNode) + enqueueNodeAddedEvent(child); + kidCache.put(token, child); + } + if (!path.hasMoreTokens()) + return child; + path.nextToken(); // Consume slash + if (!path.hasMoreTokens()) + throw new IllegalArgumentException("Path ends with slash"); + return child.node(path); + } + } + + /** + * Implements the nodeExists method as per the specification in + * {@link Preferences#nodeExists(String)}. + * + *

This implementation is very similar to {@link #node(String)}, + * except that {@link #getChild(String)} is used instead of {@link + * #childSpi(String)}. + * + * @param path the path name of the node whose existence is to be checked. + * @return true if the specified node exists. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalArgumentException if the path name is invalid (i.e., + * it contains multiple consecutive slash characters, or ends + * with a slash character and is more than one character long). + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method and + * pathname is not the empty string (""). + */ + public boolean nodeExists(String path) + throws BackingStoreException + { + synchronized(lock) { + if (path.equals("")) + return !removed; + if (removed) + throw new IllegalStateException("Node has been removed."); + if (path.equals("/")) + return true; + if (path.charAt(0) != '/') + return nodeExists(new StringTokenizer(path, "/", true)); + } + + // Absolute path. Note that we've dropped our lock to avoid deadlock + return root.nodeExists(new StringTokenizer(path.substring(1), "/", + true)); + } + + /** + * tokenizer contains {'/' }* + */ + private boolean nodeExists(StringTokenizer path) + throws BackingStoreException + { + String token = path.nextToken(); + if (token.equals("/")) // Check for consecutive slashes + throw new IllegalArgumentException("Consecutive slashes in path"); + synchronized(lock) { + AbstractPreferences child = kidCache.get(token); + if (child == null) + child = getChild(token); + if (child==null) + return false; + if (!path.hasMoreTokens()) + return true; + path.nextToken(); // Consume slash + if (!path.hasMoreTokens()) + throw new IllegalArgumentException("Path ends with slash"); + return child.nodeExists(path); + } + } + + /** + + * Implements the removeNode() method as per the specification in + * {@link Preferences#removeNode()}. + * + *

This implementation checks to see that this node is the root; if so, + * it throws an appropriate exception. Then, it locks this node's parent, + * and calls a recursive helper method that traverses the subtree rooted at + * this node. The recursive method locks the node on which it was called, + * checks that it has not already been removed, and then ensures that all + * of its children are cached: The {@link #childrenNamesSpi()} method is + * invoked and each returned child name is checked for containment in the + * child-cache. If a child is not already cached, the {@link + * #childSpi(String)} method is invoked to create a Preferences + * instance for it, and this instance is put into the child-cache. Then + * the helper method calls itself recursively on each node contained in its + * child-cache. Next, it invokes {@link #removeNodeSpi()}, marks itself + * as removed, and removes itself from its parent's child-cache. Finally, + * if there are any node change listeners, it enqueues a notification + * event for processing by the event dispatch thread. + * + *

Note that the helper method is always invoked with all ancestors up + * to the "closest non-removed ancestor" locked. + * + * @throws IllegalStateException if this node (or an ancestor) has already + * been removed with the {@link #removeNode()} method. + * @throws UnsupportedOperationException if this method is invoked on + * the root node. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + */ + public void removeNode() throws BackingStoreException { + if (this==root) + throw new UnsupportedOperationException("Can't remove the root!"); + synchronized(parent.lock) { + removeNode2(); + parent.kidCache.remove(name); + } + } + + /* + * Called with locks on all nodes on path from parent of "removal root" + * to this (including the former but excluding the latter). + */ + private void removeNode2() throws BackingStoreException { + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node already removed."); + + // Ensure that all children are cached + String[] kidNames = childrenNamesSpi(); + for (int i=0; i i = kidCache.values().iterator(); + i.hasNext();) { + try { + i.next().removeNode2(); + i.remove(); + } catch (BackingStoreException x) { } + } + + // Now we have no descendants - it's time to die! + removeNodeSpi(); + removed = true; + parent.enqueueNodeRemovedEvent(this); + } + } + + /** + * Implements the name method as per the specification in + * {@link Preferences#name()}. + * + *

This implementation merely returns the name that was + * passed to this node's constructor. + * + * @return this preference node's name, relative to its parent. + */ + public String name() { + return name; + } + + /** + * Implements the absolutePath method as per the specification in + * {@link Preferences#absolutePath()}. + * + *

This implementation merely returns the absolute path name that + * was computed at the time that this node was constructed (based on + * the name that was passed to this node's constructor, and the names + * that were passed to this node's ancestors' constructors). + * + * @return this preference node's absolute path name. + */ + public String absolutePath() { + return absolutePath; + } + + /** + * Implements the isUserNode method as per the specification in + * {@link Preferences#isUserNode()}. + * + *

This implementation compares this node's root node (which is stored + * in a private field) with the value returned by + * {@link Preferences#userRoot()}. If the two object references are + * identical, this method returns true. + * + * @return true if this preference node is in the user + * preference tree, false if it's in the system + * preference tree. + */ + public boolean isUserNode() { + return AccessController.doPrivileged( + new PrivilegedAction() { + public Boolean run() { + return root == Preferences.userRoot(); + } + }).booleanValue(); + } + + public void addPreferenceChangeListener(PreferenceChangeListener pcl) { + if (pcl==null) + throw new NullPointerException("Change listener is null."); + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + // Copy-on-write + PreferenceChangeListener[] old = prefListeners; + prefListeners = new PreferenceChangeListener[old.length + 1]; + System.arraycopy(old, 0, prefListeners, 0, old.length); + prefListeners[old.length] = pcl; + } + startEventDispatchThreadIfNecessary(); + } + + public void removePreferenceChangeListener(PreferenceChangeListener pcl) { + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + if ((prefListeners == null) || (prefListeners.length == 0)) + throw new IllegalArgumentException("Listener not registered."); + + // Copy-on-write + PreferenceChangeListener[] newPl = + new PreferenceChangeListener[prefListeners.length - 1]; + int i = 0; + while (i < newPl.length && prefListeners[i] != pcl) + newPl[i] = prefListeners[i++]; + + if (i == newPl.length && prefListeners[i] != pcl) + throw new IllegalArgumentException("Listener not registered."); + while (i < newPl.length) + newPl[i] = prefListeners[++i]; + prefListeners = newPl; + } + } + + public void addNodeChangeListener(NodeChangeListener ncl) { + if (ncl==null) + throw new NullPointerException("Change listener is null."); + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + + // Copy-on-write + if (nodeListeners == null) { + nodeListeners = new NodeChangeListener[1]; + nodeListeners[0] = ncl; + } else { + NodeChangeListener[] old = nodeListeners; + nodeListeners = new NodeChangeListener[old.length + 1]; + System.arraycopy(old, 0, nodeListeners, 0, old.length); + nodeListeners[old.length] = ncl; + } + } + startEventDispatchThreadIfNecessary(); + } + + public void removeNodeChangeListener(NodeChangeListener ncl) { + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed."); + if ((nodeListeners == null) || (nodeListeners.length == 0)) + throw new IllegalArgumentException("Listener not registered."); + + // Copy-on-write + int i = 0; + while (i < nodeListeners.length && nodeListeners[i] != ncl) + i++; + if (i == nodeListeners.length) + throw new IllegalArgumentException("Listener not registered."); + NodeChangeListener[] newNl = + new NodeChangeListener[nodeListeners.length - 1]; + if (i != 0) + System.arraycopy(nodeListeners, 0, newNl, 0, i); + if (i != newNl.length) + System.arraycopy(nodeListeners, i + 1, + newNl, i, newNl.length - i); + nodeListeners = newNl; + } + } + + // "SPI" METHODS + + /** + * Put the given key-value association into this preference node. It is + * guaranteed that key and value are non-null and of + * legal length. Also, it is guaranteed that this node has not been + * removed. (The implementor needn't check for any of these things.) + * + *

This method is invoked with the lock on this node held. + * @param key the key + * @param value the value + */ + protected abstract void putSpi(String key, String value); + + /** + * Return the value associated with the specified key at this preference + * node, or null if there is no association for this key, or the + * association cannot be determined at this time. It is guaranteed that + * key is non-null. Also, it is guaranteed that this node has + * not been removed. (The implementor needn't check for either of these + * things.) + * + *

Generally speaking, this method should not throw an exception + * under any circumstances. If, however, if it does throw an exception, + * the exception will be intercepted and treated as a null + * return value. + * + *

This method is invoked with the lock on this node held. + * + * @param key the key + * @return the value associated with the specified key at this preference + * node, or null if there is no association for this + * key, or the association cannot be determined at this time. + */ + protected abstract String getSpi(String key); + + /** + * Remove the association (if any) for the specified key at this + * preference node. It is guaranteed that key is non-null. + * Also, it is guaranteed that this node has not been removed. + * (The implementor needn't check for either of these things.) + * + *

This method is invoked with the lock on this node held. + * @param key the key + */ + protected abstract void removeSpi(String key); + + /** + * Removes this preference node, invalidating it and any preferences that + * it contains. The named child will have no descendants at the time this + * invocation is made (i.e., the {@link Preferences#removeNode()} method + * invokes this method repeatedly in a bottom-up fashion, removing each of + * a node's descendants before removing the node itself). + * + *

This method is invoked with the lock held on this node and its + * parent (and all ancestors that are being removed as a + * result of a single invocation to {@link Preferences#removeNode()}). + * + *

The removal of a node needn't become persistent until the + * flush method is invoked on this node (or an ancestor). + * + *

If this node throws a BackingStoreException, the exception + * will propagate out beyond the enclosing {@link #removeNode()} + * invocation. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + */ + protected abstract void removeNodeSpi() throws BackingStoreException; + + /** + * Returns all of the keys that have an associated value in this + * preference node. (The returned array will be of size zero if + * this node has no preferences.) It is guaranteed that this node has not + * been removed. + * + *

This method is invoked with the lock on this node held. + * + *

If this node throws a BackingStoreException, the exception + * will propagate out beyond the enclosing {@link #keys()} invocation. + * + * @return an array of the keys that have an associated value in this + * preference node. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + */ + protected abstract String[] keysSpi() throws BackingStoreException; + + /** + * Returns the names of the children of this preference node. (The + * returned array will be of size zero if this node has no children.) + * This method need not return the names of any nodes already cached, + * but may do so without harm. + * + *

This method is invoked with the lock on this node held. + * + *

If this node throws a BackingStoreException, the exception + * will propagate out beyond the enclosing {@link #childrenNames()} + * invocation. + * + * @return an array containing the names of the children of this + * preference node. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + */ + protected abstract String[] childrenNamesSpi() + throws BackingStoreException; + + /** + * Returns the named child if it exists, or null if it does not. + * It is guaranteed that nodeName is non-null, non-empty, + * does not contain the slash character ('/'), and is no longer than + * {@link #MAX_NAME_LENGTH} characters. Also, it is guaranteed + * that this node has not been removed. (The implementor needn't check + * for any of these things if he chooses to override this method.) + * + *

Finally, it is guaranteed that the named node has not been returned + * by a previous invocation of this method or {@link #childSpi} after the + * last time that it was removed. In other words, a cached value will + * always be used in preference to invoking this method. (The implementor + * needn't maintain his own cache of previously returned children if he + * chooses to override this method.) + * + *

This implementation obtains this preference node's lock, invokes + * {@link #childrenNames()} to get an array of the names of this node's + * children, and iterates over the array comparing the name of each child + * with the specified node name. If a child node has the correct name, + * the {@link #childSpi(String)} method is invoked and the resulting + * node is returned. If the iteration completes without finding the + * specified name, null is returned. + * + * @param nodeName name of the child to be searched for. + * @return the named child if it exists, or null if it does not. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + */ + protected AbstractPreferences getChild(String nodeName) + throws BackingStoreException { + synchronized(lock) { + // assert kidCache.get(nodeName)==null; + String[] kidNames = childrenNames(); + for (int i=0; iname is non-null, + * non-empty, does not contain the slash character ('/'), and is no longer + * than {@link #MAX_NAME_LENGTH} characters. Also, it is guaranteed that + * this node has not been removed. (The implementor needn't check for any + * of these things.) + * + *

Finally, it is guaranteed that the named node has not been returned + * by a previous invocation of this method or {@link #getChild(String)} + * after the last time that it was removed. In other words, a cached + * value will always be used in preference to invoking this method. + * Subclasses need not maintain their own cache of previously returned + * children. + * + *

The implementer must ensure that the returned node has not been + * removed. If a like-named child of this node was previously removed, the + * implementer must return a newly constructed AbstractPreferences + * node; once removed, an AbstractPreferences node + * cannot be "resuscitated." + * + *

If this method causes a node to be created, this node is not + * guaranteed to be persistent until the flush method is + * invoked on this node or one of its ancestors (or descendants). + * + *

This method is invoked with the lock on this node held. + * + * @param name The name of the child node to return, relative to + * this preference node. + * @return The named child node. + */ + protected abstract AbstractPreferences childSpi(String name); + + /** + * Returns the absolute path name of this preferences node. + */ + public String toString() { + return (this.isUserNode() ? "User" : "System") + + " Preference Node: " + this.absolutePath(); + } + + /** + * Implements the sync method as per the specification in + * {@link Preferences#sync()}. + * + *

This implementation calls a recursive helper method that locks this + * node, invokes syncSpi() on it, unlocks this node, and recursively + * invokes this method on each "cached child." A cached child is a child + * of this node that has been created in this VM and not subsequently + * removed. In effect, this method does a depth first traversal of the + * "cached subtree" rooted at this node, calling syncSpi() on each node in + * the subTree while only that node is locked. Note that syncSpi() is + * invoked top-down. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #flush() + */ + public void sync() throws BackingStoreException { + sync2(); + } + + private void sync2() throws BackingStoreException { + AbstractPreferences[] cachedKids; + + synchronized(lock) { + if (removed) + throw new IllegalStateException("Node has been removed"); + syncSpi(); + cachedKids = cachedChildren(); + } + + for (int i=0; inot synchronize the preferences in + * any subnodes of this node. If the backing store naturally syncs an + * entire subtree at once, the implementer is encouraged to override + * sync(), rather than merely overriding this method. + * + *

If this node throws a BackingStoreException, the exception + * will propagate out beyond the enclosing {@link #sync()} invocation. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + */ + protected abstract void syncSpi() throws BackingStoreException; + + /** + * Implements the flush method as per the specification in + * {@link Preferences#flush()}. + * + *

This implementation calls a recursive helper method that locks this + * node, invokes flushSpi() on it, unlocks this node, and recursively + * invokes this method on each "cached child." A cached child is a child + * of this node that has been created in this VM and not subsequently + * removed. In effect, this method does a depth first traversal of the + * "cached subtree" rooted at this node, calling flushSpi() on each node in + * the subTree while only that node is locked. Note that flushSpi() is + * invoked top-down. + * + *

If this method is invoked on a node that has been removed with + * the {@link #removeNode()} method, flushSpi() is invoked on this node, + * but not on others. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @see #flush() + */ + public void flush() throws BackingStoreException { + flush2(); + } + + private void flush2() throws BackingStoreException { + AbstractPreferences[] cachedKids; + + synchronized(lock) { + flushSpi(); + if(removed) + return; + cachedKids = cachedChildren(); + } + + for (int i = 0; i < cachedKids.length; i++) + cachedKids[i].flush2(); + } + + /** + * This method is invoked with this node locked. The contract of this + * method is to force any cached changes in the contents of this + * preference node to the backing store, guaranteeing their persistence. + * (It is perfectly possible that this node does not exist on the backing + * store, either because it has been deleted by another VM, or because it + * has not yet been created.) Note that this method should not + * flush the preferences in any subnodes of this node. If the backing + * store naturally flushes an entire subtree at once, the implementer is + * encouraged to override flush(), rather than merely overriding this + * method. + * + *

If this node throws a BackingStoreException, the exception + * will propagate out beyond the enclosing {@link #flush()} invocation. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + */ + protected abstract void flushSpi() throws BackingStoreException; + + /** + * Returns true iff this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. This method + * locks this node prior to returning the contents of the private + * field used to track this state. + * + * @return true iff this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + protected boolean isRemoved() { + synchronized(lock) { + return removed; + } + } + + /** + * Queue of pending notification events. When a preference or node + * change event for which there are one or more listeners occurs, + * it is placed on this queue and the queue is notified. A background + * thread waits on this queue and delivers the events. This decouples + * event delivery from preference activity, greatly simplifying + * locking and reducing opportunity for deadlock. + */ + private static final List eventQueue = new LinkedList<>(); + + /** + * These two classes are used to distinguish NodeChangeEvents on + * eventQueue so the event dispatch thread knows whether to call + * childAdded or childRemoved. + */ + private class NodeAddedEvent extends NodeChangeEvent { + private static final long serialVersionUID = -6743557530157328528L; + NodeAddedEvent(Preferences parent, Preferences child) { + super(parent, child); + } + } + private class NodeRemovedEvent extends NodeChangeEvent { + private static final long serialVersionUID = 8735497392918824837L; + NodeRemovedEvent(Preferences parent, Preferences child) { + super(parent, child); + } + } + + /** + * A single background thread ("the event notification thread") monitors + * the event queue and delivers events that are placed on the queue. + */ + private static class EventDispatchThread extends Thread { + public void run() { + while(true) { + // Wait on eventQueue till an event is present + EventObject event = null; + synchronized(eventQueue) { + try { + while (eventQueue.isEmpty()) + eventQueue.wait(); + event = eventQueue.remove(0); + } catch (InterruptedException e) { + // XXX Log "Event dispatch thread interrupted. Exiting" + return; + } + } + + // Now we have event & hold no locks; deliver evt to listeners + AbstractPreferences src=(AbstractPreferences)event.getSource(); + if (event instanceof PreferenceChangeEvent) { + PreferenceChangeEvent pce = (PreferenceChangeEvent)event; + PreferenceChangeListener[] listeners = src.prefListeners(); + for (int i=0; iexportNode method as per the specification in + * {@link Preferences#exportNode(OutputStream)}. + * + * @param os the output stream on which to emit the XML document. + * @throws IOException if writing to the specified output stream + * results in an IOException. + * @throws BackingStoreException if preference data cannot be read from + * backing store. + */ + public void exportNode(OutputStream os) + throws IOException, BackingStoreException + { + XmlSupport.export(os, this, false); + } + + /** + * Implements the exportSubtree method as per the specification in + * {@link Preferences#exportSubtree(OutputStream)}. + * + * @param os the output stream on which to emit the XML document. + * @throws IOException if writing to the specified output stream + * results in an IOException. + * @throws BackingStoreException if preference data cannot be read from + * backing store. + */ + public void exportSubtree(OutputStream os) + throws IOException, BackingStoreException + { + XmlSupport.export(os, this, true); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/BackingStoreException.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/BackingStoreException.java new file mode 100644 index 000000000..0bce9c6cd --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/BackingStoreException.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2000, 2003, 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 java.util.prefs; + +import java.io.NotSerializableException; + +/** + * Thrown to indicate that a preferences operation could not complete because + * of a failure in the backing store, or a failure to contact the backing + * store. + * + * @author Josh Bloch + * @since 1.4 + */ +public class BackingStoreException extends Exception { + /** + * Constructs a BackingStoreException with the specified detail message. + * + * @param s the detail message. + */ + public BackingStoreException(String s) { + super(s); + } + + /** + * Constructs a BackingStoreException with the specified cause. + * + * @param cause the cause + */ + public BackingStoreException(Throwable cause) { + super(cause); + } + + private static final long serialVersionUID = 859796500401108469L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/Base64.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/Base64.java new file mode 100644 index 000000000..c0d8d5318 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/Base64.java @@ -0,0 +1,261 @@ +/* + * Copyright (c) 2000, 2005, 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 java.util.prefs; + +/** + * Static methods for translating Base64 encoded strings to byte arrays + * and vice-versa. + * + * @author Josh Bloch + * @see Preferences + * @since 1.4 + */ +class Base64 { + /** + * Translates the specified byte array into a Base64 string as per + * Preferences.put(byte[]). + */ + static String byteArrayToBase64(byte[] a) { + return byteArrayToBase64(a, false); + } + + /** + * Translates the specified byte array into an "alternate representation" + * Base64 string. This non-standard variant uses an alphabet that does + * not contain the uppercase alphabetic characters, which makes it + * suitable for use in situations where case-folding occurs. + */ + static String byteArrayToAltBase64(byte[] a) { + return byteArrayToBase64(a, true); + } + + private static String byteArrayToBase64(byte[] a, boolean alternate) { + int aLen = a.length; + int numFullGroups = aLen/3; + int numBytesInPartialGroup = aLen - 3*numFullGroups; + int resultLen = 4*((aLen + 2)/3); + StringBuffer result = new StringBuffer(resultLen); + char[] intToAlpha = (alternate ? intToAltBase64 : intToBase64); + + // Translate all full groups from byte array elements to Base64 + int inCursor = 0; + for (int i=0; i> 2]); + result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); + result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]); + result.append(intToAlpha[byte2 & 0x3f]); + } + + // Translate partial group if present + if (numBytesInPartialGroup != 0) { + int byte0 = a[inCursor++] & 0xff; + result.append(intToAlpha[byte0 >> 2]); + if (numBytesInPartialGroup == 1) { + result.append(intToAlpha[(byte0 << 4) & 0x3f]); + result.append("=="); + } else { + // assert numBytesInPartialGroup == 2; + int byte1 = a[inCursor++] & 0xff; + result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]); + result.append(intToAlpha[(byte1 << 2)&0x3f]); + result.append('='); + } + } + // assert inCursor == a.length; + // assert result.length() == resultLen; + return result.toString(); + } + + /** + * This array is a lookup table that translates 6-bit positive integer + * index values into their "Base64 Alphabet" equivalents as specified + * in Table 1 of RFC 2045. + */ + private static final char intToBase64[] = { + 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/' + }; + + /** + * This array is a lookup table that translates 6-bit positive integer + * index values into their "Alternate Base64 Alphabet" equivalents. + * This is NOT the real Base64 Alphabet as per in Table 1 of RFC 2045. + * This alternate alphabet does not use the capital letters. It is + * designed for use in environments where "case folding" occurs. + */ + private static final char intToAltBase64[] = { + '!', '"', '#', '$', '%', '&', '\'', '(', ')', ',', '-', '.', ':', + ';', '<', '>', '@', '[', ']', '^', '`', '_', '{', '|', '}', '~', + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', + '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '?' + }; + + /** + * Translates the specified Base64 string (as per Preferences.get(byte[])) + * into a byte array. + * + * @throw IllegalArgumentException if s is not a valid Base64 + * string. + */ + static byte[] base64ToByteArray(String s) { + return base64ToByteArray(s, false); + } + + /** + * Translates the specified "alternate representation" Base64 string + * into a byte array. + * + * @throw IllegalArgumentException or ArrayOutOfBoundsException + * if s is not a valid alternate representation + * Base64 string. + */ + static byte[] altBase64ToByteArray(String s) { + return base64ToByteArray(s, true); + } + + private static byte[] base64ToByteArray(String s, boolean alternate) { + byte[] alphaToInt = (alternate ? altBase64ToInt : base64ToInt); + int sLen = s.length(); + int numGroups = sLen/4; + if (4*numGroups != sLen) + throw new IllegalArgumentException( + "String length must be a multiple of four."); + int missingBytesInLastGroup = 0; + int numFullGroups = numGroups; + if (sLen != 0) { + if (s.charAt(sLen-1) == '=') { + missingBytesInLastGroup++; + numFullGroups--; + } + if (s.charAt(sLen-2) == '=') + missingBytesInLastGroup++; + } + byte[] result = new byte[3*numGroups - missingBytesInLastGroup]; + + // Translate all full groups from base64 to byte array elements + int inCursor = 0, outCursor = 0; + for (int i=0; i> 4)); + result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); + result[outCursor++] = (byte) ((ch2 << 6) | ch3); + } + + // Translate partial group, if present + if (missingBytesInLastGroup != 0) { + int ch0 = base64toInt(s.charAt(inCursor++), alphaToInt); + int ch1 = base64toInt(s.charAt(inCursor++), alphaToInt); + result[outCursor++] = (byte) ((ch0 << 2) | (ch1 >> 4)); + + if (missingBytesInLastGroup == 1) { + int ch2 = base64toInt(s.charAt(inCursor++), alphaToInt); + result[outCursor++] = (byte) ((ch1 << 4) | (ch2 >> 2)); + } + } + // assert inCursor == s.length()-missingBytesInLastGroup; + // assert outCursor == result.length; + return result; + } + + /** + * Translates the specified character, which is assumed to be in the + * "Base 64 Alphabet" into its equivalent 6-bit positive integer. + * + * @throw IllegalArgumentException or ArrayOutOfBoundsException if + * c is not in the Base64 Alphabet. + */ + private static int base64toInt(char c, byte[] alphaToInt) { + int result = alphaToInt[c]; + if (result < 0) + throw new IllegalArgumentException("Illegal character " + c); + return result; + } + + /** + * This array is a lookup table that translates unicode characters + * drawn from the "Base64 Alphabet" (as specified in Table 1 of RFC 2045) + * into their 6-bit positive integer equivalents. Characters that + * are not in the Base64 alphabet but fall within the bounds of the + * array are translated to -1. + */ + private static final byte base64ToInt[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, -1, -1, -1, -1, -1, -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51 + }; + + /** + * This array is the analogue of base64ToInt, but for the nonstandard + * variant that avoids the use of uppercase alphabetic characters. + */ + private static final byte altBase64ToInt[] = { + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, + 2, 3, 4, 5, 6, 7, 8, -1, 62, 9, 10, 11, -1 , 52, 53, 54, 55, 56, 57, + 58, 59, 60, 61, 12, 13, 14, -1, 15, 63, 16, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 17, -1, 18, 19, 21, 20, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 22, 23, 24, 25 + }; + + public static void main(String args[]) { + int numRuns = Integer.parseInt(args[0]); + int numBytes = Integer.parseInt(args[1]); + java.util.Random rnd = new java.util.Random(); + for (int i=0; i prefsCache = null; +// +// /** +// * The last modification time of the file backing this node at the time +// * that prefCache was last synchronized (or initially read). This +// * value is set *before* reading the file, so it's conservative; the +// * actual timestamp could be (slightly) higher. A value of zero indicates +// * that we were unable to initialize prefsCache from the disk, or +// * have not yet attempted to do so. (If prefsCache is non-null, it +// * indicates the former; if it's null, the latter.) +// */ +// private long lastSyncTime = 0; +// +// /** +// * Unix error code for locked file. +// */ +// private static int EAGAIN = 11; +// +// /** +// * Unix error code for denied access. +// */ +// private static int EACCES = 13; +// +// /* Used to interpret results of native functions */ +// private static int LOCK_HANDLE = 0; +// private static int ERROR_CODE = 1; +// +// /** +// * A list of all uncommitted preference changes. The elements in this +// * list are of type PrefChange. If this node is concurrently modified on +// * disk by another VM, the two sets of changes are merged when this node +// * is sync'ed by overwriting our prefsCache with the preference map last +// * written out to disk (by the other VM), and then replaying this change +// * log against that map. The resulting map is then written back +// * to the disk. +// */ +// List changeLog = new ArrayList<>(); +// +// /** +// * Represents a change to a preference. +// */ +// private abstract class Change { +// /** +// * Reapplies the change to prefsCache. +// */ +// abstract void replay(); +// }; +// +// /** +// * Represents a preference put. +// */ +// private class Put extends Change { +// String key, value; +// +// Put(String key, String value) { +// this.key = key; +// this.value = value; +// } +// +// void replay() { +// prefsCache.put(key, value); +// } +// } +// +// /** +// * Represents a preference remove. +// */ +// private class Remove extends Change { +// String key; +// +// Remove(String key) { +// this.key = key; +// } +// +// void replay() { +// prefsCache.remove(key); +// } +// } +// +// /** +// * Represents the creation of this node. +// */ +// private class NodeCreate extends Change { +// /** +// * Performs no action, but the presence of this object in changeLog +// * will force the node and its ancestors to be made permanent at the +// * next sync. +// */ +// void replay() { +// } +// } +// +// /** +// * NodeCreate object for this node. +// */ +// NodeCreate nodeCreate = null; +// +// /** +// * Replay changeLog against prefsCache. +// */ +// private void replayChanges() { +// for (int i = 0, n = changeLog.size(); i() { +// public Void run() { +// Runtime.getRuntime().addShutdownHook(new Thread() { +// public void run() { +// syncTimer.cancel(); +// syncWorld(); +// } +// }); +// return null; +// } +// }); +// } +// +// private static void syncWorld() { +// /* +// * Synchronization necessary because userRoot and systemRoot are +// * lazily initialized. +// */ +// Preferences userRt; +// Preferences systemRt; +// synchronized(FileSystemPreferences.class) { +// userRt = userRoot; +// systemRt = systemRoot; +// } +// +// try { +// if (userRt != null) +// userRt.flush(); +// } catch(BackingStoreException e) { +// getLogger().warning("Couldn't flush user prefs: " + e); +// } +// +// try { +// if (systemRt != null) +// systemRt.flush(); +// } catch(BackingStoreException e) { +// getLogger().warning("Couldn't flush system prefs: " + e); +// } +// } + + private boolean isUserNode; + + /** + * Special constructor for roots (both user and system). This constructor + * will only be called twice, by the static initializer. + */ + private FileSystemPreferences(boolean user) { + super(null, ""); + isUserNode = user; + dir = (user ? userRootDir: systemRootDir); +// prefsFile = new File(dir, "prefs.xml"); +// tmpFile = new File(dir, "prefs.tmp"); + } + + /** + * Construct a new FileSystemPreferences instance with the specified + * parent node and name. This constructor, called from childSpi, + * is used to make every node except for the two //roots. + */ + private FileSystemPreferences(FileSystemPreferences parent, String name) { + super(parent, name); + isUserNode = parent.isUserNode; + dir = new File(parent.dir, dirName(name)); + newNode = !dir.exists(); + +// prefsFile = new File(dir, "prefs.xml"); +// tmpFile = new File(dir, "prefs.tmp"); + AccessController.doPrivileged(new PrivilegedAction() { + @Override + public Void run() { + newNode = !dir.exists(); + return null; + } + }); + if (newNode) { + // These 2 things guarantee node will get wrtten at next flush/sync + prefsCache = new TreeMap<>(); +// nodeCreate = new NodeCreate(); +// changeLog.add(nodeCreate); + } + } + + @Override + public boolean isUserNode() { + return isUserNode; + } + + @Override + protected void putSpi(String key, String value) { + initCacheIfNecessary(); +// changeLog.add(new Put(key, value)); + prefsCache.put(key, value); + } + + @Override + protected String getSpi(String key) { + initCacheIfNecessary(); + return prefsCache.get(key); + } + + @Override + protected void removeSpi(String key) { + initCacheIfNecessary(); +// changeLog.add(new Remove(key)); + prefsCache.remove(key); + } + + /** + * Initialize prefsCache if it has yet to be initialized. When this method + * returns, prefsCache will be non-null. If the data was successfully + * read from the file, lastSyncTime will be updated. If prefsCache was + * null, but it was impossible to read the file (because it didn't + * exist or for any other reason) prefsCache will be initialized to an + * empty, modifiable Map, and lastSyncTime remain zero. + */ + private void initCacheIfNecessary() { + if (prefsCache != null) + return; + +// SwingJS - this where we might load a cache from some sort of cookie? +// try { +// loadCache(); +// } catch(Exception e) { + // assert lastSyncTime == 0; + prefsCache = new TreeMap<>(); +// } + } + +// /** +// * Attempt to load prefsCache from the backing store. If the attempt +// * succeeds, lastSyncTime will be updated (the new value will typically +// * correspond to the data loaded into the map, but it may be less, +// * if another VM is updating this node concurrently). If the attempt +// * fails, a BackingStoreException is thrown and both prefsCache and +// * lastSyncTime are unaffected by the call. +// */ +// private void loadCache() throws BackingStoreException { +// try { +// AccessController.doPrivileged( +// new PrivilegedExceptionAction() { +// public Void run() throws BackingStoreException { +// Map m = new TreeMap<>(); +// long newLastSyncTime = 0; +// try { +// newLastSyncTime = prefsFile.lastModified(); +// try (FileInputStream fis = new FileInputStream(prefsFile)) { +// XmlSupport.importMap(fis, m); +// } +// } catch(Exception e) { +// if (e instanceof InvalidPreferencesFormatException) { +// getLogger().warning("Invalid preferences format in " +// + prefsFile.getPath()); +// prefsFile.renameTo( new File( +// prefsFile.getParentFile(), +// "IncorrectFormatPrefs.xml")); +// m = new TreeMap<>(); +// } else if (e instanceof FileNotFoundException) { +// getLogger().warning("Prefs file removed in background " +// + prefsFile.getPath()); +// } else { +// throw new BackingStoreException(e); +// } +// } +// // Attempt succeeded; update state +// prefsCache = m; +// lastSyncTime = newLastSyncTime; +// return null; +// } +// }); +// } catch (PrivilegedActionException e) { +// throw (BackingStoreException) e.getException(); +// } +// } +// +// /** +// * Attempt to write back prefsCache to the backing store. If the attempt +// * succeeds, lastSyncTime will be updated (the new value will correspond +// * exactly to the data thust written back, as we hold the file lock, which +// * prevents a concurrent write. If the attempt fails, a +// * BackingStoreException is thrown and both the backing store (prefsFile) +// * and lastSyncTime will be unaffected by this call. This call will +// * NEVER leave prefsFile in a corrupt state. +// */ +// private void writeBackCache() throws BackingStoreException { +// try { +// AccessController.doPrivileged( +// new PrivilegedExceptionAction() { +// public Void run() throws BackingStoreException { +// try { +// if (!dir.exists() && !dir.mkdirs()) +// throw new BackingStoreException(dir + +// " create failed."); +// try (FileOutputStream fos = new FileOutputStream(tmpFile)) { +// XmlSupport.exportMap(fos, prefsCache); +// } +// if (!tmpFile.renameTo(prefsFile)) +// throw new BackingStoreException("Can't rename " + +// tmpFile + " to " + prefsFile); +// } catch(Exception e) { +// if (e instanceof BackingStoreException) +// throw (BackingStoreException)e; +// throw new BackingStoreException(e); +// } +// return null; +// } +// }); +// } catch (PrivilegedActionException e) { +// throw (BackingStoreException) e.getException(); +// } +// } +// + @Override + protected String[] keysSpi() { + initCacheIfNecessary(); + return prefsCache.keySet().toArray(new String[prefsCache.size()]); + } + + @Override + protected String[] childrenNamesSpi() { +// return AccessController.doPrivileged( +// new PrivilegedAction() { +// public String[] run() { + List result = new ArrayList<>(); + File[] dirContents = dir.listFiles(); + if (dirContents != null) { + for (int i = 0; i < dirContents.length; i++) + if (dirContents[i].isDirectory()) + result.add(nodeName(dirContents[i].getName())); + } + return result.toArray(EMPTY_STRING_ARRAY); +// } +// }); + } + + private static String[] EMPTY_STRING_ARRAY = new String[0]; + + @Override + protected AbstractPreferences childSpi(String name) { + return new FileSystemPreferences(this, name); + } + + @Override + public void removeNode() throws BackingStoreException { +// synchronized (isUserNode()? userLockFile: systemLockFile) { +// // to remove a node we need an exclusive lock +// if (!lockFile(false)) +// throw(new BackingStoreException("Couldn't get file lock.")); +// try { +// super.removeNode(); +// } finally { +// unlockFile(); +// } +// } + } + + /** + * Called with file lock held (in addition to node locks). + */ + @Override + protected void removeNodeSpi() throws BackingStoreException { +// try { +// AccessController.doPrivileged( +// new PrivilegedExceptionAction() { +// public Void run() throws BackingStoreException { +// if (changeLog.contains(nodeCreate)) { +// changeLog.remove(nodeCreate); +// nodeCreate = null; +// return null; +// } +// if (!dir.exists()) +// return null; +// prefsFile.delete(); +// tmpFile.delete(); +// // dir should be empty now. If it's not, empty it +// File[] junk = dir.listFiles(); +// if (junk.length != 0) { +// getLogger().warning( +// "Found extraneous files when removing node: " +// + Arrays.asList(junk)); +// for (int i=0; i() { +// public Long run() { +// long nmt; +// if (isUserNode()) { +// nmt = userRootModFile.lastModified(); +// isUserRootModified = userRootModTime == nmt; +// } else { +// nmt = systemRootModFile.lastModified(); +// isSystemRootModified = systemRootModTime == nmt; +// } +// return new Long(nmt); +// } +// }); +// try { +// super.sync(); +// AccessController.doPrivileged(new PrivilegedAction() { +// public Void run() { +// if (isUserNode()) { +// userRootModTime = newModTime.longValue() + 1000; +// userRootModFile.setLastModified(userRootModTime); +// } else { +// systemRootModTime = newModTime.longValue() + 1000; +// systemRootModFile.setLastModified(systemRootModTime); +// } +// return null; +// } +// }); +// } finally { +// unlockFile(); +// } +// } + } + + @Override + protected void syncSpi() throws BackingStoreException { +// try { +// AccessController.doPrivileged( +// new PrivilegedExceptionAction() { +// public Void run() throws BackingStoreException { +// syncSpiPrivileged(); +// return null; +// } +// }); +// } catch (PrivilegedActionException e) { +// throw (BackingStoreException) e.getException(); +// } + } +// private void syncSpiPrivileged() throws BackingStoreException { +// if (isRemoved()) +// throw new IllegalStateException("Node has been removed"); +// if (prefsCache == null) +// return; // We've never been used, don't bother syncing +// long lastModifiedTime; +// if ((isUserNode() ? isUserRootModified : isSystemRootModified)) { +// lastModifiedTime = prefsFile.lastModified(); +// if (lastModifiedTime != lastSyncTime) { +// // Prefs at this node were externally modified; read in node and +// // playback any local mods since last sync +// loadCache(); +// replayChanges(); +// lastSyncTime = lastModifiedTime; +// } +// } else if (lastSyncTime != 0 && !dir.exists()) { +// // This node was removed in the background. Playback any changes +// // against a virgin (empty) Map. +// prefsCache = new TreeMap<>(); +// replayChanges(); +// } +// if (!changeLog.isEmpty()) { +// writeBackCache(); // Creates directory & file if necessary +// /* +// * Attempt succeeded; it's barely possible that the call to +// * lastModified might fail (i.e., return 0), but this would not +// * be a disaster, as lastSyncTime is allowed to lag. +// */ +// lastModifiedTime = prefsFile.lastModified(); +// /* If lastSyncTime did not change, or went back +// * increment by 1 second. Since we hold the lock +// * lastSyncTime always monotonically encreases in the +// * atomic sense. +// */ +// if (lastSyncTime <= lastModifiedTime) { +// lastSyncTime = lastModifiedTime + 1000; +// prefsFile.setLastModified(lastSyncTime); +// } +// changeLog.clear(); +// } +// } + + @Override + public void flush() throws BackingStoreException { +// if (isRemoved()) +// return; +// sync(); + } + + @Override + protected void flushSpi() throws BackingStoreException { + // assert false; + } + + /** + * Returns true if the specified character is appropriate for use in + * Unix directory names. A character is appropriate if it's a printable + * ASCII character (> 0x1f && < 0x7f) and unequal to slash ('/', 0x2f), + * dot ('.', 0x2e), or underscore ('_', 0x5f). + */ + private static boolean isDirChar(char ch) { + return ch > 0x1f && ch < 0x7f && ch != '/' && ch != '.' && ch != '_'; + } + + /** + * Returns the directory name corresponding to the specified node name. + * Generally, this is just the node name. If the node name includes + * inappropriate characters (as per isDirChar) it is translated to Base64. + * with the underscore character ('_', 0x5f) prepended. + */ + private static String dirName(String nodeName) { +// for (int i=0, n=nodeName.length(); i < n; i++) +// if (!isDirChar(nodeName.charAt(i))) +// return "_" + Base64.byteArrayToAltBase64(byteArray(nodeName)); + return nodeName; + } +// +// /** +// * Translate a string into a byte array by translating each character +// * into two bytes, high-byte first ("big-endian"). +// */ +// private static byte[] byteArray(String s) { +// int len = s.length(); +// byte[] result = new byte[2*len]; +// for (int i=0, j=0; i>8); +// result[j++] = (byte) c; +// } +// return result; +// } +// + /** + * Returns the node name corresponding to the specified directory name. + * (Inverts the transformation of dirName(String). + */ + private static String nodeName(String dirName) { +// if (dirName.charAt(0) != '_') + return dirName; +// byte a[] = Base64.altBase64ToByteArray(dirName.substring(1)); +// StringBuffer result = new StringBuffer(a.length/2); +// for (int i = 0; i < a.length; ) { +// int highByte = a[i++] & 0xff; +// int lowByte = a[i++] & 0xff; +// result.append((char) ((highByte << 8) | lowByte)); +// } +// return result.toString(); + } +// +// /** +// * Try to acquire the appropriate file lock (user or system). If +// * the initial attempt fails, several more attempts are made using +// * an exponential backoff strategy. If all attempts fail, this method +// * returns false. +// * @throws SecurityException if file access denied. +// */ +// private boolean lockFile(boolean shared) throws SecurityException{ +// boolean usernode = isUserNode(); +// int[] result; +// int errorCode = 0; +// File lockFile = (usernode ? userLockFile : systemLockFile); +// long sleepTime = INIT_SLEEP_TIME; +// for (int i = 0; i < MAX_ATTEMPTS; i++) { +// try { +// int perm = (usernode? USER_READ_WRITE: USER_RW_ALL_READ); +// result = lockFile0(lockFile.getCanonicalPath(), perm, shared); +// +// errorCode = result[ERROR_CODE]; +// if (result[LOCK_HANDLE] != 0) { +// if (usernode) { +// userRootLockHandle = result[LOCK_HANDLE]; +// } else { +// systemRootLockHandle = result[LOCK_HANDLE]; +// } +// return true; +// } +// } catch(IOException e) { +//// // If at first, you don't succeed... +// } +// +// try { +// Thread.sleep(sleepTime); +// } catch(InterruptedException e) { +// checkLockFile0ErrorCode(errorCode); +// return false; +// } +// sleepTime *= 2; +// } +// checkLockFile0ErrorCode(errorCode); +// return false; +// } +// +// /** +// * Checks if unlockFile0() returned an error. Throws a SecurityException, +// * if access denied. Logs a warning otherwise. +// */ +// private void checkLockFile0ErrorCode (int errorCode) +// throws SecurityException { +// if (errorCode == EACCES) +// throw new SecurityException("Could not lock " + +// (isUserNode()? "User prefs." : "System prefs.") + +// " Lock file access denied."); +// if (errorCode != EAGAIN) +// getLogger().warning("Could not lock " + +// (isUserNode()? "User prefs. " : "System prefs.") + +// " Unix error code " + errorCode + "."); +// } +// +// /** +// * Locks file using UNIX file locking. +// * @param fileName Absolute file name of the lock file. +// * @return Returns a lock handle, used to unlock the file. +// */ +// private static native int[] +// lockFile0(String fileName, int permission, boolean shared); +// +// /** +// * Unlocks file previously locked by lockFile0(). +// * @param lockHandle Handle to the file lock. +// * @return Returns zero if OK, UNIX error code if failure. +// */ +// private static native int unlockFile0(int lockHandle); +// +// /** +// * Changes UNIX file permissions. +// */ +// private static native int chmod(String fileName, int permission); +// +// /** +// * Initial time between lock attempts, in ms. The time is doubled +// * after each failing attempt (except the first). +// */ +// private static int INIT_SLEEP_TIME = 50; +// +// /** +// * Maximum number of lock attempts. +// */ +// private static int MAX_ATTEMPTS = 5; +// +// /** +// * Release the the appropriate file lock (user or system). +// * @throws SecurityException if file access denied. +// */ +// private void unlockFile() { +// int result; +// boolean usernode = isUserNode(); +// File lockFile = (usernode ? userLockFile : systemLockFile); +// int lockHandle = ( usernode ? userRootLockHandle:systemRootLockHandle); +// if (lockHandle == 0) { +// getLogger().warning("Unlock: zero lockHandle for " + +// (usernode ? "user":"system") + " preferences.)"); +// return; +// } +// result = unlockFile0(lockHandle); +// if (result != 0) { +// getLogger().warning("Could not drop file-lock on " + +// (isUserNode() ? "user" : "system") + " preferences." + +// " Unix error code " + result + "."); +// if (result == EACCES) +// throw new SecurityException("Could not unlock" + +// (isUserNode()? "User prefs." : "System prefs.") + +// " Lock file access denied."); +// } +// if (isUserNode()) { +// userRootLockHandle = 0; +// } else { +// systemRootLockHandle = 0; +// } +// } +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/FileSystemPreferencesFactory.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/FileSystemPreferencesFactory.java new file mode 100644 index 000000000..bd1a723f6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/FileSystemPreferencesFactory.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000, 2002, 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 java.util.prefs; + +/** + * Factory for FileSystemPreferences. This class allows FileSystemPreferences + * to be installed as the Preferences implementations via the + * java.util.prefs.PreferencesFactory system property. + * + * @author Josh Bloch + * @see FileSystemPreferences + * @see Preferences + * @since 1.4 + */ + +class FileSystemPreferencesFactory implements PreferencesFactory { + public Preferences userRoot() { + return FileSystemPreferences.getUserRoot(); + } + + public Preferences systemRoot() { + return FileSystemPreferences.getSystemRoot(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/InvalidPreferencesFormatException.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/InvalidPreferencesFormatException.java new file mode 100644 index 000000000..3a5e81763 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/InvalidPreferencesFormatException.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2000, 2003, 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 java.util.prefs; + +import java.io.NotSerializableException; + +/** + * Thrown to indicate that an operation could not complete because + * the input did not conform to the appropriate XML document type + * for a collection of preferences, as per the {@link Preferences} + * specification. + * + * @author Josh Bloch + * @see Preferences + * @since 1.4 + */ +public class InvalidPreferencesFormatException extends Exception { + /** + * Constructs an InvalidPreferencesFormatException with the specified + * cause. + * + * @param cause the cause (which is saved for later retrieval by the + * {@link Throwable#getCause()} method). + */ + public InvalidPreferencesFormatException(Throwable cause) { + super(cause); + } + + /** + * Constructs an InvalidPreferencesFormatException with the specified + * detail message. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link Throwable#getMessage()} method. + */ + public InvalidPreferencesFormatException(String message) { + super(message); + } + + /** + * Constructs an InvalidPreferencesFormatException with the specified + * detail message and cause. + * + * @param message the detail message. The detail message is saved for + * later retrieval by the {@link Throwable#getMessage()} method. + * @param cause the cause (which is saved for later retrieval by the + * {@link Throwable#getCause()} method). + */ + public InvalidPreferencesFormatException(String message, Throwable cause) { + super(message, cause); + } + + private static final long serialVersionUID = -791715184232119669L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/NodeChangeEvent.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/NodeChangeEvent.java new file mode 100644 index 000000000..f108925a0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/NodeChangeEvent.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2000, 2003, 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 java.util.prefs; + +import java.io.NotSerializableException; + +/** + * An event emitted by a Preferences node to indicate that + * a child of that node has been added or removed.

+ * + * Note, that although NodeChangeEvent inherits Serializable interface from + * java.util.EventObject, it is not intended to be Serializable. Appropriate + * serialization methods are implemented to throw NotSerializableException. + * + * @author Josh Bloch + * @see Preferences + * @see NodeChangeListener + * @see PreferenceChangeEvent + * @since 1.4 + * @serial exclude + */ + +public class NodeChangeEvent extends java.util.EventObject { + /** + * The node that was added or removed. + * + * @serial + */ + private Preferences child; + + /** + * Constructs a new NodeChangeEvent instance. + * + * @param parent The parent of the node that was added or removed. + * @param child The node that was added or removed. + */ + public NodeChangeEvent(Preferences parent, Preferences child) { + super(parent); + this.child = child; + } + + /** + * Returns the parent of the node that was added or removed. + * + * @return The parent Preferences node whose child was added or removed + */ + public Preferences getParent() { + return (Preferences) getSource(); + } + + /** + * Returns the node that was added or removed. + * + * @return The node that was added or removed. + */ + public Preferences getChild() { + return child; + } + + /** + * Throws NotSerializableException, since NodeChangeEvent objects are not + * intended to be serializable. + */ + private void writeObject(java.io.ObjectOutputStream out) + throws NotSerializableException { + throw new NotSerializableException("Not serializable."); + } + + /** + * Throws NotSerializableException, since NodeChangeEvent objects are not + * intended to be serializable. + */ + private void readObject(java.io.ObjectInputStream in) + throws NotSerializableException { + throw new NotSerializableException("Not serializable."); + } + + // Defined so that this class isn't flagged as a potential problem when + // searches for missing serialVersionUID fields are done. + private static final long serialVersionUID = 8068949086596572957L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/NodeChangeListener.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/NodeChangeListener.java new file mode 100644 index 000000000..f34376410 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/NodeChangeListener.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2000, 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 java.util.prefs; + +/** + * A listener for receiving preference node change events. + * + * @author Josh Bloch + * @see Preferences + * @see NodeChangeEvent + * @see PreferenceChangeListener + * @since 1.4 + */ + +public interface NodeChangeListener extends java.util.EventListener { + /** + * This method gets called when a child node is added. + * + * @param evt A node change event object describing the parent + * and child node. + */ + void childAdded(NodeChangeEvent evt); + + /** + * This method gets called when a child node is removed. + * + * @param evt A node change event object describing the parent + * and child node. + */ + void childRemoved(NodeChangeEvent evt); +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferenceChangeEvent.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferenceChangeEvent.java new file mode 100644 index 000000000..f7cf7b5ef --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferenceChangeEvent.java @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2000, 2003, 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 java.util.prefs; + +import java.io.NotSerializableException; + +/** + * An event emitted by a Preferences node to indicate that + * a preference has been added, removed or has had its value changed.

+ * + * Note, that although PreferenceChangeEvent inherits Serializable interface + * from EventObject, it is not intended to be Serializable. Appropriate + * serialization methods are implemented to throw NotSerializableException. + * + * @author Josh Bloch + * @see Preferences + * @see PreferenceChangeListener + * @see NodeChangeEvent + * @since 1.4 + * @serial exclude + */ +public class PreferenceChangeEvent extends java.util.EventObject { + + /** + * Key of the preference that changed. + * + * @serial + */ + private String key; + + /** + * New value for preference, or null if it was removed. + * + * @serial + */ + private String newValue; + + /** + * Constructs a new PreferenceChangeEvent instance. + * + * @param node The Preferences node that emitted the event. + * @param key The key of the preference that was changed. + * @param newValue The new value of the preference, or null + * if the preference is being removed. + */ + public PreferenceChangeEvent(Preferences node, String key, + String newValue) { + super(node); + this.key = key; + this.newValue = newValue; + } + + /** + * Returns the preference node that emitted the event. + * + * @return The preference node that emitted the event. + */ + public Preferences getNode() { + return (Preferences) getSource(); + } + + /** + * Returns the key of the preference that was changed. + * + * @return The key of the preference that was changed. + */ + public String getKey() { + return key; + } + + /** + * Returns the new value for the preference. + * + * @return The new value for the preference, or null if the + * preference was removed. + */ + public String getNewValue() { + return newValue; + } + + /** + * Throws NotSerializableException, since NodeChangeEvent objects + * are not intended to be serializable. + */ + private void writeObject(java.io.ObjectOutputStream out) + throws NotSerializableException { + throw new NotSerializableException("Not serializable."); + } + + /** + * Throws NotSerializableException, since PreferenceChangeEvent objects + * are not intended to be serializable. + */ + private void readObject(java.io.ObjectInputStream in) + throws NotSerializableException { + throw new NotSerializableException("Not serializable."); + } + + // Defined so that this class isn't flagged as a potential problem when + // searches for missing serialVersionUID fields are done. + private static final long serialVersionUID = 793724513368024975L; +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferenceChangeListener.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferenceChangeListener.java new file mode 100644 index 000000000..0fb96c598 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferenceChangeListener.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2000, 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 java.util.prefs; + +/** + * A listener for receiving preference change events. + * + * @author Josh Bloch + * @see Preferences + * @see PreferenceChangeEvent + * @see NodeChangeListener + * @since 1.4 + */ +@FunctionalInterface +public interface PreferenceChangeListener extends java.util.EventListener { + /** + * This method gets called when a preference is added, removed or when + * its value is changed. + *

+ * @param evt A PreferenceChangeEvent object describing the event source + * and the preference that has changed. + */ + void preferenceChange(PreferenceChangeEvent evt); +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/Preferences.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/Preferences.java new file mode 100644 index 000000000..3b7b47f30 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/Preferences.java @@ -0,0 +1,1258 @@ +/* + * Copyright (c) 2000, 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 java.util.prefs; + +import java.io.InputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.security.AccessController; +import java.security.Permission; +import java.security.PrivilegedAction; +import java.util.Iterator; +import java.util.ServiceLoader; +import java.util.ServiceConfigurationError; + +// These imports needed only as a workaround for a JavaDoc bug +import java.lang.RuntimePermission; +import java.lang.Integer; +import java.lang.Long; +import java.lang.Float; +import java.lang.Double; + +/** + * A node in a hierarchical collection of preference data. This class + * allows applications to store and retrieve user and system + * preference and configuration data. This data is stored + * persistently in an implementation-dependent backing store. Typical + * implementations include flat files, OS-specific registries, + * directory servers and SQL databases. The user of this class needn't + * be concerned with details of the backing store. + * + *

There are two separate trees of preference nodes, one for user + * preferences and one for system preferences. Each user has a separate user + * preference tree, and all users in a given system share the same system + * preference tree. The precise description of "user" and "system" will vary + * from implementation to implementation. Typical information stored in the + * user preference tree might include font choice, color choice, or preferred + * window location and size for a particular application. Typical information + * stored in the system preference tree might include installation + * configuration data for an application. + * + *

Nodes in a preference tree are named in a similar fashion to + * directories in a hierarchical file system. Every node in a preference + * tree has a node name (which is not necessarily unique), + * a unique absolute path name, and a path name relative to each + * ancestor including itself. + * + *

The root node has a node name of the empty string (""). Every other + * node has an arbitrary node name, specified at the time it is created. The + * only restrictions on this name are that it cannot be the empty string, and + * it cannot contain the slash character ('/'). + * + *

The root node has an absolute path name of "/". Children of + * the root node have absolute path names of "/" + <node + * name>. All other nodes have absolute path names of <parent's + * absolute path name> + "/" + <node name>. + * Note that all absolute path names begin with the slash character. + * + *

A node n's path name relative to its ancestor a + * is simply the string that must be appended to a's absolute path name + * in order to form n's absolute path name, with the initial slash + * character (if present) removed. Note that: + *

    + *
  • No relative path names begin with the slash character. + *
  • Every node's path name relative to itself is the empty string. + *
  • Every node's path name relative to its parent is its node name (except + * for the root node, which does not have a parent). + *
  • Every node's path name relative to the root is its absolute path name + * with the initial slash character removed. + *
+ * + *

Note finally that: + *

    + *
  • No path name contains multiple consecutive slash characters. + *
  • No path name with the exception of the root's absolute path name + * ends in the slash character. + *
  • Any string that conforms to these two rules is a valid path name. + *
+ * + *

All of the methods that modify preferences data are permitted to operate + * asynchronously; they may return immediately, and changes will eventually + * propagate to the persistent backing store with an implementation-dependent + * delay. The flush method may be used to synchronously force + * updates to the backing store. Normal termination of the Java Virtual + * Machine will not result in the loss of pending updates -- an explicit + * flush invocation is not required upon termination to ensure + * that pending updates are made persistent. + * + *

All of the methods that read preferences from a Preferences + * object require the invoker to provide a default value. The default value is + * returned if no value has been previously set or if the backing store is + * unavailable. The intent is to allow applications to operate, albeit + * with slightly degraded functionality, even if the backing store becomes + * unavailable. Several methods, like flush, have semantics that + * prevent them from operating if the backing store is unavailable. Ordinary + * applications should have no need to invoke any of these methods, which can + * be identified by the fact that they are declared to throw {@link + * BackingStoreException}. + * + *

The methods in this class may be invoked concurrently by multiple threads + * in a single JVM without the need for external synchronization, and the + * results will be equivalent to some serial execution. If this class is used + * concurrently by multiple JVMs that store their preference data in + * the same backing store, the data store will not be corrupted, but no + * other guarantees are made concerning the consistency of the preference + * data. + * + *

This class contains an export/import facility, allowing preferences + * to be "exported" to an XML document, and XML documents representing + * preferences to be "imported" back into the system. This facility + * may be used to back up all or part of a preference tree, and + * subsequently restore from the backup. + * + *

The XML document has the following DOCTYPE declaration: + *

{@code
+ * 
+ * }
+ * Note that the system URI (http://java.sun.com/dtd/preferences.dtd) is + * not accessed when exporting or importing preferences; it merely + * serves as a string to uniquely identify the DTD, which is: + *
{@code
+ *    
+ *
+ *    
+ *
+ *    
+ *    
+ *
+ *    
+ *    
+ *
+ *    
+ *    
+ *
+ *    
+ *    
+ *
+ *    
+ *    
+ *
+ *    
+ *    
+ *
+ *    
+ *    
+ *
+ *    
+ *    
+ *    
+ * }
+ * + * Every Preferences implementation must have an associated {@link + * PreferencesFactory} implementation. Every Java(TM) SE implementation must provide + * some means of specifying which PreferencesFactory implementation + * is used to generate the root preferences nodes. This allows the + * administrator to replace the default preferences implementation with an + * alternative implementation. + * + *

Implementation note: In Sun's JRE, the PreferencesFactory + * implementation is located as follows: + * + *

    + * + *
  1. If the system property + * java.util.prefs.PreferencesFactory is defined, then it is + * taken to be the fully-qualified name of a class implementing the + * PreferencesFactory interface. The class is loaded and + * instantiated; if this process fails then an unspecified error is + * thrown.

  2. + * + *
  3. If a PreferencesFactory implementation class file + * has been installed in a jar file that is visible to the + * {@link java.lang.ClassLoader#getSystemClassLoader system class loader}, + * and that jar file contains a provider-configuration file named + * java.util.prefs.PreferencesFactory in the resource + * directory META-INF/services, then the first class name + * specified in that file is taken. If more than one such jar file is + * provided, the first one found will be used. The class is loaded + * and instantiated; if this process fails then an unspecified error + * is thrown.

  4. + * + *
  5. Finally, if neither the above-mentioned system property nor + * an extension jar file is provided, then the system-wide default + * PreferencesFactory implementation for the underlying + * platform is loaded and instantiated.

  6. + * + *
+ * + * @author Josh Bloch + * @since 1.4 + */ +public abstract class Preferences { + + private static final PreferencesFactory factory = factory(); + + private static PreferencesFactory factory() { + // 1. Try user-specified system property + String factoryName = AccessController.doPrivileged( + new PrivilegedAction() { + public String run() { + return System.getProperty( + "java.util.prefs.PreferencesFactory");}}); + if (factoryName != null) { + // FIXME: This code should be run in a doPrivileged and + // not use the context classloader, to avoid being + // dependent on the invoking thread. + // Checking AllPermission also seems wrong. + try { + return (PreferencesFactory) + Class.forName(factoryName, false, + ClassLoader.getSystemClassLoader()) + .newInstance(); + } catch (Exception ex) { + try { + // workaround for javaws, plugin, + // load factory class using non-system classloader + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPermission(new java.security.AllPermission()); + } + return (PreferencesFactory) + Class.forName(factoryName, false, + Thread.currentThread() + .getContextClassLoader()) + .newInstance(); + } catch (Exception e) { + throw new InternalError( + "Can't instantiate Preferences factory " + + factoryName, e); + } + } + } + + return AccessController.doPrivileged( + new PrivilegedAction() { + public PreferencesFactory run() { + return factory1();}}); + } + + private static PreferencesFactory factory1() { + // 2. Try service provider interface + Iterator itr = ServiceLoader + .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader()) + .iterator(); + + // choose first provider instance + while (itr.hasNext()) { + try { + return itr.next(); + } catch (ServiceConfigurationError sce) { + if (sce.getCause() instanceof SecurityException) { + // Ignore the security exception, try the next provider + continue; + } + throw sce; + } + } + + // 3. Use platform-specific system-wide default + String osName = System.getProperty("os.name"); + String platformFactory; + if (osName.startsWith("Windows")) { + platformFactory = "java.util.prefs.WindowsPreferencesFactory"; + } else if (osName.contains("OS X")) { + platformFactory = "java.util.prefs.MacOSXPreferencesFactory"; + } else { + platformFactory = "java.util.prefs.FileSystemPreferencesFactory"; + } + try { + return (PreferencesFactory) + Class.forName(platformFactory, false, + Preferences.class.getClassLoader()).newInstance(); + } catch (Exception e) { + throw new InternalError( + "Can't instantiate platform default Preferences factory " + + platformFactory, e); + } + } + + /** + * Maximum length of string allowed as a key (80 characters). + */ + public static final int MAX_KEY_LENGTH = 80; + + /** + * Maximum length of string allowed as a value (8192 characters). + */ + public static final int MAX_VALUE_LENGTH = 8*1024; + + /** + * Maximum length of a node name (80 characters). + */ + public static final int MAX_NAME_LENGTH = 80; + + /** + * Returns the preference node from the calling user's preference tree + * that is associated (by convention) with the specified class's package. + * The convention is as follows: the absolute path name of the node is the + * fully qualified package name, preceded by a slash ('/'), and + * with each period ('.') replaced by a slash. For example the + * absolute path name of the node associated with the class + * com.acme.widget.Foo is /com/acme/widget. + * + *

This convention does not apply to the unnamed package, whose + * associated preference node is <unnamed>. This node + * is not intended for long term use, but for convenience in the early + * development of programs that do not yet belong to a package, and + * for "throwaway" programs. Valuable data should not be stored + * at this node as it is shared by all programs that use it. + * + *

A class Foo wishing to access preferences pertaining to its + * package can obtain a preference node as follows:

+     *    static Preferences prefs = Preferences.userNodeForPackage(Foo.class);
+     * 
+ * This idiom obviates the need for using a string to describe the + * preferences node and decreases the likelihood of a run-time failure. + * (If the class name is misspelled, it will typically result in a + * compile-time error.) + * + *

Invoking this method will result in the creation of the returned + * node and its ancestors if they do not already exist. If the returned + * node did not exist prior to this call, this node and any ancestors that + * were created by this call are not guaranteed to become permanent until + * the flush method is called on the returned node (or one of its + * ancestors or descendants). + * + * @param c the class for whose package a user preference node is desired. + * @return the user preference node associated with the package of which + * c is a member. + * @throws NullPointerException if c is null. + * @throws SecurityException if a security manager is present and + * it denies RuntimePermission("preferences"). + * @see RuntimePermission + */ + public static Preferences userNodeForPackage(Class c) { + return userRoot().node(nodeName(c)); + } + + /** + * Returns the preference node from the system preference tree that is + * associated (by convention) with the specified class's package. The + * convention is as follows: the absolute path name of the node is the + * fully qualified package name, preceded by a slash ('/'), and + * with each period ('.') replaced by a slash. For example the + * absolute path name of the node associated with the class + * com.acme.widget.Foo is /com/acme/widget. + * + *

This convention does not apply to the unnamed package, whose + * associated preference node is <unnamed>. This node + * is not intended for long term use, but for convenience in the early + * development of programs that do not yet belong to a package, and + * for "throwaway" programs. Valuable data should not be stored + * at this node as it is shared by all programs that use it. + * + *

A class Foo wishing to access preferences pertaining to its + * package can obtain a preference node as follows:

+     *  static Preferences prefs = Preferences.systemNodeForPackage(Foo.class);
+     * 
+ * This idiom obviates the need for using a string to describe the + * preferences node and decreases the likelihood of a run-time failure. + * (If the class name is misspelled, it will typically result in a + * compile-time error.) + * + *

Invoking this method will result in the creation of the returned + * node and its ancestors if they do not already exist. If the returned + * node did not exist prior to this call, this node and any ancestors that + * were created by this call are not guaranteed to become permanent until + * the flush method is called on the returned node (or one of its + * ancestors or descendants). + * + * @param c the class for whose package a system preference node is desired. + * @return the system preference node associated with the package of which + * c is a member. + * @throws NullPointerException if c is null. + * @throws SecurityException if a security manager is present and + * it denies RuntimePermission("preferences"). + * @see RuntimePermission + */ + public static Preferences systemNodeForPackage(Class c) { + return systemRoot().node(nodeName(c)); + } + + /** + * Returns the absolute path name of the node corresponding to the package + * of the specified object. + * + * @throws IllegalArgumentException if the package has node preferences + * node associated with it. + */ + private static String nodeName(Class c) { + if (c.isArray()) + throw new IllegalArgumentException( + "Arrays have no associated preferences node."); + String className = c.getName(); + int pkgEndIndex = className.lastIndexOf('.'); + if (pkgEndIndex < 0) + return "/"; + String packageName = className.substring(0, pkgEndIndex); + return "/" + packageName.replace('.', '/'); + } + + /** + * This permission object represents the permission required to get + * access to the user or system root (which in turn allows for all + * other operations). + */ + private static Permission prefsPerm = new RuntimePermission("preferences"); + + /** + * Returns the root preference node for the calling user. + * + * @return the root preference node for the calling user. + * @throws SecurityException If a security manager is present and + * it denies RuntimePermission("preferences"). + * @see RuntimePermission + */ + public static Preferences userRoot() { + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkPermission(prefsPerm); + + return factory.userRoot(); + } + + /** + * Returns the root preference node for the system. + * + * @return the root preference node for the system. + * @throws SecurityException If a security manager is present and + * it denies RuntimePermission("preferences"). + * @see RuntimePermission + */ + public static Preferences systemRoot() { + SecurityManager security = System.getSecurityManager(); + if (security != null) + security.checkPermission(prefsPerm); + + return factory.systemRoot(); + } + + /** + * Sole constructor. (For invocation by subclass constructors, typically + * implicit.) + */ + protected Preferences() { + } + + /** + * Associates the specified value with the specified key in this + * preference node. + * + * @param key key with which the specified value is to be associated. + * @param value value to be associated with the specified key. + * @throws NullPointerException if key or value is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH or if value.length exceeds + * MAX_VALUE_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public abstract void put(String key, String value); + + /** + * Returns the value associated with the specified key in this preference + * node. Returns the specified default if there is no value associated + * with the key, or the backing store is inaccessible. + * + *

Some implementations may store default values in their backing + * stores. If there is no value associated with the specified key + * but there is such a stored default, it is returned in + * preference to the specified default. + * + * @param key key whose associated value is to be returned. + * @param def the value to be returned in the event that this + * preference node has no value associated with key. + * @return the value associated with key, or def + * if no value is associated with key, or the backing + * store is inaccessible. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. (A + * null value for def is permitted.) + */ + public abstract String get(String key, String def); + + /** + * Removes the value associated with the specified key in this preference + * node, if any. + * + *

If this implementation supports stored defaults, and there is + * such a default for the specified preference, the stored default will be + * "exposed" by this call, in the sense that it will be returned + * by a succeeding call to get. + * + * @param key key whose mapping is to be removed from the preference node. + * @throws NullPointerException if key is null. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public abstract void remove(String key); + + /** + * Removes all of the preferences (key-value associations) in this + * preference node. This call has no effect on any descendants + * of this node. + * + *

If this implementation supports stored defaults, and this + * node in the preferences hierarchy contains any such defaults, + * the stored defaults will be "exposed" by this call, in the sense that + * they will be returned by succeeding calls to get. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #removeNode() + */ + public abstract void clear() throws BackingStoreException; + + /** + * Associates a string representing the specified int value with the + * specified key in this preference node. The associated string is the + * one that would be returned if the int value were passed to + * {@link Integer#toString(int)}. This method is intended for use in + * conjunction with {@link #getInt}. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #getInt(String,int) + */ + public abstract void putInt(String key, int value); + + /** + * Returns the int value represented by the string associated with the + * specified key in this preference node. The string is converted to + * an integer as by {@link Integer#parseInt(String)}. Returns the + * specified default if there is no value associated with the key, + * the backing store is inaccessible, or if + * Integer.parseInt(String) would throw a {@link + * NumberFormatException} if the associated value were passed. This + * method is intended for use in conjunction with {@link #putInt}. + * + *

If the implementation supports stored defaults and such a + * default exists, is accessible, and could be converted to an int + * with Integer.parseInt, this int is returned in preference to + * the specified default. + * + * @param key key whose associated value is to be returned as an int. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as an int, + * or the backing store is inaccessible. + * @return the int value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * an int. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + * @see #putInt(String,int) + * @see #get(String,String) + */ + public abstract int getInt(String key, int def); + + /** + * Associates a string representing the specified long value with the + * specified key in this preference node. The associated string is the + * one that would be returned if the long value were passed to + * {@link Long#toString(long)}. This method is intended for use in + * conjunction with {@link #getLong}. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #getLong(String,long) + */ + public abstract void putLong(String key, long value); + + /** + * Returns the long value represented by the string associated with the + * specified key in this preference node. The string is converted to + * a long as by {@link Long#parseLong(String)}. Returns the + * specified default if there is no value associated with the key, + * the backing store is inaccessible, or if + * Long.parseLong(String) would throw a {@link + * NumberFormatException} if the associated value were passed. This + * method is intended for use in conjunction with {@link #putLong}. + * + *

If the implementation supports stored defaults and such a + * default exists, is accessible, and could be converted to a long + * with Long.parseLong, this long is returned in preference to + * the specified default. + * + * @param key key whose associated value is to be returned as a long. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a long, + * or the backing store is inaccessible. + * @return the long value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a long. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + * @see #putLong(String,long) + * @see #get(String,String) + */ + public abstract long getLong(String key, long def); + + /** + * Associates a string representing the specified boolean value with the + * specified key in this preference node. The associated string is + * "true" if the value is true, and "false" if it is + * false. This method is intended for use in conjunction with + * {@link #getBoolean}. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #getBoolean(String,boolean) + * @see #get(String,String) + */ + public abstract void putBoolean(String key, boolean value); + + /** + * Returns the boolean value represented by the string associated with the + * specified key in this preference node. Valid strings + * are "true", which represents true, and "false", which + * represents false. Case is ignored, so, for example, "TRUE" + * and "False" are also valid. This method is intended for use in + * conjunction with {@link #putBoolean}. + * + *

Returns the specified default if there is no value + * associated with the key, the backing store is inaccessible, or if the + * associated value is something other than "true" or + * "false", ignoring case. + * + *

If the implementation supports stored defaults and such a + * default exists and is accessible, it is used in preference to the + * specified default, unless the stored default is something other than + * "true" or "false", ignoring case, in which case the + * specified default is used. + * + * @param key key whose associated value is to be returned as a boolean. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a boolean, + * or the backing store is inaccessible. + * @return the boolean value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a boolean. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + * @see #get(String,String) + * @see #putBoolean(String,boolean) + */ + public abstract boolean getBoolean(String key, boolean def); + + /** + * Associates a string representing the specified float value with the + * specified key in this preference node. The associated string is the + * one that would be returned if the float value were passed to + * {@link Float#toString(float)}. This method is intended for use in + * conjunction with {@link #getFloat}. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #getFloat(String,float) + */ + public abstract void putFloat(String key, float value); + + /** + * Returns the float value represented by the string associated with the + * specified key in this preference node. The string is converted to an + * integer as by {@link Float#parseFloat(String)}. Returns the specified + * default if there is no value associated with the key, the backing store + * is inaccessible, or if Float.parseFloat(String) would throw a + * {@link NumberFormatException} if the associated value were passed. + * This method is intended for use in conjunction with {@link #putFloat}. + * + *

If the implementation supports stored defaults and such a + * default exists, is accessible, and could be converted to a float + * with Float.parseFloat, this float is returned in preference to + * the specified default. + * + * @param key key whose associated value is to be returned as a float. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a float, + * or the backing store is inaccessible. + * @return the float value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a float. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + * @see #putFloat(String,float) + * @see #get(String,String) + */ + public abstract float getFloat(String key, float def); + + /** + * Associates a string representing the specified double value with the + * specified key in this preference node. The associated string is the + * one that would be returned if the double value were passed to + * {@link Double#toString(double)}. This method is intended for use in + * conjunction with {@link #getDouble}. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key is null. + * @throws IllegalArgumentException if key.length() exceeds + * MAX_KEY_LENGTH. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #getDouble(String,double) + */ + public abstract void putDouble(String key, double value); + + /** + * Returns the double value represented by the string associated with the + * specified key in this preference node. The string is converted to an + * integer as by {@link Double#parseDouble(String)}. Returns the specified + * default if there is no value associated with the key, the backing store + * is inaccessible, or if Double.parseDouble(String) would throw a + * {@link NumberFormatException} if the associated value were passed. + * This method is intended for use in conjunction with {@link #putDouble}. + * + *

If the implementation supports stored defaults and such a + * default exists, is accessible, and could be converted to a double + * with Double.parseDouble, this double is returned in preference + * to the specified default. + * + * @param key key whose associated value is to be returned as a double. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a double, + * or the backing store is inaccessible. + * @return the double value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a double. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. + * @see #putDouble(String,double) + * @see #get(String,String) + */ + public abstract double getDouble(String key, double def); + + /** + * Associates a string representing the specified byte array with the + * specified key in this preference node. The associated string is + * the Base64 encoding of the byte array, as defined in RFC 2045, Section 6.8, + * with one minor change: the string will consist solely of characters + * from the Base64 Alphabet; it will not contain any newline + * characters. Note that the maximum length of the byte array is limited + * to three quarters of MAX_VALUE_LENGTH so that the length + * of the Base64 encoded String does not exceed MAX_VALUE_LENGTH. + * This method is intended for use in conjunction with + * {@link #getByteArray}. + * + * @param key key with which the string form of value is to be associated. + * @param value value whose string form is to be associated with key. + * @throws NullPointerException if key or value is null. + * @throws IllegalArgumentException if key.length() exceeds MAX_KEY_LENGTH + * or if value.length exceeds MAX_VALUE_LENGTH*3/4. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #getByteArray(String,byte[]) + * @see #get(String,String) + */ + public abstract void putByteArray(String key, byte[] value); + + /** + * Returns the byte array value represented by the string associated with + * the specified key in this preference node. Valid strings are + * Base64 encoded binary data, as defined in RFC 2045, Section 6.8, + * with one minor change: the string must consist solely of characters + * from the Base64 Alphabet; no newline characters or + * extraneous characters are permitted. This method is intended for use + * in conjunction with {@link #putByteArray}. + * + *

Returns the specified default if there is no value + * associated with the key, the backing store is inaccessible, or if the + * associated value is not a valid Base64 encoded byte array + * (as defined above). + * + *

If the implementation supports stored defaults and such a + * default exists and is accessible, it is used in preference to the + * specified default, unless the stored default is not a valid Base64 + * encoded byte array (as defined above), in which case the + * specified default is used. + * + * @param key key whose associated value is to be returned as a byte array. + * @param def the value to be returned in the event that this + * preference node has no value associated with key + * or the associated value cannot be interpreted as a byte array, + * or the backing store is inaccessible. + * @return the byte array value represented by the string associated with + * key in this preference node, or def if the + * associated value does not exist or cannot be interpreted as + * a byte array. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @throws NullPointerException if key is null. (A + * null value for def is permitted.) + * @see #get(String,String) + * @see #putByteArray(String,byte[]) + */ + public abstract byte[] getByteArray(String key, byte[] def); + + /** + * Returns all of the keys that have an associated value in this + * preference node. (The returned array will be of size zero if + * this node has no preferences.) + * + *

If the implementation supports stored defaults and there + * are any such defaults at this node that have not been overridden, + * by explicit preferences, the defaults are returned in the array in + * addition to any explicit preferences. + * + * @return an array of the keys that have an associated value in this + * preference node. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public abstract String[] keys() throws BackingStoreException; + + /** + * Returns the names of the children of this preference node, relative to + * this node. (The returned array will be of size zero if this node has + * no children.) + * + * @return the names of the children of this preference node. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public abstract String[] childrenNames() throws BackingStoreException; + + /** + * Returns the parent of this preference node, or null if this is + * the root. + * + * @return the parent of this preference node. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public abstract Preferences parent(); + + /** + * Returns the named preference node in the same tree as this node, + * creating it and any of its ancestors if they do not already exist. + * Accepts a relative or absolute path name. Relative path names + * (which do not begin with the slash character ('/')) are + * interpreted relative to this preference node. + * + *

If the returned node did not exist prior to this call, this node and + * any ancestors that were created by this call are not guaranteed + * to become permanent until the flush method is called on + * the returned node (or one of its ancestors or descendants). + * + * @param pathName the path name of the preference node to return. + * @return the specified preference node. + * @throws IllegalArgumentException if the path name is invalid (i.e., + * it contains multiple consecutive slash characters, or ends + * with a slash character and is more than one character long). + * @throws NullPointerException if path name is null. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #flush() + */ + public abstract Preferences node(String pathName); + + /** + * Returns true if the named preference node exists in the same tree + * as this node. Relative path names (which do not begin with the slash + * character ('/')) are interpreted relative to this preference + * node. + * + *

If this node (or an ancestor) has already been removed with the + * {@link #removeNode()} method, it is legal to invoke this method, + * but only with the path name ""; the invocation will return + * false. Thus, the idiom p.nodeExists("") may be + * used to test whether p has been removed. + * + * @param pathName the path name of the node whose existence + * is to be checked. + * @return true if the specified node exists. + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalArgumentException if the path name is invalid (i.e., + * it contains multiple consecutive slash characters, or ends + * with a slash character and is more than one character long). + * @throws NullPointerException if path name is null. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method and + * pathName is not the empty string (""). + */ + public abstract boolean nodeExists(String pathName) + throws BackingStoreException; + + /** + * Removes this preference node and all of its descendants, invalidating + * any preferences contained in the removed nodes. Once a node has been + * removed, attempting any method other than {@link #name()}, + * {@link #absolutePath()}, {@link #isUserNode()}, {@link #flush()} or + * {@link #node(String) nodeExists("")} on the corresponding + * Preferences instance will fail with an + * IllegalStateException. (The methods defined on {@link Object} + * can still be invoked on a node after it has been removed; they will not + * throw IllegalStateException.) + * + *

The removal is not guaranteed to be persistent until the + * flush method is called on this node (or an ancestor). + * + *

If this implementation supports stored defaults, removing a + * node exposes any stored defaults at or below this node. Thus, a + * subsequent call to nodeExists on this node's path name may + * return true, and a subsequent call to node on this + * path name may return a (different) Preferences instance + * representing a non-empty collection of preferences and/or children. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has already + * been removed with the {@link #removeNode()} method. + * @throws UnsupportedOperationException if this method is invoked on + * the root node. + * @see #flush() + */ + public abstract void removeNode() throws BackingStoreException; + + /** + * Returns this preference node's name, relative to its parent. + * + * @return this preference node's name, relative to its parent. + */ + public abstract String name(); + + /** + * Returns this preference node's absolute path name. + * + * @return this preference node's absolute path name. + */ + public abstract String absolutePath(); + + /** + * Returns true if this preference node is in the user + * preference tree, false if it's in the system preference tree. + * + * @return true if this preference node is in the user + * preference tree, false if it's in the system + * preference tree. + */ + public abstract boolean isUserNode(); + + /** + * Returns a string representation of this preferences node, + * as if computed by the expression:(this.isUserNode() ? "User" : + * "System") + " Preference Node: " + this.absolutePath(). + */ + public abstract String toString(); + + /** + * Forces any changes in the contents of this preference node and its + * descendants to the persistent store. Once this method returns + * successfully, it is safe to assume that all changes made in the + * subtree rooted at this node prior to the method invocation have become + * permanent. + * + *

Implementations are free to flush changes into the persistent store + * at any time. They do not need to wait for this method to be called. + * + *

When a flush occurs on a newly created node, it is made persistent, + * as are any ancestors (and descendants) that have yet to be made + * persistent. Note however that any preference value changes in + * ancestors are not guaranteed to be made persistent. + * + *

If this method is invoked on a node that has been removed with + * the {@link #removeNode()} method, flushSpi() is invoked on this node, + * but not on others. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @see #sync() + */ + public abstract void flush() throws BackingStoreException; + + /** + * Ensures that future reads from this preference node and its + * descendants reflect any changes that were committed to the persistent + * store (from any VM) prior to the sync invocation. As a + * side-effect, forces any changes in the contents of this preference node + * and its descendants to the persistent store, as if the flush + * method had been invoked on this node. + * + * @throws BackingStoreException if this operation cannot be completed + * due to a failure in the backing store, or inability to + * communicate with it. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #flush() + */ + public abstract void sync() throws BackingStoreException; + + /** + * Registers the specified listener to receive preference change + * events for this preference node. A preference change event is + * generated when a preference is added to this node, removed from this + * node, or when the value associated with a preference is changed. + * (Preference change events are not generated by the {@link + * #removeNode()} method, which generates a node change event. + * Preference change events are generated by the clear + * method.) + * + *

Events are only guaranteed for changes made within the same JVM + * as the registered listener, though some implementations may generate + * events for changes made outside this JVM. Events may be generated + * before the changes have been made persistent. Events are not generated + * when preferences are modified in descendants of this node; a caller + * desiring such events must register with each descendant. + * + * @param pcl The preference change listener to add. + * @throws NullPointerException if pcl is null. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #removePreferenceChangeListener(PreferenceChangeListener) + * @see #addNodeChangeListener(NodeChangeListener) + */ + public abstract void addPreferenceChangeListener( + PreferenceChangeListener pcl); + + /** + * Removes the specified preference change listener, so it no longer + * receives preference change events. + * + * @param pcl The preference change listener to remove. + * @throws IllegalArgumentException if pcl was not a registered + * preference change listener on this node. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #addPreferenceChangeListener(PreferenceChangeListener) + */ + public abstract void removePreferenceChangeListener( + PreferenceChangeListener pcl); + + /** + * Registers the specified listener to receive node change events + * for this node. A node change event is generated when a child node is + * added to or removed from this node. (A single {@link #removeNode()} + * invocation results in multiple node change events, one for every + * node in the subtree rooted at the removed node.) + * + *

Events are only guaranteed for changes made within the same JVM + * as the registered listener, though some implementations may generate + * events for changes made outside this JVM. Events may be generated + * before the changes have become permanent. Events are not generated + * when indirect descendants of this node are added or removed; a + * caller desiring such events must register with each descendant. + * + *

Few guarantees can be made regarding node creation. Because nodes + * are created implicitly upon access, it may not be feasible for an + * implementation to determine whether a child node existed in the backing + * store prior to access (for example, because the backing store is + * unreachable or cached information is out of date). Under these + * circumstances, implementations are neither required to generate node + * change events nor prohibited from doing so. + * + * @param ncl The NodeChangeListener to add. + * @throws NullPointerException if ncl is null. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #removeNodeChangeListener(NodeChangeListener) + * @see #addPreferenceChangeListener(PreferenceChangeListener) + */ + public abstract void addNodeChangeListener(NodeChangeListener ncl); + + /** + * Removes the specified NodeChangeListener, so it no longer + * receives change events. + * + * @param ncl The NodeChangeListener to remove. + * @throws IllegalArgumentException if ncl was not a registered + * NodeChangeListener on this node. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #addNodeChangeListener(NodeChangeListener) + */ + public abstract void removeNodeChangeListener(NodeChangeListener ncl); + + /** + * Emits on the specified output stream an XML document representing all + * of the preferences contained in this node (but not its descendants). + * This XML document is, in effect, an offline backup of the node. + * + *

The XML document will have the following DOCTYPE declaration: + *

{@code
+     * 
+     * }
+ * The UTF-8 character encoding will be used. + * + *

This method is an exception to the general rule that the results of + * concurrently executing multiple methods in this class yields + * results equivalent to some serial execution. If the preferences + * at this node are modified concurrently with an invocation of this + * method, the exported preferences comprise a "fuzzy snapshot" of the + * preferences contained in the node; some of the concurrent modifications + * may be reflected in the exported data while others may not. + * + * @param os the output stream on which to emit the XML document. + * @throws IOException if writing to the specified output stream + * results in an IOException. + * @throws BackingStoreException if preference data cannot be read from + * backing store. + * @see #importPreferences(InputStream) + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + */ + public abstract void exportNode(OutputStream os) + throws IOException, BackingStoreException; + + /** + * Emits an XML document representing all of the preferences contained + * in this node and all of its descendants. This XML document is, in + * effect, an offline backup of the subtree rooted at the node. + * + *

The XML document will have the following DOCTYPE declaration: + *

{@code
+     * 
+     * }
+ * The UTF-8 character encoding will be used. + * + *

This method is an exception to the general rule that the results of + * concurrently executing multiple methods in this class yields + * results equivalent to some serial execution. If the preferences + * or nodes in the subtree rooted at this node are modified concurrently + * with an invocation of this method, the exported preferences comprise a + * "fuzzy snapshot" of the subtree; some of the concurrent modifications + * may be reflected in the exported data while others may not. + * + * @param os the output stream on which to emit the XML document. + * @throws IOException if writing to the specified output stream + * results in an IOException. + * @throws BackingStoreException if preference data cannot be read from + * backing store. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link #removeNode()} method. + * @see #importPreferences(InputStream) + * @see #exportNode(OutputStream) + */ + public abstract void exportSubtree(OutputStream os) + throws IOException, BackingStoreException; + + /** + * Imports all of the preferences represented by the XML document on the + * specified input stream. The document may represent user preferences or + * system preferences. If it represents user preferences, the preferences + * will be imported into the calling user's preference tree (even if they + * originally came from a different user's preference tree). If any of + * the preferences described by the document inhabit preference nodes that + * do not exist, the nodes will be created. + * + *

The XML document must have the following DOCTYPE declaration: + *

{@code
+     * 
+     * }
+ * (This method is designed for use in conjunction with + * {@link #exportNode(OutputStream)} and + * {@link #exportSubtree(OutputStream)}. + * + *

This method is an exception to the general rule that the results of + * concurrently executing multiple methods in this class yields + * results equivalent to some serial execution. The method behaves + * as if implemented on top of the other public methods in this class, + * notably {@link #node(String)} and {@link #put(String, String)}. + * + * @param is the input stream from which to read the XML document. + * @throws IOException if reading from the specified input stream + * results in an IOException. + * @throws InvalidPreferencesFormatException Data on input stream does not + * constitute a valid XML document with the mandated document type. + * @throws SecurityException If a security manager is present and + * it denies RuntimePermission("preferences"). + * @see RuntimePermission + */ + public static void importPreferences(InputStream is) + throws IOException, InvalidPreferencesFormatException + { + XmlSupport.importPreferences(is); + } +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferencesFactory.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferencesFactory.java new file mode 100644 index 000000000..d7341e656 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/PreferencesFactory.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2000, 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 java.util.prefs; +import java.util.*; + +/** + * A factory object that generates Preferences objects. Providers of + * new {@link Preferences} implementations should provide corresponding + * PreferencesFactory implementations so that the new + * Preferences implementation can be installed in place of the + * platform-specific default implementation. + * + *

This class is for Preferences implementers only. + * Normal users of the Preferences facility should have no need to + * consult this documentation. + * + * @author Josh Bloch + * @see Preferences + * @since 1.4 + */ +public interface PreferencesFactory { + /** + * Returns the system root preference node. (Multiple calls on this + * method will return the same object reference.) + * @return the system root preference node + */ + Preferences systemRoot(); + + /** + * Returns the user root preference node corresponding to the calling + * user. In a server, the returned value will typically depend on + * some implicit client-context. + * @return the user root preference node corresponding to the calling + * user + */ + Preferences userRoot(); +} diff --git a/sources/net.sf.j2s.java.core/src/java/util/prefs/XmlSupport.java b/sources/net.sf.j2s.java.core/src/java/util/prefs/XmlSupport.java new file mode 100644 index 000000000..002d9326a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/java/util/prefs/XmlSupport.java @@ -0,0 +1,421 @@ +/* + * Copyright (c) 2002, 2012, 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 java.util.prefs; + +import java.util.*; +import java.io.*; +import javax.xml.parsers.*; +import javax.xml.transform.*; +import javax.xml.transform.dom.*; +import javax.xml.transform.stream.*; +import org.xml.sax.*; +import org.w3c.dom.*; + +/** + * XML Support for java.util.prefs. Methods to import and export preference + * nodes and subtrees. + * + * @author Josh Bloch and Mark Reinhold + * @see Preferences + * @since 1.4 + */ +class XmlSupport { + // The required DTD URI for exported preferences + private static final String PREFS_DTD_URI = + "http://java.sun.com/dtd/preferences.dtd"; + + // The actual DTD corresponding to the URI + private static final String PREFS_DTD = + "" + + + "" + + + "" + + "" + + + "" + + "" + + + "" + + "" + + + "" + + "" + + "" + + "" ; + /** + * Version number for the format exported preferences files. + */ + private static final String EXTERNAL_XML_VERSION = "1.0"; + + /* + * Version number for the internal map files. + */ + private static final String MAP_XML_VERSION = "1.0"; + + /** + * Export the specified preferences node and, if subTree is true, all + * subnodes, to the specified output stream. Preferences are exported as + * an XML document conforming to the definition in the Preferences spec. + * + * @throws IOException if writing to the specified output stream + * results in an IOException. + * @throws BackingStoreException if preference data cannot be read from + * backing store. + * @throws IllegalStateException if this node (or an ancestor) has been + * removed with the {@link Preferences#removeNode()} method. + */ + static void export(OutputStream os, final Preferences p, boolean subTree) + throws IOException, BackingStoreException { + if (((AbstractPreferences)p).isRemoved()) + throw new IllegalStateException("Node has been removed"); + Document doc = createPrefsDoc("preferences"); + Element preferences = doc.getDocumentElement() ; + preferences.setAttribute("EXTERNAL_XML_VERSION", EXTERNAL_XML_VERSION); + Element xmlRoot = (Element) + preferences.appendChild(doc.createElement("root")); + xmlRoot.setAttribute("type", (p.isUserNode() ? "user" : "system")); + + // Get bottom-up list of nodes from p to root, excluding root + List ancestors = new ArrayList<>(); + + for (Preferences kid = p, dad = kid.parent(); dad != null; + kid = dad, dad = kid.parent()) { + ancestors.add(kid); + } + Element e = xmlRoot; + for (int i=ancestors.size()-1; i >= 0; i--) { + e.appendChild(doc.createElement("map")); + e = (Element) e.appendChild(doc.createElement("node")); + e.setAttribute("name", ancestors.get(i).name()); + } + putPreferencesInXml(e, doc, p, subTree); + + writeDoc(doc, os); + } + + /** + * Put the preferences in the specified Preferences node into the + * specified XML element which is assumed to represent a node + * in the specified XML document which is assumed to conform to + * PREFS_DTD. If subTree is true, create children of the specified + * XML node conforming to all of the children of the specified + * Preferences node and recurse. + * + * @throws BackingStoreException if it is not possible to read + * the preferences or children out of the specified + * preferences node. + */ + private static void putPreferencesInXml(Element elt, Document doc, + Preferences prefs, boolean subTree) throws BackingStoreException + { + Preferences[] kidsCopy = null; + String[] kidNames = null; + + // Node is locked to export its contents and get a + // copy of children, then lock is released, + // and, if subTree = true, recursive calls are made on children + synchronized (((AbstractPreferences)prefs).lock) { + // Check if this node was concurrently removed. If yes + // remove it from XML Document and return. + if (((AbstractPreferences)prefs).isRemoved()) { + elt.getParentNode().removeChild(elt); + return; + } + // Put map in xml element + String[] keys = prefs.keys(); + Element map = (Element) elt.appendChild(doc.createElement("map")); + for (int i=0; iIOException. + * @throws InvalidPreferencesFormatException Data on input stream does not + * constitute a valid XML document with the mandated document type. + */ + static void importPreferences(InputStream is) + throws IOException, InvalidPreferencesFormatException + { + try { + Document doc = loadPrefsDoc(is); + String xmlVersion = + doc.getDocumentElement().getAttribute("EXTERNAL_XML_VERSION"); + if (xmlVersion.compareTo(EXTERNAL_XML_VERSION) > 0) + throw new InvalidPreferencesFormatException( + "Exported preferences file format version " + xmlVersion + + " is not supported. This java installation can read" + + " versions " + EXTERNAL_XML_VERSION + " or older. You may need" + + " to install a newer version of JDK."); + + Element xmlRoot = (Element) doc.getDocumentElement(). + getChildNodes().item(0); + Preferences prefsRoot = + (xmlRoot.getAttribute("type").equals("user") ? + Preferences.userRoot() : Preferences.systemRoot()); + ImportSubtree(prefsRoot, xmlRoot); + } catch(SAXException e) { + throw new InvalidPreferencesFormatException(e); + } + } + + /** + * Create a new prefs XML document. + */ + private static Document createPrefsDoc( String qname ) { + try { + DOMImplementation di = DocumentBuilderFactory.newInstance(). + newDocumentBuilder().getDOMImplementation(); + DocumentType dt = di.createDocumentType(qname, null, PREFS_DTD_URI); + return di.createDocument(null, qname, dt); + } catch(ParserConfigurationException e) { + throw new AssertionError(e); + } + } + + /** + * Load an XML document from specified input stream, which must + * have the requisite DTD URI. + */ + private static Document loadPrefsDoc(InputStream in) + throws SAXException, IOException + { + DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance(); + dbf.setIgnoringElementContentWhitespace(true); + dbf.setValidating(true); + dbf.setCoalescing(true); + dbf.setIgnoringComments(true); + try { + DocumentBuilder db = dbf.newDocumentBuilder(); + db.setEntityResolver(new Resolver()); + db.setErrorHandler(new EH()); + return db.parse(new InputSource(in)); + } catch (ParserConfigurationException e) { + throw new AssertionError(e); + } + } + + /** + * Write XML document to the specified output stream. + */ + private static final void writeDoc(Document doc, OutputStream out) + throws IOException + { + try { + TransformerFactory tf = TransformerFactory.newInstance(); + try { + tf.setAttribute("indent-number", new Integer(2)); + } catch (IllegalArgumentException iae) { + //Ignore the IAE. Should not fail the writeout even the + //transformer provider does not support "indent-number". + } + Transformer t = tf.newTransformer(); + t.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM, doc.getDoctype().getSystemId()); + t.setOutputProperty(OutputKeys.INDENT, "yes"); + //Transformer resets the "indent" info if the "result" is a StreamResult with + //an OutputStream object embedded, creating a Writer object on top of that + //OutputStream object however works. + t.transform(new DOMSource(doc), + new StreamResult(new BufferedWriter(new OutputStreamWriter(out, "UTF-8")))); + } catch(TransformerException e) { + throw new AssertionError(e); + } + } + + /** + * Recursively traverse the specified preferences node and store + * the described preferences into the system or current user + * preferences tree, as appropriate. + */ + private static void ImportSubtree(Preferences prefsNode, Element xmlNode) { + NodeList xmlKids = xmlNode.getChildNodes(); + int numXmlKids = xmlKids.getLength(); + /* + * We first lock the node, import its contents and get + * child nodes. Then we unlock the node and go to children + * Since some of the children might have been concurrently + * deleted we check for this. + */ + Preferences[] prefsKids; + /* Lock the node */ + synchronized (((AbstractPreferences)prefsNode).lock) { + //If removed, return silently + if (((AbstractPreferences)prefsNode).isRemoved()) + return; + + // Import any preferences at this node + Element firstXmlKid = (Element) xmlKids.item(0); + ImportPrefs(prefsNode, firstXmlKid); + prefsKids = new Preferences[numXmlKids - 1]; + + // Get involved children + for (int i=1; i < numXmlKids; i++) { + Element xmlKid = (Element) xmlKids.item(i); + prefsKids[i-1] = prefsNode.node(xmlKid.getAttribute("name")); + } + } // unlocked the node + // import children + for (int i=1; i < numXmlKids; i++) + ImportSubtree(prefsKids[i-1], (Element)xmlKids.item(i)); + } + + /** + * Import the preferences described by the specified XML element + * (a map from a preferences document) into the specified + * preferences node. + */ + private static void ImportPrefs(Preferences prefsNode, Element map) { + NodeList entries = map.getChildNodes(); + for (int i=0, numEntries = entries.getLength(); i < numEntries; i++) { + Element entry = (Element) entries.item(i); + prefsNode.put(entry.getAttribute("key"), + entry.getAttribute("value")); + } + } + + /** + * Export the specified Map to a map document on + * the specified OutputStream as per the prefs DTD. This is used + * as the internal (undocumented) format for FileSystemPrefs. + * + * @throws IOException if writing to the specified output stream + * results in an IOException. + */ + static void exportMap(OutputStream os, Map map) throws IOException { + Document doc = createPrefsDoc("map"); + Element xmlMap = doc.getDocumentElement( ) ; + xmlMap.setAttribute("MAP_XML_VERSION", MAP_XML_VERSION); + + for (Iterator> i = map.entrySet().iterator(); i.hasNext(); ) { + Map.Entry e = i.next(); + Element xe = (Element) + xmlMap.appendChild(doc.createElement("entry")); + xe.setAttribute("key", e.getKey()); + xe.setAttribute("value", e.getValue()); + } + + writeDoc(doc, os); + } + + /** + * Import Map from the specified input stream, which is assumed + * to contain a map document as per the prefs DTD. This is used + * as the internal (undocumented) format for FileSystemPrefs. The + * key-value pairs specified in the XML document will be put into + * the specified Map. (If this Map is empty, it will contain exactly + * the key-value pairs int the XML-document when this method returns.) + * + * @throws IOException if reading from the specified output stream + * results in an IOException. + * @throws InvalidPreferencesFormatException Data on input stream does not + * constitute a valid XML document with the mandated document type. + */ + static void importMap(InputStream is, Map m) + throws IOException, InvalidPreferencesFormatException + { + try { + Document doc = loadPrefsDoc(is); + Element xmlMap = doc.getDocumentElement(); + // check version + String mapVersion = xmlMap.getAttribute("MAP_XML_VERSION"); + if (mapVersion.compareTo(MAP_XML_VERSION) > 0) + throw new InvalidPreferencesFormatException( + "Preferences map file format version " + mapVersion + + " is not supported. This java installation can read" + + " versions " + MAP_XML_VERSION + " or older. You may need" + + " to install a newer version of JDK."); + + NodeList entries = xmlMap.getChildNodes(); + for (int i=0, numEntries=entries.getLength(); iJTextPane. A new instance of * StyledEditorKit is diff --git a/sources/net.sf.j2s.java.core/src/javax/swing/RepaintManager.java b/sources/net.sf.j2s.java.core/src/javax/swing/RepaintManager.java index b2e83197e..b590b6d02 100644 --- a/sources/net.sf.j2s.java.core/src/javax/swing/RepaintManager.java +++ b/sources/net.sf.j2s.java.core/src/javax/swing/RepaintManager.java @@ -49,7 +49,7 @@ import java.util.Set; import javajs.util.Lst; -import sun.awt.AWTAccessor; +//import sun.awt.AWTAccessor; import sun.awt.AppContext; import sun.awt.SunToolkit; import swingjs.JSToolkit; diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/XMLConstants.java b/sources/net.sf.j2s.java.core/src/javax/xml/XMLConstants.java index 22d15a18c..2e570f1de 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/XMLConstants.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/XMLConstants.java @@ -1,13 +1,194 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml; +/** + *

Utility class to contain basic XML values as constants.

+ * + * @author Jeff Suttor + * @version $Revision: 1.8 $, $Date: 2010/05/25 16:19:45 $ + * @see Extensible Markup Language (XML) 1.1 + * @see Extensible Markup Language (XML) 1.0 (Second Edition) + * @see XML 1.0 Second Edition Specification Errata + * @see Namespaces in XML 1.1 + * @see Namespaces in XML + * @see Namespaces in XML Errata + * @see XML Schema Part 1: Structures + * @since 1.5 + **/ + public final class XMLConstants { - public static final String NULL_NS_URI = ""; - public static final String DEFAULT_NS_PREFIX = ""; - public static final String XML_NS_URI = "http://www.w3.org/XML/1998/namespace"; - public static final String XML_NS_PREFIX = "xml"; - public static final String XMLNS_ATTRIBUTE_NS_URI = "http://www.w3.org/2000/xmlns/"; - public static final String XMLNS_ATTRIBUTE = "xmlns"; - public static final String W3C_XML_SCHEMA_NS_URI = "http://www.w3.org/2001/XMLSchema"; - public static final String W3C_XML_SCHEMA_INSTANCE_NS_URI = "http://www.w3.org/2001/XMLSchema-instance"; - public static final String W3C_XPATH_DATATYPE_NS_URI = "http://www.w3.org/2003/11/xpath-datatypes"; + + /** + *

Private constructor to prevent instantiation.

+ */ + private XMLConstants() { + } + + /** + *

Namespace URI to use to represent that there is no Namespace.

+ * + *

Defined by the Namespace specification to be "".

+ * + * @see + * Namespaces in XML, 5.2 Namespace Defaulting + */ + public static final String NULL_NS_URI = ""; + + /** + *

Prefix to use to represent the default XML Namespace.

+ * + *

Defined by the XML specification to be "".

+ * + * @see + * Namespaces in XML, 3. Qualified Names + */ + public static final String DEFAULT_NS_PREFIX = ""; + + /** + *

The official XML Namespace name URI.

+ * + *

Defined by the XML specification to be + * "http://www.w3.org/XML/1998/namespace".

+ * + * @see + * Namespaces in XML, 3. Qualified Names + */ + public static final String XML_NS_URI = + "http://www.w3.org/XML/1998/namespace"; + + /** + *

The official XML Namespace prefix.

+ * + *

Defined by the XML specification to be "xml".

+ * + * @see + * Namespaces in XML, 3. Qualified Names< + */ + public static final String XML_NS_PREFIX = "xml"; + + /** + *

The official XML attribute used for specifying XML Namespace + * declarations, {@link #XMLNS_ATTRIBUTE + * XMLConstants.XMLNS_ATTRIBUTE}, Namespace name URI.

+ * + *

Defined by the XML specification to be + * "http://www.w3.org/2000/xmlns/".

+ * + * @see + * Namespaces in XML, 3. Qualified Names + * @see + * Namespaces in XML Errata + */ + public static final String XMLNS_ATTRIBUTE_NS_URI = + "http://www.w3.org/2000/xmlns/"; + + /** + *

The official XML attribute used for specifying XML Namespace + * declarations.

+ * + *

It is NOT valid to use as a + * prefix. Defined by the XML specification to be + * "xmlns".

+ * + * @see + * Namespaces in XML, 3. Qualified Names + */ + public static final String XMLNS_ATTRIBUTE = "xmlns"; + + /** + *

W3C XML Schema Namespace URI.

+ * + *

Defined to be "http://www.w3.org/2001/XMLSchema". + * + * @see + * XML Schema Part 1: + * Structures, 2.6 Schema-Related Markup in Documents Being Validated + */ + public static final String W3C_XML_SCHEMA_NS_URI = + "http://www.w3.org/2001/XMLSchema"; + + /** + *

W3C XML Schema Instance Namespace URI.

+ * + *

Defined to be "http://www.w3.org/2001/XMLSchema-instance".

+ * + * @see + * XML Schema Part 1: + * Structures, 2.6 Schema-Related Markup in Documents Being Validated + */ + public static final String W3C_XML_SCHEMA_INSTANCE_NS_URI = + "http://www.w3.org/2001/XMLSchema-instance"; + + /** + *

W3C XPath Datatype Namespace URI.

+ * + *

Defined to be "http://www.w3.org/2003/11/xpath-datatypes".

+ * + * @see XQuery 1.0 and XPath 2.0 Data Model + */ + public static final String W3C_XPATH_DATATYPE_NS_URI = "http://www.w3.org/2003/11/xpath-datatypes"; + + /** + *

XML Document Type Declaration Namespace URI as an arbitrary value.

+ * + *

Since not formally defined by any existing standard, arbitrarily define to be "http://www.w3.org/TR/REC-xml". + */ + public static final String XML_DTD_NS_URI = "http://www.w3.org/TR/REC-xml"; + + /** + *

RELAX NG Namespace URI.

+ * + *

Defined to be "http://relaxng.org/ns/structure/1.0".

+ * + * @see RELAX NG Specification + */ + public static final String RELAXNG_NS_URI = "http://relaxng.org/ns/structure/1.0"; + + /** + *

Feature for secure processing.

+ * + *
    + *
  • + * true instructs the implementation to process XML securely. + * This may set limits on XML constructs to avoid conditions such as denial of service attacks. + *
  • + *
  • + * false instructs the implementation to process XML acording the letter of the XML specifications + * ingoring security issues such as limits on XML constructs to avoid conditions such as denial of service attacks. + *
  • + *
+ */ + public static final String FEATURE_SECURE_PROCESSING = "http://javax.xml.XMLConstants/feature/secure-processing"; } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/bind/JAXB.java b/sources/net.sf.j2s.java.core/src/javax/xml/bind/JAXB.java index 196060b68..4cc2d9c3c 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/bind/JAXB.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/bind/JAXB.java @@ -53,7 +53,7 @@ import java.io.OutputStream; import java.io.Reader; import java.io.Writer; -import java.lang.ref.WeakReference; +//import java.lang.ref.WeakReference; import java.net.HttpURLConnection; import java.net.URI; import java.net.URISyntaxException; @@ -132,7 +132,7 @@ public Cache(Class type) throws JAXBException { * Cache. We don't want to prevent the {@link Cache#type} from GC-ed, * hence {@link WeakReference}. */ - private static volatile WeakReference cache; + private static volatile Cache cache; /** * Obtains the {@link JAXBContext} from the given type, @@ -143,16 +143,15 @@ public Cache(Class type) throws JAXBException { * should be thread-safe thanks to the immutable {@link Cache} and {@code volatile}. */ private static JAXBContext getContext(Class type) throws JAXBException { - WeakReference c = cache; - if(c!=null) { - Cache d = c.get(); + + Cache d = cache; if(d!=null && d.type==type) return d.context; - } + // overwrite the cache - Cache d = new Cache(type); - cache = new WeakReference(d); + d = new Cache(type); + cache = d; return d.context; } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConfigurationException.java b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConfigurationException.java index 0a37b9f17..7f96ce9cd 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConfigurationException.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConfigurationException.java @@ -1,15 +1,79 @@ +/* + * Copyright (c) 2004, 2005, 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 javax.xml.datatype; /** - * minimal; hand written based on API documentation - * - * @author hansonr + *

Indicates a serious configuration error.

* + * @author Jeff Suttor + * @since 1.5 */ + public class DatatypeConfigurationException extends Exception { - public DatatypeConfigurationException() { - super(); - } + /** + *

Create a new DatatypeConfigurationException with + * no specified detail mesage and cause.

+ */ + + public DatatypeConfigurationException() { + super(); + } + + /** + *

Create a new DatatypeConfigurationException with + * the specified detail message.

+ * + * @param message The detail message. + */ + + public DatatypeConfigurationException(String message) { + super(message); + } + + /** + *

Create a new DatatypeConfigurationException with + * the specified detail message and cause.

+ * + * @param message The detail message. + * @param cause The cause. A null value is permitted, and indicates that the cause is nonexistent or unknown. + */ + + public DatatypeConfigurationException(String message, Throwable cause) { + super(message, cause); + } + + /** + *

Create a new DatatypeConfigurationException with + * the specified cause.

+ * + * @param cause The cause. A null value is permitted, and indicates that the cause is nonexistent or unknown. + */ + public DatatypeConfigurationException(Throwable cause) { + super(cause); + } } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConstants.java b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConstants.java index 7e580cd53..519d81d77 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConstants.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeConstants.java @@ -1,73 +1,274 @@ +/* + * Copyright (c) 2004, 2006, 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 javax.xml.datatype; import javax.xml.XMLConstants; import javax.xml.namespace.QName; +/** + *

Utility class to contain basic Datatype values as constants.

+ * + * @author Jeff Suttor + * @since 1.5 + */ + public final class DatatypeConstants { - private DatatypeConstants() { - } - - public static final Field YEARS = new Field("YEARS", 0); - public static final Field MONTHS = new Field("MONTHS", 1); - public static final Field DAYS = new Field("DAYS", 2); - public static final Field HOURS = new Field("HOURS", 3); - public static final Field MINUTES = new Field("MINUTES", 4); - public static final Field SECONDS = new Field("SECONDS", 5); - - public static final class Field { - private final String str; - private final int id; - - private Field(final String str, final int id) { - this.str = str; - this.id = id; - } - - public String toString() { - return str; - } - - public int getId() { - return id; - } - } - - public static final QName DATETIME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "dateTime"); - public static final QName TIME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "time"); - public static final QName DATE = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "date"); - public static final QName GYEARMONTH = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gYearMonth"); - public static final QName GMONTHDAY = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gMonthDay"); - public static final QName GYEAR = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gYear"); - public static final QName GMONTH = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gMonth"); - public static final QName GDAY = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gDay"); - public static final QName DURATION = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "duration"); - public static final QName DURATION_DAYTIME = new QName(XMLConstants.W3C_XPATH_DATATYPE_NS_URI, "dayTimeDuration"); - public static final QName DURATION_YEARMONTH = new QName(XMLConstants.W3C_XPATH_DATATYPE_NS_URI, - "yearMonthDuration"); - - public static final int MAX_TIMEZONE_OFFSET = -840; - public static final int MIN_TIMEZONE_OFFSET = 840; - - public static final int LESSER = -1; - public static final int EQUAL = 0; - public static final int GREATER = 1; - public static final int INDETERMINATE = 2; - public static final int FIELD_UNDEFINED = Integer.MIN_VALUE; - - public static final int JANUARY = 1; - public static final int FEBRUARY = 2; - public static final int MARCH = 3; - public static final int APRIL = 4; - public static final int MAY = 5; - public static final int JUNE = 6; - public static final int JULY = 7; - public static final int AUGUST = 8; - public static final int SEPTEMBER = 9; - public static final int OCTOBER = 10; - public static final int NOVEMBER = 11; - public static final int DECEMBER = 12; - - - + /** + *

Private constructor to prevent instantiation.

+ */ + private DatatypeConstants() { + } + + /** + * Value for first month of year. + */ + public static final int JANUARY = 1; + + /** + * Value for second month of year. + */ + public static final int FEBRUARY = 2; + + /** + * Value for third month of year. + */ + public static final int MARCH = 3; + + /** + * Value for fourth month of year. + */ + public static final int APRIL = 4; + + /** + * Value for fifth month of year. + */ + public static final int MAY = 5; + + /** + * Value for sixth month of year. + */ + public static final int JUNE = 6; + + /** + * Value for seventh month of year. + */ + public static final int JULY = 7; + + /** + * Value for eighth month of year. + */ + public static final int AUGUST = 8; + + /** + * Value for ninth month of year. + */ + public static final int SEPTEMBER = 9; + + /** + * Value for tenth month of year. + */ + public static final int OCTOBER = 10; + + /** + * Value for eleven month of year. + */ + public static final int NOVEMBER = 11; + + /** + * Value for twelve month of year. + */ + public static final int DECEMBER = 12; + + /** + *

Comparison result.

+ */ + public static final int LESSER = -1; + + /** + *

Comparison result.

+ */ + public static final int EQUAL = 0; + + /** + *

Comparison result.

+ */ + public static final int GREATER = 1; + + /** + *

Comparison result.

+ */ + public static final int INDETERMINATE = 2; + + /** + * Designation that an "int" field is not set. + */ + public static final int FIELD_UNDEFINED = Integer.MIN_VALUE; + + /** + *

A constant that represents the years field.

+ */ + public static final Field YEARS = new Field("YEARS", 0); + + /** + *

A constant that represents the months field.

+ */ + public static final Field MONTHS = new Field("MONTHS", 1); + + /** + *

A constant that represents the days field.

+ */ + public static final Field DAYS = new Field("DAYS", 2); + + /** + *

A constant that represents the hours field.

+ */ + public static final Field HOURS = new Field("HOURS", 3); + + /** + *

A constant that represents the minutes field.

+ */ + public static final Field MINUTES = new Field("MINUTES", 4); + + /** + *

A constant that represents the seconds field.

+ */ + public static final Field SECONDS = new Field("SECONDS", 5); + + /** + * Type-safe enum class that represents six fields + * of the {@link Duration} class. + * @since 1.5 + */ + public static final class Field { + + /** + *

String representation of Field.

+ */ + private final String str; + /** + *

Unique id of the field.

+ * + *

This value allows the {@link Duration} class to use switch + * statements to process fields.

+ */ + private final int id; + + /** + *

Construct a Field with specified values.

+ * @param str String representation of Field + * @param id int representation of Field + */ + private Field(final String str, final int id) { + this.str = str; + this.id = id; + } + /** + * Returns a field name in English. This method + * is intended to be used for debugging/diagnosis + * and not for display to end-users. + * + * @return + * a non-null valid String constant. + */ + public String toString() { return str; } + + /** + *

Get id of this Field.

+ * + * @return Id of field. + */ + public int getId() { + return id; + } + } + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype dateTime.

+ */ + public static final QName DATETIME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "dateTime"); + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype time.

+ */ + public static final QName TIME = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "time"); + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype date.

+ */ + public static final QName DATE = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "date"); + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype gYearMonth.

+ */ + public static final QName GYEARMONTH = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gYearMonth"); + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype gMonthDay.

+ */ + public static final QName GMONTHDAY = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gMonthDay"); + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype gYear.

+ */ + public static final QName GYEAR = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gYear"); + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype gMonth.

+ */ + public static final QName GMONTH = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gMonth"); + + /** + *

Fully qualified name for W3C XML Schema 1.0 datatype gDay.

+ */ + public static final QName GDAY = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "gDay"); + + /** + *

Fully qualified name for W3C XML Schema datatype duration.

+ */ + public static final QName DURATION = new QName(XMLConstants.W3C_XML_SCHEMA_NS_URI, "duration"); + + /** + *

Fully qualified name for XQuery 1.0 and XPath 2.0 datatype dayTimeDuration.

+ */ + public static final QName DURATION_DAYTIME = new QName(XMLConstants.W3C_XPATH_DATATYPE_NS_URI, "dayTimeDuration"); + + /** + *

Fully qualified name for XQuery 1.0 and XPath 2.0 datatype yearMonthDuration.

+ */ + public static final QName DURATION_YEARMONTH = new QName(XMLConstants.W3C_XPATH_DATATYPE_NS_URI, "yearMonthDuration"); + + /** + * W3C XML Schema max timezone offset is -14:00. Zone offset is in minutes. + */ + public static final int MAX_TIMEZONE_OFFSET = -14 * 60; + + /** + * W3C XML Schema min timezone offset is +14:00. Zone offset is in minutes. + */ + public static final int MIN_TIMEZONE_OFFSET = 14 * 60; + } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeFactory.java index fbda96c40..e34416114 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeFactory.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/DatatypeFactory.java @@ -1,142 +1,1064 @@ +/* + * Copyright (c) 2004, 2006, 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 javax.xml.datatype; -import java.math.BigDecimal; import java.math.BigInteger; +import java.math.BigDecimal; import java.util.GregorianCalendar; import java.util.regex.Matcher; import java.util.regex.Pattern; -import swingjs.api.Interface; - /** - * hand written based on API documentation - * - * Does not use BigDecimal - * - * @author hansonr + *

Factory that creates new javax.xml.datatype Objects that map XML to/from Java Objects.

* + *

{@link #newInstance()} is used to create a new DatatypeFactory. + * The following implementation resolution mechanisms are used in the following order:

+ *
    + *
  1. + * If the system property specified by {@link #DATATYPEFACTORY_PROPERTY}, "javax.xml.datatype.DatatypeFactory", + * exists, a class with the name of the property's value is instantiated. + * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}. + *
  2. + *
  3. + * If the file ${JAVA_HOME}/lib/jaxp.properties exists, it is loaded in a {@link java.util.Properties} Object. + * The Properties Object is then queried for the property as documented in the prior step + * and processed as documented in the prior step. + *
  4. + *
  5. + * The services resolution mechanism is used, e.g. META-INF/services/java.xml.datatype.DatatypeFactory. + * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}. + *
  6. + *
  7. + * The final mechanism is to attempt to instantiate the Class specified by + * {@link #DATATYPEFACTORY_IMPLEMENTATION_CLASS}. + * Any Exception thrown during the instantiation process is wrapped as a {@link DatatypeConfigurationException}. + *
  8. + *
+ * + * @author
Joseph Fialli + * @author Jeff Suttor + * @author Neeraj Bajaj + * + * @version $Revision: 1.13 $, $Date: 2010/03/11 23:10:53 $ + * @since 1.5 */ - public abstract class DatatypeFactory { - private BigInteger bigI(int x) { - return (x == DatatypeConstants.FIELD_UNDEFINED ? null : BigInteger.valueOf(x)); - } - - private BigDecimal bigD(int x) { - return (x == DatatypeConstants.FIELD_UNDEFINED ? null : BigDecimal.valueOf(x)); - } - - protected DatatypeFactory() { - } - - public static DatatypeFactory newInstance() throws DatatypeConfigurationException { - return (DatatypeFactory) Interface.getInstance("swingjs.xml.JSJAXBDatatypeFactory", false); - } - - public abstract Duration newDuration(String s); - - public abstract Duration newDuration(long ms); - - public abstract Duration newDuration(boolean isPositive, BigInteger years, BigInteger months, BigInteger days, - BigInteger hours, BigInteger minutes, BigDecimal seconds); - - public Duration newDuration(boolean isPositive, int years, int months, int days, int hours, int minutes, - int seconds) { - return newDuration(isPositive, bigI(years), bigI(months), bigI(days), bigI(hours), bigI(minutes), bigD(seconds)); - } - - public Duration newDurationDayTime(String s) { - if (s == null) { - throw new NullPointerException("DatatypeFactory.newDurationDayTime null parameter"); - } - return newDuration(s); - } - - public Duration newDurationDayTime(long ms) { - return newDuration(ms); - } - - public Duration newDurationDayTime(boolean isPositive, BigInteger day, BigInteger hour, BigInteger minute, - BigInteger second) { - return newDuration(isPositive, null, null, day, hour, minute, - (second == null ? null : new BigDecimal(second))); - } - - public Duration newDurationDayTime(boolean isPositive, int day, int hour, int minute, int second) { - return newDurationDayTime(isPositive, bigI(day), bigI(hour), - bigI(minute), bigI(second)); - } - - public Duration newDurationYearMonth(String s) { - if (s == null) { - throw new NullPointerException("DatatypeFactory.newDerationYearMonth null value"); - } - return newDuration(s); - } - - public Duration newDurationYearMonth(long ms) { - Duration d = newDuration(ms); - BigInteger years = (BigInteger) d.getField(DatatypeConstants.YEARS); - BigInteger months = (BigInteger) d.getField(DatatypeConstants.MONTHS); - return newDurationYearMonth((d.getSign() == -1), years, months); - } - - public Duration newDurationYearMonth(boolean isPositive, BigInteger year, BigInteger month) { - return newDuration(isPositive, year == null ? BigInteger.ZERO : year, month == null ? BigInteger.ZERO : month, - null, null, null, null); - } - - public Duration newDurationYearMonth(boolean isPositive, int year, int month) { - return newDurationYearMonth(isPositive, bigI(year), bigI(month)); - } - - public abstract XMLGregorianCalendar newXMLGregorianCalendar(); - public abstract XMLGregorianCalendar newXMLGregorianCalendar(String s); - public abstract XMLGregorianCalendar newXMLGregorianCalendar(GregorianCalendar cal); - public abstract XMLGregorianCalendar newXMLGregorianCalendar(BigInteger year, int month, int day, int hour, - int minute, int second, BigDecimal fractionalSecond, int timezone); - - public abstract XMLGregorianCalendar newXMLGregorianCalendar(int year, int month, int day, int hour, int minute, int second, - int millisecond, int timezone); - - public XMLGregorianCalendar newXMLGregorianCalendarDate(int year, int month, int day, int timezone) { - - return newXMLGregorianCalendar(year, month, day, DatatypeConstants.FIELD_UNDEFINED, - DatatypeConstants.FIELD_UNDEFINED, - DatatypeConstants.FIELD_UNDEFINED, - DatatypeConstants.FIELD_UNDEFINED, - timezone); - } - - public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours, int minutes, int seconds, int timezone) { - - return newXMLGregorianCalendar(DatatypeConstants.FIELD_UNDEFINED, // Year - DatatypeConstants.FIELD_UNDEFINED, // Month - DatatypeConstants.FIELD_UNDEFINED, // Day - hours, minutes, seconds, - DatatypeConstants.FIELD_UNDEFINED, // Millisecond - timezone); - } - - public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours, int minutes, int seconds, - BigDecimal fractionalSeconds, int timezone) { - - return newXMLGregorianCalendar(null, - DatatypeConstants.FIELD_UNDEFINED, - DatatypeConstants.FIELD_UNDEFINED, - hours, minutes, seconds, fractionalSeconds, timezone); - } - - public XMLGregorianCalendar newXMLGregorianCalendarTime(int hours, int minutes, int seconds, int milliseconds, - int timezone) { - BigDecimal bdMS = null; // undefined value - if (milliseconds != DatatypeConstants.FIELD_UNDEFINED) { - if (milliseconds < 0 || milliseconds > 1000) { - throw new IllegalArgumentException("milliseconds must be between 0 and 1000"); - } - bdMS = bigD(milliseconds); - } - return newXMLGregorianCalendarTime(hours, minutes, seconds, bdMS, timezone); - } + /** + *

Default property name as defined in JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.

+ * + *

Default value is javax.xml.datatype.DatatypeFactory.

+ */ + public static final String DATATYPEFACTORY_PROPERTY = "javax.xml.datatype.DatatypeFactory"; + + /** + *

Default implementation class name as defined in + * JSR 206: Java(TM) API for XML Processing (JAXP) 1.3.

+ * + *

Implementers should specify the name of an appropriate class + * to be instantiated if no other implementation resolution mechanism + * succeeds.

+ * + *

Users should not refer to this field; it is intended only to + * document a factory implementation detail. + *

+ */ + public static final String DATATYPEFACTORY_IMPLEMENTATION_CLASS = new String("org.apache.xerces.jaxp.datatype.DatatypeFactoryImpl"); + + /** + * http://www.w3.org/TR/xpath-datamodel/#xdtschema defines two regexps + * to constrain the value space of dayTimeDuration ([^YM]*[DT].*) + * and yearMonthDuration ([^DT]*). Note that these expressions rely on + * the fact that the value must be an xs:Duration, they simply exclude + * some Durations. + */ + private static final Pattern XDTSCHEMA_YMD = + Pattern.compile("[^DT]*"); + + private static final Pattern XDTSCHEMA_DTD = + Pattern.compile("[^YM]*[DT].*"); + + /** + *

Protected constructor to prevent instaniation outside of package.

+ * + *

Use {@link #newInstance()} to create a DatatypeFactory.

+ */ + protected DatatypeFactory() { + } + + /** + *

Obtain a new instance of a DatatypeFactory.

+ * + *

The implementation resolution mechanisms are defined in this + * Class's documentation.

+ * + * @return New instance of a DatatypeFactory + * + * @throws DatatypeConfigurationException If the implementation is not + * available or cannot be instantiated. + * + * @see #newInstance(String factoryClassName, ClassLoader classLoader) + */ + public static DatatypeFactory newInstance() + throws DatatypeConfigurationException { + + try { + return (DatatypeFactory) FactoryFinder.find( + /* The default property name according to the JAXP spec */ + DATATYPEFACTORY_PROPERTY, + /* The fallback implementation class name */ + DATATYPEFACTORY_IMPLEMENTATION_CLASS); + } catch (FactoryFinder.ConfigurationError e) { + throw new DatatypeConfigurationException(e.getMessage(), e.getException()); + } + } + + /** + *

Obtain a new instance of a DatatypeFactory from class name. + * This function is useful when there are multiple providers in the classpath. + * It gives more control to the application as it can specify which provider + * should be loaded.

+ * + *

Once an application has obtained a reference to a DatatypeFactory + * it can use the factory to configure and obtain datatype instances.

+ * + * + *

Tip for Trouble-shooting

+ *

Setting the jaxp.debug system property will cause + * this method to print a lot of debug messages + * to System.err about what it is doing and where it is looking at.

+ * + *

If you have problems try:

+ *
+     * java -Djaxp.debug=1 YourProgram ....
+     * 
+ * + * @param factoryClassName fully qualified factory class name that provides implementation of javax.xml.datatype.DatatypeFactory. + * + * @param classLoader ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @return New instance of a DatatypeFactory + * + * @throws DatatypeConfigurationException if factoryClassName is null, or + * the factory class cannot be loaded, instantiated. + * + * @see #newInstance() + * + * @since 1.6 + */ + public static DatatypeFactory newInstance(String factoryClassName, ClassLoader classLoader) + throws DatatypeConfigurationException { + try { + return (DatatypeFactory) FactoryFinder.newInstance(factoryClassName, classLoader, false); + } catch (FactoryFinder.ConfigurationError e) { + throw new DatatypeConfigurationException(e.getMessage(), e.getException()); + } + } + + /** + *

Obtain a new instance of a Duration + * specifying the Duration as its string representation, "PnYnMnDTnHnMnS", + * as defined in XML Schema 1.0 section 3.2.6.1.

+ * + *

XML Schema Part 2: Datatypes, 3.2.6 duration, defines duration as:

+ *
+ * duration represents a duration of time. + * The value space of duration is a six-dimensional space where the coordinates designate the + * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. + * These components are ordered in their significance by their order of appearance i.e. as + * year, month, day, hour, minute, and second. + *
+ *

All six values are set and availabe from the created {@link Duration}

+ * + *

The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.

+ * + * @param lexicalRepresentation String representation of a Duration. + * + * @return New Duration created from parsing the lexicalRepresentation. + * + * @throws IllegalArgumentException If lexicalRepresentation is not a valid representation of a Duration. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException if lexicalRepresentation is null. + */ + public abstract Duration newDuration(final String lexicalRepresentation); + + /** + *

Obtain a new instance of a Duration + * specifying the Duration as milliseconds.

+ * + *

XML Schema Part 2: Datatypes, 3.2.6 duration, defines duration as:

+ *
+ * duration represents a duration of time. + * The value space of duration is a six-dimensional space where the coordinates designate the + * Gregorian year, month, day, hour, minute, and second components defined in Section 5.5.3.2 of [ISO 8601], respectively. + * These components are ordered in their significance by their order of appearance i.e. as + * year, month, day, hour, minute, and second. + *
+ *

All six values are set by computing their values from the specified milliseconds + * and are availabe using the get methods of the created {@link Duration}. + * The values conform to and are defined by:

+ * + * + *

The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getMonths()} and {@link Duration#getDays()} can be influenced.

+ * + * @param durationInMilliSeconds Duration in milliseconds to create. + * + * @return New Duration representing durationInMilliSeconds. + */ + public abstract Duration newDuration(final long durationInMilliSeconds); + + /** + *

Obtain a new instance of a Duration + * specifying the Duration as isPositive, years, months, days, hours, minutes, seconds.

+ * + *

The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.

+ * + *

A null value indicates that field is not set.

+ * + * @param isPositive Set to false to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param years of this Duration + * @param months of this Duration + * @param days of this Duration + * @param hours of this Duration + * @param minutes of this Duration + * @param seconds of this Duration + * + * @return New Duration created from the specified values. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * Duration: if all the fields (years, months, ...) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public abstract Duration newDuration( + final boolean isPositive, + final BigInteger years, + final BigInteger months, + final BigInteger days, + final BigInteger hours, + final BigInteger minutes, + final BigDecimal seconds); + + /** + *

Obtain a new instance of a Duration + * specifying the Duration as isPositive, years, months, days, hours, minutes, seconds.

+ * + *

A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

+ * + * @param isPositive Set to false to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param years of this Duration + * @param months of this Duration + * @param days of this Duration + * @param hours of this Duration + * @param minutes of this Duration + * @param seconds of this Duration + * + * @return New Duration created from the specified values. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * Duration: if any of the fields is negative. + * + * @see #newDuration( + * boolean isPositive, + * BigInteger years, + * BigInteger months, + * BigInteger days, + * BigInteger hours, + * BigInteger minutes, + * BigDecimal seconds) + */ + public Duration newDuration( + final boolean isPositive, + final int years, + final int months, + final int days, + final int hours, + final int minutes, + final int seconds) { + + // years may not be set + BigInteger realYears = (years != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) years) : null; + + // months may not be set + BigInteger realMonths = (months != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) months) : null; + + // days may not be set + BigInteger realDays = (days != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) days) : null; + + // hours may not be set + BigInteger realHours = (hours != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) hours) : null; + + // minutes may not be set + BigInteger realMinutes = (minutes != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) minutes) : null; + + // seconds may not be set + BigDecimal realSeconds = (seconds != DatatypeConstants.FIELD_UNDEFINED) ? BigDecimal.valueOf((long) seconds) : null; + + return newDuration( + isPositive, + realYears, + realMonths, + realDays, + realHours, + realMinutes, + realSeconds + ); + } + + /** + *

Create a Duration of type xdt:dayTimeDuration by parsing its String representation, + * "PnDTnHnMnS", + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

+ * + *

The datatype xdt:dayTimeDuration is a subtype of xs:duration + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

+ * + *

All four values are set and availabe from the created {@link Duration}

+ * + *

The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.

+ * + * @param lexicalRepresentation Lexical representation of a duration. + * + * @return New Duration created using the specified lexicalRepresentation. + * + * @throws IllegalArgumentException If lexicalRepresentation is not a valid representation of a Duration expressed only in terms of days and time. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If lexicalRepresentation is null. + */ + public Duration newDurationDayTime(final String lexicalRepresentation) { + // lexicalRepresentation must be non-null + if (lexicalRepresentation == null) { + throw new NullPointerException( + "Trying to create an xdt:dayTimeDuration with an invalid" + + " lexical representation of \"null\""); + } + + // test lexicalRepresentation against spec regex + Matcher matcher = XDTSCHEMA_DTD.matcher(lexicalRepresentation); + if (!matcher.matches()) { + throw new IllegalArgumentException( + "Trying to create an xdt:dayTimeDuration with an invalid" + + " lexical representation of \"" + lexicalRepresentation + + "\", data model requires years and months only."); + } + + return newDuration(lexicalRepresentation); + } + + /** + *

Create a Duration of type xdt:dayTimeDuration using the specified milliseconds as defined in + * + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

+ * + *

The datatype xdt:dayTimeDuration is a subtype of xs:duration + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

+ * + *

All four values are set by computing their values from the specified milliseconds + * and are availabe using the get methods of the created {@link Duration}. + * The values conform to and are defined by:

+ * + * + *

The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getDays()} can be influenced.

+ * + *

Any remaining milliseconds after determining the day, hour, minute and second are discarded.

+ * + * @param durationInMilliseconds Milliseconds of Duration to create. + * + * @return New Duration created with the specified durationInMilliseconds. + * + * @see + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration + */ + public Duration newDurationDayTime(final long durationInMilliseconds) { + + return newDuration(durationInMilliseconds); + } + + /** + *

Create a Duration of type xdt:dayTimeDuration using the specified + * day, hour, minute and second as defined in + * + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

+ * + *

The datatype xdt:dayTimeDuration is a subtype of xs:duration + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

+ * + *

The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.

+ * + *

A null value indicates that field is not set.

+ * + * @param isPositive Set to false to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param day Day of Duration. + * @param hour Hour of Duration. + * @param minute Minute of Duration. + * @param second Second of Duration. + * + * @return New Duration created with the specified day, hour, minute + * and second. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * Duration: if all the fields (day, hour, ...) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public Duration newDurationDayTime( + final boolean isPositive, + final BigInteger day, + final BigInteger hour, + final BigInteger minute, + final BigInteger second) { + + return newDuration( + isPositive, + null, // years + null, // months + day, + hour, + minute, + (second != null)? new BigDecimal(second):null + ); + } + + /** + *

Create a Duration of type xdt:dayTimeDuration using the specified + * day, hour, minute and second as defined in + * + * XQuery 1.0 and XPath 2.0 Data Model, xdt:dayTimeDuration.

+ * + *

The datatype xdt:dayTimeDuration is a subtype of xs:duration + * whose lexical representation contains only day, hour, minute, and second components. + * This datatype resides in the namespace http://www.w3.org/2003/11/xpath-datatypes.

+ * + *

A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

+ * + * @param isPositive Set to false to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param day Day of Duration. + * @param hour Hour of Duration. + * @param minute Minute of Duration. + * @param second Second of Duration. + * + * @return New Duration created with the specified day, hour, minute + * and second. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * Duration: if any of the fields (day, hour, ...) is negative. + */ + public Duration newDurationDayTime( + final boolean isPositive, + final int day, + final int hour, + final int minute, + final int second) { + + return newDurationDayTime( + isPositive, + BigInteger.valueOf((long) day), + BigInteger.valueOf((long) hour), + BigInteger.valueOf((long) minute), + BigInteger.valueOf((long) second) + ); + } + + /** + *

Create a Duration of type xdt:yearMonthDuration by parsing its String representation, + * "PnYnM", + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

+ * + *

The datatype xdt:yearMonthDuration is a subtype of xs:duration + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.

+ * + *

Both values are set and availabe from the created {@link Duration}

+ * + *

The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.

+ * + * @param lexicalRepresentation Lexical representation of a duration. + * + * @return New Duration created using the specified lexicalRepresentation. + * + * @throws IllegalArgumentException If lexicalRepresentation is not a valid representation of a Duration expressed only in terms of years and months. + * @throws UnsupportedOperationException If implementation cannot support requested values. + * @throws NullPointerException If lexicalRepresentation is null. + */ + public Duration newDurationYearMonth( + final String lexicalRepresentation) { + + // lexicalRepresentation must be non-null + if (lexicalRepresentation == null) { + throw new NullPointerException( + "Trying to create an xdt:yearMonthDuration with an invalid" + + " lexical representation of \"null\""); + } + + // test lexicalRepresentation against spec regex + Matcher matcher = XDTSCHEMA_YMD.matcher(lexicalRepresentation); + if (!matcher.matches()) { + throw new IllegalArgumentException( + "Trying to create an xdt:yearMonthDuration with an invalid" + + " lexical representation of \"" + lexicalRepresentation + + "\", data model requires days and times only."); + } + + return newDuration(lexicalRepresentation); + } + + /** + *

Create a Duration of type xdt:yearMonthDuration using the specified milliseconds as defined in + * + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

+ * + *

The datatype xdt:yearMonthDuration is a subtype of xs:duration + * whose lexical representation contains only year and month components. + * This datatype resides in the namespace {@link javax.xml.XMLConstants#W3C_XPATH_DATATYPE_NS_URI}.

+ * + *

Both values are set by computing their values from the specified milliseconds + * and are availabe using the get methods of the created {@link Duration}. + * The values conform to and are defined by:

+ * + * + *

The default start instance is defined by {@link GregorianCalendar}'s use of the start of the epoch: i.e., + * {@link java.util.Calendar#YEAR} = 1970, + * {@link java.util.Calendar#MONTH} = {@link java.util.Calendar#JANUARY}, + * {@link java.util.Calendar#DATE} = 1, etc. + * This is important as there are variations in the Gregorian Calendar, + * e.g. leap years have different days in the month = {@link java.util.Calendar#FEBRUARY} + * so the result of {@link Duration#getMonths()} can be influenced.

+ * + *

Any remaining milliseconds after determining the year and month are discarded.

+ * + * @param durationInMilliseconds Milliseconds of Duration to create. + * + * @return New Duration created using the specified durationInMilliseconds. + */ + public Duration newDurationYearMonth( + final long durationInMilliseconds) { + + // create a Duration that only has sign, year & month + // Duration is immutable, so need to create a new Duration + // implementations may override this method in a more efficient way + Duration fullDuration = newDuration(durationInMilliseconds); + boolean isPositive = (fullDuration.getSign() == -1) ? false : true; + BigInteger years = + (BigInteger) fullDuration.getField(DatatypeConstants.YEARS); + if (years == null) { years = BigInteger.ZERO; } + BigInteger months = + (BigInteger) fullDuration.getField(DatatypeConstants.MONTHS); + if (months == null) { months = BigInteger.ZERO; } + + return newDurationYearMonth(isPositive, years, months); + } + + /** + *

Create a Duration of type xdt:yearMonthDuration using the specified + * year and month as defined in + * + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

+ * + *

The XML Schema specification states that values can be of an arbitrary size. + * Implementations may chose not to or be incapable of supporting arbitrarily large and/or small values. + * An {@link UnsupportedOperationException} will be thrown with a message indicating implementation limits + * if implementation capacities are exceeded.

+ * + *

A null value indicates that field is not set.

+ * + * @param isPositive Set to false to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param year Year of Duration. + * @param month Month of Duration. + * + * @return New Duration created using the specified year and month. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * Duration: if all of the fields (year, month) are null or + * if any of the fields is negative. + * @throws UnsupportedOperationException If implementation cannot support requested values. + */ + public Duration newDurationYearMonth( + final boolean isPositive, + final BigInteger year, + final BigInteger month) { + + return newDuration( + isPositive, + year, + month, + null, // days + null, // hours + null, // minutes + null // seconds + ); + } + + /** + *

Create a Duration of type xdt:yearMonthDuration using the specified + * year and month as defined in + * + * XQuery 1.0 and XPath 2.0 Data Model, xdt:yearMonthDuration.

+ * + *

A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

+ * + * @param isPositive Set to false to create a negative duration. When the length + * of the duration is zero, this parameter will be ignored. + * @param year Year of Duration. + * @param month Month of Duration. + * + * @return New Duration created using the specified year and month. + * + * @throws IllegalArgumentException If the values are not a valid representation of a + * Duration: if any of the fields (year, month) is negative. + */ + public Duration newDurationYearMonth( + final boolean isPositive, + final int year, + final int month) { + + return newDurationYearMonth( + isPositive, + BigInteger.valueOf((long) year), + BigInteger.valueOf((long) month)); + } + + /** + *

Create a new instance of an XMLGregorianCalendar.

+ * + *

All date/time datatype fields set to {@link DatatypeConstants#FIELD_UNDEFINED} or null.

+ * + * @return New XMLGregorianCalendar with all date/time datatype fields set to + * {@link DatatypeConstants#FIELD_UNDEFINED} or null. + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar(); + + /** + *

Create a new XMLGregorianCalendar by parsing the String as a lexical representation.

+ * + *

Parsing the lexical string representation is defined in + * XML Schema 1.0 Part 2, Section 3.2.[7-14].1, + * Lexical Representation.

+ * + *

The string representation may not have any leading and trailing whitespaces.

+ * + *

The parsing is done field by field so that + * the following holds for any lexically correct String x:

+ *
+     * newXMLGregorianCalendar(x).toXMLFormat().equals(x)
+     * 
+ *

Except for the noted lexical/canonical representation mismatches + * listed in + * XML Schema 1.0 errata, Section 3.2.7.2.

+ * + * @param lexicalRepresentation Lexical representation of one the eight XML Schema date/time datatypes. + * + * @return XMLGregorianCalendar created from the lexicalRepresentation. + * + * @throws IllegalArgumentException If the lexicalRepresentation is not a valid XMLGregorianCalendar. + * @throws NullPointerException If lexicalRepresentation is null. + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar(final String lexicalRepresentation); + + /** + *

Create an XMLGregorianCalendar from a {@link GregorianCalendar}.

+ * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
+ * Field by Field Conversion from + * {@link GregorianCalendar} to an {@link XMLGregorianCalendar} + *
java.util.GregorianCalendar fieldjavax.xml.datatype.XMLGregorianCalendar field
ERA == GregorianCalendar.BC ? -YEAR : YEAR{@link XMLGregorianCalendar#setYear(int year)}
MONTH + 1{@link XMLGregorianCalendar#setMonth(int month)}
DAY_OF_MONTH{@link XMLGregorianCalendar#setDay(int day)}
HOUR_OF_DAY, MINUTE, SECOND, MILLISECOND{@link XMLGregorianCalendar#setTime(int hour, int minute, int second, BigDecimal fractional)}
+ * (ZONE_OFFSET + DST_OFFSET) / (60*1000)
+ * (in minutes) + *
{@link XMLGregorianCalendar#setTimezone(int offset)}* + *
+ *

*conversion loss of information. It is not possible to represent + * a java.util.GregorianCalendar daylight savings timezone id in the + * XML Schema 1.0 date/time datatype representation.

+ * + *

To compute the return value's TimeZone field, + *

    + *
  • when this.getTimezone() != FIELD_UNDEFINED, + * create a java.util.TimeZone with a custom timezone id + * using the this.getTimezone().
  • + *
  • else use the GregorianCalendar default timezone value + * for the host is defined as specified by + * java.util.TimeZone.getDefault().
  • + * + * @param cal java.util.GregorianCalendar used to create XMLGregorianCalendar + * + * @return XMLGregorianCalendar created from java.util.GregorianCalendar + * + * @throws NullPointerException If cal is null. + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar(final GregorianCalendar cal); + + /** + *

    Constructor allowing for complete value spaces allowed by + * W3C XML Schema 1.0 recommendation for xsd:dateTime and related + * builtin datatypes. Note that year parameter supports + * arbitrarily large numbers and fractionalSecond has infinite + * precision.

    + * + *

    A null value indicates that field is not set.

    + * + * @param year of XMLGregorianCalendar to be created. + * @param month of XMLGregorianCalendar to be created. + * @param day of XMLGregorianCalendar to be created. + * @param hour of XMLGregorianCalendar to be created. + * @param minute of XMLGregorianCalendar to be created. + * @param second of XMLGregorianCalendar to be created. + * @param fractionalSecond of XMLGregorianCalendar to be created. + * @param timezone of XMLGregorianCalendar to be created. + * + * @return XMLGregorianCalendar created from specified values. + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid XMLGregorianCalendar instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public abstract XMLGregorianCalendar newXMLGregorianCalendar( + final BigInteger year, + final int month, + final int day, + final int hour, + final int minute, + final int second, + final BigDecimal fractionalSecond, + final int timezone); + + /** + *

    Constructor of value spaces that a + * java.util.GregorianCalendar instance would need to convert to an + * XMLGregorianCalendar instance.

    + * + *

    XMLGregorianCalendar eon and + * fractionalSecond are set to null

    + * + *

    A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

    + * + * @param year of XMLGregorianCalendar to be created. + * @param month of XMLGregorianCalendar to be created. + * @param day of XMLGregorianCalendar to be created. + * @param hour of XMLGregorianCalendar to be created. + * @param minute of XMLGregorianCalendar to be created. + * @param second of XMLGregorianCalendar to be created. + * @param millisecond of XMLGregorianCalendar to be created. + * @param timezone of XMLGregorianCalendar to be created. + * + * @return XMLGregorianCalendar created from specified values. + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid XMLGregorianCalendar instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendar( + final int year, + final int month, + final int day, + final int hour, + final int minute, + final int second, + final int millisecond, + final int timezone) { + + // year may be undefined + BigInteger realYear = (year != DatatypeConstants.FIELD_UNDEFINED) ? BigInteger.valueOf((long) year) : null; + + // millisecond may be undefined + // millisecond must be >= 0 millisecond <= 1000 + BigDecimal realMillisecond = null; // undefined value + if (millisecond != DatatypeConstants.FIELD_UNDEFINED) { + if (millisecond < 0 || millisecond > 1000) { + throw new IllegalArgumentException( + "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendar(" + + "int year, int month, int day, int hour, int minute, int second, int millisecond, int timezone)" + + "with invalid millisecond: " + millisecond + ); + } + + realMillisecond = BigDecimal.valueOf((long) millisecond).movePointLeft(3); + } + + return newXMLGregorianCalendar( + realYear, + month, + day, + hour, + minute, + second, + realMillisecond, + timezone + ); + } + + /** + *

    Create a Java representation of XML Schema builtin datatype date or g*.

    + * + *

    For example, an instance of gYear can be created invoking this factory + * with month and day parameters set to + * {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + *

    A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

    + * + * @param year of XMLGregorianCalendar to be created. + * @param month of XMLGregorianCalendar to be created. + * @param day of XMLGregorianCalendar to be created. + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return XMLGregorianCalendar created from parameter values. + * + * @see DatatypeConstants#FIELD_UNDEFINED + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid XMLGregorianCalendar instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendarDate( + final int year, + final int month, + final int day, + final int timezone) { + + return newXMLGregorianCalendar( + year, + month, + day, + DatatypeConstants.FIELD_UNDEFINED, // hour + DatatypeConstants.FIELD_UNDEFINED, // minute + DatatypeConstants.FIELD_UNDEFINED, // second + DatatypeConstants.FIELD_UNDEFINED, // millisecond + timezone); + } + + /** + *

    Create a Java instance of XML Schema builtin datatype time.

    + * + *

    A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

    + * + * @param hours number of hours + * @param minutes number of minutes + * @param seconds number of seconds + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return XMLGregorianCalendar created from parameter values. + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid XMLGregorianCalendar instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + * + * @see DatatypeConstants#FIELD_UNDEFINED + */ + public XMLGregorianCalendar newXMLGregorianCalendarTime( + final int hours, + final int minutes, + final int seconds, + final int timezone) { + + return newXMLGregorianCalendar( + DatatypeConstants.FIELD_UNDEFINED, // Year + DatatypeConstants.FIELD_UNDEFINED, // Month + DatatypeConstants.FIELD_UNDEFINED, // Day + hours, + minutes, + seconds, + DatatypeConstants.FIELD_UNDEFINED, //Millisecond + timezone); + } + + /** + *

    Create a Java instance of XML Schema builtin datatype time.

    + * + *

    A null value indicates that field is not set.

    + *

    A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

    + * + * @param hours number of hours + * @param minutes number of minutes + * @param seconds number of seconds + * @param fractionalSecond value of null indicates that this optional field is not set. + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return XMLGregorianCalendar created from parameter values. + * + * @see DatatypeConstants#FIELD_UNDEFINED + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid XMLGregorianCalendar instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendarTime( + final int hours, + final int minutes, + final int seconds, + final BigDecimal fractionalSecond, + final int timezone) { + + return newXMLGregorianCalendar( + null, // year + DatatypeConstants.FIELD_UNDEFINED, // month + DatatypeConstants.FIELD_UNDEFINED, // day + hours, + minutes, + seconds, + fractionalSecond, + timezone); + } + + /** + *

    Create a Java instance of XML Schema builtin datatype time.

    + * + *

    A {@link DatatypeConstants#FIELD_UNDEFINED} value indicates that field is not set.

    + * + * @param hours number of hours + * @param minutes number of minutes + * @param seconds number of seconds + * @param milliseconds number of milliseconds + * @param timezone offset in minutes. {@link DatatypeConstants#FIELD_UNDEFINED} indicates optional field is not set. + * + * @return XMLGregorianCalendar created from parameter values. + * + * @see DatatypeConstants#FIELD_UNDEFINED + * + * @throws IllegalArgumentException If any individual parameter's value is outside the maximum value constraint for the field + * as determined by the Date/Time Data Mapping table in {@link XMLGregorianCalendar} + * or if the composite values constitute an invalid XMLGregorianCalendar instance + * as determined by {@link XMLGregorianCalendar#isValid()}. + */ + public XMLGregorianCalendar newXMLGregorianCalendarTime( + final int hours, + final int minutes, + final int seconds, + final int milliseconds, + final int timezone) { + + // millisecond may be undefined + // millisecond must be >= 0 millisecond <= 1000 + BigDecimal realMilliseconds = null; // undefined value + if (milliseconds != DatatypeConstants.FIELD_UNDEFINED) { + if (milliseconds < 0 || milliseconds > 1000) { + throw new IllegalArgumentException( + "javax.xml.datatype.DatatypeFactory#newXMLGregorianCalendarTime(" + + "int hours, int minutes, int seconds, int milliseconds, int timezone)" + + "with invalid milliseconds: " + milliseconds + ); + } + + realMilliseconds = BigDecimal.valueOf((long) milliseconds).movePointLeft(3); + } + + return newXMLGregorianCalendarTime( + hours, + minutes, + seconds, + realMilliseconds, + timezone + ); + } } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/Duration.java b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/Duration.java index 2aafede88..350f4af01 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/Duration.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/Duration.java @@ -1,3 +1,28 @@ +/* + * Copyright (c) 2003, 2006, 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 javax.xml.datatype; import java.math.BigDecimal; @@ -8,61 +33,325 @@ import javax.xml.namespace.QName; +/** + *

    Immutable representation of a time span as defined in + * the W3C XML Schema 1.0 specification.

    + * + *

    A Duration object represents a period of Gregorian time, + * which consists of six fields (years, months, days, hours, + * minutes, and seconds) plus a sign (+/-) field.

    + * + *

    The first five fields have non-negative (>=0) integers or null + * (which represents that the field is not set), + * and the seconds field has a non-negative decimal or null. + * A negative sign indicates a negative duration.

    + * + *

    This class provides a number of methods that make it easy + * to use for the duration datatype of XML Schema 1.0 with + * the errata.

    + * + *

    Order relationship

    + *

    Duration objects only have partial order, where two values A and B + * maybe either:

    + *
      + *
    1. A<B (A is shorter than B) + *
    2. A>B (A is longer than B) + *
    3. A==B (A and B are of the same duration) + *
    4. A<>B (Comparison between A and B is indeterminate) + *
    + * + *

    For example, 30 days cannot be meaningfully compared to one month. + * The {@link #compare(Duration duration)} method implements this + * relationship.

    + * + *

    See the {@link #isLongerThan(Duration)} method for details about + * the order relationship among Duration objects.

    + * + *

    Operations over Duration

    + *

    This class provides a set of basic arithmetic operations, such + * as addition, subtraction and multiplication. + * Because durations don't have total order, an operation could + * fail for some combinations of operations. For example, you cannot + * subtract 15 days from 1 month. See the javadoc of those methods + * for detailed conditions where this could happen.

    + * + *

    Also, division of a duration by a number is not provided because + * the Duration class can only deal with finite precision + * decimal numbers. For example, one cannot represent 1 sec divided by 3.

    + * + *

    However, you could substitute a division by 3 with multiplying + * by numbers such as 0.3 or 0.333.

    + * + *

    Range of allowed values

    + *

    + * Because some operations of Duration rely on {@link Calendar} + * even though {@link Duration} can hold very large or very small values, + * some of the methods may not work correctly on such Durations. + * The impacted methods document their dependency on {@link Calendar}. + * + * @author Joseph Fialli + * @author Kohsuke Kawaguchi + * @author Jeff Suttor + * @author Sunitha Reddy + * @see XMLGregorianCalendar#add(Duration) + * @since 1.5 + */ public abstract class Duration { + /** + *

    Debugging true or false.

    + */ + private static final boolean DEBUG = true; + + /** + * Default no-arg constructor. + * + *

    Note: Always use the {@link DatatypeFactory} to + * construct an instance of Duration. + * The constructor on this class cannot be guaranteed to + * produce an object with a consistent state and may be + * removed in the future.

    + */ public Duration() { } - public QName getXMLSchemaType() { - - boolean yearSet = isSet(DatatypeConstants.YEARS); - boolean monthSet = isSet(DatatypeConstants.MONTHS); - boolean daySet = isSet(DatatypeConstants.DAYS); - boolean hourSet = isSet(DatatypeConstants.HOURS); - boolean minuteSet = isSet(DatatypeConstants.MINUTES); - boolean secondSet = isSet(DatatypeConstants.SECONDS); - - if (yearSet && monthSet && daySet && hourSet && minuteSet && secondSet) { - return DatatypeConstants.DURATION; - } + /** + *

    Return the name of the XML Schema date/time type that this instance + * maps to. Type is computed based on fields that are set, + * i.e. {@link #isSet(DatatypeConstants.Field field)} == true.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    + * Required fields for XML Schema 1.0 Date/Time Datatypes.
    + * (timezone is optional for all date/time datatypes) + *
    Datatypeyearmonthdayhourminutesecond
    {@link DatatypeConstants#DURATION}XXXXXX
    {@link DatatypeConstants#DURATION_DAYTIME}XXXX
    {@link DatatypeConstants#DURATION_YEARMONTH}XX
    + * + * @return one of the following constants: + * {@link DatatypeConstants#DURATION}, + * {@link DatatypeConstants#DURATION_DAYTIME} or + * {@link DatatypeConstants#DURATION_YEARMONTH}. + * + * @throws IllegalStateException If the combination of set fields does not match one of the XML Schema date/time datatypes. + */ + public QName getXMLSchemaType() { + + boolean yearSet = isSet(DatatypeConstants.YEARS); + boolean monthSet = isSet(DatatypeConstants.MONTHS); + boolean daySet = isSet(DatatypeConstants.DAYS); + boolean hourSet = isSet(DatatypeConstants.HOURS); + boolean minuteSet = isSet(DatatypeConstants.MINUTES); + boolean secondSet = isSet(DatatypeConstants.SECONDS); + + // DURATION + if (yearSet + && monthSet + && daySet + && hourSet + && minuteSet + && secondSet) { + return DatatypeConstants.DURATION; + } - if (!yearSet && !monthSet && daySet && hourSet && minuteSet && secondSet) { - return DatatypeConstants.DURATION_DAYTIME; - } + // DURATION_DAYTIME + if (!yearSet + && !monthSet + && daySet + && hourSet + && minuteSet + && secondSet) { + return DatatypeConstants.DURATION_DAYTIME; + } - if (yearSet && monthSet && !daySet && !hourSet && !minuteSet && !secondSet) { - return DatatypeConstants.DURATION_YEARMONTH; - } + // DURATION_YEARMONTH + if (yearSet + && monthSet + && !daySet + && !hourSet + && !minuteSet + && !secondSet) { + return DatatypeConstants.DURATION_YEARMONTH; + } - throw new IllegalStateException("javax.xml.datatype.Duration exception"); - } + // nothing matches + throw new IllegalStateException( + "javax.xml.datatype.Duration#getXMLSchemaType():" + + " this Duration does not match one of the XML Schema date/time datatypes:" + + " year set = " + yearSet + + " month set = " + monthSet + + " day set = " + daySet + + " hour set = " + hourSet + + " minute set = " + minuteSet + + " second set = " + secondSet + ); + } + /** + * Returns the sign of this duration in -1,0, or 1. + * + * @return + * -1 if this duration is negative, 0 if the duration is zero, + * and 1 if the duration is positive. + */ public abstract int getSign(); + /** + *

    Get the years value of this Duration as an int or 0 if not present.

    + * + *

    getYears() is a convenience method for + * {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)}.

    + * + *

    As the return value is an int, an incorrect value will be returned for Durations + * with years that go beyond the range of an int. + * Use {@link #getField(DatatypeConstants.Field field) getField(DatatypeConstants.YEARS)} to avoid possible loss of precision.

    + * + * @return If the years field is present, return its value as an int, else return 0. + */ public int getYears() { return getField(DatatypeConstants.YEARS).intValue(); } + /** + * Obtains the value of the MONTHS field as an integer value, + * or 0 if not present. + * + * This method works just like {@link #getYears()} except + * that this method works on the MONTHS field. + * + * @return Months of this Duration. + */ public int getMonths() { return getField(DatatypeConstants.MONTHS).intValue(); } + /** + * Obtains the value of the DAYS field as an integer value, + * or 0 if not present. + * + * This method works just like {@link #getYears()} except + * that this method works on the DAYS field. + * + * @return Days of this Duration. + */ public int getDays() { return getField(DatatypeConstants.DAYS).intValue(); } + /** + * Obtains the value of the HOURS field as an integer value, + * or 0 if not present. + * + * This method works just like {@link #getYears()} except + * that this method works on the HOURS field. + * + * @return Hours of this Duration. + * + */ public int getHours() { return getField(DatatypeConstants.HOURS).intValue(); } + /** + * Obtains the value of the MINUTES field as an integer value, + * or 0 if not present. + * + * This method works just like {@link #getYears()} except + * that this method works on the MINUTES field. + * + * @return Minutes of this Duration. + * + */ public int getMinutes() { return getField(DatatypeConstants.MINUTES).intValue(); } + /** + * Obtains the value of the SECONDS field as an integer value, + * or 0 if not present. + * + * This method works just like {@link #getYears()} except + * that this method works on the SECONDS field. + * + * @return seconds in the integer value. The fraction of seconds + * will be discarded (for example, if the actual value is 2.5, + * this method returns 2) + */ public int getSeconds() { return getField(DatatypeConstants.SECONDS).intValue(); } + /** + *

    Returns the length of the duration in milli-seconds.

    + * + *

    If the seconds field carries more digits than milli-second order, + * those will be simply discarded (or in other words, rounded to zero.) + * For example, for any Calendar value x,

    + *
    +     * new Duration("PT10.00099S").getTimeInMills(x) == 10000.
    +     * new Duration("-PT10.00099S").getTimeInMills(x) == -10000.
    +     * 
    + * + *

    + * Note that this method uses the {@link #addTo(Calendar)} method, + * which may work incorrectly with Duration objects with + * very large values in its fields. See the {@link #addTo(Calendar)} + * method for details. + * + * @param startInstant + * The length of a month/year varies. The startInstant is + * used to disambiguate this variance. Specifically, this method + * returns the difference between startInstant and + * startInstant+duration + * + * @return milliseconds between startInstant and + * startInstant plus this Duration + * + * @throws NullPointerException if startInstant parameter + * is null. + * + */ public long getTimeInMillis(final Calendar startInstant) { Calendar cal = (Calendar) startInstant.clone(); addTo(cal); @@ -70,6 +359,37 @@ public long getTimeInMillis(final Calendar startInstant) { - getCalendarTimeInMillis(startInstant); } + /** + *

    Returns the length of the duration in milli-seconds.

    + * + *

    If the seconds field carries more digits than milli-second order, + * those will be simply discarded (or in other words, rounded to zero.) + * For example, for any Date value x,

    + *
    +     * new Duration("PT10.00099S").getTimeInMills(x) == 10000.
    +     * new Duration("-PT10.00099S").getTimeInMills(x) == -10000.
    +     * 
    + * + *

    + * Note that this method uses the {@link #addTo(Date)} method, + * which may work incorrectly with Duration objects with + * very large values in its fields. See the {@link #addTo(Date)} + * method for details. + * + * @param startInstant + * The length of a month/year varies. The startInstant is + * used to disambiguate this variance. Specifically, this method + * returns the difference between startInstant and + * startInstant+duration. + * + * @throws NullPointerException + * If the startInstant parameter is null. + * + * @return milliseconds between startInstant and + * startInstant plus this Duration + * + * @see #getTimeInMillis(Calendar) + */ public long getTimeInMillis(final Date startInstant) { Calendar cal = new GregorianCalendar(); cal.setTime(startInstant); @@ -77,54 +397,469 @@ public long getTimeInMillis(final Date startInstant) { return getCalendarTimeInMillis(cal) - startInstant.getTime(); } - private static long getCalendarTimeInMillis(final Calendar cal) { - return cal.getTime().getTime(); - } - + /** + * Gets the value of a field. + * + * Fields of a duration object may contain arbitrary large value. + * Therefore this method is designed to return a {@link Number} object. + * + * In case of YEARS, MONTHS, DAYS, HOURS, and MINUTES, the returned + * number will be a non-negative integer. In case of seconds, + * the returned number may be a non-negative decimal value. + * + * @param field + * one of the six Field constants (YEARS,MONTHS,DAYS,HOURS, + * MINUTES, or SECONDS.) + * @return + * If the specified field is present, this method returns + * a non-null non-negative {@link Number} object that + * represents its value. If it is not present, return null. + * For YEARS, MONTHS, DAYS, HOURS, and MINUTES, this method + * returns a {@link java.math.BigInteger} object. For SECONDS, this + * method returns a {@link java.math.BigDecimal}. + * + * @throws NullPointerException If the field is null. + */ public abstract Number getField(final DatatypeConstants.Field field); + /** + * Checks if a field is set. + * + * A field of a duration object may or may not be present. + * This method can be used to test if a field is present. + * + * @param field + * one of the six Field constants (YEARS,MONTHS,DAYS,HOURS, + * MINUTES, or SECONDS.) + * @return + * true if the field is present. false if not. + * + * @throws NullPointerException + * If the field parameter is null. + */ public abstract boolean isSet(final DatatypeConstants.Field field); + /** + *

    Computes a new duration whose value is this+rhs.

    + * + *

    For example,

    + *
    +     * "1 day" + "-3 days" = "-2 days"
    +     * "1 year" + "1 day" = "1 year and 1 day"
    +     * "-(1 hour,50 minutes)" + "-20 minutes" = "-(1 hours,70 minutes)"
    +     * "15 hours" + "-3 days" = "-(2 days,9 hours)"
    +     * "1 year" + "-1 day" = IllegalStateException
    +     * 
    + * + *

    Since there's no way to meaningfully subtract 1 day from 1 month, + * there are cases where the operation fails in + * {@link IllegalStateException}.

    + * + *

    + * Formally, the computation is defined as follows.

    + *

    + * Firstly, we can assume that two Durations to be added + * are both positive without losing generality (i.e., + * (-X)+Y=Y-X, X+(-Y)=X-Y, + * (-X)+(-Y)=-(X+Y)) + * + *

    + * Addition of two positive Durations are simply defined as + * field by field addition where missing fields are treated as 0. + *

    + * A field of the resulting Duration will be unset if and + * only if respective fields of two input Durations are unset. + *

    + * Note that lhs.add(rhs) will be always successful if + * lhs.signum()*rhs.signum()!=-1 or both of them are + * normalized.

    + * + * @param rhs Duration to add to this Duration + * + * @return + * non-null valid Duration object. + * + * @throws NullPointerException + * If the rhs parameter is null. + * @throws IllegalStateException + * If two durations cannot be meaningfully added. For + * example, adding negative one day to one month causes + * this exception. + * + * + * @see #subtract(Duration) + */ public abstract Duration add(final Duration rhs); + /** + * Adds this duration to a {@link Calendar} object. + * + *

    + * Calls {@link java.util.Calendar#add(int,int)} in the + * order of YEARS, MONTHS, DAYS, HOURS, MINUTES, SECONDS, and MILLISECONDS + * if those fields are present. Because the {@link Calendar} class + * uses int to hold values, there are cases where this method + * won't work correctly (for example if values of fields + * exceed the range of int.) + *

    + * + *

    + * Also, since this duration class is a Gregorian duration, this + * method will not work correctly if the given {@link Calendar} + * object is based on some other calendar systems. + *

    + * + *

    + * Any fractional parts of this Duration object + * beyond milliseconds will be simply ignored. For example, if + * this duration is "P1.23456S", then 1 is added to SECONDS, + * 234 is added to MILLISECONDS, and the rest will be unused. + *

    + * + *

    + * Note that because {@link Calendar#add(int, int)} is using + * int, Duration with values beyond the + * range of int in its fields + * will cause overflow/underflow to the given {@link Calendar}. + * {@link XMLGregorianCalendar#add(Duration)} provides the same + * basic operation as this method while avoiding + * the overflow/underflow issues. + * + * @param calendar + * A calendar object whose value will be modified. + * @throws NullPointerException + * if the calendar parameter is null. + */ public abstract void addTo(Calendar calendar); + /** + * Adds this duration to a {@link Date} object. + * + *

    + * The given date is first converted into + * a {@link java.util.GregorianCalendar}, then the duration + * is added exactly like the {@link #addTo(Calendar)} method. + * + *

    + * The updated time instant is then converted back into a + * {@link Date} object and used to update the given {@link Date} object. + * + *

    + * This somewhat redundant computation is necessary to unambiguously + * determine the duration of months and years. + * + * @param date + * A date object whose value will be modified. + * @throws NullPointerException + * if the date parameter is null. + */ public void addTo(Date date) { + // check data parameter if (date == null) { - throw new NullPointerException("Duration.addTo(Date): date is null"); + throw new NullPointerException( + "Cannot call " + + this.getClass().getName() + + "#addTo(Date date) with date == null." + ); } Calendar cal = new GregorianCalendar(); cal.setTime(date); - addTo(cal); + this.addTo(cal); date.setTime(getCalendarTimeInMillis(cal)); } + /** + *

    Computes a new duration whose value is this-rhs.

    + * + *

    For example:

    + *
    +     * "1 day" - "-3 days" = "4 days"
    +     * "1 year" - "1 day" = IllegalStateException
    +     * "-(1 hour,50 minutes)" - "-20 minutes" = "-(1hours,30 minutes)"
    +     * "15 hours" - "-3 days" = "3 days and 15 hours"
    +     * "1 year" - "-1 day" = "1 year and 1 day"
    +     * 
    + * + *

    Since there's no way to meaningfully subtract 1 day from 1 month, + * there are cases where the operation fails in {@link IllegalStateException}.

    + * + *

    Formally the computation is defined as follows. + * First, we can assume that two Durations are both positive + * without losing generality. (i.e., + * (-X)-Y=-(X+Y), X-(-Y)=X+Y, + * (-X)-(-Y)=-(X-Y))

    + * + *

    Then two durations are subtracted field by field. + * If the sign of any non-zero field F is different from + * the sign of the most significant field, + * 1 (if F is negative) or -1 (otherwise) + * will be borrowed from the next bigger unit of F.

    + * + *

    This process is repeated until all the non-zero fields have + * the same sign.

    + * + *

    If a borrow occurs in the days field (in other words, if + * the computation needs to borrow 1 or -1 month to compensate + * days), then the computation fails by throwing an + * {@link IllegalStateException}.

    + * + * @param rhs Duration to subtract from this Duration. + * + * @return New Duration created from subtracting rhs from this Duration. + * + * @throws IllegalStateException + * If two durations cannot be meaningfully subtracted. For + * example, subtracting one day from one month causes + * this exception. + * + * @throws NullPointerException + * If the rhs parameter is null. + * + * @see #add(Duration) + */ public Duration subtract(final Duration rhs) { return add(rhs.negate()); } + /** + *

    Computes a new duration whose value is factor times + * longer than the value of this duration.

    + * + *

    This method is provided for the convenience. + * It is functionally equivalent to the following code:

    + *
    +     * multiply(new BigDecimal(String.valueOf(factor)))
    +     * 
    + * + * @param factor Factor times longer of new Duration to create. + * + * @return New Duration that is factortimes longer than this Duration. + * + * @see #multiply(BigDecimal) + */ public Duration multiply(int factor) { return multiply(new BigDecimal(String.valueOf(factor))); } + /** + * Computes a new duration whose value is factor times + * longer than the value of this duration. + * + *

    + * For example, + *

    +     * "P1M" (1 month) * "12" = "P12M" (12 months)
    +     * "PT1M" (1 min) * "0.3" = "PT18S" (18 seconds)
    +     * "P1M" (1 month) * "1.5" = IllegalStateException
    +     * 
    + * + *

    + * Since the Duration class is immutable, this method + * doesn't change the value of this object. It simply computes + * a new Duration object and returns it. + * + *

    + * The operation will be performed field by field with the precision + * of {@link BigDecimal}. Since all the fields except seconds are + * restricted to hold integers, + * any fraction produced by the computation will be + * carried down toward the next lower unit. For example, + * if you multiply "P1D" (1 day) with "0.5", then it will be 0.5 day, + * which will be carried down to "PT12H" (12 hours). + * When fractions of month cannot be meaningfully carried down + * to days, or year to months, this will cause an + * {@link IllegalStateException} to be thrown. + * For example if you multiple one month by 0.5.

    + * + *

    + * To avoid {@link IllegalStateException}, use + * the {@link #normalizeWith(Calendar)} method to remove the years + * and months fields. + * + * @param factor to multiply by + * + * @return + * returns a non-null valid Duration object + * + * @throws IllegalStateException if operation produces fraction in + * the months field. + * + * @throws NullPointerException if the factor parameter is + * null. + * + */ public abstract Duration multiply(final BigDecimal factor); + /** + * Returns a new Duration object whose + * value is -this. + * + *

    + * Since the Duration class is immutable, this method + * doesn't change the value of this object. It simply computes + * a new Duration object and returns it. + * + * @return + * always return a non-null valid Duration object. + */ public abstract Duration negate(); + /** + *

    Converts the years and months fields into the days field + * by using a specific time instant as the reference point.

    + * + *

    For example, duration of one month normalizes to 31 days + * given the start time instance "July 8th 2003, 17:40:32".

    + * + *

    Formally, the computation is done as follows:

    + *
      + *
    1. the given Calendar object is cloned
    2. + *
    3. the years, months and days fields will be added to the {@link Calendar} object + * by using the {@link Calendar#add(int,int)} method
    4. + *
    5. the difference between the two Calendars in computed in milliseconds and converted to days, + * if a remainder occurs due to Daylight Savings Time, it is discarded
    6. + *
    7. the computed days, along with the hours, minutes and seconds + * fields of this duration object is used to construct a new + * Duration object.
    8. + *
    + * + *

    Note that since the Calendar class uses int to + * hold the value of year and month, this method may produce + * an unexpected result if this duration object holds + * a very large value in the years or months fields.

    + * + * @param startTimeInstant Calendar reference point. + * + * @return Duration of years and months of this Duration as days. + * + * @throws NullPointerException If the startTimeInstant parameter is null. + */ public abstract Duration normalizeWith(final Calendar startTimeInstant); + /** + *

    Partial order relation comparison with this Duration instance.

    + * + *

    Comparison result must be in accordance with + * W3C XML Schema 1.0 Part 2, Section 3.2.7.6.2, + * Order relation on duration.

    + * + *

    Return:

    + *
      + *
    • {@link DatatypeConstants#LESSER} if this Duration is shorter than duration parameter
    • + *
    • {@link DatatypeConstants#EQUAL} if this Duration is equal to duration parameter
    • + *
    • {@link DatatypeConstants#GREATER} if this Duration is longer than duration parameter
    • + *
    • {@link DatatypeConstants#INDETERMINATE} if a conclusive partial order relation cannot be determined
    • + *
    + * + * @param duration to compare + * + * @return the relationship between this Durationand duration parameter as + * {@link DatatypeConstants#LESSER}, {@link DatatypeConstants#EQUAL}, {@link DatatypeConstants#GREATER} + * or {@link DatatypeConstants#INDETERMINATE}. + * + * @throws UnsupportedOperationException If the underlying implementation + * cannot reasonably process the request, e.g. W3C XML Schema allows for + * arbitrarily large/small/precise values, the request may be beyond the + * implementations capability. + * @throws NullPointerException if duration is null. + * + * @see #isShorterThan(Duration) + * @see #isLongerThan(Duration) + */ public abstract int compare(final Duration duration); + /** + *

    Checks if this duration object is strictly longer than + * another Duration object.

    + * + *

    Duration X is "longer" than Y if and only if X>Y + * as defined in the section 3.2.6.2 of the XML Schema 1.0 + * specification.

    + * + *

    For example, "P1D" (one day) > "PT12H" (12 hours) and + * "P2Y" (two years) > "P23M" (23 months).

    + * + * @param duration Duration to test this Duration against. + * + * @throws UnsupportedOperationException If the underlying implementation + * cannot reasonably process the request, e.g. W3C XML Schema allows for + * arbitrarily large/small/precise values, the request may be beyond the + * implementations capability. + * @throws NullPointerException If duration is null. + * + * @return + * true if the duration represented by this object + * is longer than the given duration. false otherwise. + * + * @see #isShorterThan(Duration) + * @see #compare(Duration duration) + */ public boolean isLongerThan(final Duration duration) { return compare(duration) == DatatypeConstants.GREATER; } + /** + *

    Checks if this duration object is strictly shorter than + * another Duration object.

    + * + * @param duration Duration to test this Duration against. + * + * @return true if duration parameter is shorter than this Duration, + * else false. + * + * @throws UnsupportedOperationException If the underlying implementation + * cannot reasonably process the request, e.g. W3C XML Schema allows for + * arbitrarily large/small/precise values, the request may be beyond the + * implementations capability. + * @throws NullPointerException if duration is null. + * + * @see #isLongerThan(Duration duration) + * @see #compare(Duration duration) + */ public boolean isShorterThan(final Duration duration) { return compare(duration) == DatatypeConstants.LESSER; } + /** + *

    Checks if this duration object has the same duration + * as another Duration object.

    + * + *

    For example, "P1D" (1 day) is equal to "PT24H" (24 hours).

    + * + *

    Duration X is equal to Y if and only if time instant + * t+X and t+Y are the same for all the test time instants + * specified in the section 3.2.6.2 of the XML Schema 1.0 + * specification.

    + * + *

    Note that there are cases where two Durations are + * "incomparable" to each other, like one month and 30 days. + * For example,

    + *
    +     * !new Duration("P1M").isShorterThan(new Duration("P30D"))
    +     * !new Duration("P1M").isLongerThan(new Duration("P30D"))
    +     * !new Duration("P1M").equals(new Duration("P30D"))
    +     * 
    + * + * @param duration + * The object to compare this Duration against. + * + * @return + * true if this duration is the same length as + * duration. + * false if duration is null, + * is not a + * Duration object, + * or its length is different from this duration. + * + * @throws UnsupportedOperationException If the underlying implementation + * cannot reasonably process the request, e.g. W3C XML Schema allows for + * arbitrarily large/small/precise values, the request may be beyond the + * implementations capability. + * + * @see #compare(Duration duration) + */ public boolean equals(final Object duration) { if (duration == null || !(duration instanceof Duration)) { @@ -134,8 +869,27 @@ public boolean equals(final Object duration) { return compare((Duration) duration) == DatatypeConstants.EQUAL; } + /** + * Returns a hash code consistent with the definition of the equals method. + * + * @see Object#hashCode() + */ public abstract int hashCode(); + /** + *

    Returns a String representation of this Duration Object.

    + * + *

    The result is formatted according to the XML Schema 1.0 spec and can be always parsed back later into the + * equivalent Duration Object by {@link DatatypeFactory#newDuration(String lexicalRepresentation)}.

    + * + *

    Formally, the following holds for any Duration + * Object x:

    + *
    +     * new Duration(x.toString()).equals(x)
    +     * 
    + * + * @return A non-null valid String representation of this Duration. + */ public String toString() { StringBuffer buf = new StringBuffer(); @@ -179,6 +933,16 @@ public String toString() { return buf.toString(); } + /** + *

    Turns {@link BigDecimal} to a string representation.

    + * + *

    Due to a behavior change in the {@link BigDecimal#toString()} + * method in JDK1.5, this had to be implemented here.

    + * + * @param bd BigDecimal to format as a String + * + * @return String representation of BigDecimal + */ private String toString(BigDecimal bd) { String intString = bd.unscaledValue().toString(); int scale = bd.scale(); @@ -187,6 +951,7 @@ private String toString(BigDecimal bd) { return intString; } + /* Insert decimal point */ StringBuffer buf; int insertionPoint = intString.length() - scale; if (insertionPoint == 0) { /* Point goes right before intVal */ @@ -205,4 +970,19 @@ private String toString(BigDecimal bd) { return buf.toString(); } + + /** + *

    Calls the {@link Calendar#getTimeInMillis} method. + * Prior to JDK1.4, this method was protected and therefore + * cannot be invoked directly.

    + * + *

    TODO: In future, this should be replaced by cal.getTimeInMillis().

    + * + * @param cal Calendar to get time in milliseconds. + * + * @return Milliseconds of cal. + */ + private static long getCalendarTimeInMillis(final Calendar cal) { + return cal.getTime().getTime(); + } } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/FactoryFinder.java b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/FactoryFinder.java new file mode 100644 index 000000000..37811e6fa --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/FactoryFinder.java @@ -0,0 +1,327 @@ +/* + * Copyright (c) 2004, 2006, 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 javax.xml.datatype; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; + +import java.util.Properties; +import java.io.BufferedReader; +import java.io.InputStreamReader; +import java.net.URL; + +/** + *

    Implements pluggable Datatypes.

    + * + *

    This class is duplicated for each JAXP subpackage so keep it in + * sync. It is package private for secure class loading.

    + * + * @author Santiago.PericasGeertsen@sun.com + */ +class FactoryFinder { + + /** + * Internal debug flag. + */ + private static boolean debug = false; + + /** + * Cache for properties in java.home/lib/jaxp.properties + */ + static Properties cacheProps = new Properties(); + + /** + * Flag indicating if properties from java.home/lib/jaxp.properties + * have been cached. + */ + static volatile boolean firstTime = true; + + /** + * Security support class use to check access control before + * getting certain system resources. + */ + static SecuritySupport ss = new SecuritySupport(); + + // Define system property "jaxp.debug" to get output + static { + // Use try/catch block to support applets, which throws + // SecurityException out of this code. + try { + String val = ss.getSystemProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); + } + catch (SecurityException se) { + debug = false; + } + } + + private static void dPrint(String msg) { + if (debug) { + System.err.println("JAXP: " + msg); + } + } + + /** + * Attempt to load a class using the class loader supplied. If that fails + * and fall back is enabled, the current (i.e. bootstrap) class loader is + * tried. + * + * If the class loader supplied is null, first try using the + * context class loader followed by the current (i.e. bootstrap) class + * loader. + */ + static private Class getProviderClass(String className, ClassLoader cl, + boolean doFallback) throws ClassNotFoundException + { + try { + if (cl == null) { + cl = ss.getContextClassLoader(); + if (cl == null) { + throw new ClassNotFoundException(); + } + else { + return cl.loadClass(className); + } + } + else { + return cl.loadClass(className); + } + } + catch (ClassNotFoundException e1) { + if (doFallback) { + // Use current class loader - should always be bootstrap CL + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } + else { + throw e1; + } + } + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader to use to load the class, null means to use + * the bootstrap ClassLoader + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback) + throws ConfigurationError + { + try { + Class providerClass = getProviderClass(className, cl, doFallback); + Object instance = providerClass.newInstance(); + if (debug) { // Extra check to avoid computing cl strings + dPrint("created new instance of " + providerClass + + " using ClassLoader: " + cl); + } + return instance; + } + catch (ClassNotFoundException x) { + throw new ConfigurationError( + "Provider " + className + " not found", x); + } + catch (Exception x) { + throw new ConfigurationError( + "Provider " + className + " could not be instantiated: " + x, + x); + } + } + + /** + * Finds the implementation Class object in the specified order. Main + * entry point. + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * Package private so this code can be shared. + */ + static Object find(String factoryId, String fallbackClassName) + throws ConfigurationError + { + dPrint("find factoryId =" + factoryId); + + // Use the system property first + try { + String systemProp = ss.getSystemProperty(factoryId); + if (systemProp != null) { + dPrint("found system property, value=" + systemProp); + return newInstance(systemProp, null, true); + } + } + catch (SecurityException se) { + if (debug) se.printStackTrace(); + } + + // try to read from $java.home/lib/jaxp.properties + try { + String factoryClassName = null; + if (firstTime) { + synchronized (cacheProps) { + if (firstTime) { + String configFile = ss.getSystemProperty("java.home") + File.separator + + "lib" + File.separator + "jaxp.properties"; + File f = new File(configFile); + firstTime = false; + if (ss.doesFileExist(f)) { + dPrint("Read properties file "+f); + cacheProps.load(ss.getFileInputStream(f)); + } + } + } + } + factoryClassName = cacheProps.getProperty(factoryId); + + if (factoryClassName != null) { + dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName); + return newInstance(factoryClassName, null, true); + } + } + catch (Exception ex) { + if (debug) ex.printStackTrace(); + } + + // Try Jar Service Provider Mechanism + Object provider = findJarServiceProvider(factoryId); + if (provider != null) { + return provider; + } + if (fallbackClassName == null) { + throw new ConfigurationError( + "Provider for " + factoryId + " cannot be found", null); + } + + dPrint("loaded from fallback value: " + fallbackClassName); + return newInstance(fallbackClassName, null, true); + } + + /* + * Try to find provider using Jar Service Provider Mechanism + * + * @return instance of provider class if found or null + */ + private static Object findJarServiceProvider(String factoryId) + throws ConfigurationError + { + String serviceId = "META-INF/services/" + factoryId; + InputStream is = null; + + // First try the Context ClassLoader + ClassLoader cl = ss.getContextClassLoader(); + if (cl != null) { + is = ss.getResourceAsStream(cl, serviceId); + + // If no provider found then try the current ClassLoader + if (is == null) { + cl = FactoryFinder.class.getClassLoader(); + is = ss.getResourceAsStream(cl, serviceId); + } + } else { + // No Context ClassLoader, try the current ClassLoader + cl = FactoryFinder.class.getClassLoader(); + is = ss.getResourceAsStream(cl, serviceId); + } + + if (is == null) { + // No provider found + return null; + } + + if (debug) { // Extra check to avoid computing cl strings + dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl); + } + + BufferedReader rd; + try { + rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); + } + catch (java.io.UnsupportedEncodingException e) { + rd = new BufferedReader(new InputStreamReader(is)); + } + + String factoryClassName = null; + try { + // XXX Does not handle all possible input as specified by the + // Jar Service Provider specification + factoryClassName = rd.readLine(); + rd.close(); + } catch (IOException x) { + // No provider found + return null; + } + + if (factoryClassName != null && !"".equals(factoryClassName)) { + dPrint("found in resource, value=" + factoryClassName); + + // Note: here we do not want to fall back to the current + // ClassLoader because we want to avoid the case where the + // resource file was found using one ClassLoader and the + // provider class was instantiated using a different one. + return newInstance(factoryClassName, cl, false); + } + + // No provider found + return null; + } + + static class ConfigurationError extends Error { + private Exception exception; + + /** + * Construct a new instance with the specified detail string and + * exception. + */ + ConfigurationError(String msg, Exception x) { + super(msg); + this.exception = x; + } + + Exception getException() { + return exception; + } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/SecuritySupport.java b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/SecuritySupport.java new file mode 100644 index 000000000..127db229a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/SecuritySupport.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2005, 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 javax.xml.datatype; + +import java.security.*; +import java.net.*; +import java.io.*; +import java.util.*; + +/** + * This class is duplicated for each JAXP subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of the JAXP + * API. + * + * Security related methods that only work on J2SE 1.2 and newer. + */ +class SecuritySupport { + + + ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { } + return cl; + } + }); + } + + String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + FileInputStream getFileInputStream(final File file) + throws FileNotFoundException + { + try { + return (FileInputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws FileNotFoundException { + return new FileInputStream(file); + } + }); + } catch (PrivilegedActionException e) { + throw (FileNotFoundException)e.getException(); + } + } + + InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + boolean doesFileExist(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Boolean(f.exists()); + } + })).booleanValue(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/XMLGregorianCalendar.java b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/XMLGregorianCalendar.java index dfe4bebdc..ce16b9c9e 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/datatype/XMLGregorianCalendar.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/datatype/XMLGregorianCalendar.java @@ -1,127 +1,1062 @@ +/* + * Copyright (c) 2003, 2006, 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 javax.xml.datatype; +import javax.xml.namespace.QName; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.GregorianCalendar; import java.util.TimeZone; +import java.util.GregorianCalendar; -import javax.xml.namespace.QName; +/** + *

    Representation for W3C XML Schema 1.0 date/time datatypes. + * Specifically, these date/time datatypes are + * {@link DatatypeConstants#DATETIME}, + * {@link DatatypeConstants#TIME}, + * {@link DatatypeConstants#DATE}, + * {@link DatatypeConstants#GYEARMONTH}, + * {@link DatatypeConstants#GMONTHDAY}, + * {@link DatatypeConstants#GYEAR}, + * {@link DatatypeConstants#GMONTH}, and + * {@link DatatypeConstants#GDAY} + * defined in the XML Namespace + * "http://www.w3.org/2001/XMLSchema". + * These datatypes are normatively defined in + * W3C XML Schema 1.0 Part 2, Section 3.2.7-14.

    + * + *

    The table below defines the mapping between XML Schema 1.0 + * date/time datatype fields and this class' fields. It also summarizes + * the value constraints for the date and time fields defined in + * W3C XML Schema 1.0 Part 2, Appendix D, + * ISO 8601 Date and Time Formats.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    + * Date/Time Datatype Field Mapping Between XML Schema 1.0 and Java Representation + *
    XML Schema 1.0
    + * datatype
    + * field
    Related
    XMLGregorianCalendar
    Accessor(s)
    Value Range
    year {@link #getYear()} + {@link #getEon()} or
    + * {@link #getEonAndYear} + *
    getYear() is a value between -(10^9-1) to (10^9)-1 + * or {@link DatatypeConstants#FIELD_UNDEFINED}.
    + * {@link #getEon()} is high order year value in billion of years.
    + * getEon() has values greater than or equal to (10^9) or less than or equal to -(10^9). + * A value of null indicates field is undefined.
    + * Given that XML Schema 1.0 errata states that the year zero + * will be a valid lexical value in a future version of XML Schema, + * this class allows the year field to be set to zero. Otherwise, + * the year field value is handled exactly as described + * in the errata and [ISO-8601-1988]. Note that W3C XML Schema 1.0 + * validation does not allow for the year field to have a value of zero. + *
    month {@link #getMonth()} 1 to 12 or {@link DatatypeConstants#FIELD_UNDEFINED}
    day {@link #getDay()} Independent of month, max range is 1 to 31 or {@link DatatypeConstants#FIELD_UNDEFINED}.
    + * The normative value constraint stated relative to month + * field's value is in W3C XML Schema 1.0 Part 2, Appendix D. + *
    hour{@link #getHour()} + * 0 to 23 or {@link DatatypeConstants#FIELD_UNDEFINED}. + * An hour value of 24 is allowed to be set in the lexical space provided the minute and second + * field values are zero. However, an hour value of 24 is not allowed in value space and will be + * transformed to represent the value of the first instance of the following day as per + * + * XML Schema Part 2: Datatypes Second Edition, 3.2 Primitive datatypes. + *
    minute {@link #getMinute()} 0 to 59 or {@link DatatypeConstants#FIELD_UNDEFINED}
    second + * {@link #getSecond()} + {@link #getMillisecond()}/1000 or
    + * {@link #getSecond()} + {@link #getFractionalSecond()} + *
    + * {@link #getSecond()} from 0 to 60 or {@link DatatypeConstants#FIELD_UNDEFINED}.
    + * (Note: 60 only allowable for leap second.)
    + * {@link #getFractionalSecond()} allows for infinite precision over the range from 0.0 to 1.0 when + * the {@link #getSecond()} is defined.
    + * FractionalSecond is optional and has a value of null when it is undefined.
    + * {@link #getMillisecond()} is the convenience + * millisecond precision of value of {@link #getFractionalSecond()}. + *
    timezone {@link #getTimezone()} Number of minutes or {@link DatatypeConstants#FIELD_UNDEFINED}. + * Value range from -14 hours (-14 * 60 minutes) to 14 hours (14 * 60 minutes). + *
    + * + *

    All maximum value space constraints listed for the fields in the table + * above are checked by factory methods, @{link DatatypeFactory}, + * setter methods and parse methods of + * this class. IllegalArgumentException is thrown when a + * parameter's value is outside the value constraint for the field or + * if the composite + * values constitute an invalid XMLGregorianCalendar instance (for example, if + * the 31st of June is specified). + *

    + * + *

    The following operations are defined for this class: + *

    + *

    + * + * @author Joseph Fialli + * @author Kohsuke Kawaguchi + * @author Jeff Suttor + * @author Sunitha Reddy + * @see Duration + * @see DatatypeFactory + * @since 1.5 + */ + +public abstract class XMLGregorianCalendar + implements Cloneable { + + /** + * Default no-arg constructor. + * + *

    Note: Always use the {@link DatatypeFactory} to + * construct an instance of XMLGregorianCalendar. + * The constructor on this class cannot be guaranteed to + * produce an object with a consistent state and may be + * removed in the future.

    + */ + public XMLGregorianCalendar() { + } + + /** + *

    Unset all fields to undefined.

    + * + *

    Set all int fields to {@link DatatypeConstants#FIELD_UNDEFINED} and reference fields + * to null.

    + */ + public abstract void clear(); + + /** + *

    Reset this XMLGregorianCalendar to its original values.

    + * + *

    XMLGregorianCalendar is reset to the same values as when it was created with + * {@link DatatypeFactory#newXMLGregorianCalendar()}, + * {@link DatatypeFactory#newXMLGregorianCalendar(String lexicalRepresentation)}, + * {@link DatatypeFactory#newXMLGregorianCalendar( + * BigInteger year, + * int month, + * int day, + * int hour, + * int minute, + * int second, + * BigDecimal fractionalSecond, + * int timezone)}, + * {@link DatatypeFactory#newXMLGregorianCalendar( + * int year, + * int month, + * int day, + * int hour, + * int minute, + * int second, + * int millisecond, + * int timezone)}, + * {@link DatatypeFactory#newXMLGregorianCalendar(GregorianCalendar cal)}, + * {@link DatatypeFactory#newXMLGregorianCalendarDate( + * int year, + * int month, + * int day, + * int timezone)}, + * {@link DatatypeFactory#newXMLGregorianCalendarTime( + * int hours, + * int minutes, + * int seconds, + * int timezone)}, + * {@link DatatypeFactory#newXMLGregorianCalendarTime( + * int hours, + * int minutes, + * int seconds, + * BigDecimal fractionalSecond, + * int timezone)} or + * {@link DatatypeFactory#newXMLGregorianCalendarTime( + * int hours, + * int minutes, + * int seconds, + * int milliseconds, + * int timezone)}. + *

    + * + *

    reset() is designed to allow the reuse of existing XMLGregorianCalendars + * thus saving resources associated with the creation of new XMLGregorianCalendars.

    + */ + public abstract void reset(); + + /** + *

    Set low and high order component of XSD dateTime year field.

    + * + *

    Unset this field by invoking the setter with a parameter value of null.

    + * + * @param year value constraints summarized in year field of date/time field mapping table. + * + * @throws IllegalArgumentException if year parameter is + * outside value constraints for the field as specified in + * date/time field mapping table. + */ + public abstract void setYear(BigInteger year); + + /** + *

    Set year of XSD dateTime year field.

    + * + *

    Unset this field by invoking the setter with a parameter value of + * {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + *

    Note: if the absolute value of the year parameter + * is less than 10^9, the eon component of the XSD year field is set to + * null by this method.

    + * + * @param year value constraints are summarized in year field of date/time field mapping table. + * If year is {@link DatatypeConstants#FIELD_UNDEFINED}, then eon is set to null. + */ + public abstract void setYear(int year); + + /** + *

    Set month.

    + * + *

    Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @param month value constraints summarized in month field of date/time field mapping table. + * + * @throws IllegalArgumentException if month parameter is + * outside value constraints for the field as specified in + * date/time field mapping table. + */ + public abstract void setMonth(int month); + + /** + *

    Set days in month.

    + * + *

    Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @param day value constraints summarized in day field of date/time field mapping table. + * + * @throws IllegalArgumentException if day parameter is + * outside value constraints for the field as specified in + * date/time field mapping table. + */ + public abstract void setDay(int day); + + /** + *

    Set the number of minutes in the timezone offset.

    + * + *

    Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @param offset value constraints summarized in + * timezone field of date/time field mapping table. + * + * @throws IllegalArgumentException if offset parameter is + * outside value constraints for the field as specified in + * date/time field mapping table. + */ + public abstract void setTimezone(int offset); + + /** + *

    Set time as one unit.

    + * + * @param hour value constraints are summarized in + * hour field of date/time field mapping table. + * @param minute value constraints are summarized in + * minute field of date/time field mapping table. + * @param second value constraints are summarized in + * second field of date/time field mapping table. + * + * @see #setTime(int, int, int, BigDecimal) + * + * @throws IllegalArgumentException if any parameter is + * outside value constraints for the field as specified in + * date/time field mapping table. + */ + public void setTime(int hour, int minute, int second) { + + setTime( + hour, + minute, + second, + null // fractional + ); + } + + /** + *

    Set hours.

    + * + *

    Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @param hour value constraints summarized in hour field of date/time field mapping table. + * + * @throws IllegalArgumentException if hour parameter is outside value constraints for the field as specified in + * date/time field mapping table. + */ + public abstract void setHour(int hour); + + /** + *

    Set minutes.

    + * + *

    Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @param minute value constraints summarized in minute field of date/time field mapping table. + * + * @throws IllegalArgumentException if minute parameter is outside value constraints for the field as specified in + * date/time field mapping table. + */ + public abstract void setMinute(int minute); + + /** + *

    Set seconds.

    + * + *

    Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @param second value constraints summarized in second field of date/time field mapping table. + * + * @throws IllegalArgumentException if second parameter is outside value constraints for the field as specified in + * date/time field mapping table. + */ + public abstract void setSecond(int second); + + /** + *

    Set milliseconds.

    + * + *

    Unset this field by invoking the setter with a parameter value of {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @param millisecond value constraints summarized in + * second field of date/time field mapping table. + * + * @throws IllegalArgumentException if millisecond parameter is outside value constraints for the field as specified + * in date/time field mapping table. + */ + public abstract void setMillisecond(int millisecond); -public abstract class XMLGregorianCalendar implements Cloneable { - public XMLGregorianCalendar() { - } + /** + *

    Set fractional seconds.

    + * + *

    Unset this field by invoking the setter with a parameter value of null.

    + * + * @param fractional value constraints summarized in + * second field of date/time field mapping table. + * + * @throws IllegalArgumentException if fractional parameter is outside value constraints for the field as specified + * in date/time field mapping table. + */ + public abstract void setFractionalSecond(BigDecimal fractional); - public abstract void clear(); - public abstract void reset(); + /** + *

    Set time as one unit, including the optional infinite precision + * fractional seconds.

    + * + * @param hour value constraints are summarized in + * hour field of date/time field mapping table. + * @param minute value constraints are summarized in + * minute field of date/time field mapping table. + * @param second value constraints are summarized in + * second field of date/time field mapping table. + * @param fractional value of null indicates this optional + * field is not set. + * + * @throws IllegalArgumentException if any parameter is + * outside value constraints for the field as specified in + * date/time field mapping table. + */ + public void setTime( + int hour, + int minute, + int second, + BigDecimal fractional) { - public abstract void setYear(BigInteger year); + setHour(hour); + setMinute(minute); + setSecond(second); + setFractionalSecond(fractional); + } - public abstract void setYear(int year); - public abstract void setMonth(int month); + /** + *

    Set time as one unit, including optional milliseconds.

    + * + * @param hour value constraints are summarized in + * hour field of date/time field mapping table. + * @param minute value constraints are summarized in + * minute field of date/time field mapping table. + * @param second value constraints are summarized in + * second field of date/time field mapping table. + * @param millisecond value of {@link DatatypeConstants#FIELD_UNDEFINED} indicates this + * optional field is not set. + * + * @throws IllegalArgumentException if any parameter is + * outside value constraints for the field as specified in + * date/time field mapping table. + */ + public void setTime(int hour, int minute, int second, int millisecond) { - public abstract void setDay(int day); + setHour(hour); + setMinute(minute); + setSecond(second); + setMillisecond(millisecond); + } - public abstract void setTimezone(int offset); + /** + *

    Return high order component for XML Schema 1.0 dateTime datatype field for + * year. + * null if this optional part of the year field is not defined.

    + * + *

    Value constraints for this value are summarized in + * year field of date/time field mapping table.

    + * @return eon of this XMLGregorianCalendar. The value + * returned is an integer multiple of 10^9. + * + * @see #getYear() + * @see #getEonAndYear() + */ + public abstract BigInteger getEon(); - public abstract void setHour(int hour); + /** + *

    Return low order component for XML Schema 1.0 dateTime datatype field for + * year or {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + *

    Value constraints for this value are summarized in + * year field of date/time field mapping table.

    + * + * @return year of this XMLGregorianCalendar. + * + * @see #getEon() + * @see #getEonAndYear() + */ + public abstract int getYear(); - public abstract void setMinute(int minute); + /** + *

    Return XML Schema 1.0 dateTime datatype field for + * year.

    + * + *

    Value constraints for this value are summarized in + * year field of date/time field mapping table.

    + * + * @return sum of eon and BigInteger.valueOf(year) + * when both fields are defined. When only year is defined, + * return it. When both eon and year are not + * defined, return null. + * + * @see #getEon() + * @see #getYear() + */ + public abstract BigInteger getEonAndYear(); - public abstract void setSecond(int second); + /** + *

    Return number of month or {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + *

    Value constraints for this value are summarized in + * month field of date/time field mapping table.

    + * + * @return year of this XMLGregorianCalendar. + * + */ + public abstract int getMonth(); - public abstract void setMillisecond(int millisecond); + /** + * Return day in month or {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + *

    Value constraints for this value are summarized in + * day field of date/time field mapping table.

    + * + * @see #setDay(int) + */ + public abstract int getDay(); - public abstract void setFractionalSecond(BigDecimal fractional); + /** + * Return timezone offset in minutes or + * {@link DatatypeConstants#FIELD_UNDEFINED} if this optional field is not defined. + * + *

    Value constraints for this value are summarized in + * timezone field of date/time field mapping table.

    + * + * @see #setTimezone(int) + */ + public abstract int getTimezone(); - public abstract BigInteger getEon(); + /** + * Return hours or {@link DatatypeConstants#FIELD_UNDEFINED}. + * Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined. + * + *

    Value constraints for this value are summarized in + * hour field of date/time field mapping table.

    + * @see #setTime(int, int, int) + */ + public abstract int getHour(); - public abstract int getYear(); + /** + * Return minutes or {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined. + * + *

    Value constraints for this value are summarized in + * minute field of date/time field mapping table.

    + * @see #setTime(int, int, int) + */ + public abstract int getMinute(); - public abstract BigInteger getEonAndYear(); + /** + *

    Return seconds or {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + *

    Returns {@link DatatypeConstants#FIELD_UNDEFINED} if this field is not defined. + * When this field is not defined, the optional xs:dateTime + * fractional seconds field, represented by + * {@link #getFractionalSecond()} and {@link #getMillisecond()}, + * must not be defined.

    + * + *

    Value constraints for this value are summarized in + * second field of date/time field mapping table.

    + * + * @return Second of this XMLGregorianCalendar. + * + * @see #getFractionalSecond() + * @see #getMillisecond() + * @see #setTime(int, int, int) + */ + public abstract int getSecond(); - public abstract int getMonth(); + /** + *

    Return millisecond precision of {@link #getFractionalSecond()}.

    + * + *

    This method represents a convenience accessor to infinite + * precision fractional second value returned by + * {@link #getFractionalSecond()}. The returned value is the rounded + * down to milliseconds value of + * {@link #getFractionalSecond()}. When {@link #getFractionalSecond()} + * returns null, this method must return + * {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + *

    Value constraints for this value are summarized in + * second field of date/time field mapping table.

    + * + * @return Millisecond of this XMLGregorianCalendar. + * + * @see #getFractionalSecond() + * @see #setTime(int, int, int) + */ + public int getMillisecond() { - public abstract int getDay(); + BigDecimal fractionalSeconds = getFractionalSecond(); - public abstract int getTimezone(); + // is field undefined? + if (fractionalSeconds == null) { + return DatatypeConstants.FIELD_UNDEFINED; + } - public abstract int getHour(); + return getFractionalSecond().movePointRight(3).intValue(); + } - public abstract int getMinute(); + /** + *

    Return fractional seconds.

    + * + *

    null is returned when this optional field is not defined.

    + * + *

    Value constraints are detailed in + * second field of date/time field mapping table.

    + * + *

    This optional field can only have a defined value when the + * xs:dateTime second field, represented by {@link #getSecond()}, + * does not return {@link DatatypeConstants#FIELD_UNDEFINED}.

    + * + * @return fractional seconds of this XMLGregorianCalendar. + * + * @see #getSecond() + * @see #setTime(int, int, int, BigDecimal) + */ + public abstract BigDecimal getFractionalSecond(); - public abstract int getSecond(); + // comparisons + /** + *

    Compare two instances of W3C XML Schema 1.0 date/time datatypes + * according to partial order relation defined in + * W3C XML Schema 1.0 Part 2, Section 3.2.7.3, + * Order relation on dateTime.

    + * + *

    xsd:dateTime datatype field mapping to accessors of + * this class are defined in + * date/time field mapping table.

    + * + * @param xmlGregorianCalendar Instance of XMLGregorianCalendar to compare + * + * @return The relationship between this XMLGregorianCalendar and + * the specified xmlGregorianCalendar as + * {@link DatatypeConstants#LESSER}, + * {@link DatatypeConstants#EQUAL}, + * {@link DatatypeConstants#GREATER} or + * {@link DatatypeConstants#INDETERMINATE}. + * + * @throws NullPointerException if xmlGregorianCalendar is null. + */ + public abstract int compare(XMLGregorianCalendar xmlGregorianCalendar); - public abstract BigDecimal getFractionalSecond(); + /** + *

    Normalize this instance to UTC.

    + * + *

    2000-03-04T23:00:00+03:00 normalizes to 2000-03-04T20:00:00Z

    + *

    Implements W3C XML Schema Part 2, Section 3.2.7.3 (A).

    + * + * @return this XMLGregorianCalendar normalized to UTC. + */ + public abstract XMLGregorianCalendar normalize(); - public abstract int compare(XMLGregorianCalendar xmlGregorianCalendar); + /** + *

    Compares this calendar to the specified object. The result is + * true if and only if the argument is not null and is an + * XMLGregorianCalendar object that represents the same + * instant in time as this object.

    + * + * @param obj to compare. + * + * @return true when obj is an instance of + * XMLGregorianCalendar and + * {@link #compare(XMLGregorianCalendar obj)} + * returns {@link DatatypeConstants#EQUAL}, + * otherwise false. + */ + public boolean equals(Object obj) { - public abstract XMLGregorianCalendar normalize(); + if (obj == null || !(obj instanceof XMLGregorianCalendar)) { + return false; + } + return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL; + } - public abstract String toXMLFormat(); + /** + *

    Returns a hash code consistent with the definition of the equals method.

    + * + * @return hash code of this object. + */ + public int hashCode() { - public abstract QName getXMLSchemaType(); + // Following two dates compare to EQUALS since in different timezones. + // 2000-01-15T12:00:00-05:00 == 2000-01-15T13:00:00-04:00 + // + // Must ensure both instances generate same hashcode by normalizing + // this to UTC timezone. + int timezone = getTimezone(); + if (timezone == DatatypeConstants.FIELD_UNDEFINED) { + timezone = 0; + } + XMLGregorianCalendar gc = this; + if (timezone != 0) { + gc = this.normalize(); + } + return gc.getYear() + + gc.getMonth() + + gc.getDay() + + gc.getHour() + + gc.getMinute() + + gc.getSecond(); + } - public abstract boolean isValid(); + /** + *

    Return the lexical representation of this instance. + * The format is specified in + * XML Schema 1.0 Part 2, Section 3.2.[7-14].1, + * Lexical Representation".

    + * + *

    Specific target lexical representation format is determined by + * {@link #getXMLSchemaType()}.

    + * + * @return XML, as String, representation of this XMLGregorianCalendar + * + * @throws IllegalStateException if the combination of set fields + * does not match one of the eight defined XML Schema builtin date/time datatypes. + */ + public abstract String toXMLFormat(); - public abstract void add(Duration duration); + /** + *

    Return the name of the XML Schema date/time type that this instance + * maps to. Type is computed based on fields that are set.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    + * Required fields for XML Schema 1.0 Date/Time Datatypes.
    + * (timezone is optional for all date/time datatypes) + *
    Datatypeyearmonthdayhourminutesecond
    {@link DatatypeConstants#DATETIME}XXXXXX
    {@link DatatypeConstants#DATE}XXX
    {@link DatatypeConstants#TIME}XXX
    {@link DatatypeConstants#GYEARMONTH}XX
    {@link DatatypeConstants#GMONTHDAY}XX
    {@link DatatypeConstants#GYEAR}X
    {@link DatatypeConstants#GMONTH}X
    {@link DatatypeConstants#GDAY}X
    + * + * @throws java.lang.IllegalStateException if the combination of set fields + * does not match one of the eight defined XML Schema builtin + * date/time datatypes. + * @return One of the following class constants: + * {@link DatatypeConstants#DATETIME}, + * {@link DatatypeConstants#TIME}, + * {@link DatatypeConstants#DATE}, + * {@link DatatypeConstants#GYEARMONTH}, + * {@link DatatypeConstants#GMONTHDAY}, + * {@link DatatypeConstants#GYEAR}, + * {@link DatatypeConstants#GMONTH} or + * {@link DatatypeConstants#GDAY}. + */ + public abstract QName getXMLSchemaType(); - public abstract GregorianCalendar toGregorianCalendar(); + /** + *

    Returns a String representation of this XMLGregorianCalendar Object.

    + * + *

    The result is a lexical representation generated by {@link #toXMLFormat()}.

    + * + * @return A non-null valid String representation of this XMLGregorianCalendar. + * + * @throws IllegalStateException if the combination of set fields + * does not match one of the eight defined XML Schema builtin date/time datatypes. + * + * @see #toXMLFormat() + */ + public String toString() { -// not supported public abstract GregorianCalendar toGregorianCalendar(TimeZone timezone, Locale aLocale, -// XMLGregorianCalendar defaults); - public abstract TimeZone getTimeZone(int defaultZoneoffset); + return toXMLFormat(); + } - public abstract Object clone(); + /** + * Validate instance by getXMLSchemaType() constraints. + * @return true if data values are valid. + */ + public abstract boolean isValid(); - - public int getMillisecond() { - BigDecimal f = getFractionalSecond(); - return (f == null ? DatatypeConstants.FIELD_UNDEFINED - : f.movePointRight(3).intValue()); - } - - public void setTime(int hour, int minute, int second) { - setTime(hour, minute, second, null); - } + /** + *

    Add duration to this instance.

    + * + *

    The computation is specified in + * XML Schema 1.0 Part 2, Appendix E, + * Adding durations to dateTimes>. + * date/time field mapping table + * defines the mapping from XML Schema 1.0 dateTime fields + * to this class' representation of those fields.

    + * + * @param duration Duration to add to this XMLGregorianCalendar. + * + * @throws NullPointerException when duration parameter is null. + */ + public abstract void add(Duration duration); - public void setTime(int hour, int minute, int second, BigDecimal fractional) { - setHour(hour); - setMinute(minute); - setSecond(second); - setFractionalSecond(fractional); - } + /** + *

    Convert this XMLGregorianCalendar to a {@link GregorianCalendar}.

    + * + *

    When this instance has an undefined field, this + * conversion relies on the java.util.GregorianCalendar default + * for its corresponding field. A notable difference between + * XML Schema 1.0 date/time datatypes and java.util.GregorianCalendar + * is that Timezone value is optional for date/time datatypes and it is + * a required field for java.util.GregorianCalendar. See javadoc + * for java.util.TimeZone.getDefault() on how the default + * is determined. To explicitly specify the TimeZone + * instance, see + * {@link #toGregorianCalendar(TimeZone, Locale, XMLGregorianCalendar)}.

    + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
    + * Field by Field Conversion from this class to + * java.util.GregorianCalendar + *
    java.util.GregorianCalendar fieldjavax.xml.datatype.XMLGregorianCalendar field
    ERA{@link #getEonAndYear()}.signum() < 0 ? GregorianCalendar.BC : GregorianCalendar.AD
    YEAR{@link #getEonAndYear()}.abs().intValue()*
    MONTH{@link #getMonth()} - {@link DatatypeConstants#JANUARY} + {@link GregorianCalendar#JANUARY}
    DAY_OF_MONTH{@link #getDay()}
    HOUR_OF_DAY{@link #getHour()}
    MINUTE{@link #getMinute()}
    SECOND{@link #getSecond()}
    MILLISECONDget millisecond order from {@link #getFractionalSecond()}*
    GregorianCalendar.setTimeZone(TimeZone){@link #getTimezone()} formatted into Custom timezone id
    + * * designates possible loss of precision during the conversion due + * to source datatype having higher precision than target datatype. + * + *

    To ensure consistency in conversion implementations, the new + * GregorianCalendar should be instantiated in following + * manner. + *

      + *
    • Using timeZone value as defined above, create a new + * java.util.GregorianCalendar(timeZone,Locale.getDefault()). + *
    • + *
    • Initialize all GregorianCalendar fields by calling {@link java.util.GregorianCalendar#clear()}.
    • + *
    • Obtain a pure Gregorian Calendar by invoking + * GregorianCalendar.setGregorianChange( + * new Date(Long.MIN_VALUE)).
    • + *
    • Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, + * MINUTE, SECOND and MILLISECOND are set using the method + * Calendar.set(int,int)
    • + *
    + *

    + * + * @see #toGregorianCalendar(java.util.TimeZone, java.util.Locale, XMLGregorianCalendar) + */ + public abstract GregorianCalendar toGregorianCalendar(); - public void setTime(int hour, int minute, int second, int millisecond) { - setHour(hour); - setMinute(minute); - setSecond(second); - setMillisecond(millisecond); - } + /** + *

    Convert this XMLGregorianCalendar along with provided parameters + * to a {@link GregorianCalendar} instance.

    + * + *

    Since XML Schema 1.0 date/time datetypes has no concept of + * timezone ids or daylight savings timezone ids, this conversion operation + * allows the user to explicitly specify one with + * timezone parameter.

    + * + *

    To compute the return value's TimeZone field, + *

      + *
    • when parameter timeZone is non-null, + * it is the timezone field.
    • + *
    • else when this.getTimezone() != FIELD_UNDEFINED, + * create a java.util.TimeZone with a custom timezone id + * using the this.getTimezone().
    • + *
    • else when defaults.getTimezone() != FIELD_UNDEFINED, + * create a java.util.TimeZone with a custom timezone id + * using defaults.getTimezone().
    • + *
    • else use the GregorianCalendar default timezone value + * for the host is defined as specified by + * java.util.TimeZone.getDefault().
    • + * + *

      To ensure consistency in conversion implementations, the new + * GregorianCalendar should be instantiated in following + * manner. + *

        + *
      • Create a new java.util.GregorianCalendar(TimeZone, + * Locale) with TimeZone set as specified above and the + * Locale parameter. + *
      • + *
      • Initialize all GregorianCalendar fields by calling {@link GregorianCalendar#clear()}
      • + *
      • Obtain a pure Gregorian Calendar by invoking + * GregorianCalendar.setGregorianChange( + * new Date(Long.MIN_VALUE)).
      • + *
      • Its fields ERA, YEAR, MONTH, DAY_OF_MONTH, HOUR_OF_DAY, + * MINUTE, SECOND and MILLISECOND are set using the method + * Calendar.set(int,int)
      • + *
      + * + * @param timezone provide Timezone. null is a legal value. + * @param aLocale provide explicit Locale. Use default GregorianCalendar locale if + * value is null. + * @param defaults provide default field values to use when corresponding + * field for this instance is FIELD_UNDEFINED or null. + * If defaultsis null or a field + * within the specified defaults is undefined, + * just use java.util.GregorianCalendar defaults. + * @return a java.util.GregorianCalendar conversion of this instance. + */ + public abstract GregorianCalendar toGregorianCalendar( + java.util.TimeZone timezone, + java.util.Locale aLocale, + XMLGregorianCalendar defaults); - public boolean equals(Object obj) { - if (obj == null || !(obj instanceof XMLGregorianCalendar)) { - return false; - } - return compare((XMLGregorianCalendar) obj) == DatatypeConstants.EQUAL; - } + /** + *

      Returns a java.util.TimeZone for this class.

      + * + *

      If timezone field is defined for this instance, + * returns TimeZone initialized with custom timezone id + * of zoneoffset. If timezone field is undefined, + * try the defaultZoneoffset that was passed in. + * If defaultZoneoffset is FIELD_UNDEFINED, return + * default timezone for this host. + * (Same default as java.util.GregorianCalendar).

      + * + * @param defaultZoneoffset default zoneoffset if this zoneoffset is + * {@link DatatypeConstants#FIELD_UNDEFINED}. + * + * @return TimeZone for this. + */ + public abstract TimeZone getTimeZone(int defaultZoneoffset); - public int hashCode() { - int timezone = getTimezone(); - if (timezone == DatatypeConstants.FIELD_UNDEFINED) { - timezone = 0; - } - XMLGregorianCalendar gc = this; - if (timezone != 0) { - gc = normalize(); - } - return gc.getYear() + gc.getMonth() + gc.getDay() + gc.getHour() + gc.getMinute() + gc.getSecond(); - } - public String toString() { - return toXMLFormat(); - } + /** + *

      Creates and returns a copy of this object.

      + * + * @return copy of this Object + */ + public abstract Object clone(); } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/namespace/NamespaceContext.java b/sources/net.sf.j2s.java.core/src/javax/xml/namespace/NamespaceContext.java index c06ae31f2..f1ce69321 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/namespace/NamespaceContext.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/namespace/NamespaceContext.java @@ -1,8 +1,288 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.namespace; import java.util.Iterator; + +/** + *

      Interface for read only XML Namespace context processing.

      + * + *

      An XML Namespace has the properties:

      + *
        + *
      • Namespace URI: + * Namespace name expressed as a URI to which the prefix is bound
      • + *
      • prefix: syntactically, this is the part of the attribute name + * following the XMLConstants.XMLNS_ATTRIBUTE + * ("xmlns") in the Namespace declaration
      • + *
      + *

      example: + * <element xmlns:prefix="http://Namespace-name-URI">

      + * + *

      All get*(*) methods operate in the current scope + * for Namespace URI and prefix resolution.

      + * + *

      Note that a Namespace URI can be bound to + * multiple prefixes in the current scope. This can + * occur when multiple XMLConstants.XMLNS_ATTRIBUTE + * ("xmlns") Namespace declarations occur in the same Start-Tag and + * refer to the same Namespace URI. e.g.
      + *

      + * <element xmlns:prefix1="http://Namespace-name-URI"
      + *          xmlns:prefix2="http://Namespace-name-URI">
      + * 
      + * This can also occur when the same Namespace URI is used in multiple + * XMLConstants.XMLNS_ATTRIBUTE ("xmlns") Namespace + * declarations in the logical parent element hierarchy. e.g.
      + *
      + * <parent xmlns:prefix1="http://Namespace-name-URI">
      + *   <child xmlns:prefix2="http://Namespace-name-URI">
      + *     ...
      + *   </child>
      + * </parent>
      + * 

      + * + *

      A prefix can only be bound to a single + * Namespace URI in the current scope.

      + * + * @author Jeff Suttor + * @see javax.xml.XMLConstants + * javax.xml.XMLConstants for declarations of common XML values + * @see + * XML Schema Part2: Datatypes + * @see + * Namespaces in XML + * @see + * Namespaces in XML Errata + * @since 1.5 + */ + public interface NamespaceContext { + + /** + *

      Get Namespace URI bound to a prefix in the current scope.

      + * + *

      When requesting a Namespace URI by prefix, the following + * table describes the returned Namespace URI value for all + * possible prefix values:

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      + * getNamespaceURI(prefix) + * return value for specified prefixes + *
      prefix parameterNamespace URI return value
      DEFAULT_NS_PREFIX ("")default Namespace URI in the current scope or + * {@link + * javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI("")} + * + * when there is no default Namespace URI in the current scope
      bound prefixNamespace URI bound to prefix in current scope
      unbound prefix + * {@link + * javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI("")} + * + *
      XMLConstants.XML_NS_PREFIX ("xml")XMLConstants.XML_NS_URI + * ("http://www.w3.org/XML/1998/namespace")
      XMLConstants.XMLNS_ATTRIBUTE ("xmlns")XMLConstants.XMLNS_ATTRIBUTE_NS_URI + * ("http://www.w3.org/2000/xmlns/")
      nullIllegalArgumentException is thrown
      + * + * @param prefix prefix to look up + * + * @return Namespace URI bound to prefix in the current scope + * + * @throws IllegalArgumentException When prefix is + * null + */ String getNamespaceURI(String prefix); + + /** + *

      Get prefix bound to Namespace URI in the current scope.

      + * + *

      To get all prefixes bound to a Namespace URI in the current + * scope, use {@link #getPrefixes(String namespaceURI)}.

      + * + *

      When requesting a prefix by Namespace URI, the following + * table describes the returned prefix value for all Namespace URI + * values:

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      + * getPrefix(namespaceURI) return value for + * specified Namespace URIs + *
      Namespace URI parameterprefix value returned
      <default Namespace URI>XMLConstants.DEFAULT_NS_PREFIX ("") + *
      bound Namespace URIprefix bound to Namespace URI in the current scope, + * if multiple prefixes are bound to the Namespace URI in + * the current scope, a single arbitrary prefix, whose + * choice is implementation dependent, is returned
      unbound Namespace URInull
      XMLConstants.XML_NS_URI + * ("http://www.w3.org/XML/1998/namespace")XMLConstants.XML_NS_PREFIX ("xml")
      XMLConstants.XMLNS_ATTRIBUTE_NS_URI + * ("http://www.w3.org/2000/xmlns/")XMLConstants.XMLNS_ATTRIBUTE ("xmlns")
      nullIllegalArgumentException is thrown
      + * + * @param namespaceURI URI of Namespace to lookup + * + * @return prefix bound to Namespace URI in current context + * + * @throws IllegalArgumentException When namespaceURI is + * null + */ String getPrefix(String namespaceURI); - Iterator getPrefixes(String namespaceURI); + + /** + *

      Get all prefixes bound to a Namespace URI in the current + * scope.

      + * + *

      An Iterator over String elements is returned in an arbitrary, + * implementation dependent, order.

      + * + *

      The Iterator is + * not modifiable. e.g. the + * remove() method will throw + * UnsupportedOperationException.

      + * + *

      When requesting prefixes by Namespace URI, the following + * table describes the returned prefixes value for all Namespace + * URI values:

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      + * getPrefixes(namespaceURI) return value for + * specified Namespace URIs
      Namespace URI parameterprefixes value returned
      bound Namespace URI, + * including the <default Namespace URI> + * Iterator over prefixes bound to Namespace URI in + * the current scope in an arbitrary, + * implementation dependent, + * order + *
      unbound Namespace URIempty Iterator
      XMLConstants.XML_NS_URI + * ("http://www.w3.org/XML/1998/namespace")Iterator with one element set to + * XMLConstants.XML_NS_PREFIX ("xml")
      XMLConstants.XMLNS_ATTRIBUTE_NS_URI + * ("http://www.w3.org/2000/xmlns/")Iterator with one element set to + * XMLConstants.XMLNS_ATTRIBUTE ("xmlns")
      nullIllegalArgumentException is thrown
      + * + * @param namespaceURI URI of Namespace to lookup + * + * @return Iterator for all prefixes bound to the + * Namespace URI in the current scope + * + * @throws IllegalArgumentException When namespaceURI is + * null + */ + Iterator getPrefixes(String namespaceURI); } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/namespace/QName.java b/sources/net.sf.j2s.java.core/src/javax/xml/namespace/QName.java index ebbe218f8..981a8b20e 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/namespace/QName.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/namespace/QName.java @@ -1,197 +1,516 @@ -/* JBoss, the OpenSource WebOS +/* + * Copyright (c) 2003, 2006, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * - * Distributable under LGPL license. - * See terms of license at gnu.org. - * - * modified for SwingJS by Bob Hanson, hansonr@stolaf.edu - * + * 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 javax.xml.namespace; -// $Id: QName.java,v 1.2.6.8 2005/04/12 03:35:26 starksm Exp $ - -import java.util.StringTokenizer; - -/** QName represents an immutable qualified name. - * The value of a QName contains a Namespace URI, local part and prefix. - * - * The prefix is included in QName to retain lexical information when present - * in an XML input source. The prefix is NOT used in QName.equals(Object) or - * to compute the QName.hashCode(). Equality and the hash code are defined - * using only the Namespace URI and local part. - * - * If not specified, the Namespace URI is set to "" (the empty string). - * If not specified, the prefix is set to "" (the empty string). - * - * @author Scott.Stark@jboss.org - * @author Thomas.Diesler@jboss.org - * @author Jeff Suttor (javadoc) - * @version $Revision: 1.2.6.8 $ +import java.io.Serializable; +import java.security.AccessController; +import java.security.PrivilegedAction; + +import javax.xml.XMLConstants; + +/** + *

      QName represents a qualified name + * as defined in the XML specifications: XML Schema Part2: + * Datatypes specification, Namespaces + * in XML, Namespaces + * in XML Errata.

      + * + *

      The value of a QName contains a Namespace + * URI, local part and + * prefix.

      + * + *

      The prefix is included in QName to retain lexical + * information when present in an {@link + * javax.xml.transform.Source XML input source}. The prefix is + * NOT used in {@link #equals(Object) + * QName.equals(Object)} or to compute the {@link #hashCode() + * QName.hashCode()}. Equality and the hash code are defined using + * only the Namespace URI and local part.

      + * + *

      If not specified, the Namespace URI is set to {@link + * javax.xml.XMLConstants#NULL_NS_URI XMLConstants.NULL_NS_URI}. + * If not specified, the prefix is set to {@link + * javax.xml.XMLConstants#DEFAULT_NS_PREFIX + * XMLConstants.DEFAULT_NS_PREFIX}.

      + * + *

      QName is immutable.

      + * + * @author Jeff Suttor + * @version $Revision: 1.8 $, $Date: 2010/03/18 03:06:17 $ + * @see + * XML Schema Part2: Datatypes specification + * @see + * Namespaces in XML + * @see + * Namespaces in XML Errata + * @since 1.5 */ -public class QName //implements Serializable -{ -// /** @since 4.0.2, compatible with jdk5 by default */ -// final static long serialVersionUID; -// static -// { -// if (SerialVersion.version == SerialVersion.LEGACY) -// serialVersionUID = 8217399441836960859L; -// else -// serialVersionUID = -3852060120346905000L; -// } -// - private String namespaceURI; - private String localPart; - private String prefix; - - /** QName derived from parsing the formatted String. - * If the String is null or does not conform to QName.toString() formatting, - * an IllegalArgumentException is thrown. - * - * The String MUST be in the form returned by QName.toString(). There is NO - * standard specification for representing a QName as a String. The String - * format is NOT portable across implementations and will change when a - * standard String representation is defined. This implementation currently - * parses a String formatted as: "{" + Namespace URI + "}" + local part. If - * the Namespace URI .equals(""), only the local part should be provided. - * - * The prefix value CANNOT be represented in the String and will be set to "" - * - * This method does not do full validation of the resulting QName. In - * particular, the local part is not validated as a NCName as specified in - * Namespaces in XML. - * - * @see #toString() - * @param toStringName - a QName string in the format of toString(). - * @return QName for the toStringName - */ - public static QName valueOf(String toStringName) - { - String uri = null; - String localPart = null; - - StringTokenizer tokenizer = new StringTokenizer(toStringName, "{}"); - int tokenCount = tokenizer.countTokens(); - - if (tokenCount < 1 || tokenCount > 2) - throw new IllegalArgumentException("Invalid QName string: " + toStringName); - - if (tokenCount > 1) - uri = tokenizer.nextToken(); - - localPart = tokenizer.nextToken(); - return new QName(uri, localPart); - } - - public QName(String localPart) - { - this(null, localPart); - } - - public QName(String namespaceURI, String localPart) - { - this(namespaceURI, localPart, ""); - } - - /** QName constructor specifying the Namespace URI, local part and prefix. - * If the Namespace URI is null, it is set to "". This value represents no - * explicitly defined Namespace as defined by the Namespaces in XML - * specification. This action preserves compatible behavior with QName 1.0. - * - * If the local part is null, an IllegalArgumentException is thrown. - * - * If the prefix is null, an IllegalArgumentException is thrown. Use "" to - * explicitly indicate that no prefix is present or the prefix is not - * relevant. - * - * @param namespaceURI - Namespace URI of the QName - * @param localPart - local part of the QName - * @param prefix - prefix of the QName - */ - public QName(String namespaceURI, String localPart, String prefix) - { - this.namespaceURI = namespaceURI; - if (this.namespaceURI == null) - this.namespaceURI = ""; - - if (localPart == null) - throw new IllegalArgumentException("localPart cannot be null"); - - if (localPart.startsWith(":")) - throw new IllegalArgumentException("Illegal localPart: " + localPart); - - this.localPart = localPart; - - this.prefix = prefix; - if (this.prefix == null) - this.prefix = ""; - } - - public String getNamespaceURI() - { - return namespaceURI; - } - - public String getLocalPart() - { - return localPart; - } - - public String getPrefix() - { - return prefix; - } - - /** There is NO standard specification for representing a QName as a String. - * The returned String is not portable across implementations and will change when a standard String representation is defined. - * This implementation currently represents a QName as: "{" + Namespace URI + "}" + local part. - * If the Namespace URI .equals(""), only the local part is returned. - * An appropriate use of this method is for debugging or logging for human consumption. - * - * Note the prefix value is NOT returned as part of the String representation. - * - * @return '{' + namespaceURI + '}' + localPart - */ - public String toString() - { - if (namespaceURI.equals("")) - return localPart; - else - return '{' + namespaceURI + '}' + localPart; - } - - /** Equality is based on the namespaceURI and localPart - * @param obj the QName to compare too - * @return true if both namespaceURI and localPart, false otherwise - */ - public boolean equals(Object obj) - { - if (obj instanceof QName) - { - QName qn = (QName)obj; - boolean equals = namespaceURI.equals(qn.namespaceURI); - return equals && localPart.equals(qn.localPart); - } - return false; - } - - /** Calculate the hash of namespaceURI and localPart - * @return namespaceURI.hashCode() + localPart.hashCode() - */ - public int hashCode() - { - int hashCode = namespaceURI.hashCode() + localPart.hashCode(); - return hashCode; - } - - /** - * Compares this object with the specified object for order. Returns a - * negative integer, zero, or a positive integer as this object is less - * than, equal to, or greater than the specified object.

      - */ - public int compareTo(Object o) - { - QName other = (QName)o; - return toString().compareTo(other.toString()); - } + +public class QName implements Serializable { + + /** + *

      Stream Unique Identifier.

      + * + *

      Due to a historical defect, QName was released with multiple + * serialVersionUID values even though its serialization was the + * same.

      + * + *

      To workaround this issue, serialVersionUID is set with either + * a default value or a compatibility value. To use the + * compatiblity value, set the system property:

      + * + * com.sun.xml.namespace.QName.useCompatibleSerialVersionUID=1.0 + * + *

      This workaround was inspired by classes in the javax.management + * package, e.g. ObjectName, etc. + * See CR6267224 for original defect report.

      + */ + private static final long serialVersionUID; + /** + *

      Default serialVersionUID value.

      + */ + private static final long defaultSerialVersionUID = -9120448754896609940L; + /** + *

      Compatibility serialVersionUID value.

      + */ + private static final long compatibleSerialVersionUID = 4418622981026545151L; + /** + *

      Flag to use default or campatible serialVersionUID.

      + */ + private static boolean useDefaultSerialVersionUID = true; + static { + try { + // use a privileged block as reading a system property + String valueUseCompatibleSerialVersionUID = (String) AccessController.doPrivileged( + new PrivilegedAction() { + public Object run() { + return System.getProperty("com.sun.xml.namespace.QName.useCompatibleSerialVersionUID"); + } + } + ); + useDefaultSerialVersionUID = (valueUseCompatibleSerialVersionUID != null && valueUseCompatibleSerialVersionUID.equals("1.0")) ? false : true; + } catch (Exception exception) { + // use default if any Exceptions + useDefaultSerialVersionUID = true; + } + + // set serialVersionUID to desired value + if (useDefaultSerialVersionUID) { + serialVersionUID = defaultSerialVersionUID; + } else { + serialVersionUID = compatibleSerialVersionUID; + } + } + + /** + *

      Namespace URI of this QName.

      + */ + private final String namespaceURI; + + /** + *

      local part of this QName.

      + */ + private final String localPart; + + /** + *

      prefix of this QName.

      + */ + private final String prefix; + + /** + *

      QName constructor specifying the Namespace URI + * and local part.

      + * + *

      If the Namespace URI is null, it is set to + * {@link javax.xml.XMLConstants#NULL_NS_URI + * XMLConstants.NULL_NS_URI}. This value represents no + * explicitly defined Namespace as defined by the Namespaces + * in XML specification. This action preserves compatible + * behavior with QName 1.0. Explicitly providing the {@link + * javax.xml.XMLConstants#NULL_NS_URI + * XMLConstants.NULL_NS_URI} value is the preferred coding + * style.

      + * + *

      If the local part is null an + * IllegalArgumentException is thrown. + * A local part of "" is allowed to preserve + * compatible behavior with QName 1.0.

      + * + *

      When using this constructor, the prefix is set to {@link + * javax.xml.XMLConstants#DEFAULT_NS_PREFIX + * XMLConstants.DEFAULT_NS_PREFIX}.

      + * + *

      The Namespace URI is not validated as a + * URI reference. + * The local part is not validated as a + * NCName + * as specified in Namespaces + * in XML.

      + * + * @param namespaceURI Namespace URI of the QName + * @param localPart local part of the QName + * + * @throws IllegalArgumentException When localPart is + * null + * + * @see #QName(String namespaceURI, String localPart, String + * prefix) QName(String namespaceURI, String localPart, String + * prefix) + */ + public QName(final String namespaceURI, final String localPart) { + this(namespaceURI, localPart, XMLConstants.DEFAULT_NS_PREFIX); + } + + /** + *

      QName constructor specifying the Namespace URI, + * local part and prefix.

      + * + *

      If the Namespace URI is null, it is set to + * {@link javax.xml.XMLConstants#NULL_NS_URI + * XMLConstants.NULL_NS_URI}. This value represents no + * explicitly defined Namespace as defined by the Namespaces + * in XML specification. This action preserves compatible + * behavior with QName 1.0. Explicitly providing the {@link + * javax.xml.XMLConstants#NULL_NS_URI + * XMLConstants.NULL_NS_URI} value is the preferred coding + * style.

      + * + *

      If the local part is null an + * IllegalArgumentException is thrown. + * A local part of "" is allowed to preserve + * compatible behavior with QName 1.0.

      + * + *

      If the prefix is null, an + * IllegalArgumentException is thrown. Use {@link + * javax.xml.XMLConstants#DEFAULT_NS_PREFIX + * XMLConstants.DEFAULT_NS_PREFIX} to explicitly indicate that no + * prefix is present or the prefix is not relevant.

      + * + *

      The Namespace URI is not validated as a + * URI reference. + * The local part and prefix are not validated as a + * NCName + * as specified in Namespaces + * in XML.

      + * + * @param namespaceURI Namespace URI of the QName + * @param localPart local part of the QName + * @param prefix prefix of the QName + * + * @throws IllegalArgumentException When localPart + * or prefix is null + */ + public QName(String namespaceURI, String localPart, String prefix) { + + // map null Namespace URI to default + // to preserve compatibility with QName 1.0 + if (namespaceURI == null) { + this.namespaceURI = XMLConstants.NULL_NS_URI; + } else { + this.namespaceURI = namespaceURI; + } + + // local part is required. + // "" is allowed to preserve compatibility with QName 1.0 + if (localPart == null) { + throw new IllegalArgumentException( + "local part cannot be \"null\" when creating a QName"); + } + this.localPart = localPart; + + // prefix is required + if (prefix == null) { + throw new IllegalArgumentException( + "prefix cannot be \"null\" when creating a QName"); + } + this.prefix = prefix; + } + + /** + *

      QName constructor specifying the local part.

      + * + *

      If the local part is null an + * IllegalArgumentException is thrown. + * A local part of "" is allowed to preserve + * compatible behavior with QName 1.0.

      + * + *

      When using this constructor, the Namespace URI is set to + * {@link javax.xml.XMLConstants#NULL_NS_URI + * XMLConstants.NULL_NS_URI} and the prefix is set to {@link + * javax.xml.XMLConstants#DEFAULT_NS_PREFIX + * XMLConstants.DEFAULT_NS_PREFIX}.

      + * + *

      In an XML context, all Element and Attribute names exist + * in the context of a Namespace. Making this explicit during the + * construction of a QName helps prevent hard to + * diagnosis XML validity errors. The constructors {@link + * #QName(String namespaceURI, String localPart) QName(String + * namespaceURI, String localPart)} and + * {@link #QName(String namespaceURI, String localPart, String prefix)} + * are preferred.

      + * + *

      The local part is not validated as a + * NCName + * as specified in Namespaces + * in XML.

      + * + * @param localPart local part of the QName + * + * @throws IllegalArgumentException When localPart is + * null + * + * @see #QName(String namespaceURI, String localPart) QName(String + * namespaceURI, String localPart) + * @see #QName(String namespaceURI, String localPart, String + * prefix) QName(String namespaceURI, String localPart, String + * prefix) + */ + public QName(String localPart) { + this( + XMLConstants.NULL_NS_URI, + localPart, + XMLConstants.DEFAULT_NS_PREFIX); + } + + /** + *

      Get the Namespace URI of this QName.

      + * + * @return Namespace URI of this QName + */ + public String getNamespaceURI() { + return namespaceURI; + } + + /** + *

      Get the local part of this QName.

      + * + * @return local part of this QName + */ + public String getLocalPart() { + return localPart; + } + + /** + *

      Get the prefix of this QName.

      + * + *

      The prefix assigned to a QName might + * NOT be valid in a different + * context. For example, a QName may be assigned a + * prefix in the context of parsing a document but that prefix may + * be invalid in the context of a different document.

      + * + * @return prefix of this QName + */ + public String getPrefix() { + return prefix; + } + + /** + *

      Test this QName for equality with another + * Object.

      + * + *

      If the Object to be tested is not a + * QName or is null, then this method + * returns false.

      + * + *

      Two QNames are considered equal if and only if + * both the Namespace URI and local part are equal. This method + * uses String.equals() to check equality of the + * Namespace URI and local part. The prefix is + * NOT used to determine equality.

      + * + *

      This method satisfies the general contract of {@link + * java.lang.Object#equals(Object) Object.equals(Object)}

      + * + * @param objectToTest the Object to test for + * equality with this QName + * @return true if the given Object is + * equal to this QName else false + */ + public final boolean equals(Object objectToTest) { + if (objectToTest == this) { + return true; + } + + if (objectToTest == null || !(objectToTest instanceof QName)) { + return false; + } + + QName qName = (QName) objectToTest; + + return localPart.equals(qName.localPart) + && namespaceURI.equals(qName.namespaceURI); + } + + /** + *

      Generate the hash code for this QName.

      + * + *

      The hash code is calculated using both the Namespace URI and + * the local part of the QName. The prefix is + * NOT used to calculate the hash + * code.

      + * + *

      This method satisfies the general contract of {@link + * java.lang.Object#hashCode() Object.hashCode()}.

      + * + * @return hash code for this QName Object + */ + public final int hashCode() { + return namespaceURI.hashCode() ^ localPart.hashCode(); + } + + /** + *

      String representation of this + * QName.

      + * + *

      The commonly accepted way of representing a QName + * as a String was + * defined + * by James Clark. Although this is not a standard + * specification, it is in common use, e.g. {@link + * javax.xml.transform.Transformer#setParameter(String name, Object value)}. + * This implementation represents a QName as: + * "{" + Namespace URI + "}" + local part. If the Namespace URI + * .equals(XMLConstants.NULL_NS_URI), only the + * local part is returned. An appropriate use of this method is + * for debugging or logging for human consumption.

      + * + *

      Note the prefix value is NOT + * returned as part of the String representation.

      + * + *

      This method satisfies the general contract of {@link + * java.lang.Object#toString() Object.toString()}.

      + * + * @return String representation of this QName + */ + public String toString() { + if (namespaceURI.equals(XMLConstants.NULL_NS_URI)) { + return localPart; + } else { + return "{" + namespaceURI + "}" + localPart; + } + } + + /** + *

      QName derived from parsing the formatted + * String.

      + * + *

      If the String is null or does not conform to + * {@link #toString() QName.toString()} formatting, an + * IllegalArgumentException is thrown.

      + * + *

      The String MUST be in the + * form returned by {@link #toString() QName.toString()}.

      + * + *

      The commonly accepted way of representing a QName + * as a String was + * defined + * by James Clark. Although this is not a standard + * specification, it is in common use, e.g. {@link + * javax.xml.transform.Transformer#setParameter(String name, Object value)}. + * This implementation parses a String formatted + * as: "{" + Namespace URI + "}" + local part. If the Namespace + * URI .equals(XMLConstants.NULL_NS_URI), only the + * local part should be provided.

      + * + *

      The prefix value CANNOT be + * represented in the String and will be set to + * {@link javax.xml.XMLConstants#DEFAULT_NS_PREFIX + * XMLConstants.DEFAULT_NS_PREFIX}.

      + * + *

      This method does not do full validation of the resulting + * QName. + *

      The Namespace URI is not validated as a + * URI reference. + * The local part is not validated as a + * NCName + * as specified in + * Namespaces in XML.

      + * + * @param qNameAsString String representation + * of the QName + * + * @throws IllegalArgumentException When qNameAsString is + * null or malformed + * + * @return QName corresponding to the given String + * @see #toString() QName.toString() + */ + public static QName valueOf(String qNameAsString) { + + // null is not valid + if (qNameAsString == null) { + throw new IllegalArgumentException( + "cannot create QName from \"null\" or \"\" String"); + } + + // "" local part is valid to preserve compatible behavior with QName 1.0 + if (qNameAsString.length() == 0) { + return new QName( + XMLConstants.NULL_NS_URI, + qNameAsString, + XMLConstants.DEFAULT_NS_PREFIX); + } + + // local part only? + if (qNameAsString.charAt(0) != '{') { + return new QName( + XMLConstants.NULL_NS_URI, + qNameAsString, + XMLConstants.DEFAULT_NS_PREFIX); + } + + // Namespace URI improperly specified? + if (qNameAsString.startsWith("{" + XMLConstants.NULL_NS_URI + "}")) { + throw new IllegalArgumentException( + "Namespace URI .equals(XMLConstants.NULL_NS_URI), " + + ".equals(\"" + XMLConstants.NULL_NS_URI + "\"), " + + "only the local part, " + + "\"" + + qNameAsString.substring(2 + XMLConstants.NULL_NS_URI.length()) + + "\", " + + "should be provided."); + } + + // Namespace URI and local part specified + int endOfNamespaceURI = qNameAsString.indexOf('}'); + if (endOfNamespaceURI == -1) { + throw new IllegalArgumentException( + "cannot create QName from \"" + + qNameAsString + + "\", missing closing \"}\""); + } + return new QName( + qNameAsString.substring(1, endOfNamespaceURI), + qNameAsString.substring(endOfNamespaceURI + 1), + XMLConstants.DEFAULT_NS_PREFIX); + } } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/DocumentBuilder.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/DocumentBuilder.java new file mode 100644 index 000000000..18e87a527 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/DocumentBuilder.java @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2000, 2006, 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 javax.xml.parsers; + +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.validation.Schema; + +import org.w3c.dom.Document; +import org.w3c.dom.DOMImplementation; + +import org.xml.sax.EntityResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +/** + * Defines the API to obtain DOM Document instances from an XML + * document. Using this class, an application programmer can obtain a + * {@link Document} from XML.

      + * + * An instance of this class can be obtained from the + * {@link DocumentBuilderFactory#newDocumentBuilder()} method. Once + * an instance of this class is obtained, XML can be parsed from a + * variety of input sources. These input sources are InputStreams, + * Files, URLs, and SAX InputSources.

      + * + * Note that this class reuses several classes from the SAX API. This + * does not require that the implementor of the underlying DOM + * implementation use a SAX parser to parse XML document into a + * Document. It merely requires that the implementation + * communicate with the application using these existing APIs. + * + * @author Jeff Suttor + */ + +public abstract class DocumentBuilder { + + + /** Protected constructor */ + protected DocumentBuilder () { + } + + /** + *

      Reset this DocumentBuilder to its original configuration.

      + * + *

      DocumentBuilder is reset to the same state as when it was created with + * {@link DocumentBuilderFactory#newDocumentBuilder()}. + * reset() is designed to allow the reuse of existing DocumentBuilders + * thus saving resources associated with the creation of new DocumentBuilders.

      + * + *

      The reset DocumentBuilder is not guaranteed to have the same {@link EntityResolver} or {@link ErrorHandler} + * Objects, e.g. {@link Object#equals(Object obj)}. It is guaranteed to have a functionally equal + * EntityResolver and ErrorHandler.

      + * + * @throws UnsupportedOperationException When implementation does not + * override this method. + * + * @since 1.5 + */ + public void reset() { + + // implementors should override this method + throw new UnsupportedOperationException( + "This DocumentBuilder, \"" + this.getClass().getName() + + "\", does not support the reset functionality." +// + " Specification \"" + this.getClass().getPackage().getSpecificationTitle() + "\"" +// + " version \"" + this.getClass().getPackage().getSpecificationVersion() + "\"" + ); + } + + /** + * Parse the content of the given InputStream as an XML + * document and return a new DOM {@link Document} object. + * An IllegalArgumentException is thrown if the + * InputStream is null. + * + * @param is InputStream containing the content to be parsed. + * + * @return Document result of parsing the + * InputStream + * + * @throws IOException If any IO errors occur. + * @throws SAXException If any parse errors occur. + * @throws IllegalArgumentException When is is null + * + * @see org.xml.sax.DocumentHandler + */ + + public Document parse(InputStream is) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputStream cannot be null"); + } + + InputSource in = new InputSource(is); + return parse(in); + } + + /** + * Parse the content of the given InputStream as an + * XML document and return a new DOM {@link Document} object. + * An IllegalArgumentException is thrown if the + * InputStream is null. + * + * @param is InputStream containing the content to be parsed. + * @param systemId Provide a base for resolving relative URIs. + * + * @return A new DOM Document object. + * + * @throws IOException If any IO errors occur. + * @throws SAXException If any parse errors occur. + * @throws IllegalArgumentException When is is null + * + * @see org.xml.sax.DocumentHandler + */ + + public Document parse(InputStream is, String systemId) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputStream cannot be null"); + } + + InputSource in = new InputSource(is); + in.setSystemId(systemId); + return parse(in); + } + + /** + * Parse the content of the given URI as an XML document + * and return a new DOM {@link Document} object. + * An IllegalArgumentException is thrown if the + * URI is null null. + * + * @param uri The location of the content to be parsed. + * + * @return A new DOM Document object. + * + * @throws IOException If any IO errors occur. + * @throws SAXException If any parse errors occur. + * @throws IllegalArgumentException When uri is null + * + * @see org.xml.sax.DocumentHandler + */ + + public Document parse(String uri) + throws SAXException, IOException { + if (uri == null) { + throw new IllegalArgumentException("URI cannot be null"); + } + + InputSource in = new InputSource(uri); + return parse(in); + } + + /** + * Parse the content of the given file as an XML document + * and return a new DOM {@link Document} object. + * An IllegalArgumentException is thrown if the + * File is null null. + * + * @param f The file containing the XML to parse. + * + * @throws IOException If any IO errors occur. + * @throws SAXException If any parse errors occur. + * @throws IllegalArgumentException When f is null + * + * @see org.xml.sax.DocumentHandler + * @return A new DOM Document object. + */ + + public Document parse(File f) throws SAXException, IOException { + if (f == null) { + throw new IllegalArgumentException("File cannot be null"); + } + + //convert file to appropriate URI, f.toURI().toASCIIString() + //converts the URI to string as per rule specified in + //RFC 2396, + InputSource in = new InputSource(f.toURI().toASCIIString()); + return parse(in); + } + + /** + * Parse the content of the given input source as an XML document + * and return a new DOM {@link Document} object. + * An IllegalArgumentException is thrown if the + * InputSource is null null. + * + * @param is InputSource containing the content to be parsed. + * + * @return A new DOM Document object. + * + * @throws IOException If any IO errors occur. + * @throws SAXException If any parse errors occur. + * @throws IllegalArgumentException When is is null + * + * @see org.xml.sax.DocumentHandler + */ + + public abstract Document parse(InputSource is) + throws SAXException, IOException; + + + /** + * Indicates whether or not this parser is configured to + * understand namespaces. + * + * @return true if this parser is configured to understand + * namespaces; false otherwise. + */ + + public abstract boolean isNamespaceAware(); + + /** + * Indicates whether or not this parser is configured to + * validate XML documents. + * + * @return true if this parser is configured to validate + * XML documents; false otherwise. + */ + + public abstract boolean isValidating(); + + /** + * Specify the {@link EntityResolver} to be used to resolve + * entities present in the XML document to be parsed. Setting + * this to null will result in the underlying + * implementation using it's own default implementation and + * behavior. + * + * @param er The EntityResolver to be used to resolve entities + * present in the XML document to be parsed. + */ + + public abstract void setEntityResolver(EntityResolver er); + + /** + * Specify the {@link ErrorHandler} to be used by the parser. + * Setting this to null will result in the underlying + * implementation using it's own default implementation and + * behavior. + * + * @param eh The ErrorHandler to be used by the parser. + */ + + public abstract void setErrorHandler(ErrorHandler eh); + + /** + * Obtain a new instance of a DOM {@link Document} object + * to build a DOM tree with. + * + * @return A new instance of a DOM Document object. + */ + + public abstract Document newDocument(); + + /** + * Obtain an instance of a {@link DOMImplementation} object. + * + * @return A new instance of a DOMImplementation. + */ + + public abstract DOMImplementation getDOMImplementation(); + + /**

      Get current state of canonicalization.

      + * + * @return current state canonicalization control + */ + /* + public boolean getCanonicalization() { + return canonicalState; + } + */ + + /**

      Get a reference to the the {@link Schema} being used by + * the XML processor.

      + * + *

      If no schema is being used, null is returned.

      + * + * @return {@link Schema} being used or null + * if none in use + * + * @throws UnsupportedOperationException When implementation does not + * override this method + * + * @since 1.5 + */ + public Schema getSchema() { + throw new UnsupportedOperationException( + "This parser does not support specification \"" +// + this.getClass().getPackage().getSpecificationTitle() +// + "\" version \"" +// + this.getClass().getPackage().getSpecificationVersion() +// + "\"" + ); + } + + + /** + *

      Get the XInclude processing mode for this parser.

      + * + * @return + * the return value of + * the {@link DocumentBuilderFactory#isXIncludeAware()} + * when this parser was created from factory. + * + * @throws UnsupportedOperationException When implementation does not + * override this method + * + * @since 1.5 + * + * @see DocumentBuilderFactory#setXIncludeAware(boolean) + */ + public boolean isXIncludeAware() { + throw new UnsupportedOperationException( + "This parser does not support specification \"" +// + this.getClass().getPackage().getSpecificationTitle() +// + "\" version \"" +// + this.getClass().getPackage().getSpecificationVersion() + + "\"" + ); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/DocumentBuilderFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/DocumentBuilderFactory.java new file mode 100644 index 000000000..d45d16f55 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/DocumentBuilderFactory.java @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2000, 2006, 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 javax.xml.parsers; + +import javax.xml.validation.Schema; + +/** + * Defines a factory API that enables applications to obtain a + * parser that produces DOM object trees from XML documents. + * + * @author Jeff Suttor + * @author Neeraj Bajaj + * + * @version $Revision: 1.9 $, $Date: 2010/05/25 16:19:44 $ + + */ + +public abstract class DocumentBuilderFactory { + + /** The default property name according to the JAXP spec */ + private static final String DEFAULT_PROPERTY_NAME = "javax.xml.parsers.DocumentBuilderFactory"; + + public static boolean useXerces; + + private boolean validating = false; + private boolean namespaceAware = false; + private boolean whitespace = false; + private boolean expandEntityRef = true; + private boolean ignoreComments = false; + private boolean coalescing = false; + + private boolean canonicalState = false; + + /** + *

      Protected constructor to prevent instantiation. + * Use {@link #newInstance()}.

      + */ + protected DocumentBuilderFactory () { + } + + /** + * Obtain a new instance of a + * DocumentBuilderFactory. This static method creates + * a new factory instance. + * This method uses the following ordered lookup procedure to determine + * the DocumentBuilderFactory implementation class to + * load: + *
        + *
      • + * Use the javax.xml.parsers.DocumentBuilderFactory system + * property. + *
      • + *
      • + * Use the properties file "lib/jaxp.properties" in the JRE directory. + * This configuration file is in standard java.util.Properties + * format and contains the fully qualified name of the + * implementation class with the key being the system property defined + * above. + * + * The jaxp.properties file is read only once by the JAXP implementation + * and it's values are then cached for future use. If the file does not exist + * when the first attempt is made to read from it, no further attempts are + * made to check for its existence. It is not possible to change the value + * of any property in jaxp.properties after it has been read for the first time. + *
      • + *
      • + * Use the Services API (as detailed in the JAR specification), if + * available, to determine the classname. The Services API will look + * for a classname in the file + * META-INF/services/javax.xml.parsers.DocumentBuilderFactory + * in jars available to the runtime. + *
      • + *
      • + * Platform default DocumentBuilderFactory instance. + *
      • + *
      + * + * Once an application has obtained a reference to a + * DocumentBuilderFactory it can use the factory to + * configure and obtain parser instances. + * + * + *

      Tip for Trouble-shooting

      + *

      Setting the jaxp.debug system property will cause + * this method to print a lot of debug messages + * to System.err about what it is doing and where it is looking at.

      + * + *

      If you have problems loading {@link DocumentBuilder}s, try:

      + *
      +     * java -Djaxp.debug=1 YourProgram ....
      +     * 
      + * + * @return New instance of a DocumentBuilderFactory + * + * @throws FactoryConfigurationError if the implementation is not + * available or cannot be instantiated. + */ + public static DocumentBuilderFactory newInstance() { + try { + return (DocumentBuilderFactory) FactoryFinder.find( + /* The default property name according to the JAXP spec */ + "javax.xml.parsers.DocumentBuilderFactory", + /* The fallback implementation class name */ + useXerces ? "com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl" + : "swingjs.xml.JSXMLDocumentBuilderFactory"); // BH SwingJS + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + + } + + /** + *

      Obtain a new instance of a DocumentBuilderFactory from class name. + * This function is useful when there are multiple providers in the classpath. + * It gives more control to the application as it can specify which provider + * should be loaded.

      + * + *

      Once an application has obtained a reference to a DocumentBuilderFactory + * it can use the factory to configure and obtain parser instances.

      + * + * + *

      Tip for Trouble-shooting

      + *

      Setting the jaxp.debug system property will cause + * this method to print a lot of debug messages + * to System.err about what it is doing and where it is looking at.

      + * + *

      If you have problems try:

      + *
      +     * java -Djaxp.debug=1 YourProgram ....
      +     * 
      + * + * @param factoryClassName fully qualified factory class name that provides implementation of javax.xml.parsers.DocumentBuilderFactory. + * + * @param classLoader ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @return New instance of a DocumentBuilderFactory + * + * @throws FactoryConfigurationError if factoryClassName is null, or + * the factory class cannot be loaded, instantiated. + * + * @see #newInstance() + * + * @since 1.6 + */ + public static DocumentBuilderFactory newInstance(String factoryClassName, ClassLoader classLoader){ + try { + //do not fallback if given classloader can't find the class, throw exception + return (DocumentBuilderFactory) FactoryFinder.newInstance(factoryClassName, classLoader, false); + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + } + + /** + * Creates a new instance of a {@link javax.xml.parsers.DocumentBuilder} + * using the currently configured parameters. + * + * @return A new instance of a DocumentBuilder. + * + * @throws ParserConfigurationException if a DocumentBuilder + * cannot be created which satisfies the configuration requested. + */ + + public abstract DocumentBuilder newDocumentBuilder() + throws ParserConfigurationException; + + + /** + * Specifies that the parser produced by this code will + * provide support for XML namespaces. By default the value of this is set + * to false + * + * @param awareness true if the parser produced will provide support + * for XML namespaces; false otherwise. + */ + + public void setNamespaceAware(boolean awareness) { + this.namespaceAware = awareness; + } + + /** + * Specifies that the parser produced by this code will + * validate documents as they are parsed. By default the value of this + * is set to false. + * + *

      + * Note that "the validation" here means + * a validating + * parser as defined in the XML recommendation. + * In other words, it essentially just controls the DTD validation. + * (except the legacy two properties defined in JAXP 1.2.) + *

      + * + *

      + * To use modern schema languages such as W3C XML Schema or + * RELAX NG instead of DTD, you can configure your parser to be + * a non-validating parser by leaving the {@link #setValidating(boolean)} + * method false, then use the {@link #setSchema(Schema)} + * method to associate a schema to a parser. + *

      + * + * @param validating true if the parser produced will validate documents + * as they are parsed; false otherwise. + */ + + public void setValidating(boolean validating) { + this.validating = validating; + } + + /** + * Specifies that the parsers created by this factory must eliminate + * whitespace in element content (sometimes known loosely as + * 'ignorable whitespace') when parsing XML documents (see XML Rec + * 2.10). Note that only whitespace which is directly contained within + * element content that has an element only content model (see XML + * Rec 3.2.1) will be eliminated. Due to reliance on the content model + * this setting requires the parser to be in validating mode. By default + * the value of this is set to false. + * + * @param whitespace true if the parser created must eliminate whitespace + * in the element content when parsing XML documents; + * false otherwise. + */ + + public void setIgnoringElementContentWhitespace(boolean whitespace) { + this.whitespace = whitespace; + } + + /** + * Specifies that the parser produced by this code will + * expand entity reference nodes. By default the value of this is set to + * true + * + * @param expandEntityRef true if the parser produced will expand entity + * reference nodes; false otherwise. + */ + + public void setExpandEntityReferences(boolean expandEntityRef) { + this.expandEntityRef = expandEntityRef; + } + + /** + *

      Specifies that the parser produced by this code will + * ignore comments. By default the value of this is set to false + * .

      + * + * @param ignoreComments boolean value to ignore comments during processing + */ + + public void setIgnoringComments(boolean ignoreComments) { + this.ignoreComments = ignoreComments; + } + + /** + * Specifies that the parser produced by this code will + * convert CDATA nodes to Text nodes and append it to the + * adjacent (if any) text node. By default the value of this is set to + * false + * + * @param coalescing true if the parser produced will convert CDATA nodes + * to Text nodes and append it to the adjacent (if any) + * text node; false otherwise. + */ + + public void setCoalescing(boolean coalescing) { + this.coalescing = coalescing; + } + + /** + * Indicates whether or not the factory is configured to produce + * parsers which are namespace aware. + * + * @return true if the factory is configured to produce parsers which + * are namespace aware; false otherwise. + */ + + public boolean isNamespaceAware() { + return namespaceAware; + } + + /** + * Indicates whether or not the factory is configured to produce + * parsers which validate the XML content during parse. + * + * @return true if the factory is configured to produce parsers + * which validate the XML content during parse; false otherwise. + */ + + public boolean isValidating() { + return validating; + } + + /** + * Indicates whether or not the factory is configured to produce + * parsers which ignore ignorable whitespace in element content. + * + * @return true if the factory is configured to produce parsers + * which ignore ignorable whitespace in element content; + * false otherwise. + */ + + public boolean isIgnoringElementContentWhitespace() { + return whitespace; + } + + /** + * Indicates whether or not the factory is configured to produce + * parsers which expand entity reference nodes. + * + * @return true if the factory is configured to produce parsers + * which expand entity reference nodes; false otherwise. + */ + + public boolean isExpandEntityReferences() { + return expandEntityRef; + } + + /** + * Indicates whether or not the factory is configured to produce + * parsers which ignores comments. + * + * @return true if the factory is configured to produce parsers + * which ignores comments; false otherwise. + */ + + public boolean isIgnoringComments() { + return ignoreComments; + } + + /** + * Indicates whether or not the factory is configured to produce + * parsers which converts CDATA nodes to Text nodes and appends it to + * the adjacent (if any) Text node. + * + * @return true if the factory is configured to produce parsers + * which converts CDATA nodes to Text nodes and appends it to + * the adjacent (if any) Text node; false otherwise. + */ + + public boolean isCoalescing() { + return coalescing; + } + + /** + * Allows the user to set specific attributes on the underlying + * implementation. + * + * @param name The name of the attribute. + * @param value The value of the attribute. + * + * @throws IllegalArgumentException thrown if the underlying + * implementation doesn't recognize the attribute. + */ + public abstract void setAttribute(String name, Object value) + throws IllegalArgumentException; + + /** + * Allows the user to retrieve specific attributes on the underlying + * implementation. + * + * @param name The name of the attribute. + * + * @return value The value of the attribute. + * + * @throws IllegalArgumentException thrown if the underlying + * implementation doesn't recognize the attribute. + */ + public abstract Object getAttribute(String name) + throws IllegalArgumentException; + + /** + *

      Set a feature for this DocumentBuilderFactory and DocumentBuilders created by this factory.

      + * + *

      + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * A {@link ParserConfigurationException} is thrown if this DocumentBuilderFactory or the + * DocumentBuilders it creates cannot support the feature. + * It is possible for a DocumentBuilderFactory to expose a feature value but be unable to change its state. + *

      + * + *

      + * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. + * When the feature is:

      + *
        + *
      • + * true: the implementation will limit XML processing to conform to implementation limits. + * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. + * If XML processing is limited for security reasons, it will be reported via a call to the registered + * {@link org.xml.sax.ErrorHandler#fatalError(SAXParseException exception)}. + * See {@link DocumentBuilder#setErrorHandler(org.xml.sax.ErrorHandler errorHandler)}. + *
      • + *
      • + * false: the implementation will processing XML according to the XML specifications without + * regard to possible implementation limits. + *
      • + *
      + * + * @param name Feature name. + * @param value Is feature state true or false. + * + * @throws ParserConfigurationException if this DocumentBuilderFactory or the DocumentBuilders + * it creates cannot support this feature. + * @throws NullPointerException If the name parameter is null. + */ + public abstract void setFeature(String name, boolean value) + throws ParserConfigurationException; + + /** + *

      Get the state of the named feature.

      + * + *

      + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * An {@link ParserConfigurationException} is thrown if this DocumentBuilderFactory or the + * DocumentBuilders it creates cannot support the feature. + * It is possible for an DocumentBuilderFactory to expose a feature value but be unable to change its state. + *

      + * + * @param name Feature name. + * + * @return State of the named feature. + * + * @throws ParserConfigurationException if this DocumentBuilderFactory + * or the DocumentBuilders it creates cannot support this feature. + */ + public abstract boolean getFeature(String name) + throws ParserConfigurationException; + + + /**

      Get current state of canonicalization.

      + * + * @return current state canonicalization control + */ + /* + public boolean getCanonicalization() { + return canonicalState; + } + */ + + + /** + * Gets the {@link Schema} object specified through + * the {@link #setSchema(Schema schema)} method. + * + * @return + * the {@link Schema} object that was last set through + * the {@link #setSchema(Schema)} method, or null + * if the method was not invoked since a {@link DocumentBuilderFactory} + * is created. + * + * @throws UnsupportedOperationException When implementation does not + * override this method. + * + * @since 1.5 + */ + public Schema getSchema() { + throw new UnsupportedOperationException( + "This parser does not support specification " + //\"" +// + this.getClass().getPackage().getSpecificationTitle() +// + "\" version \"" +// + this.getClass().getPackage().getSpecificationVersion() + // + "\"" + ); + + } + + /*

      Set canonicalization control to true or + * false.

      + * + * @param state of canonicalization + */ + /* + public void setCanonicalization(boolean state) { + canonicalState = state; + } + */ + + /** + *

      Set the {@link Schema} to be used by parsers created + * from this factory. + * + *

      + * When a {@link Schema} is non-null, a parser will use a validator + * created from it to validate documents before it passes information + * down to the application. + * + *

      When errors are found by the validator, the parser is responsible + * to report them to the user-specified {@link org.xml.sax.ErrorHandler} + * (or if the error handler is not set, ignore them or throw them), just + * like any other errors found by the parser itself. + * In other words, if the user-specified {@link org.xml.sax.ErrorHandler} + * is set, it must receive those errors, and if not, they must be + * treated according to the implementation specific + * default error handling rules. + * + *

      + * A validator may modify the outcome of a parse (for example by + * adding default values that were missing in documents), and a parser + * is responsible to make sure that the application will receive + * modified DOM trees. + * + *

      + * Initialy, null is set as the {@link Schema}. + * + *

      + * This processing will take effect even if + * the {@link #isValidating()} method returns false. + * + *

      It is an error to use + * the http://java.sun.com/xml/jaxp/properties/schemaSource + * property and/or the http://java.sun.com/xml/jaxp/properties/schemaLanguage + * property in conjunction with a {@link Schema} object. + * Such configuration will cause a {@link ParserConfigurationException} + * exception when the {@link #newDocumentBuilder()} is invoked.

      + * + * + *

      Note for implmentors

      + * + *

      + * A parser must be able to work with any {@link Schema} + * implementation. However, parsers and schemas are allowed + * to use implementation-specific custom mechanisms + * as long as they yield the result described in the specification. + *

      + * + * @param schema Schema to use or null + * to remove a schema. + * + * @throws UnsupportedOperationException When implementation does not + * override this method. + * + * @since 1.5 + */ + public void setSchema(Schema schema) { + throw new UnsupportedOperationException( + "This parser does not support specification \"" +// + this.getClass().getPackage().getSpecificationTitle() +// + "\" version \"" +// + this.getClass().getPackage().getSpecificationVersion() + + "\"" + ); + } + + + + /** + *

      Set state of XInclude processing.

      + * + *

      If XInclude markup is found in the document instance, should it be + * processed as specified in + * XML Inclusions (XInclude) Version 1.0.

      + * + *

      XInclude processing defaults to false.

      + * + * @param state Set XInclude processing to true or + * false + * + * @throws UnsupportedOperationException When implementation does not + * override this method. + * + * @since 1.5 + */ + public void setXIncludeAware(final boolean state) { + if (state) { + throw new UnsupportedOperationException(" setXIncludeAware " + + "is not supported on this JAXP" + + " implementation or earlier: " + this.getClass()); + } + } + + /** + *

      Get state of XInclude processing.

      + * + * @return current state of XInclude processing + * + * @throws UnsupportedOperationException When implementation does not + * override this method. + * + * @since 1.5 + */ + public boolean isXIncludeAware() { + throw new UnsupportedOperationException( + "This parser does not support specification \"" +// + this.getClass().getPackage().getSpecificationTitle() +// + "\" version \"" +// + this.getClass().getPackage().getSpecificationVersion() +// + "\"" + ); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/FactoryConfigurationError.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/FactoryConfigurationError.java new file mode 100644 index 000000000..c70e4ae39 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/FactoryConfigurationError.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.parsers; + +/** + * Thrown when a problem with configuration with the Parser Factories + * exists. This error will typically be thrown when the class of a + * parser factory specified in the system properties cannot be found + * or instantiated. + * + * @author Jeff Suttor + * @version $Revision: 1.7 $, $Date: 2010-11-01 04:36:09 $ + */ + +public class FactoryConfigurationError extends Error { + private static final long serialVersionUID = -827108682472263355L; + + /** + *Exception that represents the error. + */ + private Exception exception; + + /** + * Create a new FactoryConfigurationError with no + * detail mesage. + */ + + public FactoryConfigurationError() { + super(); + this.exception = null; + } + + /** + * Create a new FactoryConfigurationError with + * the String specified as an error message. + * + * @param msg The error message for the exception. + */ + + public FactoryConfigurationError(String msg) { + super(msg); + this.exception = null; + } + + + /** + * Create a new FactoryConfigurationError with a + * given Exception base cause of the error. + * + * @param e The exception to be encapsulated in a + * FactoryConfigurationError. + */ + + public FactoryConfigurationError(Exception e) { + super(e.toString()); + this.exception = e; + } + + /** + * Create a new FactoryConfigurationError with the + * given Exception base cause and detail message. + * + * @param e The exception to be encapsulated in a + * FactoryConfigurationError + * @param msg The detail message. + */ + + public FactoryConfigurationError(Exception e, String msg) { + super(msg); + this.exception = e; + } + + + /** + * Return the message (if any) for this error . If there is no + * message for the exception and there is an encapsulated + * exception then the message of that exception, if it exists will be + * returned. Else the name of the encapsulated exception will be + * returned. + * + * @return The error message. + */ + + public String getMessage () { + String message = super.getMessage (); + + if (message == null && exception != null) { + return exception.getMessage(); + } + + return message; + } + + /** + * Return the actual exception (if any) that caused this exception to + * be raised. + * + * @return The encapsulated exception, or null if there is none. + */ + + public Exception getException () { + return exception; + } + + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/FactoryFinder.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/FactoryFinder.java new file mode 100644 index 000000000..43a6e020a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/FactoryFinder.java @@ -0,0 +1,356 @@ +/* + * Copyright (c) 2003, 2006, 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 javax.xml.parsers; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.Properties; + +/** + *

      Implements pluggable Datatypes.

      + * + *

      This class is duplicated for each JAXP subpackage so keep it in + * sync. It is package private for secure class loading.

      + * + * @author Santiago.PericasGeertsen@sun.com + * @author Huizhe.Wang@oracle.com + */ +class FactoryFinder { + + /** + * Internal debug flag. + */ + private static boolean debug = false; + + /** + * Cache for properties in java.home/lib/jaxp.properties + */ + static Properties cacheProps = new Properties(); + + /** + * Flag indicating if properties from java.home/lib/jaxp.properties + * have been cached. + */ + static volatile boolean firstTime = true; + + /** + * Security support class use to check access control before + * getting certain system resources. + */ + static SecuritySupport ss = new SecuritySupport(); + + // Define system property "jaxp.debug" to get output + static { + // Use try/catch block to support applets, which throws + // SecurityException out of this code. + try { + String val = ss.getSystemProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); + } + catch (SecurityException se) { + debug = false; + } + } + + private static void dPrint(String msg) { + if (debug) { + System.err.println("JAXP: " + msg); + } + } + + /** + * Attempt to load a class using the class loader supplied. If that fails + * and fall back is enabled, the current (i.e. bootstrap) class loader is + * tried. + * + * If the class loader supplied is null, first try using the + * context class loader followed by the current (i.e. bootstrap) class + * loader. + * + * Use bootstrap classLoader if cl = null and useBSClsLoader is true + */ + static private Class getProviderClass(String className, ClassLoader cl, + boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException + { + try { + if (cl == null) { + if (useBSClsLoader) { + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } else { + cl = ss.getContextClassLoader(); + if (cl == null) { + throw new ClassNotFoundException(); + } + else { + return cl.loadClass(className); + } + } + } + else { + return cl.loadClass(className); + } + } + catch (ClassNotFoundException e1) { + if (doFallback) { + // Use current class loader - should always be bootstrap CL + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } + else { + throw e1; + } + } + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback) + throws ConfigurationError + { + return newInstance(className, cl, doFallback, false); + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + * + * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter + * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader) + throws ConfigurationError + { + try { + Class providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); + Object instance = providerClass.newInstance(); + if (debug) { // Extra check to avoid computing cl strings + dPrint("created new instance of " + providerClass + + " using ClassLoader: " + cl); + } + return instance; + } + catch (ClassNotFoundException x) { + throw new ConfigurationError( + "Provider " + className + " not found", x); + } + catch (Exception x) { + throw new ConfigurationError( + "Provider " + className + " could not be instantiated: " + x, + x); + } + } + + /** + * Finds the implementation Class object in the specified order. Main + * entry point. + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * Package private so this code can be shared. + */ + static Object find(String factoryId, String fallbackClassName) + throws ConfigurationError + { + dPrint("find factoryId =" + factoryId); + + // Use the system property first + try { + String systemProp = ss.getSystemProperty(factoryId); + if (systemProp != null) { + dPrint("found system property, value=" + systemProp); + return newInstance(systemProp, null, true); + } + } + catch (SecurityException se) { + if (debug) se.printStackTrace(); + } + + // try to read from $java.home/lib/jaxp.properties + try { + String factoryClassName = null; + if (firstTime) { + synchronized (cacheProps) { + if (firstTime) { + String configFile = ss.getSystemProperty("java.home") + File.separator + + "lib" + File.separator + "jaxp.properties"; + File f = new File(configFile); + firstTime = false; + if (ss.doesFileExist(f)) { + dPrint("Read properties file "+f); + cacheProps.load(ss.getFileInputStream(f)); + } + } + } + } + factoryClassName = cacheProps.getProperty(factoryId); + + if (factoryClassName != null) { + dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName); + return newInstance(factoryClassName, null, true); + } + } + catch (Exception ex) { + if (debug) ex.printStackTrace(); + } + + // Try Jar Service Provider Mechanism + Object provider = findJarServiceProvider(factoryId); + if (provider != null) { + return provider; + } + if (fallbackClassName == null) { + throw new ConfigurationError( + "Provider for " + factoryId + " cannot be found", null); + } + + dPrint("loaded from fallback value: " + fallbackClassName); + return newInstance(fallbackClassName, null, true); + } + + /* + * Try to find provider using Jar Service Provider Mechanism + * + * @return instance of provider class if found or null + */ + private static Object findJarServiceProvider(String factoryId) + throws ConfigurationError + { + String serviceId = "META-INF/services/" + factoryId; + InputStream is = null; + + // First try the Context ClassLoader + ClassLoader cl = ss.getContextClassLoader(); + boolean useBSClsLoader = false; + if (cl != null) { + is = ss.getResourceAsStream(cl, serviceId); + + // If no provider found then try the current ClassLoader + if (is == null) { + cl = FactoryFinder.class.getClassLoader(); + is = ss.getResourceAsStream(cl, serviceId); + useBSClsLoader = true; + } + } else { + // No Context ClassLoader, try the current ClassLoader + cl = FactoryFinder.class.getClassLoader(); + is = ss.getResourceAsStream(cl, serviceId); + useBSClsLoader = true; + } + + if (is == null) { + // No provider found + return null; + } + + if (debug) { // Extra check to avoid computing cl strings + dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl); + } + + BufferedReader rd; + try { + rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); + } + catch (java.io.UnsupportedEncodingException e) { + rd = new BufferedReader(new InputStreamReader(is)); + } + + String factoryClassName = null; + try { + // XXX Does not handle all possible input as specified by the + // Jar Service Provider specification + factoryClassName = rd.readLine(); + rd.close(); + } catch (IOException x) { + // No provider found + return null; + } + + if (factoryClassName != null && !"".equals(factoryClassName)) { + dPrint("found in resource, value=" + factoryClassName); + + // Note: here we do not want to fall back to the current + // ClassLoader because we want to avoid the case where the + // resource file was found using one ClassLoader and the + // provider class was instantiated using a different one. + return newInstance(factoryClassName, cl, false, useBSClsLoader); + } + + // No provider found + return null; + } + + static class ConfigurationError extends Error { + private Exception exception; + + /** + * Construct a new instance with the specified detail string and + * exception. + */ + ConfigurationError(String msg, Exception x) { + super(msg); + this.exception = x; + } + + Exception getException() { + return exception; + } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/ParserConfigurationException.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/ParserConfigurationException.java index 029e52f95..0467ca0e3 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/ParserConfigurationException.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/ParserConfigurationException.java @@ -1,10 +1,56 @@ -package javax.xml.parsers; - -public class ParserConfigurationException extends Exception { - public ParserConfigurationException() { - super(); - } - public ParserConfigurationException(String msg) { - super(msg); - } -} +/* + * Copyright (c) 2000, 2005, 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 javax.xml.parsers; + +/** + * Indicates a serious configuration error. + * + * @author Jeff Suttor + */ + +public class ParserConfigurationException extends Exception { + + /** + * Create a new ParserConfigurationException with no + * detail mesage. + */ + + public ParserConfigurationException() { + super(); + } + + /** + * Create a new ParserConfigurationException with + * the String specified as an error message. + * + * @param msg The error message for the exception. + */ + + public ParserConfigurationException(String msg) { + super(msg); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParser.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParser.java index 20a131d0c..b01b64d32 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParser.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParser.java @@ -1,22 +1,534 @@ -// SAX parser factory. -// No warranty; no copyright -- use this as you will. -// $Id: ParserFactory.java,v 1.5 1998/05/01 20:58:23 david Exp $ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.parsers; -import javax.xml.sax.Parser; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; + +import javax.xml.validation.Schema; +import org.xml.sax.HandlerBase; +import org.xml.sax.InputSource; +import org.xml.sax.Parser; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; import org.xml.sax.XMLReader; +import org.xml.sax.helpers.DefaultHandler; + /** - * Just an interface to fill in for the JavaScript version - * - * @author Bob Hanson + * Defines the API that wraps an {@link org.xml.sax.XMLReader} + * implementation class. In JAXP 1.0, this class wrapped the + * {@link org.xml.sax.Parser} interface, however this interface was + * replaced by the {@link org.xml.sax.XMLReader}. For ease + * of transition, this class continues to support the same name + * and interface as well as supporting new methods. + * + * An instance of this class can be obtained from the + * {@link javax.xml.parsers.SAXParserFactory#newSAXParser()} method. + * Once an instance of this class is obtained, XML can be parsed from + * a variety of input sources. These input sources are InputStreams, + * Files, URLs, and SAX InputSources.

      + * + * This static method creates a new factory instance based + * on a system property setting or uses the platform default + * if no property has been defined.

      + * + * The system property that controls which Factory implementation + * to create is named "javax.xml.parsers.SAXParserFactory". + * This property names a class that is a concrete subclass of this + * abstract class. If no property is defined, a platform default + * will be used.

      + * + * As the content is parsed by the underlying parser, methods of the + * given {@link org.xml.sax.HandlerBase} or the + * {@link org.xml.sax.helpers.DefaultHandler} are called.

      + * + * Implementors of this class which wrap an underlaying implementation + * can consider using the {@link org.xml.sax.helpers.ParserAdapter} + * class to initially adapt their SAX1 implementation to work under + * this revised class. * + * @author Jeff Suttor */ -@SuppressWarnings("deprecation") -public abstract class SAXParser implements Parser { +public abstract class SAXParser { - public abstract XMLReader getXMLReader(); -} + /** + *

      Protected constructor to prevent instaniation. + * Use {@link javax.xml.parsers.SAXParserFactory#newSAXParser()}.

      + */ + protected SAXParser () { + + } + + /** + *

      Reset this SAXParser to its original configuration.

      + * + *

      SAXParser is reset to the same state as when it was created with + * {@link SAXParserFactory#newSAXParser()}. + * reset() is designed to allow the reuse of existing SAXParsers + * thus saving resources associated with the creation of new SAXParsers.

      + * + *

      The reset SAXParser is not guaranteed to have the same {@link Schema} + * Object, e.g. {@link Object#equals(Object obj)}. It is guaranteed to have a functionally equal + * Schema.

      + * + * @throws UnsupportedOperationException When Implementations do not + * override this method + * + * @since 1.5 + */ + public void reset() { + + // implementors should override this method + throw new UnsupportedOperationException( + "This SAXParser, \"" + this.getClass().getName() + "\", does not support the reset functionality." + + // + " Specification \"" + this.getClass().getPackage().getSpecificationTitle() + "\"" + // + " version \"" + this.getClass().getPackage().getSpecificationVersion() + "\"" + ); + } + + /** + *

      Parse the content of the given {@link java.io.InputStream} + * instance as XML using the specified {@link org.xml.sax.HandlerBase}. + * Use of the DefaultHandler version of this method is recommended as + * the HandlerBase class has been deprecated in SAX 2.0.

      + * + * @param is InputStream containing the content to be parsed. + * @param hb The SAX HandlerBase to use. + * + * @throws IllegalArgumentException If the given InputStream is null. + * @throws SAXException If parse produces a SAX error. + * @throws IOException If an IO error occurs interacting with the + * InputStream. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(InputStream is, HandlerBase hb) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputStream cannot be null"); + } + + InputSource input = new InputSource(is); + this.parse(input, hb); + } + + /** + *

      Parse the content of the given {@link java.io.InputStream} + * instance as XML using the specified {@link org.xml.sax.HandlerBase}. + * Use of the DefaultHandler version of this method is recommended as + * the HandlerBase class has been deprecated in SAX 2.0.

      + * + * @param is InputStream containing the content to be parsed. + * @param hb The SAX HandlerBase to use. + * @param systemId The systemId which is needed for resolving relative URIs. + * + * @throws IllegalArgumentException If the given InputStream is + * null. + * @throws IOException If any IO error occurs interacting with the + * InputStream. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler version of this method instead. + */ + public void parse( + InputStream is, + HandlerBase hb, + String systemId) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputStream cannot be null"); + } + + InputSource input = new InputSource(is); + input.setSystemId(systemId); + this.parse(input, hb); + } + + /** + * Parse the content of the given {@link java.io.InputStream} + * instance as XML using the specified + * {@link org.xml.sax.helpers.DefaultHandler}. + * + * @param is InputStream containing the content to be parsed. + * @param dh The SAX DefaultHandler to use. + * + * @throws IllegalArgumentException If the given InputStream is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(InputStream is, DefaultHandler dh) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputStream cannot be null"); + } + + InputSource input = new InputSource(is); + this.parse(input, dh); + } + + /** + * Parse the content of the given {@link java.io.InputStream} + * instance as XML using the specified + * {@link org.xml.sax.helpers.DefaultHandler}. + * + * @param is InputStream containing the content to be parsed. + * @param dh The SAX DefaultHandler to use. + * @param systemId The systemId which is needed for resolving relative URIs. + * + * @throws IllegalArgumentException If the given InputStream is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler version of this method instead. + */ + public void parse( + InputStream is, + DefaultHandler dh, + String systemId) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputStream cannot be null"); + } + + InputSource input = new InputSource(is); + input.setSystemId(systemId); + this.parse(input, dh); + } + /** + * Parse the content described by the giving Uniform Resource + * Identifier (URI) as XML using the specified + * {@link org.xml.sax.HandlerBase}. + * Use of the DefaultHandler version of this method is recommended as + * the HandlerBase class has been deprecated in SAX 2.0 + * + * @param uri The location of the content to be parsed. + * @param hb The SAX HandlerBase to use. + * + * @throws IllegalArgumentException If the uri is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(String uri, HandlerBase hb) + throws SAXException, IOException { + if (uri == null) { + throw new IllegalArgumentException("uri cannot be null"); + } + + InputSource input = new InputSource(uri); + this.parse(input, hb); + } + + /** + * Parse the content described by the giving Uniform Resource + * Identifier (URI) as XML using the specified + * {@link org.xml.sax.helpers.DefaultHandler}. + * + * @param uri The location of the content to be parsed. + * @param dh The SAX DefaultHandler to use. + * + * @throws IllegalArgumentException If the uri is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(String uri, DefaultHandler dh) + throws SAXException, IOException { + if (uri == null) { + throw new IllegalArgumentException("uri cannot be null"); + } + + InputSource input = new InputSource(uri); + this.parse(input, dh); + } + + /** + * Parse the content of the file specified as XML using the + * specified {@link org.xml.sax.HandlerBase}. + * Use of the DefaultHandler version of this method is recommended as + * the HandlerBase class has been deprecated in SAX 2.0 + * + * @param f The file containing the XML to parse + * @param hb The SAX HandlerBase to use. + * + * @throws IllegalArgumentException If the File object is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(File f, HandlerBase hb) + throws SAXException, IOException { + if (f == null) { + throw new IllegalArgumentException("File cannot be null"); + } + + //convert file to appropriate URI, f.toURI().toASCIIString() + //converts the URI to string as per rule specified in + //RFC 2396, + InputSource input = new InputSource(f.toURI().toASCIIString()); + this.parse(input, hb); + } + + /** + * Parse the content of the file specified as XML using the + * specified {@link org.xml.sax.helpers.DefaultHandler}. + * + * @param f The file containing the XML to parse + * @param dh The SAX DefaultHandler to use. + * + * @throws IllegalArgumentException If the File object is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(File f, DefaultHandler dh) + throws SAXException, IOException { + if (f == null) { + throw new IllegalArgumentException("File cannot be null"); + } + + //convert file to appropriate URI, f.toURI().toASCIIString() + //converts the URI to string as per rule specified in + //RFC 2396, + InputSource input = new InputSource(f.toURI().toASCIIString()); + this.parse(input, dh); + } + + /** + * Parse the content given {@link org.xml.sax.InputSource} + * as XML using the specified + * {@link org.xml.sax.HandlerBase}. + * Use of the DefaultHandler version of this method is recommended as + * the HandlerBase class has been deprecated in SAX 2.0 + * + * @param is The InputSource containing the content to be parsed. + * @param hb The SAX HandlerBase to use. + * + * @throws IllegalArgumentException If the InputSource object + * is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(InputSource is, HandlerBase hb) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputSource cannot be null"); + } + + Parser parser = this.getParser(); + if (hb != null) { + parser.setDocumentHandler(hb); + parser.setEntityResolver(hb); + parser.setErrorHandler(hb); + parser.setDTDHandler(hb); + } + parser.parse(is); + } + + /** + * Parse the content given {@link org.xml.sax.InputSource} + * as XML using the specified + * {@link org.xml.sax.helpers.DefaultHandler}. + * + * @param is The InputSource containing the content to be parsed. + * @param dh The SAX DefaultHandler to use. + * + * @throws IllegalArgumentException If the InputSource object + * is null. + * @throws IOException If any IO errors occur. + * @throws SAXException If any SAX errors occur during processing. + * + * @see org.xml.sax.DocumentHandler + */ + public void parse(InputSource is, DefaultHandler dh) + throws SAXException, IOException { + if (is == null) { + throw new IllegalArgumentException("InputSource cannot be null"); + } + + XMLReader reader = this.getXMLReader(); + if (dh != null) { + reader.setContentHandler(dh); + reader.setEntityResolver(dh); + reader.setErrorHandler(dh); + reader.setDTDHandler(dh); + } + reader.parse(is); + } + + /** + * Returns the SAX parser that is encapsultated by the + * implementation of this class. + * + * @return The SAX parser that is encapsultated by the + * implementation of this class. + * + * @throws SAXException If any SAX errors occur during processing. + */ + public abstract org.xml.sax.Parser getParser() throws SAXException; + + /** + * Returns the {@link org.xml.sax.XMLReader} that is encapsulated by the + * implementation of this class. + * + * @return The XMLReader that is encapsulated by the + * implementation of this class. + * + * @throws SAXException If any SAX errors occur during processing. + */ + + public abstract org.xml.sax.XMLReader getXMLReader() throws SAXException; + + /** + * Indicates whether or not this parser is configured to + * understand namespaces. + * + * @return true if this parser is configured to + * understand namespaces; false otherwise. + */ + + public abstract boolean isNamespaceAware(); + + /** + * Indicates whether or not this parser is configured to + * validate XML documents. + * + * @return true if this parser is configured to + * validate XML documents; false otherwise. + */ + + public abstract boolean isValidating(); + + /** + *

      Sets the particular property in the underlying implementation of + * {@link org.xml.sax.XMLReader}. + * A list of the core features and properties can be found at + * + * http://sax.sourceforge.net/?selected=get-set.

      + * + * @param name The name of the property to be set. + * @param value The value of the property to be set. + * + * @throws SAXNotRecognizedException When the underlying XMLReader does + * not recognize the property name. + * @throws SAXNotSupportedException When the underlying XMLReader + * recognizes the property name but doesn't support the property. + * + * @see org.xml.sax.XMLReader#setProperty + */ + public abstract void setProperty(String name, Object value) + throws SAXNotRecognizedException, SAXNotSupportedException; + + /** + *

      Returns the particular property requested for in the underlying + * implementation of {@link org.xml.sax.XMLReader}.

      + * + * @param name The name of the property to be retrieved. + * @return Value of the requested property. + * + * @throws SAXNotRecognizedException When the underlying XMLReader does + * not recognize the property name. + * @throws SAXNotSupportedException When the underlying XMLReader + * recognizes the property name but doesn't support the property. + * + * @see org.xml.sax.XMLReader#getProperty + */ + public abstract Object getProperty(String name) + throws SAXNotRecognizedException, SAXNotSupportedException; + + /**

      Get current state of canonicalization.

      + * + * @return current state canonicalization control + */ + /* + public boolean getCanonicalization() { + return canonicalState; + } + */ + + /**

      Get a reference to the the {@link Schema} being used by + * the XML processor.

      + * + *

      If no schema is being used, null is returned.

      + * + * @return {@link Schema} being used or null + * if none in use + * + * @throws UnsupportedOperationException When implementation does not + * override this method + * + * @since 1.5 + */ + public Schema getSchema() { + throw new UnsupportedOperationException( + "This parser does not support specification \"" +// + this.getClass().getPackage().getSpecificationTitle() +// + "\" version \"" +// + this.getClass().getPackage().getSpecificationVersion() + + "\"" + ); + } + + /** + *

      Get the XInclude processing mode for this parser.

      + * + * @return + * the return value of + * the {@link SAXParserFactory#isXIncludeAware()} + * when this parser was created from factory. + * + * @throws UnsupportedOperationException When implementation does not + * override this method + * + * @since 1.5 + * + * @see SAXParserFactory#setXIncludeAware(boolean) + */ + public boolean isXIncludeAware() { + throw new UnsupportedOperationException( + "This parser does not support specification \"" +// + this.getClass().getPackage().getSpecificationTitle() +// + "\" version \"" +// + this.getClass().getPackage().getSpecificationVersion() + + "\"" + ); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParserFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParserFactory.java index c87adb1a2..bc9c6f5b8 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParserFactory.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SAXParserFactory.java @@ -17,6 +17,8 @@ import javax.xml.validation.Schema; import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; /** * @@ -177,8 +179,11 @@ public static Parser makeParser(String className) * * @param name * @return + * @throws SAXNotSupportedException + * @throws SAXNotRecognizedException + * @throws ParserConfigurationException */ - public boolean getFeature(String name) { + public boolean getFeature(String name) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { return props.getProperty(name, "false").equals("true"); } @@ -221,7 +226,7 @@ public boolean isXIncludeAware() { return xIncludeAware; } - public void setFeature(String name, boolean value) { + public void setFeature(String name, boolean value) throws ParserConfigurationException, SAXNotRecognizedException, SAXNotSupportedException { props.setProperty(name, "" + value); } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SecuritySupport.java b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SecuritySupport.java new file mode 100644 index 000000000..cfcd708b0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/parsers/SecuritySupport.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2004, 2006, 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 javax.xml.parsers; + +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.InputStream; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +/** + * This class is duplicated for each JAXP subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of the JAXP + * API. + * + * Security related methods that only work on J2SE 1.2 and newer. + */ +class SecuritySupport { + + + ClassLoader getContextClassLoader() throws SecurityException{ + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + //try { + cl = Thread.currentThread().getContextClassLoader(); + //} catch (SecurityException ex) { } + + if (cl == null) + cl = ClassLoader.getSystemClassLoader(); + + return cl; + } + }); + } + + String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + FileInputStream getFileInputStream(final File file) + throws FileNotFoundException + { + try { + return (FileInputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws FileNotFoundException { + return new FileInputStream(file); + } + }); + } catch (PrivilegedActionException e) { + throw (FileNotFoundException)e.getException(); + } + } + + InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + boolean doesFileExist(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Boolean(f.exists()); + } + })).booleanValue(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/sax/helpers/package.html b/sources/net.sf.j2s.java.core/src/javax/xml/sax/helpers/package.html deleted file mode 100644 index 8f323c05e..000000000 --- a/sources/net.sf.j2s.java.core/src/javax/xml/sax/helpers/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - -

      This package contains "helper" classes, including -support for bootstrapping SAX-based applications. - -

      See http://www.saxproject.org -for more information about SAX.

      - - diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/EventFilter.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/EventFilter.java new file mode 100644 index 000000000..61feecbf5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/EventFilter.java @@ -0,0 +1,50 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +import javax.xml.stream.events.XMLEvent; + +/** + * This interface declares a simple filter interface that one can + * create to filter XMLEventReaders + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface EventFilter { + /** + * Tests whether this event is part of this stream. This method + * will return true if this filter accepts this event and false + * otherwise. + * + * @param event the event to test + * @return true if this filter accepts this event, false otherwise + */ + public boolean accept(XMLEvent event); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/FactoryConfigurationError.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/FactoryConfigurationError.java index 104b160cd..6192f3d4a 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/stream/FactoryConfigurationError.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/FactoryConfigurationError.java @@ -1,85 +1,125 @@ -/* FactoryConfigurationError.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. +/* + * 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. + */ -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ package javax.xml.stream; /** - * Error indicating that a factory could not be configured. + * An error class for reporting factory configuration errors. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 */ -public class FactoryConfigurationError - extends Error -{ - - private final Exception exception; - - public FactoryConfigurationError() - { - this((String) null, (Exception) null); +public class FactoryConfigurationError extends Error { + private static final long serialVersionUID = -2994412584589975744L; + + Exception nested; + + /** + * Default constructor + */ + public FactoryConfigurationError(){} + + /** + * Construct an exception with a nested inner exception + * + * @param e the exception to nest + */ + public FactoryConfigurationError(java.lang.Exception e){ + nested = e; } - public FactoryConfigurationError(Exception e) - { - this(e, null); + /** + * Construct an exception with a nested inner exception + * and a message + * + * @param e the exception to nest + * @param msg the message to report + */ + public FactoryConfigurationError(java.lang.Exception e, java.lang.String msg){ + super(msg); + nested = e; } - public FactoryConfigurationError(Exception e, String msg) - { + /** + * Construct an exception with a nested inner exception + * and a message + * + * @param msg the message to report + * @param e the exception to nest + */ + public FactoryConfigurationError(java.lang.String msg, java.lang.Exception e){ super(msg); - exception = e; + nested = e; } - public FactoryConfigurationError(String msg, Exception e) - { - this(e, msg); + /** + * Construct an exception with associated message + * + * @param msg the message to report + */ + public FactoryConfigurationError(java.lang.String msg) { + super(msg); } - public FactoryConfigurationError(String msg) - { - this(null, msg); + /** + * Return the nested exception (if any) + * + * @return the nested exception or null + */ + public Exception getException() { + return nested; } - - public Exception getException() - { - return exception; + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return nested; + } + + /** + * Report the message associated with this error + * + * @return the string value of the message + */ + public String getMessage() { + String msg = super.getMessage(); + if(msg != null) + return msg; + if(nested != null){ + msg = nested.getMessage(); + if(msg == null) + msg = nested.getClass().toString(); + } + return msg; } - public String getMessage() - { - return super.getMessage(); - } + } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/FactoryFinder.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/FactoryFinder.java new file mode 100644 index 000000000..a2491ac8c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/FactoryFinder.java @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2005, 2006, 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 javax.xml.stream; + +import java.io.InputStream; +import java.io.IOException; +import java.io.File; +import java.io.FileInputStream; + +import java.util.Properties; +import java.io.BufferedReader; +import java.io.InputStreamReader; + +/** + *

      Implements pluggable Datatypes.

      + * + *

      This class is duplicated for each JAXP subpackage so keep it in + * sync. It is package private for secure class loading.

      + * + * @author Santiago.PericasGeertsen@sun.com + */ +class FactoryFinder { + + /** + * Internal debug flag. + */ + private static boolean debug = false; + + /** + * Cache for properties in java.home/lib/jaxp.properties + */ + static Properties cacheProps = new Properties(); + + /** + * Flag indicating if properties from java.home/lib/jaxp.properties + * have been cached. + */ + static volatile boolean firstTime = true; + + /** + * Security support class use to check access control before + * getting certain system resources. + */ + static SecuritySupport ss = new SecuritySupport(); + + // Define system property "jaxp.debug" to get output + static { + // Use try/catch block to support applets, which throws + // SecurityException out of this code. + try { + String val = ss.getSystemProperty("jaxp.debug"); + // Allow simply setting the prop to turn on debug + debug = val != null && !"false".equals(val); + } + catch (SecurityException se) { + debug = false; + } + } + + private static void dPrint(String msg) { + if (debug) { + System.err.println("JAXP: " + msg); + } + } + + /** + * Attempt to load a class using the class loader supplied. If that fails + * and fall back is enabled, the current (i.e. bootstrap) class loader is + * tried. + * + * If the class loader supplied is null, first try using the + * context class loader followed by the current (i.e. bootstrap) class + * loader. + */ + static private Class getProviderClass(String className, ClassLoader cl, + boolean doFallback) throws ClassNotFoundException + { + try { + if (cl == null) { + cl = ss.getContextClassLoader(); + if (cl == null) { + throw new ClassNotFoundException(); + } + else { + return cl.loadClass(className); + } + } + else { + return cl.loadClass(className); + } + } + catch (ClassNotFoundException e1) { + if (doFallback) { + // Use current class loader - should always be bootstrap CL + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } + else { + throw e1; + } + } + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader to use to load the class, null means to use + * the bootstrap ClassLoader + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback) + throws ConfigurationError + { + try { + Class providerClass = getProviderClass(className, cl, doFallback); + Object instance = providerClass.newInstance(); + if (debug) { // Extra check to avoid computing cl strings + dPrint("created new instance of " + providerClass + + " using ClassLoader: " + cl); + } + return instance; + } + catch (ClassNotFoundException x) { + throw new ConfigurationError( + "Provider " + className + " not found", x); + } + catch (Exception x) { + throw new ConfigurationError( + "Provider " + className + " could not be instantiated: " + x, + x); + } + } + + /** + * Finds the implementation Class object in the specified order. + * + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * Package private so this code can be shared. + */ + static Object find(String factoryId, String fallbackClassName) + throws ConfigurationError + { + return find(factoryId, null, fallbackClassName); + } + + /** + * Finds the implementation Class object in the specified order. Main + * entry point. + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * + * @param cl ClassLoader to be used to load the class, null means to use + * the bootstrap ClassLoader + * + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * Package private so this code can be shared. + */ + static Object find(String factoryId, ClassLoader cl, String fallbackClassName) + throws ConfigurationError + { + dPrint("find factoryId =" + factoryId); + + // Use the system property first + try { + String systemProp = ss.getSystemProperty(factoryId); + if (systemProp != null) { + dPrint("found system property, value=" + systemProp); + return newInstance(systemProp, null, true); + } + } + catch (SecurityException se) { + if (debug) se.printStackTrace(); + } + + // Try read $java.home/lib/stax.properties followed by + // $java.home/lib/jaxp.properties if former not present + String configFile = null; + try { + String factoryClassName = null; + if (firstTime) { + synchronized (cacheProps) { + if (firstTime) { + configFile = ss.getSystemProperty("java.home") + File.separator + + "lib" + File.separator + "stax.properties"; + File f = new File(configFile); + firstTime = false; + if (ss.doesFileExist(f)) { + dPrint("Read properties file "+f); + cacheProps.load(ss.getFileInputStream(f)); + } + else { + configFile = ss.getSystemProperty("java.home") + File.separator + + "lib" + File.separator + "jaxp.properties"; + f = new File(configFile); + if (ss.doesFileExist(f)) { + dPrint("Read properties file "+f); + cacheProps.load(ss.getFileInputStream(f)); + } + } + } + } + } + factoryClassName = cacheProps.getProperty(factoryId); + + if (factoryClassName != null) { + dPrint("found in " + configFile + " value=" + factoryClassName); + return newInstance(factoryClassName, null, true); + } + } + catch (Exception ex) { + if (debug) ex.printStackTrace(); + } + + // Try Jar Service Provider Mechanism + Object provider = findJarServiceProvider(factoryId); + if (provider != null) { + return provider; + } + if (fallbackClassName == null) { + throw new ConfigurationError( + "Provider for " + factoryId + " cannot be found", null); + } + + dPrint("loaded from fallback value: " + fallbackClassName); + return newInstance(fallbackClassName, cl, true); + } + + /* + * Try to find provider using Jar Service Provider Mechanism + * + * @return instance of provider class if found or null + */ + private static Object findJarServiceProvider(String factoryId) + throws ConfigurationError + { + String serviceId = "META-INF/services/" + factoryId; + InputStream is = null; + + // First try the Context ClassLoader + ClassLoader cl = ss.getContextClassLoader(); + if (cl != null) { + is = ss.getResourceAsStream(cl, serviceId); + + // If no provider found then try the current ClassLoader + if (is == null) { + cl = FactoryFinder.class.getClassLoader(); + is = ss.getResourceAsStream(cl, serviceId); + } + } else { + // No Context ClassLoader, try the current ClassLoader + cl = FactoryFinder.class.getClassLoader(); + is = ss.getResourceAsStream(cl, serviceId); + } + + if (is == null) { + // No provider found + return null; + } + + if (debug) { // Extra check to avoid computing cl strings + dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl); + } + + BufferedReader rd; + try { + rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); + } + catch (java.io.UnsupportedEncodingException e) { + rd = new BufferedReader(new InputStreamReader(is)); + } + + String factoryClassName = null; + try { + // XXX Does not handle all possible input as specified by the + // Jar Service Provider specification + factoryClassName = rd.readLine(); + rd.close(); + } catch (IOException x) { + // No provider found + return null; + } + + if (factoryClassName != null && !"".equals(factoryClassName)) { + dPrint("found in resource, value=" + factoryClassName); + + // Note: here we do not want to fall back to the current + // ClassLoader because we want to avoid the case where the + // resource file was found using one ClassLoader and the + // provider class was instantiated using a different one. + return newInstance(factoryClassName, cl, false); + } + + // No provider found + return null; + } + + static class ConfigurationError extends Error { + private Exception exception; + + /** + * Construct a new instance with the specified detail string and + * exception. + */ + ConfigurationError(String msg, Exception x) { + super(msg); + this.exception = x; + } + + Exception getException() { + return exception; + } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/Location.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/Location.java index fd5c8c6d7..74a25f37f 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/stream/Location.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/Location.java @@ -1,25 +1,25 @@ /* - * ORACLE PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * + * 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. */ /* diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/SecuritySupport.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/SecuritySupport.java new file mode 100644 index 000000000..500aa9af1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/SecuritySupport.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2006, 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 javax.xml.stream; + +import java.security.*; +import java.net.*; +import java.io.*; +import java.util.*; + +/** + * This class is duplicated for each JAXP subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of the JAXP + * API. + * + * Security related methods that only work on J2SE 1.2 and newer. + */ +class SecuritySupport { + + + ClassLoader getContextClassLoader() throws SecurityException{ + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + //try { + cl = Thread.currentThread().getContextClassLoader(); + //} catch (SecurityException ex) { } + + if (cl == null) + cl = ClassLoader.getSystemClassLoader(); + + return cl; + } + }); + } + + String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + FileInputStream getFileInputStream(final File file) + throws FileNotFoundException + { + try { + return (FileInputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws FileNotFoundException { + return new FileInputStream(file); + } + }); + } catch (PrivilegedActionException e) { + throw (FileNotFoundException)e.getException(); + } + } + + InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + boolean doesFileExist(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Boolean(f.exists()); + } + })).booleanValue(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/StreamFilter.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/StreamFilter.java new file mode 100644 index 000000000..d248d6dbb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/StreamFilter.java @@ -0,0 +1,51 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +/** + * This interface declares a simple filter interface that one can + * create to filter XMLStreamReaders + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface StreamFilter { + + /** + * Tests whether the current state is part of this stream. This method + * will return true if this filter accepts this event and false otherwise. + * + * The method should not change the state of the reader when accepting + * a state. + * + * @param reader the event to test + * @return true if this filter accepts this event, false otherwise + */ + public boolean accept(XMLStreamReader reader); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventFactory.java new file mode 100644 index 000000000..9f9e86ef8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventFactory.java @@ -0,0 +1,412 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; +import javax.xml.stream.events.*; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; +import java.util.Iterator; +/** + * This interface defines a utility class for creating instances of + * XMLEvents + * @version 1.2 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see javax.xml.stream.events.StartElement + * @see javax.xml.stream.events.EndElement + * @see javax.xml.stream.events.ProcessingInstruction + * @see javax.xml.stream.events.Comment + * @see javax.xml.stream.events.Characters + * @see javax.xml.stream.events.StartDocument + * @see javax.xml.stream.events.EndDocument + * @see javax.xml.stream.events.DTD + * @since 1.6 + */ +public abstract class XMLEventFactory { + protected XMLEventFactory(){} + + /** + * Create a new instance of the factory + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLEventFactory newInstance() + throws FactoryConfigurationError + { + return (XMLEventFactory) FactoryFinder.find( + "javax.xml.stream.XMLEventFactory", + "com.sun.xml.internal.stream.events.XMLEventFactoryImpl"); + } + + /** + * Create a new instance of the factory. + * This static method creates a new factory instance. + * This method uses the following ordered lookup procedure to determine + * the XMLEventFactory implementation class to load: + * Use the javax.xml.stream.XMLEventFactory system property. + * Use the properties file "lib/stax.properties" in the JRE directory. + * This configuration file is in standard java.util.Properties format + * and contains the fully qualified name of the implementation class + * with the key being the system property defined above. + * Use the Services API (as detailed in the JAR specification), if available, + * to determine the classname. The Services API will look for a classname + * in the file META-INF/services/javax.xml.stream.XMLEventFactory in jars + * available to the runtime. + * Platform default XMLEventFactory instance. + * + * Once an application has obtained a reference to a XMLEventFactory it + * can use the factory to configure and obtain stream instances. + * + * Note that this is a new method that replaces the deprecated newInstance() method. + * No changes in behavior are defined by this replacement method relative to + * the deprecated method. + * + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLEventFactory newFactory() + throws FactoryConfigurationError + { + return (XMLEventFactory) FactoryFinder.find( + "javax.xml.stream.XMLEventFactory", + "com.sun.xml.internal.stream.events.XMLEventFactoryImpl"); + } + + /** + * Create a new instance of the factory + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param classLoader classLoader to use + * @return the factory implementation + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + * + * @deprecated This method has been deprecated to maintain API consistency. + * All newInstance methods have been replaced with corresponding + * newFactory methods. The replacement {@link + * #newFactory(java.lang.String, java.lang.ClassLoader)} + * method defines no changes in behavior. + */ + public static XMLEventFactory newInstance(String factoryId, + ClassLoader classLoader) + throws FactoryConfigurationError { + try { + //do not fallback if given classloader can't find the class, throw exception + return (XMLEventFactory) FactoryFinder.newInstance(factoryId, classLoader, false); + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + } + + /** + * Create a new instance of the factory. + * If the classLoader argument is null, then the ContextClassLoader is used. + * + * Note that this is a new method that replaces the deprecated + * newInstance(String factoryId, ClassLoader classLoader) method. + * No changes in behavior are defined by this replacement method relative + * to the deprecated method. + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param classLoader classLoader to use + * @return the factory implementation + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLEventFactory newFactory(String factoryId, + ClassLoader classLoader) + throws FactoryConfigurationError { + try { + //do not fallback if given classloader can't find the class, throw exception + return (XMLEventFactory) FactoryFinder.newInstance(factoryId, classLoader, false); + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + } + + /** + * This method allows setting of the Location on each event that + * is created by this factory. The values are copied by value into + * the events created by this factory. To reset the location + * information set the location to null. + * @param location the location to set on each event created + */ + public abstract void setLocation(Location location); + + /** + * Create a new Attribute + * @param prefix the prefix of this attribute, may not be null + * @param namespaceURI the attribute value is set to this value, may not be null + * @param localName the local name of the XML name of the attribute, localName cannot be null + * @param value the attribute value to set, may not be null + * @return the Attribute with specified values + */ + public abstract Attribute createAttribute(String prefix, String namespaceURI, String localName, String value); + + /** + * Create a new Attribute + * @param localName the local name of the XML name of the attribute, localName cannot be null + * @param value the attribute value to set, may not be null + * @return the Attribute with specified values + */ + public abstract Attribute createAttribute(String localName, String value); + + /** + * Create a new Attribute + * @param name the qualified name of the attribute, may not be null + * @param value the attribute value to set, may not be null + * @return the Attribute with specified values + */ + public abstract Attribute createAttribute(QName name, String value); + + /** + * Create a new default Namespace + * @param namespaceURI the default namespace uri + * @return the Namespace with the specified value + */ + public abstract Namespace createNamespace(String namespaceURI); + + /** + * Create a new Namespace + * @param prefix the prefix of this namespace, may not be null + * @param namespaceUri the attribute value is set to this value, may not be null + * @return the Namespace with the specified values + */ + public abstract Namespace createNamespace(String prefix, String namespaceUri); + + /** + * Create a new StartElement. Namespaces can be added to this StartElement + * by passing in an Iterator that walks over a set of Namespace interfaces. + * Attributes can be added to this StartElement by passing an iterator + * that walks over a set of Attribute interfaces. + * + * @param name the qualified name of the attribute, may not be null + * @param attributes an optional unordered set of objects that + * implement Attribute to add to the new StartElement, may be null + * @param namespaces an optional unordered set of objects that + * implement Namespace to add to the new StartElement, may be null + * @return an instance of the requested StartElement + */ + public abstract StartElement createStartElement(QName name, + Iterator attributes, + Iterator namespaces); + + /** + * Create a new StartElement. This defaults the NamespaceContext to + * an empty NamespaceContext. Querying this event for its namespaces or + * attributes will result in an empty iterator being returned. + * + * @param namespaceUri the uri of the QName of the new StartElement + * @param localName the local name of the QName of the new StartElement + * @param prefix the prefix of the QName of the new StartElement + * @return an instance of the requested StartElement + */ + public abstract StartElement createStartElement(String prefix, + String namespaceUri, + String localName); + /** + * Create a new StartElement. Namespaces can be added to this StartElement + * by passing in an Iterator that walks over a set of Namespace interfaces. + * Attributes can be added to this StartElement by passing an iterator + * that walks over a set of Attribute interfaces. + * + * @param namespaceUri the uri of the QName of the new StartElement + * @param localName the local name of the QName of the new StartElement + * @param prefix the prefix of the QName of the new StartElement + * @param attributes an unordered set of objects that implement + * Attribute to add to the new StartElement + * @param namespaces an unordered set of objects that implement + * Namespace to add to the new StartElement + * @return an instance of the requested StartElement + */ + public abstract StartElement createStartElement(String prefix, + String namespaceUri, + String localName, + Iterator attributes, + Iterator namespaces + ); + /** + * Create a new StartElement. Namespaces can be added to this StartElement + * by passing in an Iterator that walks over a set of Namespace interfaces. + * Attributes can be added to this StartElement by passing an iterator + * that walks over a set of Attribute interfaces. + * + * @param namespaceUri the uri of the QName of the new StartElement + * @param localName the local name of the QName of the new StartElement + * @param prefix the prefix of the QName of the new StartElement + * @param attributes an unordered set of objects that implement + * Attribute to add to the new StartElement, may be null + * @param namespaces an unordered set of objects that implement + * Namespace to add to the new StartElement, may be null + * @param context the namespace context of this element + * @return an instance of the requested StartElement + */ + public abstract StartElement createStartElement(String prefix, + String namespaceUri, + String localName, + Iterator attributes, + Iterator namespaces, + NamespaceContext context + ); + + /** + * Create a new EndElement + * @param name the qualified name of the EndElement + * @param namespaces an optional unordered set of objects that + * implement Namespace that have gone out of scope, may be null + * @return an instance of the requested EndElement + */ + public abstract EndElement createEndElement(QName name, + Iterator namespaces); + + /** + * Create a new EndElement + * @param namespaceUri the uri of the QName of the new StartElement + * @param localName the local name of the QName of the new StartElement + * @param prefix the prefix of the QName of the new StartElement + * @return an instance of the requested EndElement + */ + public abstract EndElement createEndElement(String prefix, + String namespaceUri, + String localName); + /** + * Create a new EndElement + * @param namespaceUri the uri of the QName of the new StartElement + * @param localName the local name of the QName of the new StartElement + * @param prefix the prefix of the QName of the new StartElement + * @param namespaces an unordered set of objects that implement + * Namespace that have gone out of scope, may be null + * @return an instance of the requested EndElement + */ + public abstract EndElement createEndElement(String prefix, + String namespaceUri, + String localName, + Iterator namespaces); + + /** + * Create a Characters event, this method does not check if the content + * is all whitespace. To create a space event use #createSpace(String) + * @param content the string to create + * @return a Characters event + */ + public abstract Characters createCharacters(String content); + + /** + * Create a Characters event with the CData flag set to true + * @param content the string to create + * @return a Characters event + */ + public abstract Characters createCData(String content); + + /** + * Create a Characters event with the isSpace flag set to true + * @param content the content of the space to create + * @return a Characters event + */ + public abstract Characters createSpace(String content); + /** + * Create an ignorable space + * @param content the space to create + * @return a Characters event + */ + public abstract Characters createIgnorableSpace(String content); + + /** + * Creates a new instance of a StartDocument event + * @return a StartDocument event + */ + public abstract StartDocument createStartDocument(); + + /** + * Creates a new instance of a StartDocument event + * + * @param encoding the encoding style + * @param version the XML version + * @param standalone the status of standalone may be set to "true" or "false" + * @return a StartDocument event + */ + public abstract StartDocument createStartDocument(String encoding, + String version, + boolean standalone); + + /** + * Creates a new instance of a StartDocument event + * + * @param encoding the encoding style + * @param version the XML version + * @return a StartDocument event + */ + public abstract StartDocument createStartDocument(String encoding, + String version); + + /** + * Creates a new instance of a StartDocument event + * + * @param encoding the encoding style + * @return a StartDocument event + */ + public abstract StartDocument createStartDocument(String encoding); + + /** + * Creates a new instance of an EndDocument event + * @return an EndDocument event + */ + public abstract EndDocument createEndDocument(); + + /** Creates a new instance of a EntityReference event + * + * @param name The name of the reference + * @param declaration the declaration for the event + * @return an EntityReference event + */ + public abstract EntityReference createEntityReference(String name, + EntityDeclaration declaration); + /** + * Create a comment + * @param text The text of the comment + * a Comment event + */ + public abstract Comment createComment(String text); + + /** + * Create a processing instruction + * @param target The target of the processing instruction + * @param data The text of the processing instruction + * @return a ProcessingInstruction event + */ + public abstract ProcessingInstruction createProcessingInstruction(String target, + String data); + + /** + * Create a document type definition event + * This string contains the entire document type declaration that matches + * the doctypedecl in the XML 1.0 specification + * @param dtd the text of the document type definition + * @return a DTD event + */ + public abstract DTD createDTD(String dtd); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventReader.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventReader.java new file mode 100644 index 000000000..97d207670 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventReader.java @@ -0,0 +1,106 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +import javax.xml.stream.events.XMLEvent; + +import java.util.Iterator; + +/** + * + * This is the top level interface for parsing XML Events. It provides + * the ability to peek at the next event and returns configuration + * information through the property interface. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see XMLInputFactory + * @see XMLEventWriter + * @since 1.6 + */ +public interface XMLEventReader extends Iterator { + /** + * Get the next XMLEvent + * @see XMLEvent + * @throws XMLStreamException if there is an error with the underlying XML. + * @throws NoSuchElementException iteration has no more elements. + */ + public XMLEvent nextEvent() throws XMLStreamException; + + /** + * Check if there are more events. + * Returns true if there are more events and false otherwise. + * @return true if the event reader has more events, false otherwise + */ + public boolean hasNext(); + + /** + * Check the next XMLEvent without reading it from the stream. + * Returns null if the stream is at EOF or has no more XMLEvents. + * A call to peek() will be equal to the next return of next(). + * @see XMLEvent + * @throws XMLStreamException + */ + public XMLEvent peek() throws XMLStreamException; + + /** + * Reads the content of a text-only element. Precondition: + * the current event is START_ELEMENT. Postcondition: + * The current event is the corresponding END_ELEMENT. + * @throws XMLStreamException if the current event is not a START_ELEMENT + * or if a non text element is encountered + */ + public String getElementText() throws XMLStreamException; + + /** + * Skips any insignificant space events until a START_ELEMENT or + * END_ELEMENT is reached. If anything other than space characters are + * encountered, an exception is thrown. This method should + * be used when processing element-only content because + * the parser is not able to recognize ignorable whitespace if + * the DTD is missing or not interpreted. + * @throws XMLStreamException if anything other than space characters are encountered + */ + public XMLEvent nextTag() throws XMLStreamException; + + /** + * Get the value of a feature/property from the underlying implementation + * @param name The name of the property + * @return The value of the property + * @throws IllegalArgumentException if the property is not supported + */ + public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException; + + /** + * Frees any resources associated with this Reader. This method does not close the + * underlying input source. + * @throws XMLStreamException if there are errors freeing associated resources + */ + public void close() throws XMLStreamException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventWriter.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventWriter.java new file mode 100644 index 000000000..f389da613 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLEventWriter.java @@ -0,0 +1,256 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +import javax.xml.stream.events.*; +import javax.xml.stream.util.XMLEventConsumer; +import javax.xml.namespace.NamespaceContext; + +/** + * + * This is the top level interface for writing XML documents. + * + * Instances of this interface are not required to validate the + * form of the XML. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see XMLEventReader + * @see javax.xml.stream.events.XMLEvent + * @see javax.xml.stream.events.Characters + * @see javax.xml.stream.events.ProcessingInstruction + * @see javax.xml.stream.events.StartElement + * @see javax.xml.stream.events.EndElement + * @since 1.6 + */ +public interface XMLEventWriter extends XMLEventConsumer { + + /** + * Writes any cached events to the underlying output mechanism + * @throws XMLStreamException + */ + public void flush() throws XMLStreamException; + + /** + * Frees any resources associated with this stream + * @throws XMLStreamException + */ + public void close() throws XMLStreamException; + + /** + * Add an event to the output stream + * Adding a START_ELEMENT will open a new namespace scope that + * will be closed when the corresponding END_ELEMENT is written. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      + * Required and optional fields for events added to the writer + *
      Event TypeRequired FieldsOptional FieldsRequired Behavior
      START_ELEMENT QName name namespaces , attributes A START_ELEMENT will be written by writing the name, + * namespaces, and attributes of the event in XML 1.0 valid + * syntax for START_ELEMENTs. + * The name is written by looking up the prefix for + * the namespace uri. The writer can be configured to + * respect prefixes of QNames. If the writer is respecting + * prefixes it must use the prefix set on the QName. The + * default behavior is to lookup the value for the prefix + * on the EventWriter's internal namespace context. + * Each attribute (if any) + * is written using the behavior specified in the attribute + * section of this table. Each namespace (if any) is written + * using the behavior specified in the namespace section of this + * table. + *
      END_ELEMENT Qname name None A well formed END_ELEMENT tag is written. + * The name is written by looking up the prefix for + * the namespace uri. The writer can be configured to + * respect prefixes of QNames. If the writer is respecting + * prefixes it must use the prefix set on the QName. The + * default behavior is to lookup the value for the prefix + * on the EventWriter's internal namespace context. + * If the END_ELEMENT name does not match the START_ELEMENT + * name an XMLStreamException is thrown. + *
      ATTRIBUTE QName name , String value QName type An attribute is written using the same algorithm + * to find the lexical form as used in START_ELEMENT. + * The default is to use double quotes to wrap attribute + * values and to escape any double quotes found in the + * value. The type value is ignored. + *
      NAMESPACE String prefix, String namespaceURI, + * boolean isDefaultNamespaceDeclaration + * None A namespace declaration is written. If the + * namespace is a default namespace declaration + * (isDefault is true) then xmlns="$namespaceURI" + * is written and the prefix is optional. If + * isDefault is false, the prefix must be declared + * and the writer must prepend xmlns to the prefix + * and write out a standard prefix declaration. + *
      PROCESSING_INSTRUCTION None String target, String data The data does not need to be present and may be + * null. Target is required and many not be null. + * The writer + * will write data section + * directly after the target, + * enclosed in appropriate XML 1.0 syntax + *
      COMMENT None String comment If the comment is present (not null) it is written, otherwise an + * an empty comment is written + *
      START_DOCUMENT None String encoding , boolean standalone, String version A START_DOCUMENT event is not required to be written to the + * stream. If present the attributes are written inside + * the appropriate XML declaration syntax + *
      END_DOCUMENT None None Nothing is written to the output
      DTD String DocumentTypeDefinition None The DocumentTypeDefinition is written to the output
      + * @param event the event to be added + * @throws XMLStreamException + */ + public void add(XMLEvent event) throws XMLStreamException; + + /** + * Adds an entire stream to an output stream, + * calls next() on the inputStream argument until hasNext() returns false + * This should be treated as a convenience method that will + * perform the following loop over all the events in an + * event reader and call add on each event. + * + * @param reader the event stream to add to the output + * @throws XMLStreamException + */ + + public void add(XMLEventReader reader) throws XMLStreamException; + + /** + * Gets the prefix the uri is bound to + * @param uri the uri to look up + * @throws XMLStreamException + */ + public String getPrefix(String uri) throws XMLStreamException; + + /** + * Sets the prefix the uri is bound to. This prefix is bound + * in the scope of the current START_ELEMENT / END_ELEMENT pair. + * If this method is called before a START_ELEMENT has been written + * the prefix is bound in the root scope. + * @param prefix the prefix to bind to the uri + * @param uri the uri to bind to the prefix + * @throws XMLStreamException + */ + public void setPrefix(String prefix, String uri) throws XMLStreamException; + + /** + * Binds a URI to the default namespace + * This URI is bound + * in the scope of the current START_ELEMENT / END_ELEMENT pair. + * If this method is called before a START_ELEMENT has been written + * the uri is bound in the root scope. + * @param uri the uri to bind to the default namespace + * @throws XMLStreamException + */ + public void setDefaultNamespace(String uri) throws XMLStreamException; + + /** + * Sets the current namespace context for prefix and uri bindings. + * This context becomes the root namespace context for writing and + * will replace the current root namespace context. Subsequent calls + * to setPrefix and setDefaultNamespace will bind namespaces using + * the context passed to the method as the root context for resolving + * namespaces. + * @param context the namespace context to use for this writer + * @throws XMLStreamException + */ + public void setNamespaceContext(NamespaceContext context) + throws XMLStreamException; + + /** + * Returns the current namespace context. + * @return the current namespace context + */ + public NamespaceContext getNamespaceContext(); + + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLInputFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLInputFactory.java index 97cdd0446..48dc3675f 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLInputFactory.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLInputFactory.java @@ -1,438 +1,444 @@ -/* XMLInputFactory.java -- - Copyright (C) 2005,2006,2009 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ package javax.xml.stream; -import java.io.InputStream; -import java.io.Reader; +import javax.xml.transform.Source; +import javax.xml.stream.util.XMLEventAllocator; /** - * Factory for creating stream and event readers from various kinds of input - * source. - *

      Parameters

      - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - * - *
      NameDescriptionTypeDefaultRequired
      javax.xml.stream.isValidatingControls DTD validationBooleanBoolean.FALSEno
      javax.xml.stream.isNamespaceAwareControls namespace processing for XML 1.0BooleanBoolean.TRUEtrue is required, false is optional
      javax.xml.stream.isCoalescingControls coalescing (normalization of adjacent character data)BooleanBoolean.FALSEyes
      javax.xml.stream.isReplacingEntityReferencesControls replacement of entity references with their replacement - * textBooleanBoolean.TRUEyes
      javax.xml.stream.isSupportingExternalEntitiesControls whether to resolve external entitiesBooleannot specifiedyes
      javax.xml.stream.supportDTDControls whether to support DTDsBooleanBoolean.TRUEyes
      javax.xml.stream.reporterjavax.xml.stream.XMLReporteryes
      javax.xml.stream.resolverjavax.xml.stream.XMLResolveryes
      javax.xml.stream.allocatorjavax.xml.stream.util.XMLEventAllocatoryes
      + * Defines an abstract implementation of a factory for getting streams. + * + * The following table defines the standard properties of this specification. + * Each property varies in the level of support required by each implementation. + * The level of support required is described in the 'Required' column. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      + * Configuration parameters + *
      Property NameBehaviorReturn typeDefault ValueRequired
      javax.xml.stream.isValidatingTurns on/off implementation specific DTD validationBooleanFalseNo
      javax.xml.stream.isNamespaceAwareTurns on/off namespace processing for XML 1.0 supportBooleanTrueTrue (required) / False (optional)
      javax.xml.stream.isCoalescingRequires the processor to coalesce adjacent character dataBooleanFalseYes
      javax.xml.stream.isReplacingEntityReferencesreplace internal entity references with their replacement text and report them as charactersBooleanTrueYes
      javax.xml.stream.isSupportingExternalEntitiesResolve external parsed entitiesBooleanUnspecifiedYes
      javax.xml.stream.supportDTDUse this property to request processors that do not support DTDsBooleanTrueYes
      javax.xml.stream.reportersets/gets the impl of the XMLReporter javax.xml.stream.XMLReporterNullYes
      javax.xml.stream.resolversets/gets the impl of the XMLResolver interfacejavax.xml.stream.XMLResolverNullYes
      javax.xml.stream.allocatorsets/gets the impl of the XMLEventAllocator interfacejavax.xml.stream.util.XMLEventAllocatorNullYes
      + * + * + * @version 1.2 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see XMLOutputFactory + * @see XMLEventReader + * @see XMLStreamReader + * @see EventFilter + * @see XMLReporter + * @see XMLResolver + * @see javax.xml.stream.util.XMLEventAllocator + * @since 1.6 */ + public abstract class XMLInputFactory { + /** + * The property used to turn on/off namespace support, + * this is to support XML 1.0 documents, + * only the true setting must be supported + */ + public static final String IS_NAMESPACE_AWARE= + "javax.xml.stream.isNamespaceAware"; + + /** + * The property used to turn on/off implementation specific validation + */ + public static final String IS_VALIDATING= + "javax.xml.stream.isValidating"; + + /** + * The property that requires the parser to coalesce adjacent character data sections + */ + public static final String IS_COALESCING= + "javax.xml.stream.isCoalescing"; + + /** + * Requires the parser to replace internal + * entity references with their replacement + * text and report them as characters + */ + public static final String IS_REPLACING_ENTITY_REFERENCES= + "javax.xml.stream.isReplacingEntityReferences"; + + /** + * The property that requires the parser to resolve external parsed entities + */ + public static final String IS_SUPPORTING_EXTERNAL_ENTITIES= + "javax.xml.stream.isSupportingExternalEntities"; + + /** + * The property that requires the parser to support DTDs + */ + public static final String SUPPORT_DTD= + "javax.xml.stream.supportDTD"; + + /** + * The property used to + * set/get the implementation of the XMLReporter interface + */ + public static final String REPORTER= + "javax.xml.stream.reporter"; + + /** + * The property used to set/get the implementation of the XMLResolver + */ + public static final String RESOLVER= + "javax.xml.stream.resolver"; + + /** + * The property used to set/get the implementation of the allocator + */ + public static final String ALLOCATOR= + "javax.xml.stream.allocator"; + + static final String DEFAULIMPL = "com.sun.xml.internal.stream.XMLInputFactoryImpl"; + + protected XMLInputFactory(){} + + /** + * Create a new instance of the factory. + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLInputFactory newInstance() + throws FactoryConfigurationError + { + return (XMLInputFactory) FactoryFinder.find( + "javax.xml.stream.XMLInputFactory", + DEFAULIMPL); + } + + /** + * Create a new instance of the factory. + * This static method creates a new factory instance. + * This method uses the following ordered lookup procedure to determine + * the XMLInputFactory implementation class to load: + * Use the javax.xml.stream.XMLInputFactory system property. + * Use the properties file "lib/stax.properties" in the JRE directory. + * This configuration file is in standard java.util.Properties format + * and contains the fully qualified name of the implementation class + * with the key being the system property defined above. + * Use the Services API (as detailed in the JAR specification), if available, + * to determine the classname. The Services API will look for a classname + * in the file META-INF/services/javax.xml.stream.XMLInputFactory in jars + * available to the runtime. + * Platform default XMLInputFactory instance. + * + * Once an application has obtained a reference to a XMLInputFactory it + * can use the factory to configure and obtain stream instances. + * + * Note that this is a new method that replaces the deprecated newInstance() method. + * No changes in behavior are defined by this replacement method relative to + * the deprecated method. + * + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLInputFactory newFactory() + throws FactoryConfigurationError + { + return (XMLInputFactory) FactoryFinder.find( + "javax.xml.stream.XMLInputFactory", + DEFAULIMPL); + } + + /** + * Create a new instance of the factory + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param classLoader classLoader to use + * @return the factory implementation + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + * + * @deprecated This method has been deprecated to maintain API consistency. + * All newInstance methods have been replaced with corresponding + * newFactory methods. The replacement {@link + * #newFactory(java.lang.String, java.lang.ClassLoader)} method + * defines no changes in behavior. + */ + public static XMLInputFactory newInstance(String factoryId, + ClassLoader classLoader) + throws FactoryConfigurationError { + try { + //do not fallback if given classloader can't find the class, throw exception + return (XMLInputFactory) FactoryFinder.find(factoryId, classLoader, null); + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + } + + /** + * Create a new instance of the factory. + * If the classLoader argument is null, then the ContextClassLoader is used. + * + * Note that this is a new method that replaces the deprecated + * newInstance(String factoryId, ClassLoader classLoader) method. + * No changes in behavior are defined by this replacement method relative + * to the deprecated method. + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param classLoader classLoader to use + * @return the factory implementation + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLInputFactory newFactory(String factoryId, + ClassLoader classLoader) + throws FactoryConfigurationError { + try { + //do not fallback if given classloader can't find the class, throw exception + return (XMLInputFactory) FactoryFinder.find(factoryId, classLoader, null); + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + } + + /** + * Create a new XMLStreamReader from a reader + * @param reader the XML data to read from + * @throws XMLStreamException + */ + public abstract XMLStreamReader createXMLStreamReader(java.io.Reader reader) + throws XMLStreamException; + + /** + * Create a new XMLStreamReader from a JAXP source. This method is optional. + * @param source the source to read from + * @throws UnsupportedOperationException if this method is not + * supported by this XMLInputFactory + * @throws XMLStreamException + */ + public abstract XMLStreamReader createXMLStreamReader(Source source) + throws XMLStreamException; + + /** + * Create a new XMLStreamReader from a java.io.InputStream + * @param stream the InputStream to read from + * @throws XMLStreamException + */ + public abstract XMLStreamReader createXMLStreamReader(java.io.InputStream stream) + throws XMLStreamException; + + /** + * Create a new XMLStreamReader from a java.io.InputStream + * @param stream the InputStream to read from + * @param encoding the character encoding of the stream + * @throws XMLStreamException + */ + public abstract XMLStreamReader createXMLStreamReader(java.io.InputStream stream, String encoding) + throws XMLStreamException; + + /** + * Create a new XMLStreamReader from a java.io.InputStream + * @param systemId the system ID of the stream + * @param stream the InputStream to read from + */ + public abstract XMLStreamReader createXMLStreamReader(String systemId, java.io.InputStream stream) + throws XMLStreamException; + + /** + * Create a new XMLStreamReader from a java.io.InputStream + * @param systemId the system ID of the stream + * @param reader the InputStream to read from + */ + public abstract XMLStreamReader createXMLStreamReader(String systemId, java.io.Reader reader) + throws XMLStreamException; + + /** + * Create a new XMLEventReader from a reader + * @param reader the XML data to read from + * @throws XMLStreamException + */ + public abstract XMLEventReader createXMLEventReader(java.io.Reader reader) + throws XMLStreamException; + + /** + * Create a new XMLEventReader from a reader + * @param systemId the system ID of the input + * @param reader the XML data to read from + * @throws XMLStreamException + */ + public abstract XMLEventReader createXMLEventReader(String systemId, java.io.Reader reader) + throws XMLStreamException; + + /** + * Create a new XMLEventReader from an XMLStreamReader. After being used + * to construct the XMLEventReader instance returned from this method + * the XMLStreamReader must not be used. + * @param reader the XMLStreamReader to read from (may not be modified) + * @return a new XMLEventReader + * @throws XMLStreamException + */ + public abstract XMLEventReader createXMLEventReader(XMLStreamReader reader) + throws XMLStreamException; + + /** + * Create a new XMLEventReader from a JAXP source. + * Support of this method is optional. + * @param source the source to read from + * @throws UnsupportedOperationException if this method is not + * supported by this XMLInputFactory + */ + public abstract XMLEventReader createXMLEventReader(Source source) + throws XMLStreamException; + + /** + * Create a new XMLEventReader from a java.io.InputStream + * @param stream the InputStream to read from + * @throws XMLStreamException + */ + public abstract XMLEventReader createXMLEventReader(java.io.InputStream stream) + throws XMLStreamException; + + /** + * Create a new XMLEventReader from a java.io.InputStream + * @param stream the InputStream to read from + * @param encoding the character encoding of the stream + * @throws XMLStreamException + */ + public abstract XMLEventReader createXMLEventReader(java.io.InputStream stream, String encoding) + throws XMLStreamException; + + /** + * Create a new XMLEventReader from a java.io.InputStream + * @param systemId the system ID of the stream + * @param stream the InputStream to read from + * @throws XMLStreamException + */ + public abstract XMLEventReader createXMLEventReader(String systemId, java.io.InputStream stream) + throws XMLStreamException; + + /** + * Create a filtered reader that wraps the filter around the reader + * @param reader the reader to filter + * @param filter the filter to apply to the reader + * @throws XMLStreamException + */ + public abstract XMLStreamReader createFilteredReader(XMLStreamReader reader, StreamFilter filter) + throws XMLStreamException; + + /** + * Create a filtered event reader that wraps the filter around the event reader + * @param reader the event reader to wrap + * @param filter the filter to apply to the event reader + * @throws XMLStreamException + */ + public abstract XMLEventReader createFilteredReader(XMLEventReader reader, EventFilter filter) + throws XMLStreamException; + + /** + * The resolver that will be set on any XMLStreamReader or XMLEventReader created + * by this factory instance. + */ + public abstract XMLResolver getXMLResolver(); + + /** + * The resolver that will be set on any XMLStreamReader or XMLEventReader created + * by this factory instance. + * @param resolver the resolver to use to resolve references + */ + public abstract void setXMLResolver(XMLResolver resolver); + + /** + * The reporter that will be set on any XMLStreamReader or XMLEventReader created + * by this factory instance. + */ + public abstract XMLReporter getXMLReporter(); + + /** + * The reporter that will be set on any XMLStreamReader or XMLEventReader created + * by this factory instance. + * @param reporter the resolver to use to report non fatal errors + */ + public abstract void setXMLReporter(XMLReporter reporter); + + /** + * Allows the user to set specific feature/property on the underlying implementation. The underlying implementation + * is not required to support every setting of every property in the specification and may use IllegalArgumentException + * to signal that an unsupported property may not be set with the specified value. + * @param name The name of the property (may not be null) + * @param value The value of the property + * @throws java.lang.IllegalArgumentException if the property is not supported + */ + public abstract void setProperty(java.lang.String name, Object value) + throws java.lang.IllegalArgumentException; + + /** + * Get the value of a feature/property from the underlying implementation + * @param name The name of the property (may not be null) + * @return The value of the property + * @throws IllegalArgumentException if the property is not supported + */ + public abstract Object getProperty(java.lang.String name) + throws java.lang.IllegalArgumentException; + + + /** + * Query the set of properties that this factory supports. + * + * @param name The name of the property (may not be null) + * @return true if the property is supported and false otherwise + */ + public abstract boolean isPropertySupported(String name); + + /** + * Set a user defined event allocator for events + * @param allocator the user defined allocator + */ + public abstract void setEventAllocator(XMLEventAllocator allocator); -// /** -// * Property used to control namespace support. -// */ -// public static final String IS_NAMESPACE_AWARE = -// "javax.xml.stream.isNamespaceAware"; -// -// /** -// * Property used to control DTD validation. -// */ -// public static final String IS_VALIDATING = "javax.xml.stream.isValidating"; -// -// /** -// * Property used to control whether to coalesce adjacent text events. -// */ -// public static final String IS_COALESCING = "javax.xml.stream.isCoalescing"; -// -// /** -// * Property used to control whether to replace entity references with -// * their replacement text. -// */ -// public static final String IS_REPLACING_ENTITY_REFERENCES = -// "javax.xml.stream.isReplacingEntityReferences"; -// -// /** -// * Property used to control whether to resolve external entities. -// */ -// public static final String IS_SUPPORTING_EXTERNAL_ENTITIES = -// "javax.xml.stream.isSupportingExternalEntities"; -// -// /** -// * Property used to indicate whether to support DTDs. -// */ -// public static final String SUPPORT_DTD = "javax.xml.stream.supportDTD"; -// -// /** -// * Property used to control the error reporter implementation. -// */ -// public static final String REPORTER = "javax.xml.stream.reporter"; -// -// /** -// * Property used to control the entity resolver implementation. -// */ -// public static final String RESOLVER = "javax.xml.stream.resolver"; -// -// /** -// * Property used to control the event allocator implementation. -// */ -// public static final String ALLOCATOR = "javax.xml.stream.allocator"; - - protected XMLInputFactory() { - } - - /** - * Creates a new factory instance. - * - * @see #newInstance(String,ClassLoader) - */ - public static XMLInputFactory newInstance() throws FactoryConfigurationError { - return new swingjs.xml.JSXMLInputFactory(); -// return newInstance(null, null); - } - -// /** -// * Creates a new factory instance. -// * The implementation class to load is the first found in the following -// * locations: -// *
        -// *
      1. the javax.xml.stream.XMLInputFactory system -// * property
      2. -// *
      3. the above named property value in the -// * $JAVA_HOME/lib/stax.properties file
      4. -// *
      5. the class name specified in the -// * META-INF/services/javax.xml.stream.XMLInputFactory -// * system resource
      6. -// *
      7. the default factory class
      8. -// *
      -// * @param factoryId name of the factory, same as a property name -// * @param classLoader the class loader to use -// * @return the factory implementation -// * @exception FactoryConfigurationError if an instance of this factory -// * cannot be loaded -// */ -// public static XMLInputFactory newInstance(String factoryId, -// ClassLoader classLoader) -// throws FactoryConfigurationError -// { -// ClassLoader loader = classLoader; -// if (loader == null) -// { -// loader = Thread.currentThread().getContextClassLoader(); -// } -// if (loader == null) -// { -// loader = XMLInputFactory.class.getClassLoader(); -// } -// String className = null; -// int count = 0; -// do -// { -// className = getFactoryClassName(loader, count++); -// if (className != null) -// { -// try -// { -// Class t = (loader != null) ? loader.loadClass(className) : -// Class.forName(className); -// return (XMLInputFactory) t.newInstance(); -// } -// catch (ClassNotFoundException e) -// { -// className = null; -// } -// catch (Exception e) -// { -// throw new FactoryConfigurationError(e, -// "error instantiating class " + className); -// } -// } -// } -// while (className == null && count < 3); -// return new swingjs.xml.XMLInputFactoryImpl(); -// } -// -// private static String getFactoryClassName(ClassLoader loader, int attempt) -// { -// final String propertyName = "javax.xml.stream.XMLInputFactory"; -// switch (attempt) -// { -// case 0: -// return System.getProperty(propertyName); -// case 1: -// try -// { -// File file = new File(System.getProperty("java.home")); -// file = new File(file, "lib"); -// file = new File(file, "stax.properties"); -// InputStream in = new FileInputStream(file); -// Properties props = new Properties(); -// props.load(in); -// in.close(); -// return props.getProperty(propertyName); -// } -// catch (IOException e) -// { -// return null; -// } -// case 2: -// try -// { -// String serviceKey = "/META-INF/services/" + propertyName; -// InputStream in = (loader != null) ? -// loader.getResourceAsStream(serviceKey) : -// XMLInputFactory.class.getResourceAsStream(serviceKey); -// if (in != null) -// { -// BufferedReader r = -// new BufferedReader(new InputStreamReader(in)); -// String ret = r.readLine(); -// r.close(); -// return ret; -// } -// } -// catch (IOException e) -// { -// } -// return null; -// default: -// return null; -// } -// } -// - /** - * Creates a new stream reader. - */ - public abstract XMLStreamReader createXMLStreamReader(Reader reader) throws XMLStreamException; - -// /** -// * Creates a new stream reader. -// */ -// public abstract XMLStreamReader createXMLStreamReader(Source source) -// throws XMLStreamException; -// - /** - * Creates a new stream reader. - */ - public abstract XMLStreamReader createXMLStreamReader(InputStream stream) throws XMLStreamException; - - /** - * Creates a new stream reader. - */ - public abstract XMLStreamReader createXMLStreamReader(InputStream stream, String encoding) - throws XMLStreamException; - -// /** -// * Creates a new stream reader. -// */ -// public abstract XMLStreamReader createXMLStreamReader(String systemId, -// InputStream stream) -// throws XMLStreamException; - -// /** -// * Creates a new stream reader. -// */ -// public abstract XMLStreamReader createXMLStreamReader(String systemId, -// Reader reader) -// throws XMLStreamException; -// -// /** -// * Creates a new event reader. -// */ -// public abstract XMLEventReader createXMLEventReader(Reader reader) -// throws XMLStreamException; -// -// /** -// * Creates a new event reader. -// */ -// public abstract XMLEventReader createXMLEventReader(String systemId, -// Reader reader) -// throws XMLStreamException; -// -// /** -// * Creates a new event reader. -// */ -// public abstract XMLEventReader createXMLEventReader(XMLStreamReader reader) -// throws XMLStreamException; -// -// /** -// * Creates a new event reader. -// */ -// public abstract XMLEventReader createXMLEventReader(Source source) -// throws XMLStreamException; -// -// /** -// * Creates a new event reader. -// */ -// public abstract XMLEventReader createXMLEventReader(InputStream stream) -// throws XMLStreamException; -// -// /** -// * Creates a new event reader. -// */ -// public abstract XMLEventReader createXMLEventReader(InputStream stream, -// String encoding) -// throws XMLStreamException; -// -// /** -// * Creates a new event reader. -// */ -// public abstract XMLEventReader createXMLEventReader(String systemId, -// InputStream stream) -// throws XMLStreamException; -// -// /** -// * Create a new filtered reader. -// */ -// public abstract XMLStreamReader createFilteredReader(XMLStreamReader reader, -// StreamFilter filter) -// throws XMLStreamException; -// -// /** -// * Create a new filtered reader. -// */ -// public abstract XMLEventReader createFilteredReader(XMLEventReader reader, -// EventFilter filter) -// throws XMLStreamException; -// -// /** -// * Returns the entity resolver. -// */ -// public abstract XMLResolver getXMLResolver(); -// -// /** -// * Sets the entity resolver. -// */ -// public abstract void setXMLResolver(XMLResolver resolver); -// -// /** -// * Returns the error reporter. -// */ -// public abstract XMLReporter getXMLReporter(); -// -// /** -// * Sets the error reporter. -// */ -// public abstract void setXMLReporter(XMLReporter reporter); - - /** - * Sets the implementation-specific property of the given name. - * - * @exception IllegalArgumentException if the property is not supported - */ - public abstract void setProperty(String name, Object value) throws IllegalArgumentException; - - /** - * Returns the implementation-specific property of the given name. - * - * @exception IllegalArgumentException if the property is not supported - */ - public abstract Object getProperty(String name) throws IllegalArgumentException; - -// /** -// * Indicates whether the specified property is supported. -// */ -// public abstract boolean isPropertySupported(String name); -// -// /** -// * Sets the event allocator. -// */ -// public abstract void setEventAllocator(XMLEventAllocator allocator); -// -// /** -// * Returns the event allocator. -// */ -// public abstract XMLEventAllocator getEventAllocator(); + /** + * Gets the allocator used by streams created with this factory + */ + public abstract XMLEventAllocator getEventAllocator(); } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLOutputFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLOutputFactory.java new file mode 100644 index 000000000..b0d4f0b30 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLOutputFactory.java @@ -0,0 +1,313 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +import javax.xml.transform.Result; + +/** + * Defines an abstract implementation of a factory for + * getting XMLEventWriters and XMLStreamWriters. + * + * The following table defines the standard properties of this specification. + * Each property varies in the level of support required by each implementation. + * The level of support required is described in the 'Required' column. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      + * Configuration parameters + *
      Property NameBehaviorReturn typeDefault ValueRequired
      javax.xml.stream.isRepairingNamespacesdefaults prefixes on the output sideBooleanFalseYes
      + * + *

      The following paragraphs describe the namespace and prefix repair algorithm:

      + * + *

      The property can be set with the following code line: + * setProperty("javax.xml.stream.isRepairingNamespaces",new Boolean(true|false));

      + * + *

      This property specifies that the writer default namespace prefix declarations. + * The default value is false.

      + * + *

      If a writer isRepairingNamespaces it will create a namespace declaration + * on the current StartElement for + * any attribute that does not + * currently have a namespace declaration in scope. If the StartElement + * has a uri but no prefix specified a prefix will be assigned, if the prefix + * has not been declared in a parent of the current StartElement it will be declared + * on the current StartElement. If the defaultNamespace is bound and in scope + * and the default namespace matches the URI of the attribute or StartElement + * QName no prefix will be assigned.

      + * + *

      If an element or attribute name has a prefix, but is not + * bound to any namespace URI, then the prefix will be removed + * during serialization.

      + * + *

      If element and/or attribute names in the same start or + * empty-element tag are bound to different namespace URIs and + * are using the same prefix then the element or the first + * occurring attribute retains the original prefix and the + * following attributes have their prefixes replaced with a + * new prefix that is bound to the namespace URIs of those + * attributes.

      + * + *

      If an element or attribute name uses a prefix that is + * bound to a different URI than that inherited from the + * namespace context of the parent of that element and there + * is no namespace declaration in the context of the current + * element then such a namespace declaration is added.

      + * + *

      If an element or attribute name is bound to a prefix and + * there is a namespace declaration that binds that prefix + * to a different URI then that namespace declaration is + * either removed if the correct mapping is inherited from + * the parent context of that element, or changed to the + * namespace URI of the element or attribute using that prefix.

      + * + * @version 1.2 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see XMLInputFactory + * @see XMLEventWriter + * @see XMLStreamWriter + * @since 1.6 + */ +public abstract class XMLOutputFactory { + /** + * Property used to set prefix defaulting on the output side + */ + public static final String IS_REPAIRING_NAMESPACES= + "javax.xml.stream.isRepairingNamespaces"; + + static final String DEFAULIMPL = "com.sun.xml.internal.stream.XMLOutputFactoryImpl"; + + protected XMLOutputFactory(){} + + /** + * Create a new instance of the factory. + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLOutputFactory newInstance() + throws FactoryConfigurationError + { + return (XMLOutputFactory) FactoryFinder.find("javax.xml.stream.XMLOutputFactory", + DEFAULIMPL); + } + + /** + * Create a new instance of the factory. + * This static method creates a new factory instance. This method uses the + * following ordered lookup procedure to determine the XMLOutputFactory + * implementation class to load: + * Use the javax.xml.stream.XMLOutputFactory system property. + * Use the properties file "lib/stax.properties" in the JRE directory. + * This configuration file is in standard java.util.Properties format + * and contains the fully qualified name of the implementation class + * with the key being the system property defined above. + * Use the Services API (as detailed in the JAR specification), if available, + * to determine the classname. The Services API will look for a classname + * in the file META-INF/services/javax.xml.stream.XMLOutputFactory in jars + * available to the runtime. + * Platform default XMLOutputFactory instance. + * + * Once an application has obtained a reference to a XMLOutputFactory it + * can use the factory to configure and obtain stream instances. + * + * Note that this is a new method that replaces the deprecated newInstance() method. + * No changes in behavior are defined by this replacement method relative to the + * deprecated method. + * + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLOutputFactory newFactory() + throws FactoryConfigurationError + { + return (XMLOutputFactory) FactoryFinder.find("javax.xml.stream.XMLOutputFactory", + DEFAULIMPL); + } + + /** + * Create a new instance of the factory. + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param classLoader classLoader to use + * @return the factory implementation + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + * + * @deprecated This method has been deprecated because it returns an + * instance of XMLInputFactory, which is of the wrong class. + * Use the new method {@link #newFactory(java.lang.String, + * java.lang.ClassLoader)} instead. + */ + public static XMLInputFactory newInstance(String factoryId, + ClassLoader classLoader) + throws FactoryConfigurationError { + try { + //do not fallback if given classloader can't find the class, throw exception + return (XMLInputFactory) FactoryFinder.find(factoryId, classLoader, null); + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + } + + /** + * Create a new instance of the factory. + * If the classLoader argument is null, then the ContextClassLoader is used. + * + * Note that this is a new method that replaces the deprecated + * newInstance(String factoryId, ClassLoader classLoader) method. + * + * No changes in behavior are defined by this replacement method relative + * to the deprecated method. + * + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param classLoader classLoader to use + * @return the factory implementation + * @throws FactoryConfigurationError if an instance of this factory cannot be loaded + */ + public static XMLOutputFactory newFactory(String factoryId, + ClassLoader classLoader) + throws FactoryConfigurationError { + try { + //do not fallback if given classloader can't find the class, throw exception + return (XMLOutputFactory) FactoryFinder.find(factoryId, classLoader, null); + } catch (FactoryFinder.ConfigurationError e) { + throw new FactoryConfigurationError(e.getException(), + e.getMessage()); + } + } + + /** + * Create a new XMLStreamWriter that writes to a writer + * @param stream the writer to write to + * @throws XMLStreamException + */ + public abstract XMLStreamWriter createXMLStreamWriter(java.io.Writer stream) throws XMLStreamException; + + /** + * Create a new XMLStreamWriter that writes to a stream + * @param stream the stream to write to + * @throws XMLStreamException + */ + public abstract XMLStreamWriter createXMLStreamWriter(java.io.OutputStream stream) throws XMLStreamException; + + /** + * Create a new XMLStreamWriter that writes to a stream + * @param stream the stream to write to + * @param encoding the encoding to use + * @throws XMLStreamException + */ + public abstract XMLStreamWriter createXMLStreamWriter(java.io.OutputStream stream, + String encoding) throws XMLStreamException; + + /** + * Create a new XMLStreamWriter that writes to a JAXP result. This method is optional. + * @param result the result to write to + * @throws UnsupportedOperationException if this method is not + * supported by this XMLOutputFactory + * @throws XMLStreamException + */ + public abstract XMLStreamWriter createXMLStreamWriter(Result result) throws XMLStreamException; + + + /** + * Create a new XMLEventWriter that writes to a JAXP result. This method is optional. + * @param result the result to write to + * @throws UnsupportedOperationException if this method is not + * supported by this XMLOutputFactory + * @throws XMLStreamException + */ + public abstract XMLEventWriter createXMLEventWriter(Result result) throws XMLStreamException; + + /** + * Create a new XMLEventWriter that writes to a stream + * @param stream the stream to write to + * @throws XMLStreamException + */ + public abstract XMLEventWriter createXMLEventWriter(java.io.OutputStream stream) throws XMLStreamException; + + + + /** + * Create a new XMLEventWriter that writes to a stream + * @param stream the stream to write to + * @param encoding the encoding to use + * @throws XMLStreamException + */ + public abstract XMLEventWriter createXMLEventWriter(java.io.OutputStream stream, + String encoding) throws XMLStreamException; + + /** + * Create a new XMLEventWriter that writes to a writer + * @param stream the stream to write to + * @throws XMLStreamException + */ + public abstract XMLEventWriter createXMLEventWriter(java.io.Writer stream) throws XMLStreamException; + + /** + * Allows the user to set specific features/properties on the underlying implementation. + * @param name The name of the property + * @param value The value of the property + * @throws java.lang.IllegalArgumentException if the property is not supported + */ + public abstract void setProperty(java.lang.String name, + Object value) + throws IllegalArgumentException; + + /** + * Get a feature/property on the underlying implementation + * @param name The name of the property + * @return The value of the property + * @throws java.lang.IllegalArgumentException if the property is not supported + */ + public abstract Object getProperty(java.lang.String name) + throws IllegalArgumentException; + + /** + * Query the set of properties that this factory supports. + * + * @param name The name of the property (may not be null) + * @return true if the property is supported and false otherwise + */ + public abstract boolean isPropertySupported(String name); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLReporter.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLReporter.java new file mode 100644 index 000000000..f78648e20 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLReporter.java @@ -0,0 +1,65 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +/** + * This interface is used to report non-fatal errors. + * Only warnings should be echoed through this interface. + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface XMLReporter { + + /** + + * Report the desired message in an application specific format. + + * Only warnings and non-fatal errors should be reported through + + * this interface. + + * Fatal errors should be thrown as XMLStreamException. + + * + + * @param message the error message + + * @param errorType an implementation defined error type + + * @param relatedInformation information related to the error, if available + + * @param location the location of the error, if available + + * @throws XMLStreamException + + */ + public void report(String message, String errorType, Object relatedInformation, Location location) + throws XMLStreamException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLResolver.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLResolver.java new file mode 100644 index 000000000..dbb177b0e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLResolver.java @@ -0,0 +1,60 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +/** + * This interface is used to resolve resources during an XML parse. If an application wishes to + * perform custom entity resolution it must register an instance of this interface with + * the XMLInputFactory using the setXMLResolver method. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface XMLResolver { + + /** + * Retrieves a resource. This resource can be of the following three return types: + * (1) java.io.InputStream (2) javax.xml.stream.XMLStreamReader (3) java.xml.stream.XMLEventReader. + * If this method returns null the processor will attempt to resolve the entity using its + * default mechanism. + * + * @param publicID The public identifier of the external entity being referenced, or null if none was supplied. + * @param systemID The system identifier of the external entity being referenced. + * @param baseURI Absolute base URI associated with systemId. + * @param namespace The namespace of the entity to resolve. + * @return The resource requested or null. + * @throws XMLStreamException if there was a failure attempting to resolve the resource. + */ + public Object resolveEntity(String publicID, + String systemID, + String baseURI, + String namespace) + throws XMLStreamException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamConstants.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamConstants.java new file mode 100644 index 000000000..6ceb1c61b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamConstants.java @@ -0,0 +1,127 @@ +/* + * 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 javax.xml.stream; + +/** + * This interface declares the constants used in this API. + * Numbers in the range 0 to 256 are reserved for the specification, + * user defined events must use event codes outside that range. + * + * @since 1.6 + */ + +public interface XMLStreamConstants { + /** + * Indicates an event is a start element + * @see javax.xml.stream.events.StartElement + */ + public static final int START_ELEMENT=1; + /** + * Indicates an event is an end element + * @see javax.xml.stream.events.EndElement + */ + public static final int END_ELEMENT=2; + /** + * Indicates an event is a processing instruction + * @see javax.xml.stream.events.ProcessingInstruction + */ + public static final int PROCESSING_INSTRUCTION=3; + + /** + * Indicates an event is characters + * @see javax.xml.stream.events.Characters + */ + public static final int CHARACTERS=4; + + /** + * Indicates an event is a comment + * @see javax.xml.stream.events.Comment + */ + public static final int COMMENT=5; + + /** + * The characters are white space + * (see [XML], 2.10 "White Space Handling"). + * Events are only reported as SPACE if they are ignorable white + * space. Otherwise they are reported as CHARACTERS. + * @see javax.xml.stream.events.Characters + */ + public static final int SPACE=6; + + /** + * Indicates an event is a start document + * @see javax.xml.stream.events.StartDocument + */ + public static final int START_DOCUMENT=7; + + /** + * Indicates an event is an end document + * @see javax.xml.stream.events.EndDocument + */ + public static final int END_DOCUMENT=8; + + /** + * Indicates an event is an entity reference + * @see javax.xml.stream.events.EntityReference + */ + public static final int ENTITY_REFERENCE=9; + + /** + * Indicates an event is an attribute + * @see javax.xml.stream.events.Attribute + */ + public static final int ATTRIBUTE=10; + + /** + * Indicates an event is a DTD + * @see javax.xml.stream.events.DTD + */ + public static final int DTD=11; + + /** + * Indicates an event is a CDATA section + * @see javax.xml.stream.events.Characters + */ + public static final int CDATA=12; + + /** + * Indicates the event is a namespace declaration + * + * @see javax.xml.stream.events.Namespace + */ + public static final int NAMESPACE=13; + + /** + * Indicates a Notation + * @see javax.xml.stream.events.NotationDeclaration + */ + public static final int NOTATION_DECLARATION=14; + + /** + * Indicates a Entity Declaration + * @see javax.xml.stream.events.NotationDeclaration + */ + public static final int ENTITY_DECLARATION=15; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamException.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamException.java index 929afbb75..48e510cf7 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamException.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamException.java @@ -1,97 +1,129 @@ -/* XMLStreamException.java -- - Copyright (C) 2005 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. +/* + * 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. + */ -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ package javax.xml.stream; /** - * Exception indicating an XML stream processing error. + * The base exception for unexpected processing errors. This Exception + * class is used to report well-formedness errors as well as unexpected + * processing conditions. + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 */ -public class XMLStreamException - extends Exception -{ - protected Location location; +public class XMLStreamException extends Exception { + protected Throwable nested; + protected Location location; - public XMLStreamException() - { - this(null, null, null); + /** + * Default constructor + */ + public XMLStreamException(){ + super(); } - public XMLStreamException(String msg) - { - this(msg, null, null); + /** + * Construct an exception with the assocated message. + * + * @param msg the message to report + */ + public XMLStreamException(String msg) { + super(msg); } - public XMLStreamException(Throwable th) - { - this(null, null, th); + /** + * Construct an exception with the assocated exception + * + * @param th a nested exception + */ + public XMLStreamException(Throwable th) { + super(th); + nested = th; } - public XMLStreamException(String msg, Throwable th) - { - this(msg, null, th); + /** + * Construct an exception with the assocated message and exception + * + * @param th a nested exception + * @param msg the message to report + */ + public XMLStreamException(String msg, Throwable th) { + super(msg, th); + nested = th; } - public XMLStreamException(String msg, Location location, Throwable th) - { - super(msg); - this.location = location; + /** + * Construct an exception with the assocated message, exception and location. + * + * @param th a nested exception + * @param msg the message to report + * @param location the location of the error + */ + public XMLStreamException(String msg, Location location, Throwable th) { + super("ParseError at [row,col]:["+location.getLineNumber()+","+ + location.getColumnNumber()+"]\n"+ + "Message: "+msg); nested = th; + this.location = location; } - public XMLStreamException(String msg, Location location) - { - this(msg, location, null); + /** + * Construct an exception with the assocated message, exception and location. + * + * @param msg the message to report + * @param location the location of the error + */ + public XMLStreamException(String msg, + Location location) { + super("ParseError at [row,col]:["+location.getLineNumber()+","+ + location.getColumnNumber()+"]\n"+ + "Message: "+msg); + this.location = location; } + /** - * Returns the nested exception. + * Gets the nested exception. + * + * @return Nested exception */ - public Throwable getNestedException() - { + public Throwable getNestedException() { return nested; } /** - * Returns the location of the exception. + * Gets the location of the exception + * + * @return the location of the exception, may be null if none is available */ - public Location getLocation() - { + public Location getLocation() { return location; } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamReader.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamReader.java index 34441f4c1..fd15819f3 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamReader.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamReader.java @@ -1,297 +1,704 @@ -/* XMLStreamReader.java -- - Copyright (C) 2005,2006 Free Software Foundation, Inc. - -This file is part of GNU Classpath. - -GNU Classpath is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) -any later version. - -GNU Classpath 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 for more details. - -You should have received a copy of the GNU General Public License -along with GNU Classpath; see the file COPYING. If not, write to the -Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -02110-1301 USA. - -Linking this library statically or dynamically with other modules is -making a combined work based on this library. Thus, the terms and -conditions of the GNU General Public License cover the whole -combination. - -As a special exception, the copyright holders of this library give you -permission to link this library with independent modules to produce an -executable, regardless of the license terms of these independent -modules, and to copy and distribute the resulting executable under -terms of your choice, provided that you also meet, for each linked -independent module, the terms and conditions of the license of that -module. An independent module is a module which is not derived from -or based on this library. If you modify this library, you may extend -this exception to your version of the library, but you are not -obligated to do so. If you do not wish to do so, delete this -exception statement from your version. */ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ package javax.xml.stream; +import java.io.Reader; +import javax.xml.namespace.NamespaceContext; +import javax.xml.namespace.QName; + /** - * Interface implemented by an XML parser. + * The XMLStreamReader interface allows forward, read-only access to XML. + * It is designed to be the lowest level and most efficient way to + * read XML data. + * + *

      The XMLStreamReader is designed to iterate over XML using + * next() and hasNext(). The data can be accessed using methods such as getEventType(), + * getNamespaceURI(), getLocalName() and getText(); + * + *

      The next() method causes the reader to read the next parse event. + * The next() method returns an integer which identifies the type of event just read. + *

      The event type can be determined using getEventType(). + *

      Parsing events are defined as the XML Declaration, a DTD, + * start tag, character data, white space, end tag, comment, + * or processing instruction. An attribute or namespace event may be encountered + * at the root level of a document as the result of a query operation. + * + *

      For XML 1.0 compliance an XML processor must pass the + * identifiers of declared unparsed entities, notation declarations and their + * associated identifiers to the application. This information is + * provided through the property API on this interface. + * The following two properties allow access to this information: + * javax.xml.stream.notations and javax.xml.stream.entities. + * When the current event is a DTD the following call will return a + * list of Notations + * List l = (List) getProperty("javax.xml.stream.notations"); + * The following call will return a list of entity declarations: + * List l = (List) getProperty("javax.xml.stream.entities"); + * These properties can only be accessed during a DTD event and + * are defined to return null if the information is not available. + * + *

      The following table describes which methods are valid in what state. + * If a method is called in an invalid state the method will throw a + * java.lang.IllegalStateException. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      + * Valid methods for each state + *
      Event TypeValid Methods
      All States getProperty(), hasNext(), require(), close(), + * getNamespaceURI(), isStartElement(), + * isEndElement(), isCharacters(), isWhiteSpace(), + * getNamespaceContext(), getEventType(),getLocation(), + * hasText(), hasName() + *
      START_ELEMENT next(), getName(), getLocalName(), hasName(), getPrefix(), + * getAttributeXXX(), isAttributeSpecified(), + * getNamespaceXXX(), + * getElementText(), nextTag() + *
      ATTRIBUTE next(), nextTag() + * getAttributeXXX(), isAttributeSpecified(), + *
      NAMESPACE next(), nextTag() + * getNamespaceXXX() + *
      END_ELEMENT next(), getName(), getLocalName(), hasName(), getPrefix(), + * getNamespaceXXX(), nextTag() + *
      CHARACTERS next(), getTextXXX(), nextTag()
      CDATA next(), getTextXXX(), nextTag()
      COMMENT next(), getTextXXX(), nextTag()
      SPACE next(), getTextXXX(), nextTag()
      START_DOCUMENT next(), getEncoding(), getVersion(), isStandalone(), standaloneSet(), + * getCharacterEncodingScheme(), nextTag()
      END_DOCUMENT close()
      PROCESSING_INSTRUCTION next(), getPITarget(), getPIData(), nextTag()
      ENTITY_REFERENCE next(), getLocalName(), getText(), nextTag()
      DTD next(), getText(), nextTag()
      + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see javax.xml.stream.events.XMLEvent + * @see XMLInputFactory + * @see XMLStreamWriter + * @since 1.6 */ -public interface XMLStreamReader -// extends XMLStreamConstants -{ - -// /** -// * Returns the implementation-specific feature or property of the given -// * name. -// */ -// Object getProperty(String name) -// throws IllegalArgumentException; -// -// /** -// * Returns the next parsing event. -// */ -// int next() -// throws XMLStreamException; -// -// /** -// * Tests whether the current event is of the given type and namespace. -// * @exception XMLStreamException if the test fails -// */ -// void require(int type, String namespaceURI, String localName) -// throws XMLStreamException; -// -// /** -// * Returns the text content of a text-only element. -// * When invoked, the current event must be START_ELEMENT. -// * On completion, the current event will be END_ELEMENT. -// */ -// String getElementText() -// throws XMLStreamException; -// -// /** -// * Skips any ignorable whitespace, comments, and processing instructions -// * until a START_ELEMENT or END_ELEMENT event is encountered. -// * @exception XMLStreamException if an event of any other type is -// * encountered -// */ -// int nextTag() -// throws XMLStreamException; -// -// /** -// * Indicates whether there are any remaining events to be read. -// */ -// boolean hasNext() -// throws XMLStreamException; -// -// /** -// * Frees any resources used by this parser. -// * This method will not close the underlying input source. -// */ -// void close() -// throws XMLStreamException; -// -// /** -// * Returns the namespace URI for the given prefix. -// */ -// String getNamespaceURI(String prefix); -// -// /** -// * Indicates whether the current event is START_ELEMENT. -// */ -// boolean isStartElement(); -// -// /** -// * Indicates whether the current event is END_ELEMENT. -// */ -// boolean isEndElement(); -// -// /** -// * Indicates whether the current event is character data. -// */ -// boolean isCharacters(); -// -// /** -// * Indicates whether the current event is ignorable whitespace. -// */ -// boolean isWhiteSpace(); -// -// /** -// * Returns the normalized attribute value for the given attribute. -// */ -// String getAttributeValue(String namespaceURI, String localName); -// -// /** -// * Returns the number of attributes on this element. -// * This method can only be invoked on a START_ELEMENT event. -// */ -// int getAttributeCount(); -// -// /** -// * Returns the QName of the attribute at the given index. -// */ -// QName getAttributeName(int index); -// -// /** -// * Returns the namespace URI of the attribute at the given index. -// */ -// String getAttributeNamespace(int index); -// -// /** -// * Returns the local-name of the attribute at the given index. -// */ -// String getAttributeLocalName(int index); -// -// /** -// * Returns the namespace prefix of the attribute at the given index. -// */ -// String getAttributePrefix(int index); -// -// /** -// * Returns the type of the attribute at the specified index. -// */ -// String getAttributeType(int index); -// -// /** -// * Returns the normalized value of the attribute at the given index. -// */ -// String getAttributeValue(int index); -// -// /** -// * Indicates whether the attribute at the given index was specified in the -// * underlying XML source or created by default. -// */ -// boolean isAttributeSpecified(int index); -// -// /** -// * Returns the number of namespaces declared on this event. -// * This method is only valid on a START_ELEMENT, END_ELEMENT, or NAMESPACE -// * event. -// */ -// int getNamespaceCount(); -// -// /** -// * Returns the prefix of the namespace at the given index, or null if this -// * is the default namespace declaration. -// */ -// String getNamespacePrefix(int index); -// -// /** -// * Returns the URI of the namespace at the given index. -// */ -// String getNamespaceURI(int index); -// -// /** -// * Returns the namespace context for the current position. -// */ -// NamespaceContext getNamespaceContext(); -// -// /** -// * Returns the type of the current event. -// */ -// int getEventType(); -// -// /** -// * Returns the string value of the current event. -// */ -// String getText(); -// -// /** -// * Returns the string value of the current event as a character array. -// */ -// char[] getTextCharacters(); -// -// /** -// * Copies the string value of the current event into the specified -// * character array. -// */ -// int getTextCharacters(int sourceStart, char[] target, -// int targetStart, int length) -// throws XMLStreamException; -// -// /** -// * Returns the offset of the first character in the text character array. -// */ -// int getTextStart(); -// -// /** -// * Returns the length of the characters in the text character array. -// */ -// int getTextLength(); -// -// /** -// * Returns the input encoding. -// */ -// String getEncoding(); -// -// /** -// * Indicates whether the current event has text. -// */ -// boolean hasText(); -// -// /** -// * Returns the current location of the parser cursor in the underlying -// * input source. -// */ -// Location getLocation(); -// -// /** -// * Returns the QName of the current element. -// * This method is only valid on a START_ELEMENT or END_ELEMENT event. -// */ -// QName getName(); -// -// /** -// * Returns the local-name of the current element. -// */ -// String getLocalName(); -// -// /** -// * Indicates whether the current event has a name. -// */ -// boolean hasName(); -// -// /** -// * Returns the namespace URI of the current element. -// */ -// String getNamespaceURI(); -// -// /** -// * Returns the namespace prefix of the current element. -// */ -// String getPrefix(); -// -// /** -// * Returns the XML version declared in the XML declaration. -// */ -// String getVersion(); -// -// /** -// * Returns the standalone flag declared in the XML declaration. -// */ -// boolean isStandalone(); -// -// /** -// * Indicates whether the standalone flag was set in the document. -// */ -// boolean standaloneSet(); -// -// /** -// * Returns the encoding declared in the XML declaration. -// */ -// String getCharacterEncodingScheme(); -// -// /** -// * Returns the target of the current processing instruction event. -// */ -// String getPITarget(); -// -// /** -// * Returns the data of the current processing instruction event. -// */ -// String getPIData(); +public interface XMLStreamReader extends XMLStreamConstants { + /** + * Get the value of a feature/property from the underlying implementation + * @param name The name of the property, may not be null + * @return The value of the property + * @throws IllegalArgumentException if name is null + */ + public Object getProperty(java.lang.String name) throws java.lang.IllegalArgumentException; + + /** + * Get next parsing event - a processor may return all contiguous + * character data in a single chunk, or it may split it into several chunks. + * If the property javax.xml.stream.isCoalescing is set to true + * element content must be coalesced and only one CHARACTERS event + * must be returned for contiguous element content or + * CDATA Sections. + * + * By default entity references must be + * expanded and reported transparently to the application. + * An exception will be thrown if an entity reference cannot be expanded. + * If element content is empty (i.e. content is "") then no CHARACTERS event will be reported. + * + *

      Given the following XML:
      + * <foo><!--description-->content text<![CDATA[<greeting>Hello</greeting>]]>other content</foo>
      + * The behavior of calling next() when being on foo will be:
      + * 1- the comment (COMMENT)
      + * 2- then the characters section (CHARACTERS)
      + * 3- then the CDATA section (another CHARACTERS)
      + * 4- then the next characters section (another CHARACTERS)
      + * 5- then the END_ELEMENT
      + * + *

      NOTE: empty element (such as <tag/>) will be reported + * with two separate events: START_ELEMENT, END_ELEMENT - This preserves + * parsing equivalency of empty element to <tag></tag>. + * + * This method will throw an IllegalStateException if it is called after hasNext() returns false. + * @see javax.xml.stream.events.XMLEvent + * @return the integer code corresponding to the current parse event + * @throws NoSuchElementException if this is called when hasNext() returns false + * @throws XMLStreamException if there is an error processing the underlying XML source + */ + public int next() throws XMLStreamException; + + /** + * Test if the current event is of the given type and if the namespace and name match the current + * namespace and name of the current event. If the namespaceURI is null it is not checked for equality, + * if the localName is null it is not checked for equality. + * @param type the event type + * @param namespaceURI the uri of the event, may be null + * @param localName the localName of the event, may be null + * @throws XMLStreamException if the required values are not matched. + */ + public void require(int type, String namespaceURI, String localName) throws XMLStreamException; + + /** + * Reads the content of a text-only element, an exception is thrown if this is + * not a text-only element. + * Regardless of value of javax.xml.stream.isCoalescing this method always returns coalesced content. + *
      Precondition: the current event is START_ELEMENT. + *
      Postcondition: the current event is the corresponding END_ELEMENT. + * + *
      The method does the following (implementations are free to optimized + * but must do equivalent processing): + *

      +   * if(getEventType() != XMLStreamConstants.START_ELEMENT) {
      +   * throw new XMLStreamException(
      +   * "parser must be on START_ELEMENT to read next text", getLocation());
      +   * }
      +   * int eventType = next();
      +   * StringBuffer content = new StringBuffer();
      +   * while(eventType != XMLStreamConstants.END_ELEMENT ) {
      +   * if(eventType == XMLStreamConstants.CHARACTERS
      +   * || eventType == XMLStreamConstants.CDATA
      +   * || eventType == XMLStreamConstants.SPACE
      +   * || eventType == XMLStreamConstants.ENTITY_REFERENCE) {
      +   * buf.append(getText());
      +   * } else if(eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
      +   * || eventType == XMLStreamConstants.COMMENT) {
      +   * // skipping
      +   * } else if(eventType == XMLStreamConstants.END_DOCUMENT) {
      +   * throw new XMLStreamException(
      +   * "unexpected end of document when reading element text content", this);
      +   * } else if(eventType == XMLStreamConstants.START_ELEMENT) {
      +   * throw new XMLStreamException(
      +   * "element text content may not contain START_ELEMENT", getLocation());
      +   * } else {
      +   * throw new XMLStreamException(
      +   * "Unexpected event type "+eventType, getLocation());
      +   * }
      +   * eventType = next();
      +   * }
      +   * return buf.toString();
      +   * 
      + * + * @throws XMLStreamException if the current event is not a START_ELEMENT + * or if a non text element is encountered + */ + public String getElementText() throws XMLStreamException; + + /** + * Skips any white space (isWhiteSpace() returns true), COMMENT, + * or PROCESSING_INSTRUCTION, + * until a START_ELEMENT or END_ELEMENT is reached. + * If other than white space characters, COMMENT, PROCESSING_INSTRUCTION, START_ELEMENT, END_ELEMENT + * are encountered, an exception is thrown. This method should + * be used when processing element-only content seperated by white space. + * + *
      Precondition: none + *
      Postcondition: the current event is START_ELEMENT or END_ELEMENT + * and cursor may have moved over any whitespace event. + * + *
      Essentially it does the following (implementations are free to optimized + * but must do equivalent processing): + *
      +   * int eventType = next();
      +   * while((eventType == XMLStreamConstants.CHARACTERS && isWhiteSpace()) // skip whitespace
      +   * || (eventType == XMLStreamConstants.CDATA && isWhiteSpace())
      +   * // skip whitespace
      +   * || eventType == XMLStreamConstants.SPACE
      +   * || eventType == XMLStreamConstants.PROCESSING_INSTRUCTION
      +   * || eventType == XMLStreamConstants.COMMENT
      +   * ) {
      +   * eventType = next();
      +   * }
      +   * if (eventType != XMLStreamConstants.START_ELEMENT && eventType != XMLStreamConstants.END_ELEMENT) {
      +   * throw new String XMLStreamException("expected start or end tag", getLocation());
      +   * }
      +   * return eventType;
      +   * 
      + * + * @return the event type of the element read (START_ELEMENT or END_ELEMENT) + * @throws XMLStreamException if the current event is not white space, PROCESSING_INSTRUCTION, + * START_ELEMENT or END_ELEMENT + * @throws NoSuchElementException if this is called when hasNext() returns false + */ + public int nextTag() throws XMLStreamException; + + /** + * Returns true if there are more parsing events and false + * if there are no more events. This method will return + * false if the current state of the XMLStreamReader is + * END_DOCUMENT + * @return true if there are more events, false otherwise + * @throws XMLStreamException if there is a fatal error detecting the next state + */ + public boolean hasNext() throws XMLStreamException; + + /** + * Frees any resources associated with this Reader. This method does not close the + * underlying input source. + * @throws XMLStreamException if there are errors freeing associated resources + */ + public void close() throws XMLStreamException; + + /** + * Return the uri for the given prefix. + * The uri returned depends on the current state of the processor. + * + *

      NOTE:The 'xml' prefix is bound as defined in + * Namespaces in XML + * specification to "http://www.w3.org/XML/1998/namespace". + * + *

      NOTE: The 'xmlns' prefix must be resolved to following namespace + * http://www.w3.org/2000/xmlns/ + * @param prefix The prefix to lookup, may not be null + * @return the uri bound to the given prefix or null if it is not bound + * @throws IllegalArgumentException if the prefix is null + */ + public String getNamespaceURI(String prefix); + + /** + * Returns true if the cursor points to a start tag (otherwise false) + * @return true if the cursor points to a start tag, false otherwise + */ + public boolean isStartElement(); + + /** + * Returns true if the cursor points to an end tag (otherwise false) + * @return true if the cursor points to an end tag, false otherwise + */ + public boolean isEndElement(); + + /** + * Returns true if the cursor points to a character data event + * @return true if the cursor points to character data, false otherwise + */ + public boolean isCharacters(); + + /** + * Returns true if the cursor points to a character data event + * that consists of all whitespace + * @return true if the cursor points to all whitespace, false otherwise + */ + public boolean isWhiteSpace(); + + + /** + * Returns the normalized attribute value of the + * attribute with the namespace and localName + * If the namespaceURI is null the namespace + * is not checked for equality + * @param namespaceURI the namespace of the attribute + * @param localName the local name of the attribute, cannot be null + * @return returns the value of the attribute , returns null if not found + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public String getAttributeValue(String namespaceURI, + String localName); + + /** + * Returns the count of attributes on this START_ELEMENT, + * this method is only valid on a START_ELEMENT or ATTRIBUTE. This + * count excludes namespace definitions. Attribute indices are + * zero-based. + * @return returns the number of attributes + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public int getAttributeCount(); + + /** Returns the qname of the attribute at the provided index + * + * @param index the position of the attribute + * @return the QName of the attribute + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public QName getAttributeName(int index); + + /** + * Returns the namespace of the attribute at the provided + * index + * @param index the position of the attribute + * @return the namespace URI (can be null) + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public String getAttributeNamespace(int index); + + /** + * Returns the localName of the attribute at the provided + * index + * @param index the position of the attribute + * @return the localName of the attribute + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public String getAttributeLocalName(int index); + + /** + * Returns the prefix of this attribute at the + * provided index + * @param index the position of the attribute + * @return the prefix of the attribute + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public String getAttributePrefix(int index); + + /** + * Returns the XML type of the attribute at the provided + * index + * @param index the position of the attribute + * @return the XML type of the attribute + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public String getAttributeType(int index); + + /** + * Returns the value of the attribute at the + * index + * @param index the position of the attribute + * @return the attribute value + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public String getAttributeValue(int index); + + /** + * Returns a boolean which indicates if this + * attribute was created by default + * @param index the position of the attribute + * @return true if this is a default attribute + * @throws IllegalStateException if this is not a START_ELEMENT or ATTRIBUTE + */ + public boolean isAttributeSpecified(int index); + + /** + * Returns the count of namespaces declared on this START_ELEMENT or END_ELEMENT, + * this method is only valid on a START_ELEMENT, END_ELEMENT or NAMESPACE. On + * an END_ELEMENT the count is of the namespaces that are about to go + * out of scope. This is the equivalent of the information reported + * by SAX callback for an end element event. + * @return returns the number of namespace declarations on this specific element + * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE + */ + public int getNamespaceCount(); + + /** + * Returns the prefix for the namespace declared at the + * index. Returns null if this is the default namespace + * declaration + * + * @param index the position of the namespace declaration + * @return returns the namespace prefix + * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE + */ + public String getNamespacePrefix(int index); + + /** + * Returns the uri for the namespace declared at the + * index. + * + * @param index the position of the namespace declaration + * @return returns the namespace uri + * @throws IllegalStateException if this is not a START_ELEMENT, END_ELEMENT or NAMESPACE + */ + public String getNamespaceURI(int index); + + /** + * Returns a read only namespace context for the current + * position. The context is transient and only valid until + * a call to next() changes the state of the reader. + * @return return a namespace context + */ + public NamespaceContext getNamespaceContext(); + + /** + * Returns a reader that points to the current start element + * and all of its contents. Throws an XMLStreamException if the + * cursor does not point to a START_ELEMENT.

      + * The sub stream is read from it MUST be read before the parent stream is + * moved on, if not any call on the sub stream will cause an XMLStreamException to be + * thrown. The parent stream will always return the same result from next() + * whatever is done to the sub stream. + * @return an XMLStreamReader which points to the next element + */ + // public XMLStreamReader subReader() throws XMLStreamException; + + /** + * Allows the implementation to reset and reuse any underlying tables + */ + // public void recycle() throws XMLStreamException; + + /** + * Returns an integer code that indicates the type + * of the event the cursor is pointing to. + */ + public int getEventType(); + + /** + * Returns the current value of the parse event as a string, + * this returns the string value of a CHARACTERS event, + * returns the value of a COMMENT, the replacement value + * for an ENTITY_REFERENCE, the string value of a CDATA section, + * the string value for a SPACE event, + * or the String value of the internal subset of the DTD. + * If an ENTITY_REFERENCE has been resolved, any character data + * will be reported as CHARACTERS events. + * @return the current text or null + * @throws java.lang.IllegalStateException if this state is not + * a valid text state. + */ + public String getText(); + + /** + * Returns an array which contains the characters from this event. + * This array should be treated as read-only and transient. I.e. the array will + * contain the text characters until the XMLStreamReader moves on to the next event. + * Attempts to hold onto the character array beyond that time or modify the + * contents of the array are breaches of the contract for this interface. + * @return the current text or an empty array + * @throws java.lang.IllegalStateException if this state is not + * a valid text state. + */ + public char[] getTextCharacters(); + + /** + * Gets the the text associated with a CHARACTERS, SPACE or CDATA event. + * Text starting a "sourceStart" is copied into "target" starting at "targetStart". + * Up to "length" characters are copied. The number of characters actually copied is returned. + * + * The "sourceStart" argument must be greater or equal to 0 and less than or equal to + * the number of characters associated with the event. Usually, one requests text starting at a "sourceStart" of 0. + * If the number of characters actually copied is less than the "length", then there is no more text. + * Otherwise, subsequent calls need to be made until all text has been retrieved. For example: + * + * + * int length = 1024; + * char[] myBuffer = new char[ length ]; + * + * for ( int sourceStart = 0 ; ; sourceStart += length ) + * { + * int nCopied = stream.getTextCharacters( sourceStart, myBuffer, 0, length ); + * + * if (nCopied < length) + * break; + * } + * + * XMLStreamException may be thrown if there are any XML errors in the underlying source. + * The "targetStart" argument must be greater than or equal to 0 and less than the length of "target", + * Length must be greater than 0 and "targetStart + length" must be less than or equal to length of "target". + * + * @param sourceStart the index of the first character in the source array to copy + * @param target the destination array + * @param targetStart the start offset in the target array + * @param length the number of characters to copy + * @return the number of characters actually copied + * @throws XMLStreamException if the underlying XML source is not well-formed + * @throws IndexOutOfBoundsException if targetStart < 0 or > than the length of target + * @throws IndexOutOfBoundsException if length < 0 or targetStart + length > length of target + * @throws UnsupportedOperationException if this method is not supported + * @throws NullPointerException is if target is null + */ + public int getTextCharacters(int sourceStart, char[] target, int targetStart, int length) + throws XMLStreamException; + + /** + * Gets the text associated with a CHARACTERS, SPACE or CDATA event. Allows the underlying + * implementation to return the text as a stream of characters. The reference to the + * Reader returned by this method is only valid until next() is called. + * + * All characters must have been checked for well-formedness. + * + *

      This method is optional and will throw UnsupportedOperationException if it is not supported. + * @throws UnsupportedOperationException if this method is not supported + * @throws IllegalStateException if this is not a valid text state + */ + //public Reader getTextStream(); + + /** + * Returns the offset into the text character array where the first + * character (of this text event) is stored. + * @throws java.lang.IllegalStateException if this state is not + * a valid text state. + */ + public int getTextStart(); + + /** + * Returns the length of the sequence of characters for this + * Text event within the text character array. + * @throws java.lang.IllegalStateException if this state is not + * a valid text state. + */ + public int getTextLength(); + + /** + * Return input encoding if known or null if unknown. + * @return the encoding of this instance or null + */ + public String getEncoding(); + + /** + * Return true if the current event has text, false otherwise + * The following events have text: + * CHARACTERS,DTD ,ENTITY_REFERENCE, COMMENT, SPACE + */ + public boolean hasText(); + + /** + * Return the current location of the processor. + * If the Location is unknown the processor should return + * an implementation of Location that returns -1 for the + * location and null for the publicId and systemId. + * The location information is only valid until next() is + * called. + */ + public Location getLocation(); + + /** + * Returns a QName for the current START_ELEMENT or END_ELEMENT event + * @return the QName for the current START_ELEMENT or END_ELEMENT event + * @throws IllegalStateException if this is not a START_ELEMENT or + * END_ELEMENT + */ + public QName getName(); + + /** + * Returns the (local) name of the current event. + * For START_ELEMENT or END_ELEMENT returns the (local) name of the current element. + * For ENTITY_REFERENCE it returns entity name. + * The current event must be START_ELEMENT or END_ELEMENT, + * or ENTITY_REFERENCE + * @return the localName + * @throws IllegalStateException if this not a START_ELEMENT, + * END_ELEMENT or ENTITY_REFERENCE + */ + public String getLocalName(); + + /** + * returns true if the current event has a name (is a START_ELEMENT or END_ELEMENT) + * returns false otherwise + */ + public boolean hasName(); + + /** + * If the current event is a START_ELEMENT or END_ELEMENT this method + * returns the URI of the prefix or the default namespace. + * Returns null if the event does not have a prefix. + * @return the URI bound to this elements prefix, the default namespace, or null + */ + public String getNamespaceURI(); + + /** + * Returns the prefix of the current event or null if the event does not have a prefix + * @return the prefix or null + */ + public String getPrefix(); + + /** + * Get the xml version declared on the xml declaration + * Returns null if none was declared + * @return the XML version or null + */ + public String getVersion(); + + /** + * Get the standalone declaration from the xml declaration + * @return true if this is standalone, or false otherwise + */ + public boolean isStandalone(); + + /** + * Checks if standalone was set in the document + * @return true if standalone was set in the document, or false otherwise + */ + public boolean standaloneSet(); + + /** + * Returns the character encoding declared on the xml declaration + * Returns null if none was declared + * @return the encoding declared in the document or null + */ + public String getCharacterEncodingScheme(); + + /** + * Get the target of a processing instruction + * @return the target or null + */ + public String getPITarget(); + /** + * Get the data section of a processing instruction + * @return the data or null + */ + public String getPIData(); } diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamWriter.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamWriter.java new file mode 100644 index 000000000..f3615892b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/XMLStreamWriter.java @@ -0,0 +1,528 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream; + +import javax.xml.namespace.NamespaceContext; + +/** + * The XMLStreamWriter interface specifies how to write XML. The XMLStreamWriter does + * not perform well formedness checking on its input. However + * the writeCharacters method is required to escape & , < and > + * For attribute values the writeAttribute method will escape the + * above characters plus " to ensure that all character content + * and attribute values are well formed. + * + * Each NAMESPACE + * and ATTRIBUTE must be individually written. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      XML Namespaces, javax.xml.stream.isRepairingNamespaces and write method behaviour
      Method isRepairingNamespaces == trueisRepairingNamespaces == false
      namespaceURI boundnamespaceURI unboundnamespaceURI boundnamespaceURI unbound
      writeAttribute(namespaceURI, localName, value) + * + * prefix:localName="value" [1] + * + * + * xmlns:{generated}="namespaceURI" {generated}:localName="value" + * + * + * prefix:localName="value" [1] + * + * + * XMLStreamException + *
      writeAttribute(prefix, namespaceURI, localName, value) + * + * bound to same prefix:
      + * prefix:localName="value" [1]
      + *
      + * bound to different prefix:
      + * xmlns:{generated}="namespaceURI" {generated}:localName="value" + *
      + * + * xmlns:prefix="namespaceURI" prefix:localName="value" [3] + * + * + * bound to same prefix:
      + * prefix:localName="value" [1][2]
      + *
      + * bound to different prefix:
      + * XMLStreamException[2] + *
      + * + * xmlns:prefix="namespaceURI" prefix:localName="value" [2][5] + *
      writeStartElement(namespaceURI, localName)
      + *
      + * writeEmptyElement(namespaceURI, localName)
      + * + * <prefix:localName> [1] + * + * + * <{generated}:localName xmlns:{generated}="namespaceURI"> + * + * + * <prefix:localName> [1] + * + * + * XMLStreamException + *
      writeStartElement(prefix, localName, namespaceURI)
      + *
      + * writeEmptyElement(prefix, localName, namespaceURI)
      + * + * bound to same prefix:
      + * <prefix:localName> [1]
      + *
      + * bound to different prefix:
      + * <{generated}:localName xmlns:{generated}="namespaceURI"> + *
      + * + * <prefix:localName xmlns:prefix="namespaceURI"> [4] + * + * + * bound to same prefix:
      + * <prefix:localName> [1]
      + *
      + * bound to different prefix:
      + * XMLStreamException + *
      + * + * <prefix:localName>  + *
      + * Notes: + *
        + *
      • [1] if namespaceURI == default Namespace URI, then no prefix is written
      • + *
      • [2] if prefix == "" || null && namespaceURI == "", then no prefix or Namespace declaration is generated or written
      • + *
      • [3] if prefix == "" || null, then a prefix is randomly generated
      • + *
      • [4] if prefix == "" || null, then it is treated as the default Namespace and no prefix is generated or written, an xmlns declaration is generated and written if the namespaceURI is unbound
      • + *
      • [5] if prefix == "" || null, then it is treated as an invalid attempt to define the default Namespace and an XMLStreamException is thrown
      • + *
      + *
      + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see XMLOutputFactory + * @see XMLStreamReader + * @since 1.6 + */ +public interface XMLStreamWriter { + + /** + * Writes a start tag to the output. All writeStartElement methods + * open a new scope in the internal namespace context. Writing the + * corresponding EndElement causes the scope to be closed. + * @param localName local name of the tag, may not be null + * @throws XMLStreamException + */ + public void writeStartElement(String localName) + throws XMLStreamException; + + /** + * Writes a start tag to the output + * @param namespaceURI the namespaceURI of the prefix to use, may not be null + * @param localName local name of the tag, may not be null + * @throws XMLStreamException if the namespace URI has not been bound to a prefix and + * javax.xml.stream.isRepairingNamespaces has not been set to true + */ + public void writeStartElement(String namespaceURI, String localName) + throws XMLStreamException; + + /** + * Writes a start tag to the output + * @param localName local name of the tag, may not be null + * @param prefix the prefix of the tag, may not be null + * @param namespaceURI the uri to bind the prefix to, may not be null + * @throws XMLStreamException + */ + public void writeStartElement(String prefix, + String localName, + String namespaceURI) + throws XMLStreamException; + + /** + * Writes an empty element tag to the output + * @param namespaceURI the uri to bind the tag to, may not be null + * @param localName local name of the tag, may not be null + * @throws XMLStreamException if the namespace URI has not been bound to a prefix and + * javax.xml.stream.isRepairingNamespaces has not been set to true + */ + public void writeEmptyElement(String namespaceURI, String localName) + throws XMLStreamException; + + /** + * Writes an empty element tag to the output + * @param prefix the prefix of the tag, may not be null + * @param localName local name of the tag, may not be null + * @param namespaceURI the uri to bind the tag to, may not be null + * @throws XMLStreamException + */ + public void writeEmptyElement(String prefix, String localName, String namespaceURI) + throws XMLStreamException; + + /** + * Writes an empty element tag to the output + * @param localName local name of the tag, may not be null + * @throws XMLStreamException + */ + public void writeEmptyElement(String localName) + throws XMLStreamException; + + /** + * Writes string data to the output without checking for well formedness. + * The data is opaque to the XMLStreamWriter, i.e. the characters are written + * blindly to the underlying output. If the method cannot be supported + * in the currrent writing context the implementation may throw a + * UnsupportedOperationException. For example note that any + * namespace declarations, end tags, etc. will be ignored and could + * interfere with proper maintanence of the writers internal state. + * + * @param data the data to write + */ + // public void writeRaw(String data) throws XMLStreamException; + + /** + * Writes an end tag to the output relying on the internal + * state of the writer to determine the prefix and local name + * of the event. + * @throws XMLStreamException + */ + public void writeEndElement() + throws XMLStreamException; + + /** + * Closes any start tags and writes corresponding end tags. + * @throws XMLStreamException + */ + public void writeEndDocument() + throws XMLStreamException; + + /** + * Close this writer and free any resources associated with the + * writer. This must not close the underlying output stream. + * @throws XMLStreamException + */ + public void close() + throws XMLStreamException; + + /** + * Write any cached data to the underlying output mechanism. + * @throws XMLStreamException + */ + public void flush() + throws XMLStreamException; + + /** + * Writes an attribute to the output stream without + * a prefix. + * @param localName the local name of the attribute + * @param value the value of the attribute + * @throws IllegalStateException if the current state does not allow Attribute writing + * @throws XMLStreamException + */ + public void writeAttribute(String localName, String value) + throws XMLStreamException; + + /** + * Writes an attribute to the output stream + * @param prefix the prefix for this attribute + * @param namespaceURI the uri of the prefix for this attribute + * @param localName the local name of the attribute + * @param value the value of the attribute + * @throws IllegalStateException if the current state does not allow Attribute writing + * @throws XMLStreamException if the namespace URI has not been bound to a prefix and + * javax.xml.stream.isRepairingNamespaces has not been set to true + */ + + public void writeAttribute(String prefix, + String namespaceURI, + String localName, + String value) + throws XMLStreamException; + + /** + * Writes an attribute to the output stream + * @param namespaceURI the uri of the prefix for this attribute + * @param localName the local name of the attribute + * @param value the value of the attribute + * @throws IllegalStateException if the current state does not allow Attribute writing + * @throws XMLStreamException if the namespace URI has not been bound to a prefix and + * javax.xml.stream.isRepairingNamespaces has not been set to true + */ + public void writeAttribute(String namespaceURI, + String localName, + String value) + throws XMLStreamException; + + /** + * Writes a namespace to the output stream + * If the prefix argument to this method is the empty string, + * "xmlns", or null this method will delegate to writeDefaultNamespace + * + * @param prefix the prefix to bind this namespace to + * @param namespaceURI the uri to bind the prefix to + * @throws IllegalStateException if the current state does not allow Namespace writing + * @throws XMLStreamException + */ + public void writeNamespace(String prefix, String namespaceURI) + throws XMLStreamException; + + /** + * Writes the default namespace to the stream + * @param namespaceURI the uri to bind the default namespace to + * @throws IllegalStateException if the current state does not allow Namespace writing + * @throws XMLStreamException + */ + public void writeDefaultNamespace(String namespaceURI) + throws XMLStreamException; + + /** + * Writes an xml comment with the data enclosed + * @param data the data contained in the comment, may be null + * @throws XMLStreamException + */ + public void writeComment(String data) + throws XMLStreamException; + + /** + * Writes a processing instruction + * @param target the target of the processing instruction, may not be null + * @throws XMLStreamException + */ + public void writeProcessingInstruction(String target) + throws XMLStreamException; + + /** + * Writes a processing instruction + * @param target the target of the processing instruction, may not be null + * @param data the data contained in the processing instruction, may not be null + * @throws XMLStreamException + */ + public void writeProcessingInstruction(String target, + String data) + throws XMLStreamException; + + /** + * Writes a CData section + * @param data the data contained in the CData Section, may not be null + * @throws XMLStreamException + */ + public void writeCData(String data) + throws XMLStreamException; + + /** + * Write a DTD section. This string represents the entire doctypedecl production + * from the XML 1.0 specification. + * + * @param dtd the DTD to be written + * @throws XMLStreamException + */ + public void writeDTD(String dtd) + throws XMLStreamException; + + /** + * Writes an entity reference + * @param name the name of the entity + * @throws XMLStreamException + */ + public void writeEntityRef(String name) + throws XMLStreamException; + + /** + * Write the XML Declaration. Defaults the XML version to 1.0, and the encoding to utf-8 + * @throws XMLStreamException + */ + public void writeStartDocument() + throws XMLStreamException; + + /** + * Write the XML Declaration. Defaults the XML version to 1.0 + * @param version version of the xml document + * @throws XMLStreamException + */ + public void writeStartDocument(String version) + throws XMLStreamException; + + /** + * Write the XML Declaration. Note that the encoding parameter does + * not set the actual encoding of the underlying output. That must + * be set when the instance of the XMLStreamWriter is created using the + * XMLOutputFactory + * @param encoding encoding of the xml declaration + * @param version version of the xml document + * @throws XMLStreamException If given encoding does not match encoding + * of the underlying stream + */ + public void writeStartDocument(String encoding, + String version) + throws XMLStreamException; + + /** + * Write text to the output + * @param text the value to write + * @throws XMLStreamException + */ + public void writeCharacters(String text) + throws XMLStreamException; + + /** + * Write text to the output + * @param text the value to write + * @param start the starting position in the array + * @param len the number of characters to write + * @throws XMLStreamException + */ + public void writeCharacters(char[] text, int start, int len) + throws XMLStreamException; + + /** + * Gets the prefix the uri is bound to + * @return the prefix or null + * @throws XMLStreamException + */ + public String getPrefix(String uri) + throws XMLStreamException; + + /** + * Sets the prefix the uri is bound to. This prefix is bound + * in the scope of the current START_ELEMENT / END_ELEMENT pair. + * If this method is called before a START_ELEMENT has been written + * the prefix is bound in the root scope. + * @param prefix the prefix to bind to the uri, may not be null + * @param uri the uri to bind to the prefix, may be null + * @throws XMLStreamException + */ + public void setPrefix(String prefix, String uri) + throws XMLStreamException; + + + /** + * Binds a URI to the default namespace + * This URI is bound + * in the scope of the current START_ELEMENT / END_ELEMENT pair. + * If this method is called before a START_ELEMENT has been written + * the uri is bound in the root scope. + * @param uri the uri to bind to the default namespace, may be null + * @throws XMLStreamException + */ + public void setDefaultNamespace(String uri) + throws XMLStreamException; + + /** + * Sets the current namespace context for prefix and uri bindings. + * This context becomes the root namespace context for writing and + * will replace the current root namespace context. Subsequent calls + * to setPrefix and setDefaultNamespace will bind namespaces using + * the context passed to the method as the root context for resolving + * namespaces. This method may only be called once at the start of + * the document. It does not cause the namespaces to be declared. + * If a namespace URI to prefix mapping is found in the namespace + * context it is treated as declared and the prefix may be used + * by the StreamWriter. + * @param context the namespace context to use for this writer, may not be null + * @throws XMLStreamException + */ + public void setNamespaceContext(NamespaceContext context) + throws XMLStreamException; + + /** + * Returns the current namespace context. + * @return the current NamespaceContext + */ + public NamespaceContext getNamespaceContext(); + + /** + * Get the value of a feature/property from the underlying implementation + * @param name The name of the property, may not be null + * @return The value of the property + * @throws IllegalArgumentException if the property is not supported + * @throws NullPointerException if the name is null + */ + public Object getProperty(java.lang.String name) throws IllegalArgumentException; + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Attribute.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Attribute.java new file mode 100644 index 000000000..248d06052 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Attribute.java @@ -0,0 +1,69 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +import javax.xml.namespace.QName; + +/** + * An interface that contains information about an attribute. Attributes are reported + * as a set of events accessible from a StartElement. Other applications may report + * Attributes as first-order events, for example as the results of an XPath expression. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see StartElement + * @since 1.6 + */ +public interface Attribute extends XMLEvent { + + /** + * Returns the QName for this attribute + */ + QName getName(); + + /** + * Gets the normalized value of this attribute + */ + public String getValue(); + + /** + * Gets the type of this attribute, default is + * the String "CDATA" + * @return the type as a String, default is "CDATA" + */ + public String getDTDType(); + + /** + * A flag indicating whether this attribute was actually + * specified in the start-tag of its element, or was defaulted from the schema. + * @return returns true if this was specified in the start element + */ + public boolean isSpecified(); + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Characters.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Characters.java new file mode 100644 index 000000000..76dab7f93 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Characters.java @@ -0,0 +1,76 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +/** + * This describes the interface to Characters events. + * All text events get reported as Characters events. + * Content, CData and whitespace are all reported as + * Characters events. IgnorableWhitespace, in most cases, + * will be set to false unless an element declaration of element + * content is present for the current element. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface Characters extends XMLEvent { + /** + * Get the character data of this event + */ + public String getData(); + + /** + * Returns true if this set of Characters + * is all whitespace. Whitespace inside a document + * is reported as CHARACTERS. This method allows + * checking of CHARACTERS events to see if they + * are composed of only whitespace characters + */ + public boolean isWhiteSpace(); + + /** + * Returns true if this is a CData section. If this + * event is CData its event type will be CDATA + * + * If javax.xml.stream.isCoalescing is set to true CDATA Sections + * that are surrounded by non CDATA characters will be reported + * as a single Characters event. This method will return false + * in this case. + */ + public boolean isCData(); + + /** + * Return true if this is ignorableWhiteSpace. If + * this event is ignorableWhiteSpace its event type will + * be SPACE. + */ + public boolean isIgnorableWhiteSpace(); + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Comment.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Comment.java new file mode 100644 index 000000000..8ed0929f5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Comment.java @@ -0,0 +1,45 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +/** + * An interface for comment events + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface Comment extends XMLEvent { + + /** + * Return the string data of the comment, returns empty string if it + * does not exist + */ + public String getText(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/DTD.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/DTD.java new file mode 100644 index 000000000..3b0bb9f0b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/DTD.java @@ -0,0 +1,74 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +import java.util.List; + +/** + * This is the top level interface for events dealing with DTDs + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface DTD extends XMLEvent { + + /** + * Returns the entire Document Type Declaration as a string, including + * the internal DTD subset. + * This may be null if there is not an internal subset. + * If it is not null it must return the entire + * Document Type Declaration which matches the doctypedecl + * production in the XML 1.0 specification + */ + String getDocumentTypeDeclaration(); + + /** + * Returns an implementation defined representation of the DTD. + * This method may return null if no representation is available. + */ + Object getProcessedDTD(); + + /** + * Return a List containing the notations declared in the DTD. + * This list must contain NotationDeclaration events. + * @see NotationDeclaration + * @return an unordered list of NotationDeclaration events + */ + List getNotations(); + + /** + * Return a List containing the general entities, + * both external and internal, declared in the DTD. + * This list must contain EntityDeclaration events. + * @see EntityDeclaration + * @return an unordered list of EntityDeclaration events + */ + List getEntities(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EndDocument.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EndDocument.java new file mode 100644 index 000000000..0e7ab312a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EndDocument.java @@ -0,0 +1,42 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +/** + * A marker interface for the end of the document + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface EndDocument extends XMLEvent { + /** + * No methods are defined in this interface. + */ +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EndElement.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EndElement.java new file mode 100644 index 000000000..fd6d5f2b4 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EndElement.java @@ -0,0 +1,59 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +import java.util.Iterator; +import javax.xml.namespace.QName; +/** + * An interface for the end element event. An EndElement is reported + * for each End Tag in the document. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see XMLEvent + * @since 1.6 + */ +public interface EndElement extends XMLEvent { + + /** + * Get the name of this event + * @return the qualified name of this event + */ + public QName getName(); + + /** + * Returns an Iterator of namespaces that have gone out + * of scope. Returns an empty iterator if no namespaces have gone + * out of scope. + * @return an Iterator over Namespace interfaces, or an + * empty iterator + */ + public Iterator getNamespaces(); + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EntityDeclaration.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EntityDeclaration.java new file mode 100644 index 000000000..74610dac2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EntityDeclaration.java @@ -0,0 +1,80 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; +/** + * An interface for handling Entity Declarations + * + * This interface is used to record and report unparsed entity declarations. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface EntityDeclaration extends XMLEvent { + + /** + * The entity's public identifier, or null if none was given + * @return the public ID for this declaration or null + */ + String getPublicId(); + + /** + * The entity's system identifier. + * @return the system ID for this declaration or null + */ + String getSystemId(); + + /** + * The entity's name + * @return the name, may not be null + */ + String getName(); + + /** + * The name of the associated notation. + * @return the notation name + */ + String getNotationName(); + + /** + * The replacement text of the entity. + * This method will only return non-null + * if this is an internal entity. + * @return null or the replacment text + */ + String getReplacementText(); + + /** + * Get the base URI for this reference + * or null if this information is not available + * @return the base URI or null + */ + String getBaseURI(); + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EntityReference.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EntityReference.java new file mode 100644 index 000000000..8871460c2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/EntityReference.java @@ -0,0 +1,62 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; +/** + * An interface for handling Entity events. + * + * This event reports entities that have not been resolved + * and reports their replacement text unprocessed (if + * available). This event will be reported if javax.xml.stream.isReplacingEntityReferences + * is set to false. If javax.xml.stream.isReplacingEntityReferences is set to true + * entity references will be resolved transparently. + * + * Entities are handled in two possible ways: + * + * (1) If javax.xml.stream.isReplacingEntityReferences is set to true + * all entity references are resolved and reported as markup transparently. + * (2) If javax.xml.stream.isReplacingEntityReferences is set to false + * Entity references are reported as an EntityReference Event. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface EntityReference extends XMLEvent { + + /** + * Return the declaration of this entity. + */ + EntityDeclaration getDeclaration(); + + /** + * The name of the entity + * @return the entity's name, may not be null + */ + String getName(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Namespace.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Namespace.java new file mode 100644 index 000000000..df5e6bd97 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/Namespace.java @@ -0,0 +1,59 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +import javax.xml.namespace.QName; + +/** + * An interface that contains information about a namespace. + * Namespaces are accessed from a StartElement. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see StartElement + * @since 1.6 + */ +public interface Namespace extends Attribute { + + /** + * Gets the prefix, returns "" if this is a default + * namespace declaration. + */ + public String getPrefix(); + + /** + * Gets the uri bound to the prefix of this namespace + */ + public String getNamespaceURI(); + + /** + * returns true if this attribute declares the default namespace + */ + public boolean isDefaultNamespaceDeclaration(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/NotationDeclaration.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/NotationDeclaration.java new file mode 100644 index 000000000..fc5f790f9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/NotationDeclaration.java @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; +/** + * An interface for handling Notation Declarations + * + * Receive notification of a notation declaration event. + * It is up to the application to record the notation for later reference, + * At least one of publicId and systemId must be non-null. + * There is no guarantee that the notation declaration + * will be reported before any unparsed entities that use it. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface NotationDeclaration extends XMLEvent { + /** + * The notation name. + */ + String getName(); + + /** + * The notation's public identifier, or null if none was given. + */ + String getPublicId(); + + /** + * The notation's system identifier, or null if none was given. + */ + String getSystemId(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/ProcessingInstruction.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/ProcessingInstruction.java new file mode 100644 index 000000000..9ee77d890 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/ProcessingInstruction.java @@ -0,0 +1,52 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; +/** + * An interface that describes the data found in processing instructions + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface ProcessingInstruction extends XMLEvent { + + /** + * The target section of the processing instruction + * + * @return the String value of the PI or null + */ + public String getTarget(); + + /** + * The data section of the processing instruction + * + * @return the String value of the PI's data or null + */ + public String getData(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/StartDocument.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/StartDocument.java new file mode 100644 index 000000000..d46c070cf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/StartDocument.java @@ -0,0 +1,74 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; +/** + * An interface for the start document event + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface StartDocument extends XMLEvent { + + /** + * Returns the system ID of the XML data + * @return the system ID, defaults to "" + */ + public String getSystemId(); + + /** + * Returns the encoding style of the XML data + * @return the character encoding, defaults to "UTF-8" + */ + public String getCharacterEncodingScheme(); + + /** + * Returns true if CharacterEncodingScheme was set in + * the encoding declaration of the document + */ + public boolean encodingSet(); + + /** + * Returns if this XML is standalone + * @return the standalone state of XML, defaults to "no" + */ + public boolean isStandalone(); + + /** + * Returns true if the standalone attribute was set in + * the encoding declaration of the document. + */ + public boolean standaloneSet(); + + /** + * Returns the version of XML of this XML stream + * @return the version of XML, defaults to "1.0" + */ + public String getVersion(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/StartElement.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/StartElement.java new file mode 100644 index 000000000..9b286a6e4 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/StartElement.java @@ -0,0 +1,117 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +import javax.xml.namespace.QName; +import javax.xml.namespace.NamespaceContext; + +import java.util.Map; +import java.util.Iterator; + +/** + * The StartElement interface provides access to information about + * start elements. A StartElement is reported for each Start Tag + * in the document. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface StartElement extends XMLEvent { + + /** + * Get the name of this event + * @return the qualified name of this event + */ + public QName getName(); + + /** + * Returns an Iterator of non-namespace declared attributes declared on + * this START_ELEMENT, + * returns an empty iterator if there are no attributes. The + * iterator must contain only implementations of the javax.xml.stream.Attribute + * interface. Attributes are fundamentally unordered and may not be reported + * in any order. + * + * @return a readonly Iterator over Attribute interfaces, or an + * empty iterator + */ + public Iterator getAttributes(); + + /** + * Returns an Iterator of namespaces declared on this element. + * This Iterator does not contain previously declared namespaces + * unless they appear on the current START_ELEMENT. + * Therefore this list may contain redeclared namespaces and duplicate namespace + * declarations. Use the getNamespaceContext() method to get the + * current context of namespace declarations. + * + *

      The iterator must contain only implementations of the + * javax.xml.stream.Namespace interface. + * + *

      A Namespace isA Attribute. One + * can iterate over a list of namespaces as a list of attributes. + * However this method returns only the list of namespaces + * declared on this START_ELEMENT and does not + * include the attributes declared on this START_ELEMENT. + * + * Returns an empty iterator if there are no namespaces. + * + * @return a readonly Iterator over Namespace interfaces, or an + * empty iterator + * + */ + public Iterator getNamespaces(); + + /** + * Returns the attribute referred to by this name + * @param name the qname of the desired name + * @return the attribute corresponding to the name value or null + */ + public Attribute getAttributeByName(QName name); + + /** + * Gets a read-only namespace context. If no context is + * available this method will return an empty namespace context. + * The NamespaceContext contains information about all namespaces + * in scope for this StartElement. + * + * @return the current namespace context + */ + public NamespaceContext getNamespaceContext(); + + /** + * Gets the value that the prefix is bound to in the + * context of this element. Returns null if + * the prefix is not bound in this context + * @param prefix the prefix to lookup + * @return the uri bound to the prefix or null + */ + public String getNamespaceURI(String prefix); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/XMLEvent.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/XMLEvent.java new file mode 100644 index 000000000..4f9801219 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/events/XMLEvent.java @@ -0,0 +1,178 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.events; + +import java.io.Writer; +import javax.xml.namespace.QName; +/** + * This is the base event interface for handling markup events. + * Events are value objects that are used to communicate the + * XML 1.0 InfoSet to the Application. Events may be cached + * and referenced after the parse has completed. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see javax.xml.stream.XMLEventReader + * @see Characters + * @see ProcessingInstruction + * @see StartElement + * @see EndElement + * @see StartDocument + * @see EndDocument + * @see EntityReference + * @see EntityDeclaration + * @see NotationDeclaration + * @since 1.6 + */ +public interface XMLEvent extends javax.xml.stream.XMLStreamConstants { + + /** + * Returns an integer code for this event. + * @see #START_ELEMENT + * @see #END_ELEMENT + * @see #CHARACTERS + * @see #ATTRIBUTE + * @see #NAMESPACE + * @see #PROCESSING_INSTRUCTION + * @see #COMMENT + * @see #START_DOCUMENT + * @see #END_DOCUMENT + * @see #DTD + */ + public int getEventType(); + + /** + * Return the location of this event. The Location + * returned from this method is non-volatile and + * will retain its information. + * @see javax.xml.stream.Location + */ + javax.xml.stream.Location getLocation(); + + /** + * A utility function to check if this event is a StartElement. + * @see StartElement + */ + public boolean isStartElement(); + + /** + * A utility function to check if this event is an Attribute. + * @see Attribute + */ + public boolean isAttribute(); + + /** + * A utility function to check if this event is a Namespace. + * @see Namespace + */ + public boolean isNamespace(); + + + /** + * A utility function to check if this event is a EndElement. + * @see EndElement + */ + public boolean isEndElement(); + + /** + * A utility function to check if this event is an EntityReference. + * @see EntityReference + */ + public boolean isEntityReference(); + + /** + * A utility function to check if this event is a ProcessingInstruction. + * @see ProcessingInstruction + */ + public boolean isProcessingInstruction(); + + /** + * A utility function to check if this event is Characters. + * @see Characters + */ + public boolean isCharacters(); + + /** + * A utility function to check if this event is a StartDocument. + * @see StartDocument + */ + public boolean isStartDocument(); + + /** + * A utility function to check if this event is an EndDocument. + * @see EndDocument + */ + public boolean isEndDocument(); + + /** + * Returns this event as a start element event, may result in + * a class cast exception if this event is not a start element. + */ + public StartElement asStartElement(); + + /** + * Returns this event as an end element event, may result in + * a class cast exception if this event is not a end element. + */ + public EndElement asEndElement(); + + /** + * Returns this event as Characters, may result in + * a class cast exception if this event is not Characters. + */ + public Characters asCharacters(); + + /** + * This method is provided for implementations to provide + * optional type information about the associated event. + * It is optional and will return null if no information + * is available. + */ + public QName getSchemaType(); + + /** + * This method will write the XMLEvent as per the XML 1.0 specification as Unicode characters. + * No indentation or whitespace should be outputted. + * + * Any user defined event type SHALL have this method + * called when being written to on an output stream. + * Built in Event types MUST implement this method, + * but implementations MAY choose not call these methods + * for optimizations reasons when writing out built in + * Events to an output stream. + * The output generated MUST be equivalent in terms of the + * infoset expressed. + * + * @param writer The writer that will output the data + * @throws XMLStreamException if there is a fatal error writing the event + */ + public void writeAsEncodedUnicode(Writer writer) + throws javax.xml.stream.XMLStreamException; + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/EventReaderDelegate.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/EventReaderDelegate.java new file mode 100644 index 000000000..9e2fbd39d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/EventReaderDelegate.java @@ -0,0 +1,134 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.util; + +import javax.xml.namespace.QName; +import javax.xml.namespace.NamespaceContext; +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + +/** + * This is the base class for deriving an XMLEventReader + * filter. + * + * This class is designed to sit between an XMLEventReader and an + * application's XMLEventReader. By default each method + * does nothing but call the corresponding method on the + * parent interface. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see javax.xml.stream.XMLEventReader + * @see StreamReaderDelegate + * @since 1.6 + */ + +public class EventReaderDelegate implements XMLEventReader { + private XMLEventReader reader; + + /** + * Construct an empty filter with no parent. + */ + public EventReaderDelegate(){} + + /** + * Construct an filter with the specified parent. + * @param reader the parent + */ + public EventReaderDelegate(XMLEventReader reader) { + this.reader = reader; + } + + /** + * Set the parent of this instance. + * @param reader the new parent + */ + public void setParent(XMLEventReader reader) { + this.reader = reader; + } + + /** + * Get the parent of this instance. + * @return the parent or null if none is set + */ + public XMLEventReader getParent() { + return reader; + } + + public XMLEvent nextEvent() + throws XMLStreamException + { + return reader.nextEvent(); + } + + public Object next() { + return reader.next(); + } + + public boolean hasNext() + { + return reader.hasNext(); + } + + public XMLEvent peek() + throws XMLStreamException + { + return reader.peek(); + } + + public void close() + throws XMLStreamException + { + reader.close(); + } + + public String getElementText() + throws XMLStreamException + { + return reader.getElementText(); + } + + public XMLEvent nextTag() + throws XMLStreamException + { + return reader.nextTag(); + } + + public Object getProperty(java.lang.String name) + throws java.lang.IllegalArgumentException + { + return reader.getProperty(name); + } + + public void remove() { + reader.remove(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/StreamReaderDelegate.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/StreamReaderDelegate.java new file mode 100644 index 000000000..f04a9859f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/StreamReaderDelegate.java @@ -0,0 +1,287 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.util; + +import java.io.Reader; +import javax.xml.namespace.QName; +import javax.xml.namespace.NamespaceContext; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.Location; +import javax.xml.stream.XMLStreamException; + +/** + * This is the base class for deriving an XMLStreamReader filter + * + * This class is designed to sit between an XMLStreamReader and an + * application's XMLStreamReader. By default each method + * does nothing but call the corresponding method on the + * parent interface. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see javax.xml.stream.XMLStreamReader + * @see EventReaderDelegate + * @since 1.6 + */ + +public class StreamReaderDelegate implements XMLStreamReader { + private XMLStreamReader reader; + + /** + * Construct an empty filter with no parent. + */ + public StreamReaderDelegate(){} + + /** + * Construct an filter with the specified parent. + * @param reader the parent + */ + public StreamReaderDelegate(XMLStreamReader reader) { + this.reader = reader; + } + + /** + * Set the parent of this instance. + * @param reader the new parent + */ + public void setParent(XMLStreamReader reader) { + this.reader = reader; + } + + /** + * Get the parent of this instance. + * @return the parent or null if none is set + */ + public XMLStreamReader getParent() { + return reader; + } + + public int next() + throws XMLStreamException + { + return reader.next(); + } + + public int nextTag() + throws XMLStreamException + { + return reader.nextTag(); + } + + public String getElementText() + throws XMLStreamException + { + return reader.getElementText(); + } + + public void require(int type, String namespaceURI, String localName) + throws XMLStreamException + { + reader.require(type,namespaceURI,localName); + } + + public boolean hasNext() + throws XMLStreamException + { + return reader.hasNext(); + } + + public void close() + throws XMLStreamException + { + reader.close(); + } + + public String getNamespaceURI(String prefix) + { + return reader.getNamespaceURI(prefix); + } + + public NamespaceContext getNamespaceContext() { + return reader.getNamespaceContext(); + } + + public boolean isStartElement() { + return reader.isStartElement(); + } + + public boolean isEndElement() { + return reader.isEndElement(); + } + + public boolean isCharacters() { + return reader.isCharacters(); + } + + public boolean isWhiteSpace() { + return reader.isWhiteSpace(); + } + + public String getAttributeValue(String namespaceUri, + String localName) + { + return reader.getAttributeValue(namespaceUri,localName); + } + + public int getAttributeCount() { + return reader.getAttributeCount(); + } + + public QName getAttributeName(int index) { + return reader.getAttributeName(index); + } + + public String getAttributePrefix(int index) { + return reader.getAttributePrefix(index); + } + + public String getAttributeNamespace(int index) { + return reader.getAttributeNamespace(index); + } + + public String getAttributeLocalName(int index) { + return reader.getAttributeLocalName(index); + } + + public String getAttributeType(int index) { + return reader.getAttributeType(index); + } + + public String getAttributeValue(int index) { + return reader.getAttributeValue(index); + } + + public boolean isAttributeSpecified(int index) { + return reader.isAttributeSpecified(index); + } + + public int getNamespaceCount() { + return reader.getNamespaceCount(); + } + + public String getNamespacePrefix(int index) { + return reader.getNamespacePrefix(index); + } + + public String getNamespaceURI(int index) { + return reader.getNamespaceURI(index); + } + + public int getEventType() { + return reader.getEventType(); + } + + public String getText() { + return reader.getText(); + } + + public int getTextCharacters(int sourceStart, + char[] target, + int targetStart, + int length) + throws XMLStreamException { + return reader.getTextCharacters(sourceStart, + target, + targetStart, + length); + } + + + public char[] getTextCharacters() { + return reader.getTextCharacters(); + } + + public int getTextStart() { + return reader.getTextStart(); + } + + public int getTextLength() { + return reader.getTextLength(); + } + + public String getEncoding() { + return reader.getEncoding(); + } + + public boolean hasText() { + return reader.hasText(); + } + + public Location getLocation() { + return reader.getLocation(); + } + + public QName getName() { + return reader.getName(); + } + + public String getLocalName() { + return reader.getLocalName(); + } + + public boolean hasName() { + return reader.hasName(); + } + + public String getNamespaceURI() { + return reader.getNamespaceURI(); + } + + public String getPrefix() { + return reader.getPrefix(); + } + + public String getVersion() { + return reader.getVersion(); + } + + public boolean isStandalone() { + return reader.isStandalone(); + } + + public boolean standaloneSet() { + return reader.standaloneSet(); + } + + public String getCharacterEncodingScheme() { + return reader.getCharacterEncodingScheme(); + } + + public String getPITarget() { + return reader.getPITarget(); + } + + public String getPIData() { + return reader.getPIData(); + } + + public Object getProperty(String name) { + return reader.getProperty(name); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/XMLEventAllocator.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/XMLEventAllocator.java new file mode 100644 index 000000000..11e6e7c04 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/XMLEventAllocator.java @@ -0,0 +1,82 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.util; + +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.XMLStreamException; + +/** + * This interface defines a class that allows a user to register + * a way to allocate events given an XMLStreamReader. An implementation + * is not required to use the XMLEventFactory implementation but this + * is recommended. The XMLEventAllocator can be set on an XMLInputFactory + * using the property "javax.xml.stream.allocator" + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @see javax.xml.stream.XMLInputFactory + * @see javax.xml.stream.XMLEventFactory + * @since 1.6 + */ +public interface XMLEventAllocator { + + /** + * This method creates an instance of the XMLEventAllocator. This + * allows the XMLInputFactory to allocate a new instance per reader. + */ + public XMLEventAllocator newInstance(); + + /** + * This method allocates an event given the current + * state of the XMLStreamReader. If this XMLEventAllocator + * does not have a one-to-one mapping between reader states + * and events this method will return null. This method + * must not modify the state of the XMLStreamReader. + * @param reader The XMLStreamReader to allocate from + * @return the event corresponding to the current reader state + */ + public XMLEvent allocate(XMLStreamReader reader) + throws XMLStreamException; + + /** + * This method allocates an event or set of events + * given the current + * state of the XMLStreamReader and adds the event + * or set of events to the + * consumer that was passed in. This method can be used + * to expand or contract reader states into event states. + * This method may modify the state of the XMLStreamReader. + * @param reader The XMLStreamReader to allocate from + * @param consumer The XMLEventConsumer to add to. + */ + public void allocate(XMLStreamReader reader, XMLEventConsumer consumer) + throws XMLStreamException; + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/XMLEventConsumer.java b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/XMLEventConsumer.java new file mode 100644 index 000000000..062f706ce --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/stream/util/XMLEventConsumer.java @@ -0,0 +1,58 @@ +/* + * 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. + */ + +/* + * Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + */ + +package javax.xml.stream.util; + +import javax.xml.stream.events.XMLEvent; +import javax.xml.stream.XMLStreamException; + +/** + * This interface defines an event consumer interface. The contract of the + * of a consumer is to accept the event. This interface can be used to + * mark an object as able to receive events. Add may be called several + * times in immediate succession so a consumer must be able to cache + * events it hasn't processed yet. + * + * @version 1.0 + * @author Copyright (c) 2009 by Oracle Corporation. All Rights Reserved. + * @since 1.6 + */ +public interface XMLEventConsumer { + + /** + * This method adds an event to the consumer. Calling this method + * invalidates the event parameter. The client application should + * discard all references to this event upon calling add. + * The behavior of an application that continues to use such references + * is undefined. + * + * @param event the event to add, may not be null + */ + public void add(XMLEvent event) + throws XMLStreamException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/ErrorListener.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/ErrorListener.java new file mode 100644 index 000000000..bc288237a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/ErrorListener.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + *

      To provide customized error handling, implement this interface and + * use the setErrorListener method to register an instance of the + * implmentation with the {@link javax.xml.transform.Transformer}. The + * Transformer then reports all errors and warnings through this + * interface.

      + * + *

      If an application does not register its own custom + * ErrorListener, the default ErrorListener + * is used which reports all warnings and errors to System.err + * and does not throw any Exceptions. + * Applications are strongly encouraged to register and use + * ErrorListeners that insure proper behavior for warnings and + * errors.

      + * + *

      For transformation errors, a Transformer must use this + * interface instead of throwing an Exception: it is up to the + * application to decide whether to throw an Exception for + * different types of errors and warnings. Note however that the + * Transformer is not required to continue with the transformation + * after a call to {@link #fatalError(TransformerException exception)}.

      + * + *

      Transformers may use this mechanism to report XML parsing + * errors as well as transformation errors.

      + */ +public interface ErrorListener { + + /** + * Receive notification of a warning. + * + *

      {@link javax.xml.transform.Transformer} can use this method to report + * conditions that are not errors or fatal errors. The default behaviour + * is to take no action.

      + * + *

      After invoking this method, the Transformer must continue with + * the transformation. It should still be possible for the + * application to process the document through to the end.

      + * + * @param exception The warning information encapsulated in a + * transformer exception. + * + * @throws javax.xml.transform.TransformerException if the application + * chooses to discontinue the transformation. + * + * @see javax.xml.transform.TransformerException + */ + public abstract void warning(TransformerException exception) + throws TransformerException; + + /** + * Receive notification of a recoverable error. + * + *

      The transformer must continue to try and provide normal transformation + * after invoking this method. It should still be possible for the + * application to process the document through to the end if no other errors + * are encountered.

      + * + * @param exception The error information encapsulated in a + * transformer exception. + * + * @throws javax.xml.transform.TransformerException if the application + * chooses to discontinue the transformation. + * + * @see javax.xml.transform.TransformerException + */ + public abstract void error(TransformerException exception) + throws TransformerException; + + /** + *

      Receive notification of a non-recoverable error.

      + * + *

      The processor may choose to continue, but will not normally + * proceed to a successful completion.

      + * + *

      The method should throw an exception if it is unable to + * process the error, or if it wishes execution to terminate + * immediately. The processor will not necessarily honor this + * request.

      + * + * @param exception The error information encapsulated in a + * TransformerException. + * + * @throws javax.xml.transform.TransformerException if the application + * chooses to discontinue the transformation. + * + * @see javax.xml.transform.TransformerException + */ + public abstract void fatalError(TransformerException exception) + throws TransformerException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/FactoryFinder.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/FactoryFinder.java new file mode 100644 index 000000000..67f970f7a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/FactoryFinder.java @@ -0,0 +1,386 @@ +/* + * Copyright (c) 2003, 2006, 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 javax.xml.transform; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.util.Properties; + +/** + *

      Implements pluggable Datatypes.

      + * + *

      This class is duplicated for each JAXP subpackage so keep it in + * sync. It is package private for secure class loading.

      + * + * @author Santiago.PericasGeertsen@sun.com + * @author Huizhe.Wang@oracle.com + */ +class FactoryFinder { + + /** + * Internal debug flag. + */ + private static boolean debug = false; + + /** + * Cache for properties in java.home/lib/jaxp.properties + */ + static Properties cacheProps = new Properties(); + + /** + * Flag indicating if properties from java.home/lib/jaxp.properties + * have been cached. + */ + static volatile boolean firstTime = true; + + /** + * Security support class use to check access control before + * getting certain system resources. + */ + static SecuritySupport ss = new SecuritySupport(); + + // Define system property "jaxp.debug" to get output +// static { +// // Use try/catch block to support applets, which throws +// // SecurityException out of this code. +// try { +// String val = ss.getSystemProperty("jaxp.debug"); +// // Allow simply setting the prop to turn on debug +// debug = val != null && !"false".equals(val); +// } +// catch (SecurityException se) { +// debug = false; +// } +// } + + private static void dPrint(String msg) { + if (debug) { + System.err.println("JAXP: " + msg); + } + } + + /** + * Attempt to load a class using the class loader supplied. If that fails + * and fall back is enabled, the current (i.e. bootstrap) class loader is + * tried. + * + * If the class loader supplied is null, first try using the + * context class loader followed by the current (i.e. bootstrap) class + * loader. + * + * Use bootstrap classLoader if cl = null and useBSClsLoader is true + */ + static private Class getProviderClass(String className, ClassLoader cl, + boolean doFallback, boolean useBSClsLoader) throws ClassNotFoundException + { + try { + if (cl == null) { + if (useBSClsLoader) { + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } else { + cl = ss.getContextClassLoader(); + if (cl == null) { + throw new ClassNotFoundException(); + } + else { + return cl.loadClass(className); + } + } + } + else { + return cl.loadClass(className); + } + } + catch (ClassNotFoundException e1) { + if (doFallback) { + // Use current class loader - should always be bootstrap CL + return Class.forName(className, true, FactoryFinder.class.getClassLoader()); + } + else { + throw e1; + } + } + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback) + throws ConfigurationError + { + return newInstance(className, cl, doFallback, false, false); + } + + /** + * Create an instance of a class. Delegates to method + * getProviderClass() in order to load the class. + * + * @param className Name of the concrete class corresponding to the + * service provider + * + * @param cl ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @param doFallback True if the current ClassLoader should be tried as + * a fallback if the class is not found using cl + * + * @param useBSClsLoader True if cl=null actually meant bootstrap classLoader. This parameter + * is needed since DocumentBuilderFactory/SAXParserFactory defined null as context classLoader. + * + * @param useServicesMechanism True use services mechanism + */ + static Object newInstance(String className, ClassLoader cl, boolean doFallback, boolean useBSClsLoader, boolean useServicesMechanism) + throws ConfigurationError + { + try { + Class providerClass = getProviderClass(className, cl, doFallback, useBSClsLoader); + Object instance = null; + if (!useServicesMechanism) { + instance = newInstanceNoServiceLoader(providerClass); + } + if (instance == null) { + instance = providerClass.newInstance(); + } + if (debug) { // Extra check to avoid computing cl strings + dPrint("created new instance of " + providerClass + + " using ClassLoader: " + cl); + } + return instance; + } + catch (ClassNotFoundException x) { + throw new ConfigurationError( + "Provider " + className + " not found", x); + } + catch (Exception x) { + throw new ConfigurationError( + "Provider " + className + " could not be instantiated: " + x, + x); + } + } + /** + * Try to construct using newTransformerFactoryNoServiceLoader + * method if available. + */ + private static Object newInstanceNoServiceLoader( + Class providerClass + ) { + // Retain maximum compatibility if no security manager. + if (System.getSecurityManager() == null) { + return null; + } + try { + Method creationMethod = + providerClass.getDeclaredMethod( + "newTransformerFactoryNoServiceLoader" + ); + return creationMethod.invoke(null, null); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { + return null; + } + } + /** + * Finds the implementation Class object in the specified order. Main + * entry point. + * @return Class object of factory, never null + * + * @param factoryId Name of the factory to find, same as + * a property name + * @param fallbackClassName Implementation class name, if nothing else + * is found. Use null to mean no fallback. + * + * Package private so this code can be shared. + */ + static Object find(String factoryId, String fallbackClassName) + throws ConfigurationError + { + dPrint("find factoryId =" + factoryId); + // Use the system property first + try { + String systemProp = ss.getSystemProperty(factoryId); + if (systemProp != null) { + dPrint("found system property, value=" + systemProp); + return newInstance(systemProp, null, true, false, true); + } + } + catch (SecurityException se) { + if (debug) se.printStackTrace(); + } + + // try to read from $java.home/lib/jaxp.properties + try { + String factoryClassName = null; + if (firstTime) { + synchronized (cacheProps) { + if (firstTime) { + String configFile = ss.getSystemProperty("java.home") + File.separator + + "lib" + File.separator + "jaxp.properties"; + File f = new File(configFile); + firstTime = false; + if (ss.doesFileExist(f)) { + dPrint("Read properties file "+f); + cacheProps.load(ss.getFileInputStream(f)); + } + } + } + } + factoryClassName = cacheProps.getProperty(factoryId); + + if (factoryClassName != null) { + dPrint("found in $java.home/jaxp.properties, value=" + factoryClassName); + return newInstance(factoryClassName, null, true, false, true); + } + } + catch (Exception ex) { + if (debug) ex.printStackTrace(); + } + + // Try Jar Service Provider Mechanism +// Object provider = findJarServiceProvider(factoryId); +// if (provider != null) { +// return provider; +// } + if (fallbackClassName == null) { + throw new ConfigurationError( + "Provider for " + factoryId + " cannot be found", null); + } + + dPrint("loaded from fallback value: " + fallbackClassName); + return newInstance(fallbackClassName, null, true, false, true); + } + +// /* +// * Try to find provider using Jar Service Provider Mechanism +// * +// * @return instance of provider class if found or null +// */ +// private static Object findJarServiceProvider(String factoryId) +// throws ConfigurationError +// { +// String serviceId = "META-INF/services/" + factoryId; +// InputStream is = null; +// +// // First try the Context ClassLoader +// ClassLoader cl = ss.getContextClassLoader(); +// boolean useBSClsLoader = false; +// if (cl != null) { +// is = ss.getResourceAsStream(cl, serviceId); +// +// // If no provider found then try the current ClassLoader +// if (is == null) { +// cl = FactoryFinder.class.getClassLoader(); +// is = ss.getResourceAsStream(cl, serviceId); +// useBSClsLoader = true; +// } +// } else { +// // No Context ClassLoader, try the current ClassLoader +// cl = FactoryFinder.class.getClassLoader(); +// is = ss.getResourceAsStream(cl, serviceId); +// useBSClsLoader = true; +// } +// +// if (is == null) { +// // No provider found +// return null; +// } +// +// if (debug) { // Extra check to avoid computing cl strings +// dPrint("found jar resource=" + serviceId + " using ClassLoader: " + cl); +// } +// +// BufferedReader rd; +// try { +// rd = new BufferedReader(new InputStreamReader(is, "UTF-8")); +// } +// catch (java.io.UnsupportedEncodingException e) { +// rd = new BufferedReader(new InputStreamReader(is)); +// } +// +// String factoryClassName = null; +// try { +// // XXX Does not handle all possible input as specified by the +// // Jar Service Provider specification +// factoryClassName = rd.readLine(); +// rd.close(); +// } catch (IOException x) { +// // No provider found +// return null; +// } +// +// if (factoryClassName != null && !"".equals(factoryClassName)) { +// dPrint("found in resource, value=" + factoryClassName); +// +// // Note: here we do not want to fall back to the current +// // ClassLoader because we want to avoid the case where the +// // resource file was found using one ClassLoader and the +// // provider class was instantiated using a different one. +// return newInstance(factoryClassName, cl, false, useBSClsLoader, true); +// } +// +// // No provider found +// return null; +// } +// + static class ConfigurationError extends Error { + private Exception exception; + + /** + * Construct a new instance with the specified detail string and + * exception. + */ + ConfigurationError(String msg, Exception x) { + super(msg); + this.exception = x; + } + + Exception getException() { + return exception; + } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/OutputKeys.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/OutputKeys.java new file mode 100644 index 000000000..3c0fc35e0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/OutputKeys.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + * Provides string constants that can be used to set + * output properties for a Transformer, or to retrieve + * output properties from a Transformer or Templates object. + *

      All the fields in this class are read-only.

      + * + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ +public class OutputKeys { + + /** + * Default constructor is private on purpose. This class is + * only for static variable access, and should never be constructed. + */ + private OutputKeys() { } + + /** + * method = "xml" | "html" | "text" | expanded name. + * + *

      The value of the method property identifies the overall method that + * should be used for outputting the result tree. Other non-namespaced + * values may be used, such as "xhtml", but, if accepted, the handling + * of such values is implementation defined. If any of the method values + * are not accepted and are not namespace qualified, + * then {@link javax.xml.transform.Transformer#setOutputProperty} + * or {@link javax.xml.transform.Transformer#setOutputProperties} will + * throw a {@link java.lang.IllegalArgumentException}.

      + * + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String METHOD = "method"; + + /** + * version = nmtoken. + * + *

      version specifies the version of the output + * method.

      + *

      When the output method is "xml", the version value specifies the + * version of XML to be used for outputting the result tree. The default + * value for the xml output method is 1.0. When the output method is + * "html", the version value indicates the version of the HTML. + * The default value for the xml output method is 4.0, which specifies + * that the result should be output as HTML conforming to the HTML 4.0 + * Recommendation [HTML]. If the output method is "text", the version + * property is ignored.

      + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String VERSION = "version"; + + /** + * encoding = string. + * + *

      encoding specifies the preferred character + * encoding that the Transformer should use to encode sequences of + * characters as sequences of bytes. The value of the encoding property should be + * treated case-insensitively. The value must only contain characters in + * the range #x21 to #x7E (i.e., printable ASCII characters). The value + * should either be a charset registered with the Internet + * Assigned Numbers Authority [IANA], + * [RFC2278] + * or start with X-.

      + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String ENCODING = "encoding"; + + /** + * omit-xml-declaration = "yes" | "no". + * + *

      omit-xml-declaration specifies whether the XSLT + * processor should output an XML declaration; the value must be + * yes or no.

      + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String OMIT_XML_DECLARATION = "omit-xml-declaration"; + + /** + * standalone = "yes" | "no". + * + *

      standalone specifies whether the Transformer + * should output a standalone document declaration; the value must be + * yes or no.

      + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String STANDALONE = "standalone"; + + /** + * doctype-public = string. + *

      See the documentation for the {@link #DOCTYPE_SYSTEM} property + * for a description of what the value of the key should be.

      + * + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String DOCTYPE_PUBLIC = "doctype-public"; + + /** + * doctype-system = string. + *

      doctype-system specifies the system identifier + * to be used in the document type declaration.

      + *

      If the doctype-system property is specified, the xml output method + * should output a document type declaration immediately before the first + * element. The name following <!DOCTYPE should be the name of the first + * element. If doctype-public property is also specified, then the xml + * output method should output PUBLIC followed by the public identifier + * and then the system identifier; otherwise, it should output SYSTEM + * followed by the system identifier. The internal subset should be empty. + * The value of the doctype-public property should be ignored unless the doctype-system + * property is specified.

      + *

      If the doctype-public or doctype-system properties are specified, + * then the html output method should output a document type declaration + * immediately before the first element. The name following <!DOCTYPE + * should be HTML or html. If the doctype-public property is specified, + * then the output method should output PUBLIC followed by the specified + * public identifier; if the doctype-system property is also specified, + * it should also output the specified system identifier following the + * public identifier. If the doctype-system property is specified but + * the doctype-public property is not specified, then the output method + * should output SYSTEM followed by the specified system identifier.

      + * + *

      doctype-system specifies the system identifier + * to be used in the document type declaration.

      + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String DOCTYPE_SYSTEM = "doctype-system"; + + /** + * cdata-section-elements = expanded names. + * + *

      cdata-section-elements specifies a whitespace delimited + * list of the names of elements whose text node children should be output + * using CDATA sections. Note that these names must use the format + * described in the section Qualfied Name Representation in + * {@link javax.xml.transform}.

      + * + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation. + */ + public static final String CDATA_SECTION_ELEMENTS = + "cdata-section-elements"; + + /** + * indent = "yes" | "no". + * + *

      indent specifies whether the Transformer may + * add additional whitespace when outputting the result tree; the value + * must be yes or no.

      + * @see + * section 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String INDENT = "indent"; + + /** + * media-type = string. + * + *

      media-type specifies the media type (MIME + * content type) of the data that results from outputting the result + * tree. The charset parameter should not be specified + * explicitly; instead, when the top-level media type is + * text, a charset parameter should be added + * according to the character encoding actually used by the output + * method.

      + * @see s + * ection 16 of the XSL Transformations (XSLT) W3C Recommendation + */ + public static final String MEDIA_TYPE = "media-type"; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/Result.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Result.java index fb74a9208..474728527 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/transform/Result.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Result.java @@ -1,10 +1,86 @@ -package javax.xml.transform; - -public interface Result { - public static final String PI_DISABLE_OUTPUT_ESCAPING = - "javax.xml.transform.disable-output-escaping"; - public static final String PI_ENABLE_OUTPUT_ESCAPING = - "javax.xml.transform.enable-output-escaping"; - public void setSystemId(String systemId); - public String getSystemId(); -} +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + *

      An object that implements this interface contains the information + * needed to build a transformation result tree.

      + * + * @author Jeff Suttor + */ +public interface Result { + + /** + * The name of the processing instruction that is sent if the + * result tree disables output escaping. + * + *

      Normally, result tree serialization escapes & and < (and + * possibly other characters) when outputting text nodes. + * This ensures that the output is well-formed XML. However, + * it is sometimes convenient to be able to produce output that is + * almost, but not quite well-formed XML; for example, + * the output may include ill-formed sections that will + * be transformed into well-formed XML by a subsequent non-XML aware + * process. If a processing instruction is sent with this name, + * serialization should be output without any escaping.

      + * + *

      Result DOM trees may also have PI_DISABLE_OUTPUT_ESCAPING and + * PI_ENABLE_OUTPUT_ESCAPING inserted into the tree.

      + * + * @see disable-output-escaping in XSLT Specification + */ + public static final String PI_DISABLE_OUTPUT_ESCAPING = + "javax.xml.transform.disable-output-escaping"; + + /** + * The name of the processing instruction that is sent + * if the result tree enables output escaping at some point after having + * received a PI_DISABLE_OUTPUT_ESCAPING processing instruction. + * + * @see disable-output-escaping in XSLT Specification + */ + public static final String PI_ENABLE_OUTPUT_ESCAPING = + "javax.xml.transform.enable-output-escaping"; + + /** + * Set the system identifier for this Result. + * + *

      If the Result is not to be written to a file, the system identifier is optional. + * The application may still want to provide one, however, for use in error messages + * and warnings, or to resolve relative output identifiers.

      + * + * @param systemId The system identifier as a URI string. + */ + public void setSystemId(String systemId); + + /** + * Get the system identifier that was set with setSystemId. + * + * @return The system identifier that was set with setSystemId, + * or null if setSystemId was not called. + */ + public String getSystemId(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/SecuritySupport.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/SecuritySupport.java new file mode 100644 index 000000000..e5f1bb083 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/SecuritySupport.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2004, 2006, 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 javax.xml.transform; + +import java.security.*; +import java.net.*; +import java.io.*; +import java.util.*; + +/** + * This class is duplicated for each JAXP subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of the JAXP + * API. + * + * Security related methods that only work on J2SE 1.2 and newer. + */ +class SecuritySupport { + + + ClassLoader getContextClassLoader() throws SecurityException{ + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + //try { + cl = Thread.currentThread().getContextClassLoader(); + //} catch (SecurityException ex) { } + if (cl == null) + cl = ClassLoader.getSystemClassLoader(); + return cl; + } + }); + } + + String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + FileInputStream getFileInputStream(final File file) + throws FileNotFoundException + { + try { + return (FileInputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws FileNotFoundException { + return new FileInputStream(file); + } + }); + } catch (PrivilegedActionException e) { + throw (FileNotFoundException)e.getException(); + } + } + + InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + boolean doesFileExist(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Boolean(f.exists()); + } + })).booleanValue(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/Source.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Source.java new file mode 100644 index 000000000..3af6969d0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Source.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + * An object that implements this interface contains the information + * needed to act as source input (XML source or transformation instructions). + */ +public interface Source { + + /** + * Set the system identifier for this Source. + * + *

      The system identifier is optional if the source does not + * get its data from a URL, but it may still be useful to provide one. + * The application can use a system identifier, for example, to resolve + * relative URIs and to include in error messages and warnings.

      + * + * @param systemId The system identifier as a URL string. + */ + public void setSystemId(String systemId); + + /** + * Get the system identifier that was set with setSystemId. + * + * @return The system identifier that was set with setSystemId, or null + * if setSystemId was not called. + */ + public String getSystemId(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/SourceLocator.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/SourceLocator.java new file mode 100644 index 000000000..475e65463 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/SourceLocator.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + * This interface is primarily for the purposes of reporting where + * an error occurred in the XML source or transformation instructions. + */ +public interface SourceLocator { + + /** + * Return the public identifier for the current document event. + * + *

      The return value is the public identifier of the document + * entity or of the external parsed entity in which the markup that + * triggered the event appears.

      + * + * @return A string containing the public identifier, or + * null if none is available. + * @see #getSystemId + */ + public String getPublicId(); + + /** + * Return the system identifier for the current document event. + * + *

      The return value is the system identifier of the document + * entity or of the external parsed entity in which the markup that + * triggered the event appears.

      + * + *

      If the system identifier is a URL, the parser must resolve it + * fully before passing it to the application.

      + * + * @return A string containing the system identifier, or null + * if none is available. + * @see #getPublicId + */ + public String getSystemId(); + + /** + * Return the line number where the current document event ends. + * + *

      Warning: The return value from the method + * is intended only as an approximation for the sake of error + * reporting; it is not intended to provide sufficient information + * to edit the character content of the original XML document.

      + * + *

      The return value is an approximation of the line number + * in the document entity or external parsed entity where the + * markup that triggered the event appears.

      + * + * @return The line number, or -1 if none is available. + * @see #getColumnNumber + */ + public int getLineNumber(); + + /** + * Return the character position where the current document event ends. + * + *

      Warning: The return value from the method + * is intended only as an approximation for the sake of error + * reporting; it is not intended to provide sufficient information + * to edit the character content of the original XML document.

      + * + *

      The return value is an approximation of the column number + * in the document entity or external parsed entity where the + * markup that triggered the event appears.

      + * + * @return The column number, or -1 if none is available. + * @see #getLineNumber + */ + public int getColumnNumber(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/Templates.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Templates.java new file mode 100644 index 000000000..9952368e7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Templates.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +import java.util.Properties; + + + + +/** + * An object that implements this interface is the runtime representation of processed + * transformation instructions. + * + *

      Templates must be threadsafe for a given instance + * over multiple threads running concurrently, and may + * be used multiple times in a given session.

      + */ +public interface Templates { + + /** + * Create a new transformation context for this Templates object. + * + * @return A valid non-null instance of a Transformer. + * + * @throws TransformerConfigurationException if a Transformer can not be created. + */ + Transformer newTransformer() throws TransformerConfigurationException; + + /** + * Get the properties corresponding to the effective xsl:output element. + * The object returned will + * be a clone of the internal values. Accordingly, it can be mutated + * without mutating the Templates object, and then handed in to + * {@link javax.xml.transform.Transformer#setOutputProperties}. + * + *

      The properties returned should contain properties set by the stylesheet, + * and these properties are "defaulted" by default properties specified by + * section 16 of the + * XSL Transformations (XSLT) W3C Recommendation. The properties that + * were specifically set by the stylesheet should be in the base + * Properties list, while the XSLT default properties that were not + * specifically set should be in the "default" Properties list. Thus, + * getOutputProperties().getProperty(String key) will obtain any + * property in that was set by the stylesheet, or the default + * properties, while + * getOutputProperties().get(String key) will only retrieve properties + * that were explicitly set in the stylesheet.

      + * + *

      For XSLT, + * Attribute + * Value Templates attribute values will + * be returned unexpanded (since there is no context at this point). The + * namespace prefixes inside Attribute Value Templates will be unexpanded, + * so that they remain valid XPath values.

      + * + * @return A Properties object, never null. + */ + Properties getOutputProperties(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/Transformer.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Transformer.java new file mode 100644 index 000000000..1c4bc987c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/Transformer.java @@ -0,0 +1,339 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +import java.util.Properties; + +/** + * An instance of this abstract class can transform a + * source tree into a result tree. + * + *

      An instance of this class can be obtained with the + * {@link TransformerFactory#newTransformer TransformerFactory.newTransformer} + * method. This instance may then be used to process XML from a + * variety of sources and write the transformation output to a + * variety of sinks.

      + * + *

      An object of this class may not be used in multiple threads + * running concurrently. Different Transformers may be used + * concurrently by different threads.

      + * + *

      A Transformer may be used multiple times. Parameters and + * output properties are preserved across transformations.

      + * + * @author Jeff Suttor + */ +public abstract class Transformer { + + /** + * Default constructor is protected on purpose. + */ + protected Transformer() { } + + /** + *

      Reset this Transformer to its original configuration.

      + * + *

      Transformer is reset to the same state as when it was created with + * {@link TransformerFactory#newTransformer()}, + * {@link TransformerFactory#newTransformer(Source source)} or + * {@link Templates#newTransformer()}. + * reset() is designed to allow the reuse of existing Transformers + * thus saving resources associated with the creation of new Transformers.

      + * + *

      The reset Transformer is not guaranteed to have the same {@link URIResolver} + * or {@link ErrorListener} Objects, e.g. {@link Object#equals(Object obj)}. + * It is guaranteed to have a functionally equal URIResolver + * and ErrorListener.

      + * + * @throws UnsupportedOperationException When implementation does not + * override this method. + * + * @since 1.5 + */ + public void reset() { + + // implementors should override this method + throw new UnsupportedOperationException( + "This Transformer, \"" + this.getClass().getName() + "\", does not support the reset functionality." +// + " Specification \"" + this.getClass().getPackage().getSpecificationTitle() + "\"" +// + " version \"" + this.getClass().getPackage().getSpecificationVersion() + "\"" + ); + } + + /** + *

      Transform the XML Source to a Result. + * Specific transformation behavior is determined by the settings of the + * TransformerFactory in effect when the + * Transformer was instantiated and any modifications made to + * the Transformer instance.

      + * + *

      An empty Source is represented as an empty document + * as constructed by {@link javax.xml.parsers.DocumentBuilder#newDocument()}. + * The result of transforming an empty Source depends on + * the transformation behavior; it is not always an empty + * Result.

      + * + * @param xmlSource The XML input to transform. + * @param outputTarget The Result of transforming the + * xmlSource. + * + * @throws TransformerException If an unrecoverable error occurs + * during the course of the transformation. + */ + public abstract void transform(Source xmlSource, Result outputTarget) + throws TransformerException; + + /** + * Add a parameter for the transformation. + * + *

      Pass a qualified name as a two-part string, the namespace URI + * enclosed in curly braces ({}), followed by the local name. If the + * name has a null URL, the String only contain the local name. An + * application can safely check for a non-null URI by testing to see if the + * first character of the name is a '{' character.

      + *

      For example, if a URI and local name were obtained from an element + * defined with <xyz:foo + * xmlns:xyz="http://xyz.foo.com/yada/baz.html"/>, + * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". + * Note that no prefix is used.

      + * + * @param name The name of the parameter, which may begin with a + * namespace URI in curly braces ({}). + * @param value The value object. This can be any valid Java object. It is + * up to the processor to provide the proper object coersion or to simply + * pass the object on for use in an extension. + * + * @throws NullPointerException If value is null. + */ + public abstract void setParameter(String name, Object value); + + /** + * Get a parameter that was explicitly set with setParameter. + * + *

      This method does not return a default parameter value, which + * cannot be determined until the node context is evaluated during + * the transformation process. + * + * @param name of Object to get + * + * @return A parameter that has been set with setParameter. + */ + public abstract Object getParameter(String name); + + /** + *

      Set a list of parameters.

      + * + *

      Note that the list of parameters is specified as a + * Properties Object which limits the parameter + * values to Strings. Multiple calls to + * {@link #setParameter(String name, Object value)} should be used when the + * desired values are non-String Objects. + * The parameter names should conform as specified in + * {@link #setParameter(String name, Object value)}. + * An IllegalArgumentException is thrown if any names do not + * conform.

      + * + *

      New parameters in the list are added to any existing parameters. + * If the name of a new parameter is equal to the name of an existing + * parameter as determined by {@link java.lang.Object#equals(Object obj)}, + * the existing parameter is set to the new value.

      + * + * @param params Parameters to set. + * + * @throws IllegalArgumentException If any parameter names do not conform + * to the naming rules. + */ + + /** + * Clear all parameters set with setParameter. + */ + public abstract void clearParameters(); + + /** + * Set an object that will be used to resolve URIs used in + * document(). + * + *

      If the resolver argument is null, the URIResolver value will + * be cleared and the transformer will no longer have a resolver.

      + * + * @param resolver An object that implements the URIResolver interface, + * or null. + */ + public abstract void setURIResolver(URIResolver resolver); + + /** + * Get an object that will be used to resolve URIs used in + * document(). + * + * @return An object that implements the URIResolver interface, + * or null. + */ + public abstract URIResolver getURIResolver(); + + /** + * Set the output properties for the transformation. These + * properties will override properties set in the Templates + * with xsl:output. + * + *

      If argument to this function is null, any properties + * previously set are removed, and the value will revert to the value + * defined in the templates object.

      + * + *

      Pass a qualified property key name as a two-part string, the namespace + * URI enclosed in curly braces ({}), followed by the local name. If the + * name has a null URL, the String only contain the local name. An + * application can safely check for a non-null URI by testing to see if the + * first character of the name is a '{' character.

      + *

      For example, if a URI and local name were obtained from an element + * defined with <xyz:foo + * xmlns:xyz="http://xyz.foo.com/yada/baz.html"/>, + * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". + * Note that no prefix is used.

      + * An IllegalArgumentException is thrown if any of the + * argument keys are not recognized and are not namespace qualified. + * + * @param oformat A set of output properties that will be + * used to override any of the same properties in affect + * for the transformation. + * + * @throws IllegalArgumentException When keys are not recognized and + * are not namespace qualified. + * + * @see javax.xml.transform.OutputKeys + * @see java.util.Properties + * + */ + public abstract void setOutputProperties(Properties oformat); + + /** + *

      Get a copy of the output properties for the transformation.

      + * + *

      The properties returned should contain properties set by the user, + * and properties set by the stylesheet, and these properties + * are "defaulted" by default properties specified by + * section 16 of the + * XSL Transformations (XSLT) W3C Recommendation. The properties that + * were specifically set by the user or the stylesheet should be in the base + * Properties list, while the XSLT default properties that were not + * specifically set should be the default Properties list. Thus, + * getOutputProperties().getProperty(String key) will obtain any + * property in that was set by {@link #setOutputProperty}, + * {@link #setOutputProperties}, in the stylesheet, or the default + * properties, while + * getOutputProperties().get(String key) will only retrieve properties + * that were explicitly set by {@link #setOutputProperty}, + * {@link #setOutputProperties}, or in the stylesheet.

      + * + *

      Note that mutation of the Properties object returned will not + * effect the properties that the transformer contains.

      + * + *

      If any of the argument keys are not recognized and are not + * namespace qualified, the property will be ignored and not returned. + * In other words the behaviour is not orthogonal with + * {@link #setOutputProperties setOutputProperties}.

      + * + * @return A copy of the set of output properties in effect for + * the next transformation. + * + * @see javax.xml.transform.OutputKeys + * @see java.util.Properties + * @see + * XSL Transformations (XSLT) Version 1.0 + */ + public abstract Properties getOutputProperties(); + + /** + * Set an output property that will be in effect for the + * transformation. + * + *

      Pass a qualified property name as a two-part string, the namespace URI + * enclosed in curly braces ({}), followed by the local name. If the + * name has a null URL, the String only contain the local name. An + * application can safely check for a non-null URI by testing to see if the + * first character of the name is a '{' character.

      + *

      For example, if a URI and local name were obtained from an element + * defined with <xyz:foo + * xmlns:xyz="http://xyz.foo.com/yada/baz.html"/>, + * then the qualified name would be "{http://xyz.foo.com/yada/baz.html}foo". + * Note that no prefix is used.

      + * + *

      The Properties object that was passed to {@link #setOutputProperties} + * won't be effected by calling this method.

      + * + * @param name A non-null String that specifies an output + * property name, which may be namespace qualified. + * @param value The non-null string value of the output property. + * + * @throws IllegalArgumentException If the property is not supported, and is + * not qualified with a namespace. + * + * @see javax.xml.transform.OutputKeys + */ + public abstract void setOutputProperty(String name, String value) + throws IllegalArgumentException; + + /** + *

      Get an output property that is in effect for the transformer.

      + * + *

      If a property has been set using {@link #setOutputProperty}, + * that value will be returned. Otherwise, if a property is explicitly + * specified in the stylesheet, that value will be returned. If + * the value of the property has been defaulted, that is, if no + * value has been set explicitly either with {@link #setOutputProperty} or + * in the stylesheet, the result may vary depending on + * implementation and input stylesheet.

      + * + * @param name A non-null String that specifies an output + * property name, which may be namespace qualified. + * + * @return The string value of the output property, or null + * if no property was found. + * + * @throws IllegalArgumentException If the property is not supported. + * + * @see javax.xml.transform.OutputKeys + */ + public abstract String getOutputProperty(String name) + throws IllegalArgumentException; + + /** + * Set the error event listener in effect for the transformation. + * + * @param listener The new error listener. + * + * @throws IllegalArgumentException if listener is null. + */ + public abstract void setErrorListener(ErrorListener listener) + throws IllegalArgumentException; + + /** + * Get the error event handler in effect for the transformation. + * Implementations must provide a default error listener. + * + * @return The current error handler, which should never be null. + */ + public abstract ErrorListener getErrorListener(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerConfigurationException.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerConfigurationException.java new file mode 100644 index 000000000..9e2f3afe8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerConfigurationException.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + * Indicates a serious configuration error. + */ +public class TransformerConfigurationException extends TransformerException { + + /** + * Create a new TransformerConfigurationException with no + * detail mesage. + */ + public TransformerConfigurationException() { + super("Configuration Error"); + } + + /** + * Create a new TransformerConfigurationException with + * the String specified as an error message. + * + * @param msg The error message for the exception. + */ + public TransformerConfigurationException(String msg) { + super(msg); + } + + /** + * Create a new TransformerConfigurationException with a + * given Exception base cause of the error. + * + * @param e The exception to be encapsulated in a + * TransformerConfigurationException. + */ + public TransformerConfigurationException(Throwable e) { + super(e); + } + + /** + * Create a new TransformerConfigurationException with the + * given Exception base cause and detail message. + * + * @param e The exception to be encapsulated in a + * TransformerConfigurationException + * @param msg The detail message. + */ + public TransformerConfigurationException(String msg, Throwable e) { + super(msg, e); + } + + /** + * Create a new TransformerConfigurationException from a message and a Locator. + * + *

      This constructor is especially useful when an application is + * creating its own exception from within a DocumentHandler + * callback.

      + * + * @param message The error or warning message. + * @param locator The locator object for the error or warning. + */ + public TransformerConfigurationException(String message, + SourceLocator locator) { + super(message, locator); + } + + /** + * Wrap an existing exception in a TransformerConfigurationException. + * + * @param message The error or warning message, or null to + * use the message from the embedded exception. + * @param locator The locator object for the error or warning. + * @param e Any exception. + */ + public TransformerConfigurationException(String message, + SourceLocator locator, + Throwable e) { + super(message, locator, e); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerException.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerException.java new file mode 100644 index 000000000..0985ebb05 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerException.java @@ -0,0 +1,370 @@ +/* + * Copyright (c) 2000, 2006, 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 javax.xml.transform; + +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; + +/** + * This class specifies an exceptional condition that occured + * during the transformation process. + */ +public class TransformerException extends Exception { + + /** Field locator specifies where the error occured */ + SourceLocator locator; + + /** + * Method getLocator retrieves an instance of a SourceLocator + * object that specifies where an error occured. + * + * @return A SourceLocator object, or null if none was specified. + */ + public SourceLocator getLocator() { + return locator; + } + + /** + * Method setLocator sets an instance of a SourceLocator + * object that specifies where an error occured. + * + * @param location A SourceLocator object, or null to clear the location. + */ + public void setLocator(SourceLocator location) { + locator = location; + } + + /** Field containedException specifies a wrapped exception. May be null. */ + Throwable containedException; + + /** + * This method retrieves an exception that this exception wraps. + * + * @return An Throwable object, or null. + * @see #getCause + */ + public Throwable getException() { + return containedException; + } + + /** + * Returns the cause of this throwable or null if the + * cause is nonexistent or unknown. (The cause is the throwable that + * caused this throwable to get thrown.) + */ + public Throwable getCause() { + + return ((containedException == this) + ? null + : containedException); + } + + /** + * Initializes the cause of this throwable to the specified value. + * (The cause is the throwable that caused this throwable to get thrown.) + * + *

      This method can be called at most once. It is generally called from + * within the constructor, or immediately after creating the + * throwable. If this throwable was created + * with {@link #TransformerException(Throwable)} or + * {@link #TransformerException(String,Throwable)}, this method cannot be called + * even once. + * + * @param cause the cause (which is saved for later retrieval by the + * {@link #getCause()} method). (A null value is + * permitted, and indicates that the cause is nonexistent or + * unknown.) + * @return a reference to this Throwable instance. + * @throws IllegalArgumentException if cause is this + * throwable. (A throwable cannot + * be its own cause.) + * @throws IllegalStateException if this throwable was + * created with {@link #TransformerException(Throwable)} or + * {@link #TransformerException(String,Throwable)}, or this method has already + * been called on this throwable. + */ + public synchronized Throwable initCause(Throwable cause) { + + if (this.containedException != null) { + throw new IllegalStateException("Can't overwrite cause"); + } + + if (cause == this) { + throw new IllegalArgumentException( + "Self-causation not permitted"); + } + + this.containedException = cause; + + return this; + } + + /** + * Create a new TransformerException. + * + * @param message The error or warning message. + */ + public TransformerException(String message) { + + super(message); + + this.containedException = null; + this.locator = null; + } + + /** + * Create a new TransformerException wrapping an existing exception. + * + * @param e The exception to be wrapped. + */ + public TransformerException(Throwable e) { + + super(e.toString()); + + this.containedException = e; + this.locator = null; + } + + /** + * Wrap an existing exception in a TransformerException. + * + *

      This is used for throwing processor exceptions before + * the processing has started.

      + * + * @param message The error or warning message, or null to + * use the message from the embedded exception. + * @param e Any exception + */ + public TransformerException(String message, Throwable e) { + + super(((message == null) || (message.length() == 0)) + ? e.toString() + : message); + + this.containedException = e; + this.locator = null; + } + + /** + * Create a new TransformerException from a message and a Locator. + * + *

      This constructor is especially useful when an application is + * creating its own exception from within a DocumentHandler + * callback.

      + * + * @param message The error or warning message. + * @param locator The locator object for the error or warning. + */ + public TransformerException(String message, SourceLocator locator) { + + super(message); + + this.containedException = null; + this.locator = locator; + } + + /** + * Wrap an existing exception in a TransformerException. + * + * @param message The error or warning message, or null to + * use the message from the embedded exception. + * @param locator The locator object for the error or warning. + * @param e Any exception + */ + public TransformerException(String message, SourceLocator locator, + Throwable e) { + + super(message); + + this.containedException = e; + this.locator = locator; + } + + /** + * Get the error message with location information + * appended. + * + * @return A String representing the error message with + * location information appended. + */ + public String getMessageAndLocation() { + + StringBuffer sbuffer = new StringBuffer(); + String message = super.getMessage(); + + if (null != message) { + sbuffer.append(message); + } + + if (null != locator) { + String systemID = locator.getSystemId(); + int line = locator.getLineNumber(); + int column = locator.getColumnNumber(); + + if (null != systemID) { + sbuffer.append("; SystemID: "); + sbuffer.append(systemID); + } + + if (0 != line) { + sbuffer.append("; Line#: "); + sbuffer.append(line); + } + + if (0 != column) { + sbuffer.append("; Column#: "); + sbuffer.append(column); + } + } + + return sbuffer.toString(); + } + + /** + * Get the location information as a string. + * + * @return A string with location info, or null + * if there is no location information. + */ + public String getLocationAsString() { + + if (null != locator) { + StringBuffer sbuffer = new StringBuffer(); + String systemID = locator.getSystemId(); + int line = locator.getLineNumber(); + int column = locator.getColumnNumber(); + + if (null != systemID) { + sbuffer.append("; SystemID: "); + sbuffer.append(systemID); + } + + if (0 != line) { + sbuffer.append("; Line#: "); + sbuffer.append(line); + } + + if (0 != column) { + sbuffer.append("; Column#: "); + sbuffer.append(column); + } + + return sbuffer.toString(); + } else { + return null; + } + } + + /** + * Print the the trace of methods from where the error + * originated. This will trace all nested exception + * objects, as well as this object. + */ + public void printStackTrace() { + printStackTrace(new java.io.PrintWriter(System.err, true)); + } + + /** + * Print the the trace of methods from where the error + * originated. This will trace all nested exception + * objects, as well as this object. + * @param s The stream where the dump will be sent to. + */ + public void printStackTrace(java.io.PrintStream s) { + printStackTrace(new java.io.PrintWriter(s)); + } + + /** + * Print the the trace of methods from where the error + * originated. This will trace all nested exception + * objects, as well as this object. + * @param s The writer where the dump will be sent to. + */ + public void printStackTrace(java.io.PrintWriter s) { + + if (s == null) { + s = new java.io.PrintWriter(System.err, true); + } + + try { + String locInfo = getLocationAsString(); + + if (null != locInfo) { + s.println(locInfo); + } + + super.printStackTrace(s); + } catch (Throwable e) {} + + Throwable exception = getException(); + + for (int i = 0; (i < 10) && (null != exception); i++) { + s.println("---------"); + + try { + if (exception instanceof TransformerException) { + String locInfo = + ((TransformerException) exception) + .getLocationAsString(); + + if (null != locInfo) { + s.println(locInfo); + } + } + + exception.printStackTrace(s); + } catch (Throwable e) { + s.println("Could not print stack trace..."); + } + + try { + Method meth = + ((Object) exception).getClass().getMethod("getException", + (Class[]) null); + + if (null != meth) { + Throwable prev = exception; + + exception = (Throwable) meth.invoke(exception, (Object[]) null); + + if (prev == exception) { + break; + } + } else { + exception = null; + } + } catch (InvocationTargetException ite) { + exception = null; + } catch (IllegalAccessException iae) { + exception = null; + } catch (NoSuchMethodException nsme) { + exception = null; + } + } + // insure output is written + s.flush(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerFactory.java new file mode 100644 index 000000000..8ce729e1b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerFactory.java @@ -0,0 +1,383 @@ +/* + * Copyright (c) 2000, 2006, 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 javax.xml.transform; + +/** + *

      A TransformerFactory instance can be used to create + * {@link javax.xml.transform.Transformer} and + * {@link javax.xml.transform.Templates} objects.

      + * + *

      The system property that determines which Factory implementation + * to create is named "javax.xml.transform.TransformerFactory". + * This property names a concrete subclass of the + * TransformerFactory abstract class. If the property is not + * defined, a platform default is be used.

      + * + * @author Jeff Suttor + * @author Neeraj Bajaj + * + * @since 1.5 + */ +public abstract class TransformerFactory { + + /** + * Default constructor is protected on purpose. + */ + protected TransformerFactory() { } + + + + /** + *

      Obtain a new instance of a TransformerFactory. + * This static method creates a new factory instance + * This method uses the following ordered lookup procedure to determine + * the TransformerFactory implementation class to + * load:

      + *
        + *
      • + * Use the javax.xml.transform.TransformerFactory system + * property. + *
      • + *
      • + * Use the properties file "lib/jaxp.properties" in the JRE directory. + * This configuration file is in standard java.util.Properties + * format and contains the fully qualified name of the + * implementation class with the key being the system property defined + * above. + * + * The jaxp.properties file is read only once by the JAXP implementation + * and it's values are then cached for future use. If the file does not exist + * when the first attempt is made to read from it, no further attempts are + * made to check for its existence. It is not possible to change the value + * of any property in jaxp.properties after it has been read for the first time. + *
      • + *
      • + * Use the Services API (as detailed in the JAR specification), if + * available, to determine the classname. The Services API will look + * for a classname in the file + * META-INF/services/javax.xml.transform.TransformerFactory + * in jars available to the runtime. + *
      • + *
      • + * Platform default TransformerFactory instance. + *
      • + *
      + * + *

      Once an application has obtained a reference to a + * TransformerFactory it can use the factory to configure + * and obtain transformer instances.

      + * + * @return new TransformerFactory instance, never null. + * + * @throws TransformerFactoryConfigurationError Thrown if the implementation + * is not available or cannot be instantiated. + */ + public static TransformerFactory newInstance() + throws TransformerFactoryConfigurationError { + try { + return (TransformerFactory) FactoryFinder.find( + /* The default property name according to the JAXP spec */ + "javax.xml.transform.TransformerFactory", + /* The fallback implementation class name, XSLTC */ + "swingjs.xml.JSXMLTransformerFactory");//com.sun.org.apache.xalan.internal.xsltc.trax.TransformerFactoryImpl"); + } catch (FactoryFinder.ConfigurationError e) { + throw new TransformerFactoryConfigurationError( + e.getException(), + e.getMessage()); + } + } + + /** + *

      Obtain a new instance of a TransformerFactory from factory class name. + * This function is useful when there are multiple providers in the classpath. + * It gives more control to the application as it can specify which provider + * should be loaded.

      + * + *

      Once an application has obtained a reference to a + * TransformerFactory it can use the factory to configure + * and obtain transformer instances.

      + * + *

      Tip for Trouble-shooting

      + *

      Setting the jaxp.debug system property will cause + * this method to print a lot of debug messages + * to System.err about what it is doing and where it is looking at.

      + * + *

      If you have problems try:

      + *
      +     * java -Djaxp.debug=1 YourProgram ....
      +     * 
      + * + * @param factoryClassName fully qualified factory class name that provides implementation of javax.xml.transform.TransformerFactory. + * + * @param classLoader ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @return new TransformerFactory instance, never null. + * + * @throws TransformerFactoryConfigurationError + * if factoryClassName is null, or + * the factory class cannot be loaded, instantiated. + * + * @see #newInstance() + * + * @since 1.6 + */ + public static TransformerFactory newInstance(String factoryClassName, ClassLoader classLoader) + throws TransformerFactoryConfigurationError{ + try { + //do not fallback if given classloader can't find the class, throw exception + return (TransformerFactory) FactoryFinder.newInstance(factoryClassName, classLoader, false); + } catch (FactoryFinder.ConfigurationError e) { + throw new TransformerFactoryConfigurationError( + e.getException(), + e.getMessage()); + } + } + /** + *

      Process the Source into a Transformer + * Object. The Source is an XSLT document that + * conforms to + * XSL Transformations (XSLT) Version 1.0. Care must + * be taken not to use this Transformer in multiple + * Threads running concurrently. + * Different TransformerFactories can be used concurrently by + * different Threads.

      + * + * @param source Source of XSLT document used to create + * Transformer. + * Examples of XML Sources include + * {@link javax.xml.transform.dom.DOMSource DOMSource}, + * {@link javax.xml.transform.sax.SAXSource SAXSource}, and + * {@link javax.xml.transform.stream.StreamSource StreamSource}. + * + * @return A Transformer object that may be used to perform + * a transformation in a single Thread, never + * null. + * + * @throws TransformerConfigurationException Thrown if there are errors when + * parsing the Source or it is not possible to create a + * Transformer instance. + * + * @see + * XSL Transformations (XSLT) Version 1.0 + */ + public abstract Transformer newTransformer(Source source) + throws TransformerConfigurationException; + + /** + *

      Create a new Transformer that performs a copy + * of the Source to the Result. + * i.e. the "identity transform".

      + * + * @return A Transformer object that may be used to perform a transformation + * in a single thread, never null. + * + * @throws TransformerConfigurationException When it is not + * possible to create a Transformer instance. + */ + public abstract Transformer newTransformer() + throws TransformerConfigurationException; + + /** + * Process the Source into a Templates object, which is a + * a compiled representation of the source. This Templates object + * may then be used concurrently across multiple threads. Creating + * a Templates object allows the TransformerFactory to do detailed + * performance optimization of transformation instructions, without + * penalizing runtime transformation. + * + * @param source An object that holds a URL, input stream, etc. + * + * @return A Templates object capable of being used for transformation + * purposes, never null. + * + * @throws TransformerConfigurationException When parsing to + * construct the Templates object fails. + */ + public abstract Templates newTemplates(Source source) + throws TransformerConfigurationException; + + /** + *

      Get the stylesheet specification(s) associated with the + * XML Source document via the + * + * xml-stylesheet processing instruction that match the given criteria. + * Note that it is possible to return several stylesheets, in which case + * they are applied as if they were a list of imports or cascades in a + * single stylesheet.

      + * + * @param source The XML source document. + * @param media The media attribute to be matched. May be null, in which + * case the prefered templates will be used (i.e. alternate = no). + * @param title The value of the title attribute to match. May be null. + * @param charset The value of the charset attribute to match. May be null. + * + * @return A Source Object suitable for passing + * to the TransformerFactory. + * + * @throws TransformerConfigurationException An Exception + * is thrown if an error occurings during parsing of the + * source. + * + * @see + * Associating Style Sheets with XML documents Version 1.0 + */ + public abstract Source getAssociatedStylesheet( + Source source, + String media, + String title, + String charset) + throws TransformerConfigurationException; + + /** + * Set an object that is used by default during the transformation + * to resolve URIs used in document(), xsl:import, or xsl:include. + * + * @param resolver An object that implements the URIResolver interface, + * or null. + */ + public abstract void setURIResolver(URIResolver resolver); + + /** + * Get the object that is used by default during the transformation + * to resolve URIs used in document(), xsl:import, or xsl:include. + * + * @return The URIResolver that was set with setURIResolver. + */ + public abstract URIResolver getURIResolver(); + + //======= CONFIGURATION METHODS ======= + + /** + *

      Set a feature for this TransformerFactory and Transformers + * or Templates created by this factory.

      + * + *

      + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * An {@link TransformerConfigurationException} is thrown if this TransformerFactory or the + * Transformers or Templates it creates cannot support the feature. + * It is possible for an TransformerFactory to expose a feature value but be unable to change its state. + *

      + * + *

      All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. + * When the feature is:

      + *
        + *
      • + * true: the implementation will limit XML processing to conform to implementation limits + * and behave in a secure fashion as defined by the implementation. + * Examples include resolving user defined style sheets and functions. + * If XML processing is limited for security reasons, it will be reported via a call to the registered + * {@link ErrorListener#fatalError(TransformerException exception)}. + * See {@link #setErrorListener(ErrorListener listener)}. + *
      • + *
      • + * false: the implementation will processing XML according to the XML specifications without + * regard to possible implementation limits. + *
      • + *
      + * + * @param name Feature name. + * @param value Is feature state true or false. + * + * @throws TransformerConfigurationException if this TransformerFactory + * or the Transformers or Templates it creates cannot support this feature. + * @throws NullPointerException If the name parameter is null. + */ + public abstract void setFeature(String name, boolean value) + throws TransformerConfigurationException; + + /** + * Look up the value of a feature. + * + *

      + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * false is returned if this TransformerFactory or the + * Transformers or Templates it creates cannot support the feature. + * It is possible for an TransformerFactory to expose a feature value but be unable to change its state. + *

      + * + * @param name Feature name. + * + * @return The current state of the feature, true or false. + * + * @throws NullPointerException If the name parameter is null. + */ + public abstract boolean getFeature(String name); + + /** + * Allows the user to set specific attributes on the underlying + * implementation. An attribute in this context is defined to + * be an option that the implementation provides. + * An IllegalArgumentException is thrown if the underlying + * implementation doesn't recognize the attribute. + * + * @param name The name of the attribute. + * @param value The value of the attribute. + * + * @throws IllegalArgumentException When implementation does not + * recognize the attribute. + */ + public abstract void setAttribute(String name, Object value); + + /** + * Allows the user to retrieve specific attributes on the underlying + * implementation. + * An IllegalArgumentException is thrown if the underlying + * implementation doesn't recognize the attribute. + * + * @param name The name of the attribute. + * + * @return value The value of the attribute. + * + * @throws IllegalArgumentException When implementation does not + * recognize the attribute. + */ + public abstract Object getAttribute(String name); + + /** + * Set the error event listener for the TransformerFactory, which + * is used for the processing of transformation instructions, + * and not for the transformation itself. + * An IllegalArgumentException is thrown if the + * ErrorListener listener is null. + * + * @param listener The new error listener. + * + * @throws IllegalArgumentException When listener is + * null + */ + public abstract void setErrorListener(ErrorListener listener); + + /** + * Get the error event handler for the TransformerFactory. + * + * @return The current error handler, which should never be null. + */ + public abstract ErrorListener getErrorListener(); + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerFactoryConfigurationError.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerFactoryConfigurationError.java new file mode 100644 index 000000000..fb060b0a8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/TransformerFactoryConfigurationError.java @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + * Thrown when a problem with configuration with the Transformer Factories + * exists. This error will typically be thrown when the class of a + * transformation factory specified in the system properties cannot be found + * or instantiated. + */ +public class TransformerFactoryConfigurationError extends Error { + private static final long serialVersionUID = -6527718720676281516L; + + /** + * Exception for the + * TransformerFactoryConfigurationError. + */ + private Exception exception; + + /** + * Create a new TransformerFactoryConfigurationError with no + * detail mesage. + */ + public TransformerFactoryConfigurationError() { + + super(); + + this.exception = null; + } + + /** + * Create a new TransformerFactoryConfigurationError with + * the String specified as an error message. + * + * @param msg The error message for the exception. + */ + public TransformerFactoryConfigurationError(String msg) { + + super(msg); + + this.exception = null; + } + + /** + * Create a new TransformerFactoryConfigurationError with a + * given Exception base cause of the error. + * + * @param e The exception to be encapsulated in a + * TransformerFactoryConfigurationError. + */ + public TransformerFactoryConfigurationError(Exception e) { + + super(e.toString()); + + this.exception = e; + } + + /** + * Create a new TransformerFactoryConfigurationError with the + * given Exception base cause and detail message. + * + * @param e The exception to be encapsulated in a + * TransformerFactoryConfigurationError + * @param msg The detail message. + */ + public TransformerFactoryConfigurationError(Exception e, String msg) { + + super(msg); + + this.exception = e; + } + + /** + * Return the message (if any) for this error . If there is no + * message for the exception and there is an encapsulated + * exception then the message of that exception will be returned. + * + * @return The error message. + */ + public String getMessage() { + + String message = super.getMessage(); + + if ((message == null) && (exception != null)) { + return exception.getMessage(); + } + + return message; + } + + /** + * Return the actual exception (if any) that caused this exception to + * be raised. + * + * @return The encapsulated exception, or null if there is none. + */ + public Exception getException() { + return exception; + } + /** + * use the exception chaining mechanism of JDK1.4 + */ + @Override + public Throwable getCause() { + return exception; + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/URIResolver.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/URIResolver.java new file mode 100644 index 000000000..a4ea4c052 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/URIResolver.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform; + +/** + *

      An object that implements this interface that can be called by the processor + * to turn a URI used in document(), xsl:import, or xsl:include into a Source object. + */ +public interface URIResolver { + + /** + * Called by the processor when it encounters + * an xsl:include, xsl:import, or document() function. + * + * @param href An href attribute, which may be relative or absolute. + * @param base The base URI against which the first argument will be made + * absolute if the absolute URI is required. + * + * @return A Source object, or null if the href cannot be resolved, + * and the processor should try to resolve the URI itself. + * + * @throws TransformerException if an error occurs when trying to + * resolve the URI. + */ + public Source resolve(String href, String base) + throws TransformerException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMLocator.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMLocator.java new file mode 100644 index 000000000..13a744614 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMLocator.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.dom; + +import javax.xml.transform.SourceLocator; + +import org.w3c.dom.Node; + + +/** + * Indicates the position of a node in a source DOM, intended + * primarily for error reporting. To use a DOMLocator, the receiver of an + * error must downcast the {@link javax.xml.transform.SourceLocator} + * object returned by an exception. A {@link javax.xml.transform.Transformer} + * may use this object for purposes other than error reporting, for instance, + * to indicate the source node that originated a result node. + */ +public interface DOMLocator extends SourceLocator { + + /** + * Return the node where the event occurred. + * + * @return The node that is the location for the event. + */ + public Node getOriginatingNode(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMResult.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMResult.java new file mode 100644 index 000000000..c7adfc4ef --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMResult.java @@ -0,0 +1,362 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.dom; + +import javax.xml.transform.Result; +import org.w3c.dom.Node; + +/** + *

      Acts as a holder for a transformation result tree in the form of a Document Object Model (DOM) tree.

      + * + *

      If no output DOM source is set, the transformation will create a Document node as the holder for the result of the transformation, + * which may be retrieved with {@link #getNode()}.

      + * + * @author Jeff Suttor + */ +public class DOMResult implements Result { + + /**

      If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the Transformer supports Result output of this type.

      + */ + public static final String FEATURE = "http://javax.xml.transform.dom.DOMResult/feature"; + + /** + *

      Zero-argument default constructor.

      + * + *

      node, + * siblingNode and + * systemId + * will be set to null.

      + */ + public DOMResult() { + setNode(null); + setNextSibling(null); + setSystemId(null); + } + + /** + *

      Use a DOM node to create a new output target.

      + * + *

      In practice, the node should be + * a {@link org.w3c.dom.Document} node, + * a {@link org.w3c.dom.DocumentFragment} node, or + * a {@link org.w3c.dom.Element} node. + * In other words, a node that accepts children.

      + * + *

      siblingNode and + * systemId + * will be set to null.

      + * + * @param node The DOM node that will contain the result tree. + */ + public DOMResult(Node node) { + setNode(node); + setNextSibling(null); + setSystemId(null); + } + + /** + *

      Use a DOM node to create a new output target with the specified System ID.

      + * + *

      In practice, the node should be + * a {@link org.w3c.dom.Document} node, + * a {@link org.w3c.dom.DocumentFragment} node, or + * a {@link org.w3c.dom.Element} node. + * In other words, a node that accepts children.

      + * + *

      siblingNode will be set to null.

      + * + * @param node The DOM node that will contain the result tree. + * @param systemId The system identifier which may be used in association with this node. + */ + public DOMResult(Node node, String systemId) { + setNode(node); + setNextSibling(null); + setSystemId(systemId); + } + + /** + *

      Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before.

      + * + *

      In practice, node and nextSibling should be + * a {@link org.w3c.dom.Document} node, + * a {@link org.w3c.dom.DocumentFragment} node, or + * a {@link org.w3c.dom.Element} node. + * In other words, a node that accepts children.

      + * + *

      Use nextSibling to specify the child node + * where the result nodes should be inserted before. + * If nextSibling is not a sibling of node, + * then an IllegalArgumentException is thrown. + * If node is null and nextSibling is not null, + * then an IllegalArgumentException is thrown. + * If nextSibling is null, + * then the behavior is the same as calling {@link #DOMResult(Node node)}, + * i.e. append the result nodes as the last child of the specified node.

      + * + *

      systemId will be set to null.

      + * + * @param node The DOM node that will contain the result tree. + * @param nextSibling The child node where the result nodes should be inserted before. + * + * @throws IllegalArgumentException If nextSibling is not a sibling of node or + * node is null and nextSibling + * is not null. + * + * @since 1.5 + */ + public DOMResult(Node node, Node nextSibling) { + + // does the corrent parent/child relationship exist? + if (nextSibling != null) { + // cannot be a sibling of a null node + if (node == null) { + throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); + } + + // nextSibling contained by node? + if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { + throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); + } + } + + setNode(node); + setNextSibling(nextSibling); + setSystemId(null); + } + + /** + *

      Use a DOM node to create a new output target specifying the child node where the result nodes should be inserted before and + * the specified System ID.

      + * + *

      In practice, node and nextSibling should be + * a {@link org.w3c.dom.Document} node, + * a {@link org.w3c.dom.DocumentFragment} node, or a + * {@link org.w3c.dom.Element} node. + * In other words, a node that accepts children.

      + * + *

      Use nextSibling to specify the child node + * where the result nodes should be inserted before. + * If nextSibling is not a sibling of node, + * then an IllegalArgumentException is thrown. + * If node is null and nextSibling is not null, + * then an IllegalArgumentException is thrown. + * If nextSibling is null, + * then the behavior is the same as calling {@link #DOMResult(Node node, String systemId)}, + * i.e. append the result nodes as the last child of the specified node and use the specified System ID.

      + * + * @param node The DOM node that will contain the result tree. + * @param nextSibling The child node where the result nodes should be inserted before. + * @param systemId The system identifier which may be used in association with this node. + * + * @throws IllegalArgumentException If nextSibling is not a + * sibling of node or + * node is null and nextSibling + * is not null. + * + * @since 1.5 + */ + public DOMResult(Node node, Node nextSibling, String systemId) { + + // does the corrent parent/child relationship exist? + if (nextSibling != null) { + // cannot be a sibling of a null node + if (node == null) { + throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); + } + + // nextSibling contained by node? + if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { + throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); + } + } + + setNode(node); + setNextSibling(nextSibling); + setSystemId(systemId); + } + + /** + *

      Set the node that will contain the result DOM tree.

      + * + *

      In practice, the node should be + * a {@link org.w3c.dom.Document} node, + * a {@link org.w3c.dom.DocumentFragment} node, or + * a {@link org.w3c.dom.Element} node. + * In other words, a node that accepts children.

      + * + *

      An IllegalStateException is thrown if + * nextSibling is not null and + * node is not a parent of nextSibling. + * An IllegalStateException is thrown if node is null and + * nextSibling is not null.

      + * + * @param node The node to which the transformation will be appended. + * + * @throws IllegalStateException If nextSibling is not + * null and + * nextSibling is not a child of node or + * node is null and + * nextSibling is not null. + */ + public void setNode(Node node) { + // does the corrent parent/child relationship exist? + if (nextSibling != null) { + // cannot be a sibling of a null node + if (node == null) { + throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); + } + + // nextSibling contained by node? + if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { + throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); + } + } + + this.node = node; + } + + /** + *

      Get the node that will contain the result DOM tree.

      + * + *

      If no node was set via + * {@link #DOMResult(Node node)}, + * {@link #DOMResult(Node node, String systeId)}, + * {@link #DOMResult(Node node, Node nextSibling)}, + * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or + * {@link #setNode(Node node)}, + * then the node will be set by the transformation, and may be obtained from this method once the transformation is complete. + * Calling this method before the transformation will return null.

      + * + * @return The node to which the transformation will be appended. + */ + public Node getNode() { + return node; + } + + /** + *

      Set the child node before which the result nodes will be inserted.

      + * + *

      Use nextSibling to specify the child node + * before which the result nodes should be inserted. + * If nextSibling is not a descendant of node, + * then an IllegalArgumentException is thrown. + * If node is null and nextSibling is not null, + * then an IllegalStateException is thrown. + * If nextSibling is null, + * then the behavior is the same as calling {@link #DOMResult(Node node)}, + * i.e. append the result nodes as the last child of the specified node.

      + * + * @param nextSibling The child node before which the result nodes will be inserted. + * + * @throws IllegalArgumentException If nextSibling is not a + * descendant of node. + * @throws IllegalStateException If node is null + * and nextSibling is not null. + * + * @since 1.5 + */ + public void setNextSibling(Node nextSibling) { + + // does the corrent parent/child relationship exist? + if (nextSibling != null) { + // cannot be a sibling of a null node + if (node == null) { + throw new IllegalStateException("Cannot create a DOMResult when the nextSibling is contained by the \"null\" node."); + } + + // nextSibling contained by node? + if ((node.compareDocumentPosition(nextSibling)&Node.DOCUMENT_POSITION_CONTAINED_BY)==0) { + throw new IllegalArgumentException("Cannot create a DOMResult when the nextSibling is not contained by the node."); + } + } + + this.nextSibling = nextSibling; + } + + /** + *

      Get the child node before which the result nodes will be inserted.

      + * + *

      If no node was set via + * {@link #DOMResult(Node node, Node nextSibling)}, + * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or + * {@link #setNextSibling(Node nextSibling)}, + * then null will be returned.

      + * + * @return The child node before which the result nodes will be inserted. + * + * @since 1.5 + */ + public Node getNextSibling() { + return nextSibling; + } + + /** + *

      Set the systemId that may be used in association with the node.

      + * + * @param systemId The system identifier as a URI string. + */ + public void setSystemId(String systemId) { + this.systemId = systemId; + } + + /** + *

      Get the System Identifier.

      + * + *

      If no System ID was set via + * {@link #DOMResult(Node node, String systemId)}, + * {@link #DOMResult(Node node, Node nextSibling, String systemId)} or + * {@link #setSystemId(String systemId)}, + * then null will be returned.

      + * + * @return The system identifier. + */ + public String getSystemId() { + return systemId; + } + + ////////////////////////////////////////////////////////////////////// + // Internal state. + ////////////////////////////////////////////////////////////////////// + + /** + *

      The node to which the transformation will be appended.

      + */ + private Node node = null; + + /** + *

      The child node before which the result nodes will be inserted.

      + * + * @since 1.5 + */ + private Node nextSibling = null; + + /** + *

      The System ID that may be used in association with the node.

      + */ + private String systemId = null; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMSource.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMSource.java new file mode 100644 index 000000000..83e64fd47 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/dom/DOMSource.java @@ -0,0 +1,137 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.dom; + +import javax.xml.transform.Source; + +import org.w3c.dom.Node; + +/** + *

      Acts as a holder for a transformation Source tree in the + * form of a Document Object Model (DOM) tree.

      + * + *

      Note that XSLT requires namespace support. Attempting to transform a DOM + * that was not contructed with a namespace-aware parser may result in errors. + * Parsers can be made namespace aware by calling + * {@link javax.xml.parsers.DocumentBuilderFactory#setNamespaceAware(boolean awareness)}.

      + * + * @author Jeff Suttor + * @see Document Object Model (DOM) Level 2 Specification + */ +public class DOMSource implements Source { + + /** + *

      Node to serve as DOM source.

      + */ + private Node node; + + /** + *

      The base ID (URL or system ID) from where URLs + * will be resolved.

      + */ + private String systemID; + + /** If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the Transformer supports Source input of this type. + */ + public static final String FEATURE = + "http://javax.xml.transform.dom.DOMSource/feature"; + + /** + *

      Zero-argument default constructor. If this constructor is used, and + * no DOM source is set using {@link #setNode(Node node)} , then the + * Transformer will + * create an empty source {@link org.w3c.dom.Document} using + * {@link javax.xml.parsers.DocumentBuilder#newDocument()}.

      + * + * @see javax.xml.transform.Transformer#transform(Source xmlSource, Result outputTarget) + */ + public DOMSource() { } + + /** + * Create a new input source with a DOM node. The operation + * will be applied to the subtree rooted at this node. In XSLT, + * a "/" pattern still means the root of the tree (not the subtree), + * and the evaluation of global variables and parameters is done + * from the root node also. + * + * @param n The DOM node that will contain the Source tree. + */ + public DOMSource(Node n) { + setNode(n); + } + + /** + * Create a new input source with a DOM node, and with the + * system ID also passed in as the base URI. + * + * @param node The DOM node that will contain the Source tree. + * @param systemID Specifies the base URI associated with node. + */ + public DOMSource(Node node, String systemID) { + setNode(node); + setSystemId(systemID); + } + + /** + * Set the node that will represents a Source DOM tree. + * + * @param node The node that is to be transformed. + */ + public void setNode(Node node) { + this.node = node; + } + + /** + * Get the node that represents a Source DOM tree. + * + * @return The node that is to be transformed. + */ + public Node getNode() { + return node; + } + + /** + * Set the base ID (URL or system ID) from where URLs + * will be resolved. + * + * @param systemID Base URL for this DOM tree. + */ + public void setSystemId(String systemID) { + this.systemID = systemID; + } + + /** + * Get the base ID (URL or system ID) from where URLs + * will be resolved. + * + * @return Base URL for this DOM tree. + */ + public String getSystemId() { + return this.systemID; + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/overview.html b/sources/net.sf.j2s.java.core/src/javax/xml/transform/overview.html new file mode 100644 index 000000000..1ad906a7a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/overview.html @@ -0,0 +1,291 @@ + + + + + + + + + Transformation API For XML + + + + + + +

      Transformation API For XML

      + + +

      Introduction

      + +

      This overview describes the set of APIs contained in + javax.xml.transform. For the sake of brevity, these interfaces are referred to + as TrAX (Transformations for XML).

      + +

      There is a broad need for Java applications to be able to transform XML + and related tree-shaped data structures. In fact, XML is not normally very + useful to an application without going through some sort of transformation, + unless the semantic structure is used directly as data. Almost all XML-related + applications need to perform transformations. Transformations may be described + by Java code, Perl code, XSLT + Stylesheets, other types of script, or by proprietary formats. The inputs, one + or multiple, to a transformation, may be a URL, XML stream, a DOM tree, SAX + Events, or a proprietary format or data structure. The output types are the + pretty much the same types as the inputs, but different inputs may need to be + combined with different outputs.

      + +

      The great challenge of a transformation API is how to deal with all the + possible combinations of inputs and outputs, without becoming specialized for + any of the given types.

      + +

      The Java community will greatly benefit from a common API that will + allow them to understand and apply a single model, write to consistent + interfaces, and apply the transformations polymorphically. TrAX attempts to + define a model that is clean and generic, yet fills general application + requirements across a wide variety of uses.

      + + +

      General Terminology

      + +

      This section will explain some general terminology used in this + document. Technical terminology will be explained in the Model section. In many + cases, the general terminology overlaps with the technical terminology.

      + +
        +
      • +

        +Tree +
        This term, as used within this document, describes an + abstract structure that consists of nodes or events that may be produced by + XML. A Tree physically may be a DOM tree, a series of well balanced parse + events (such as those coming from a SAX2 ContentHander), a series of requests + (the result of which can describe a tree), or a stream of marked-up + characters.

        +
      • +
      • +

        +Source Tree(s) +
        One or more trees that are the inputs to the + transformation.

        +
      • +
      • +

        +Result Tree(s) +
        One or more trees that are the output of the + transformation.

        +
      • +
      • +

        +Transformation +
        The processor of consuming a stream or tree to produce + another stream or tree.

        +
      • +
      • +

        +Identity (or Copy) Transformation +
        The process of transformation from a source to a result, + making as few structural changes as possible and no informational changes. The + term is somewhat loosely used, as the process is really a copy. from one + "format" (such as a DOM tree, stream, or set of SAX events) to + another.

        +
      • +
      • +

        +Serialization +
        The process of taking a tree and turning it into a stream. In + some sense, a serialization is a specialized transformation.

        +
      • +
      • +

        +Parsing +
        The process of taking a stream and turning it into a tree. In + some sense, parsing is a specialized transformation.

        +
      • +
      • +

        +Transformer +
        A Transformer is the object that executes the transformation. +

        +
      • +
      • +

        +Transformation instructions +
        Describes the transformation. A form of code, script, or + simply a declaration or series of declarations.

        +
      • +
      • +

        +Stylesheet +
        The same as "transformation instructions," except it is + likely to be used in conjunction with XSLT.

        +
      • +
      • +

        +Templates +
        Another form of "transformation instructions." In the TrAX + interface, this term is used to describe processed or compiled transformation + instructions. The Source flows through a Templates object to be formed into the + Result.

        +
      • +
      • +

        +Processor +
        A general term for the thing that may both process the + transformation instructions, and perform the transformation.

        +
      • +
      • +

        +DOM +
        Document Object Model, specifically referring to the + Document Object Model + (DOM) Level 2 Specification.

        +
      • +
      • +

        + SAX
        + Simple API for XML, specifically referring to the SAX 2.0.2 release. +

        +
      • +
      + + + +

      Model

      + +

      The section defines the abstract model for TrAX, apart from the details + of the interfaces.

      + +

      A TRaX TransformerFactory is an object + that processes transformation instructions, and produces + Templates (in the technical + terminology). A Templates + object provides a Transformer, which transforms one or + more Sources into one or more + Results.

      + +

      To use the TRaX interface, you create a + TransformerFactory, + which may directly provide a Transformers, or which can provide + Templates from a variety of + Sources. The + Templates object is a processed + or compiled representation of the transformation instructions, and provides a + Transformer. The + Transformer processes a + Source according to the + instructions found in the Templates, and produces a + Result.

      + +

      The process of transformation from a tree, either in the form of an + object model, or in the form of parse events, into a stream, is known as + serialization. We believe this is the most suitable term for + this process, despite the overlap with Java object serialization.

      + +

      TRaX Patterns

      +
        +

        +Processor +
        +
        +Intent: Generic concept for the + set of objects that implement the TrAX interfaces.
        +Responsibilities: Create compiled transformation instructions, transform + sources, and manage transformation parameters and + properties.
        +Thread safety: Only the Templates object can be + used concurrently in multiple threads. The rest of the processor does not do + synchronized blocking, and so may not be used to perform multiple concurrent + operations. Different Processors can be used concurrently by different + threads.

        +

        +TransformerFactory +
        +
        +Intent: Serve as a vendor-neutral Processor interface for + XSLT and similar + processors.
        +Responsibilities: Serve as a factory for a concrete + implementation of an TransformerFactory, serve as a direct factory for + Transformer objects, serve as a factory for Templates objects, and manage + processor specific features.
        +Thread safety: A + TransformerFactory may not perform mulitple concurrent + operations.

        +

        +Templates +
        +
        +Intent: The + runtime representation of the transformation instructions.
        +Responsibilities: A data bag for transformation instructions; act as a factory + for Transformers.
        +Thread safety: Threadsafe for concurrent + usage over multiple threads once construction is complete.

        +

        +Transformer +
        +
        +Intent: Act as a per-thread + execution context for transformations, act as an interface for performing the + transformation.
        +Responsibilities: Perform the + transformation.
        +Thread safety: Only one instance per thread + is safe.
        +Notes: The Transformer is bound to the Templates + object that created it.

        +

        +Source +
        +
        +Intent: Serve as a + single vendor-neutral object for multiple types of input.
        +Responsibilities: Act as simple data holder for System IDs, DOM nodes, streams, + etc.
        +Thread safety: Threadsafe concurrently over multiple + threads for read-only operations; must be synchronized for edit + operations.

        +

        +Result +
        +
        +Potential alternate name: ResultTarget
        +Intent: Serve + as a single object for multiple types of output, so there can be simple process + method signatures.
        +Responsibilities: Act as simple data holder for + output stream, DOM node, ContentHandler, etc.
        +Thread safety: Threadsafe concurrently over multiple threads for read-only, + must be synchronized for edit.

        +
      + + + + diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXResult.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXResult.java new file mode 100644 index 000000000..b0158b3dc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXResult.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.sax; + +import javax.xml.transform.Result; + +import org.xml.sax.ContentHandler; +import org.xml.sax.ext.LexicalHandler; + +/** + *

      Acts as an holder for a transformation Result.

      + * + * @author Jeff Suttor + */ +public class SAXResult implements Result { + + /** + * If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the Transformer supports Result output of this type. + */ + public static final String FEATURE = + "http://javax.xml.transform.sax.SAXResult/feature"; + + /** + * Zero-argument default constructor. + */ + public SAXResult() { + } + + /** + * Create a SAXResult that targets a SAX2 {@link org.xml.sax.ContentHandler}. + * + * @param handler Must be a non-null ContentHandler reference. + */ + public SAXResult(ContentHandler handler) { + setHandler(handler); + } + + /** + * Set the target to be a SAX2 {@link org.xml.sax.ContentHandler}. + * + * @param handler Must be a non-null ContentHandler reference. + */ + public void setHandler(ContentHandler handler) { + this.handler = handler; + } + + /** + * Get the {@link org.xml.sax.ContentHandler} that is the Result. + * + * @return The ContentHandler that is to be transformation output. + */ + public ContentHandler getHandler() { + return handler; + } + + /** + * Set the SAX2 {@link org.xml.sax.ext.LexicalHandler} for the output. + * + *

      This is needed to handle XML comments and the like. If the + * lexical handler is not set, an attempt should be made by the + * transformer to cast the {@link org.xml.sax.ContentHandler} to a + * LexicalHandler.

      + * + * @param handler A non-null LexicalHandler for + * handling lexical parse events. + */ + public void setLexicalHandler(LexicalHandler handler) { + this.lexhandler = handler; + } + + /** + * Get a SAX2 {@link org.xml.sax.ext.LexicalHandler} for the output. + * + * @return A LexicalHandler, or null. + */ + public LexicalHandler getLexicalHandler() { + return lexhandler; + } + + /** + * Method setSystemId Set the systemID that may be used in association + * with the {@link org.xml.sax.ContentHandler}. + * + * @param systemId The system identifier as a URI string. + */ + public void setSystemId(String systemId) { + this.systemId = systemId; + } + + /** + * Get the system identifier that was set with setSystemId. + * + * @return The system identifier that was set with setSystemId, or null + * if setSystemId was not called. + */ + public String getSystemId() { + return systemId; + } + + ////////////////////////////////////////////////////////////////////// + // Internal state. + ////////////////////////////////////////////////////////////////////// + + /** + * The handler for parse events. + */ + private ContentHandler handler; + + /** + * The handler for lexical events. + */ + private LexicalHandler lexhandler; + + /** + * The systemID that may be used in association + * with the node. + */ + private String systemId; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXSource.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXSource.java new file mode 100644 index 000000000..52315646c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXSource.java @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2000, 2006, 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 javax.xml.transform.sax; + +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +import org.xml.sax.InputSource; +import org.xml.sax.XMLReader; + +/** + *

      Acts as an holder for SAX-style Source.

      + * + *

      Note that XSLT requires namespace support. Attempting to transform an + * input source that is not + * generated with a namespace-aware parser may result in errors. + * Parsers can be made namespace aware by calling the + * {@link javax.xml.parsers.SAXParserFactory#setNamespaceAware(boolean awareness)} method.

      + * + * @author Jeff Suttor + */ +public class SAXSource implements Source { + + /** + * If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the Transformer supports Source input of this type. + */ + public static final String FEATURE = + "http://javax.xml.transform.sax.SAXSource/feature"; + + /** + *

      Zero-argument default constructor. If this constructor is used, and + * no SAX source is set using + * {@link #setInputSource(InputSource inputSource)} , then the + * Transformer will + * create an empty source {@link org.xml.sax.InputSource} using + * {@link org.xml.sax.InputSource#InputSource() new InputSource()}.

      + * + * @see javax.xml.transform.Transformer#transform(Source xmlSource, Result outputTarget) + */ + public SAXSource() { } + + /** + * Create a SAXSource, using an {@link org.xml.sax.XMLReader} + * and a SAX InputSource. The {@link javax.xml.transform.Transformer} + * or {@link javax.xml.transform.sax.SAXTransformerFactory} will set itself + * to be the reader's {@link org.xml.sax.ContentHandler}, and then will call + * reader.parse(inputSource). + * + * @param reader An XMLReader to be used for the parse. + * @param inputSource A SAX input source reference that must be non-null + * and that will be passed to the reader parse method. + */ + public SAXSource(XMLReader reader, InputSource inputSource) { + this.reader = reader; + this.inputSource = inputSource; + } + + /** + * Create a SAXSource, using a SAX InputSource. + * The {@link javax.xml.transform.Transformer} or + * {@link javax.xml.transform.sax.SAXTransformerFactory} creates a + * reader via {@link org.xml.sax.helpers.XMLReaderFactory} + * (if setXMLReader is not used), sets itself as + * the reader's {@link org.xml.sax.ContentHandler}, and calls + * reader.parse(inputSource). + * + * @param inputSource An input source reference that must be non-null + * and that will be passed to the parse method of the reader. + */ + public SAXSource(InputSource inputSource) { + this.inputSource = inputSource; + } + + /** + * Set the XMLReader to be used for the Source. + * + * @param reader A valid XMLReader or XMLFilter reference. + */ + public void setXMLReader(XMLReader reader) { + this.reader = reader; + } + + /** + * Get the XMLReader to be used for the Source. + * + * @return A valid XMLReader or XMLFilter reference, or null. + */ + public XMLReader getXMLReader() { + return reader; + } + + /** + * Set the SAX InputSource to be used for the Source. + * + * @param inputSource A valid InputSource reference. + */ + public void setInputSource(InputSource inputSource) { + this.inputSource = inputSource; + } + + /** + * Get the SAX InputSource to be used for the Source. + * + * @return A valid InputSource reference, or null. + */ + public InputSource getInputSource() { + return inputSource; + } + + /** + * Set the system identifier for this Source. If an input source + * has already been set, it will set the system ID or that + * input source, otherwise it will create a new input source. + * + *

      The system identifier is optional if there is a byte stream + * or a character stream, but it is still useful to provide one, + * since the application can use it to resolve relative URIs + * and can include it in error messages and warnings (the parser + * will attempt to open a connection to the URI only if + * no byte stream or character stream is specified).

      + * + * @param systemId The system identifier as a URI string. + */ + public void setSystemId(String systemId) { + + if (null == inputSource) { + inputSource = new InputSource(systemId); + } else { + inputSource.setSystemId(systemId); + } + } + + /** + *

      Get the base ID (URI or system ID) from where URIs + * will be resolved.

      + * + * @return Base URL for the Source, or null. + */ + public String getSystemId() { + + if (inputSource == null) { + return null; + } else { + return inputSource.getSystemId(); + } + } + + /** + * The XMLReader to be used for the source tree input. May be null. + */ + private XMLReader reader; + + /** + *

      The SAX InputSource to be used for the source tree input. + * Should not be null.

      + */ + private InputSource inputSource; + + /** + * Attempt to obtain a SAX InputSource object from a Source + * object. + * + * @param source Must be a non-null Source reference. + * + * @return An InputSource, or null if Source can not be converted. + */ + public static InputSource sourceToInputSource(Source source) { + + if (source instanceof SAXSource) { + return ((SAXSource) source).getInputSource(); + } else if (source instanceof StreamSource) { + StreamSource ss = (StreamSource) source; + InputSource isource = new InputSource(ss.getSystemId()); + + isource.setByteStream(ss.getInputStream()); + isource.setCharacterStream(ss.getReader()); + isource.setPublicId(ss.getPublicId()); + + return isource; + } else { + return null; + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXTransformerFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXTransformerFactory.java new file mode 100644 index 000000000..777e0bf24 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/SAXTransformerFactory.java @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.sax; + +import javax.xml.transform.*; + +import org.xml.sax.XMLFilter; + +/** + * This class extends TransformerFactory to provide SAX-specific + * factory methods. It provides two types of ContentHandlers, + * one for creating Transformers, the other for creating Templates + * objects. + * + *

      If an application wants to set the ErrorHandler or EntityResolver + * for an XMLReader used during a transformation, it should use a URIResolver + * to return the SAXSource which provides (with getXMLReader) a reference to + * the XMLReader.

      + */ +public abstract class SAXTransformerFactory extends TransformerFactory { + + /** If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the TransformerFactory returned from + * {@link javax.xml.transform.TransformerFactory#newInstance} may + * be safely cast to a SAXTransformerFactory. + */ + public static final String FEATURE = + "http://javax.xml.transform.sax.SAXTransformerFactory/feature"; + + /** If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the {@link #newXMLFilter(Source src)} + * and {@link #newXMLFilter(Templates templates)} methods are supported. + */ + public static final String FEATURE_XMLFILTER = + "http://javax.xml.transform.sax.SAXTransformerFactory/feature/xmlfilter"; + + /** + * The default constructor is protected on purpose. + */ + protected SAXTransformerFactory() {} + + /** + * Get a TransformerHandler object that can process SAX + * ContentHandler events into a Result, based on the transformation + * instructions specified by the argument. + * + * @param src The Source of the transformation instructions. + * + * @return TransformerHandler ready to transform SAX events. + * + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. + */ + public abstract TransformerHandler newTransformerHandler(Source src) + throws TransformerConfigurationException; + + /** + * Get a TransformerHandler object that can process SAX + * ContentHandler events into a Result, based on the Templates argument. + * + * @param templates The compiled transformation instructions. + * + * @return TransformerHandler ready to transform SAX events. + * + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler can not be created. + */ + public abstract TransformerHandler newTransformerHandler( + Templates templates) throws TransformerConfigurationException; + + /** + * Get a TransformerHandler object that can process SAX + * ContentHandler events into a Result. The transformation + * is defined as an identity (or copy) transformation, for example + * to copy a series of SAX parse events into a DOM tree. + * + * @return A non-null reference to a TransformerHandler, that may + * be used as a ContentHandler for SAX parse events. + * + * @throws TransformerConfigurationException If for some reason the + * TransformerHandler cannot be created. + */ + public abstract TransformerHandler newTransformerHandler() + throws TransformerConfigurationException; + + /** + * Get a TemplatesHandler object that can process SAX + * ContentHandler events into a Templates object. + * + * @return A non-null reference to a TransformerHandler, that may + * be used as a ContentHandler for SAX parse events. + * + * @throws TransformerConfigurationException If for some reason the + * TemplatesHandler cannot be created. + */ + public abstract TemplatesHandler newTemplatesHandler() + throws TransformerConfigurationException; + + /** + * Create an XMLFilter that uses the given Source as the + * transformation instructions. + * + * @param src The Source of the transformation instructions. + * + * @return An XMLFilter object, or null if this feature is not supported. + * + * @throws TransformerConfigurationException If for some reason the + * TemplatesHandler cannot be created. + */ + public abstract XMLFilter newXMLFilter(Source src) + throws TransformerConfigurationException; + + /** + * Create an XMLFilter, based on the Templates argument.. + * + * @param templates The compiled transformation instructions. + * + * @return An XMLFilter object, or null if this feature is not supported. + * + * @throws TransformerConfigurationException If for some reason the + * TemplatesHandler cannot be created. + */ + public abstract XMLFilter newXMLFilter(Templates templates) + throws TransformerConfigurationException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/TemplatesHandler.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/TemplatesHandler.java new file mode 100644 index 000000000..34b5ba2be --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/TemplatesHandler.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.sax; + +import javax.xml.transform.*; + +import org.xml.sax.ContentHandler; + +/** + * A SAX ContentHandler that may be used to process SAX + * parse events (parsing transformation instructions) into a Templates object. + * + *

      Note that TemplatesHandler does not need to implement LexicalHandler.

      + */ +public interface TemplatesHandler extends ContentHandler { + + /** + * When a TemplatesHandler object is used as a ContentHandler + * for the parsing of transformation instructions, it creates a Templates object, + * which the caller can get once the SAX events have been completed. + * + * @return The Templates object that was created during + * the SAX event process, or null if no Templates object has + * been created. + * + */ + public Templates getTemplates(); + + /** + * Set the base ID (URI or system ID) for the Templates object + * created by this builder. This must be set in order to + * resolve relative URIs in the stylesheet. This must be + * called before the startDocument event. + * + * @param systemID Base URI for this stylesheet. + */ + public void setSystemId(String systemID); + + /** + * Get the base ID (URI or system ID) from where relative + * URLs will be resolved. + * @return The systemID that was set with {@link #setSystemId}. + */ + public String getSystemId(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/TransformerHandler.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/TransformerHandler.java new file mode 100644 index 000000000..8bced5e86 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/sax/TransformerHandler.java @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2000, 2006, 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 javax.xml.transform.sax; + +import javax.xml.transform.Result; +import javax.xml.transform.Transformer; + +import org.xml.sax.ContentHandler; +import org.xml.sax.DTDHandler; +import org.xml.sax.ext.LexicalHandler; + +/** + * A TransformerHandler + * listens for SAX ContentHandler parse events and transforms + * them to a Result. + */ +public interface TransformerHandler + extends ContentHandler, LexicalHandler, DTDHandler { + + /** + *

      Set the Result associated with this + * TransformerHandler to be used for the transformation.

      + * + * @param result A Result instance, should not be + * null. + * + * @throws IllegalArgumentException if result is invalid for some reason. + */ + public void setResult(Result result) throws IllegalArgumentException; + + /** + * Set the base ID (URI or system ID) from where relative + * URLs will be resolved. + * @param systemID Base URI for the source tree. + */ + public void setSystemId(String systemID); + + /** + * Get the base ID (URI or system ID) from where relative + * URLs will be resolved. + * @return The systemID that was set with {@link #setSystemId}. + */ + public String getSystemId(); + + /** + *

      Get the Transformer associated with this handler, which + * is needed in order to set parameters and output properties.

      + * + * @return Transformer associated with this + * TransformerHandler. + */ + public Transformer getTransformer(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/stax/StAXResult.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stax/StAXResult.java new file mode 100644 index 000000000..9bed77a5a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stax/StAXResult.java @@ -0,0 +1,183 @@ +/* + * Copyright (c) 2005, 2006, 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 javax.xml.transform.stax; + +import javax.xml.stream.XMLEventWriter; +import javax.xml.stream.XMLStreamWriter; +import javax.xml.transform.Result; + +/** + *

      Acts as a holder for an XML {@link Result} in the + * form of a StAX writer,i.e. + * {@link XMLStreamWriter} or {@link XMLEventWriter}. + * StAXResult can be used in all cases that accept + * a Result, e.g. {@link javax.xml.transform.Transformer}, + * {@link javax.xml.validation.Validator} which accept + * Result as input. + * + * @author Neeraj Bajaj + * @author Jeff Suttor + * + * @see + * JSR 173: Streaming API for XML + * @see XMLStreamWriter + * @see XMLEventWriter + * + * @since 1.6 + */ +public class StAXResult implements Result { + /** If {@link javax.xml.transform.TransformerFactory#getFeature(String name)} + * returns true when passed this value as an argument, + * the Transformer supports Result output of this type. + */ + public static final String FEATURE = + "http://javax.xml.transform.stax.StAXResult/feature"; + + /** + *

      XMLEventWriter to be used for + * Result output.

      + */ + private XMLEventWriter xmlEventWriter = null; + + /** + *

      XMLStreamWriter to be used for + * Result output.

      + */ + private XMLStreamWriter xmlStreamWriter = null; + + /**

      System identifier for this StAXResult.

      */ + private String systemId = null; + + /** + *

      Creates a new instance of a StAXResult + * by supplying an {@link XMLEventWriter}.

      + * + *

      XMLEventWriter must be a + * non-null reference.

      + * + * @param xmlEventWriter XMLEventWriter used to create + * this StAXResult. + * + * @throws IllegalArgumentException If xmlEventWriter == + * null. + */ + public StAXResult(final XMLEventWriter xmlEventWriter) { + + if (xmlEventWriter == null) { + throw new IllegalArgumentException( + "StAXResult(XMLEventWriter) with XMLEventWriter == null"); + } + + this.xmlEventWriter = xmlEventWriter; + } + + /** + *

      Creates a new instance of a StAXResult + * by supplying an {@link XMLStreamWriter}.

      + * + *

      XMLStreamWriter must be a + * non-null reference.

      + * + * @param xmlStreamWriter XMLStreamWriter used to create + * this StAXResult. + * + * @throws IllegalArgumentException If xmlStreamWriter == + * null. + */ + public StAXResult(final XMLStreamWriter xmlStreamWriter) { + + if (xmlStreamWriter == null) { + throw new IllegalArgumentException( + "StAXResult(XMLStreamWriter) with XMLStreamWriter == null"); + } + + this.xmlStreamWriter = xmlStreamWriter; + } + + /** + *

      Get the XMLEventWriter used by this + * StAXResult.

      + * + *

      XMLEventWriter will be null + * if this StAXResult was created with a + * XMLStreamWriter.

      + * + * @return XMLEventWriter used by this + * StAXResult. + */ + public XMLEventWriter getXMLEventWriter() { + + return xmlEventWriter; + } + + /** + *

      Get the XMLStreamWriter used by this + * StAXResult.

      + * + *

      XMLStreamWriter will be null + * if this StAXResult was created with a + * XMLEventWriter.

      + * + * @return XMLStreamWriter used by this + * StAXResult. + */ + public XMLStreamWriter getXMLStreamWriter() { + + return xmlStreamWriter; + } + + /** + *

      In the context of a StAXResult, it is not appropriate + * to explicitly set the system identifier. + * The XMLEventWriter or XMLStreamWriter + * used to construct this StAXResult determines the + * system identifier of the XML result.

      + * + *

      An {@link UnsupportedOperationException} is always + * thrown by this method.

      + * + * @param systemId Ignored. + * + * @throws UnsupportedOperationException Is always + * thrown by this method. + */ + public void setSystemId(final String systemId) { + + throw new UnsupportedOperationException( + "StAXResult#setSystemId(systemId) cannot set the " + + "system identifier for a StAXResult"); + } + + /** + *

      The returned system identifier is always null.

      + * + * @return The returned system identifier is always null. + */ + public String getSystemId() { + + return null; + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/stax/StAXSource.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stax/StAXSource.java new file mode 100644 index 000000000..dd04b63fb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stax/StAXSource.java @@ -0,0 +1,236 @@ +/* + * Copyright (c) 2005, 2006, 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 javax.xml.transform.stax; + +import javax.xml.stream.XMLEventReader; +import javax.xml.stream.XMLStreamConstants; +import javax.xml.stream.XMLStreamException; +import javax.xml.stream.XMLStreamReader; +import javax.xml.stream.events.XMLEvent; +import javax.xml.transform.Source; + +/** + *

      Acts as a holder for an XML {@link Source} in the + * form of a StAX reader,i.e. + * {@link XMLStreamReader} or {@link XMLEventReader}. + * StAXSource can be used in all cases that accept + * a Source, e.g. {@link javax.xml.transform.Transformer}, + * {@link javax.xml.validation.Validator} which accept + * Source as input. + * + *

      StAXSources are consumed during processing + * and are not reusable.

      + * + * @author Neeraj Bajaj + * @author Jeff Suttor + * + * @see + * JSR 173: Streaming API for XML + * @see XMLStreamReader + * @see XMLEventReader + * + * @since 1.6 + */ +public class StAXSource implements Source { + + /** If {@link javax.xml.transform.TransformerFactory#getFeature(String name)} + * returns true when passed this value as an argument, + * the Transformer supports Source input of this type. + */ + public static final String FEATURE = + "http://javax.xml.transform.stax.StAXSource/feature"; + + /**

      XMLEventReader to be used for source input.

      */ + private XMLEventReader xmlEventReader = null; + + /**

      XMLStreamReader to be used for source input.

      */ + private XMLStreamReader xmlStreamReader = null; + + /**

      System identifier of source input.

      */ + private String systemId = null; + + /** + *

      Creates a new instance of a StAXSource + * by supplying an {@link XMLEventReader}.

      + * + *

      XMLEventReader must be a + * non-null reference.

      + * + *

      XMLEventReader must be in + * {@link XMLStreamConstants#START_DOCUMENT} or + * {@link XMLStreamConstants#START_ELEMENT} state.

      + * + * @param xmlEventReader XMLEventReader used to create + * this StAXSource. + * + * @throws XMLStreamException If xmlEventReader access + * throws an Exception. + * @throws IllegalArgumentException If xmlEventReader == + * null. + * @throws IllegalStateException If xmlEventReader + * is not in XMLStreamConstants.START_DOCUMENT or + * XMLStreamConstants.START_ELEMENT state. + */ + public StAXSource(final XMLEventReader xmlEventReader) + throws XMLStreamException { + + if (xmlEventReader == null) { + throw new IllegalArgumentException( + "StAXSource(XMLEventReader) with XMLEventReader == null"); + } + + // TODO: This is ugly ... + // there is no way to know the current position(event) of + // XMLEventReader. peek() is the only way to know the next event. + // The next event on the input stream should be + // XMLStreamConstants.START_DOCUMENT or + // XMLStreamConstants.START_ELEMENT. + XMLEvent event = xmlEventReader.peek(); + int eventType = event.getEventType(); + if (eventType != XMLStreamConstants.START_DOCUMENT + && eventType != XMLStreamConstants.START_ELEMENT) { + throw new IllegalStateException( + "StAXSource(XMLEventReader) with XMLEventReader " + + "not in XMLStreamConstants.START_DOCUMENT or " + + "XMLStreamConstants.START_ELEMENT state"); + } + + this.xmlEventReader = xmlEventReader; + systemId = event.getLocation().getSystemId(); + } + + /** + *

      Creates a new instance of a StAXSource + * by supplying an {@link XMLStreamReader}.

      + * + *

      XMLStreamReader must be a + * non-null reference.

      + * + *

      XMLStreamReader must be in + * {@link XMLStreamConstants#START_DOCUMENT} or + * {@link XMLStreamConstants#START_ELEMENT} state.

      + * + * @param xmlStreamReader XMLStreamReader used to create + * this StAXSource. + * + * @throws IllegalArgumentException If xmlStreamReader == + * null. + * @throws IllegalStateException If xmlStreamReader + * is not in XMLStreamConstants.START_DOCUMENT or + * XMLStreamConstants.START_ELEMENT state. + */ + public StAXSource(final XMLStreamReader xmlStreamReader) { + + if (xmlStreamReader == null) { + throw new IllegalArgumentException( + "StAXSource(XMLStreamReader) with XMLStreamReader == null"); + } + + int eventType = xmlStreamReader.getEventType(); + if (eventType != XMLStreamConstants.START_DOCUMENT + && eventType != XMLStreamConstants.START_ELEMENT) { + throw new IllegalStateException( + "StAXSource(XMLStreamReader) with XMLStreamReader" + + "not in XMLStreamConstants.START_DOCUMENT or " + + "XMLStreamConstants.START_ELEMENT state"); + } + + this.xmlStreamReader = xmlStreamReader; + systemId = xmlStreamReader.getLocation().getSystemId(); + } + + /** + *

      Get the XMLEventReader used by this + * StAXSource.

      + * + *

      XMLEventReader will be null. + * if this StAXSource was created with a + * XMLStreamReader.

      + * + * @return XMLEventReader used by this + * StAXSource. + */ + public XMLEventReader getXMLEventReader() { + + return xmlEventReader; + } + + /** + *

      Get the XMLStreamReader used by this + * StAXSource.

      + * + *

      XMLStreamReader will be null + * if this StAXSource was created with a + * XMLEventReader.

      + * + * @return XMLStreamReader used by this + * StAXSource. + */ + public XMLStreamReader getXMLStreamReader() { + + return xmlStreamReader; + } + + /** + *

      In the context of a StAXSource, it is not appropriate + * to explicitly set the system identifier. + * The XMLStreamReader or XMLEventReader + * used to construct this StAXSource determines the + * system identifier of the XML source.

      + * + *

      An {@link UnsupportedOperationException} is always + * thrown by this method.

      + * + * @param systemId Ignored. + * + * @throws UnsupportedOperationException Is always + * thrown by this method. + */ + public void setSystemId(final String systemId) { + + throw new UnsupportedOperationException( + "StAXSource#setSystemId(systemId) cannot set the " + + "system identifier for a StAXSource"); + } + + /** + *

      Get the system identifier used by this + * StAXSource.

      + * + *

      The XMLStreamReader or XMLEventReader + * used to construct this StAXSource is queried to determine + * the system identifier of the XML source.

      + * + *

      The system identifier may be null or + * an empty "" String.

      + * + * @return System identifier used by this StAXSource. + */ + public String getSystemId() { + + return systemId; + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/stream/StreamResult.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stream/StreamResult.java index b5f735afc..39df253fa 100644 --- a/sources/net.sf.j2s.java.core/src/javax/xml/transform/stream/StreamResult.java +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stream/StreamResult.java @@ -1,31 +1,203 @@ -package javax.xml.transform.stream; - -import java.io.File; -import java.io.OutputStream; -import java.io.Writer; - -import javax.xml.transform.Result; - -public class StreamResult extends swingjs.xml.JSXMLStreamResult implements Result { - - public StreamResult() { - super(); - } - - public StreamResult(OutputStream os) { - super(os); - } - - public StreamResult(Writer writer) { - super(writer); - } - - public StreamResult(String id) { - super(id); - } - - public StreamResult(File f) { - super(f); - } - -} +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.stream; + +import javax.xml.transform.Result; + +import java.io.File; +import java.io.OutputStream; +import java.io.Writer; +import java.net.MalformedURLException; + +/** + *

      Acts as an holder for a transformation result, + * which may be XML, plain Text, HTML, or some other form of markup.

      + * + * @author Jeff Suttor + */ +public class StreamResult implements Result { + + /** If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the Transformer supports Result output of this type. + */ + public static final String FEATURE = + "http://javax.xml.transform.stream.StreamResult/feature"; + + /** + * Zero-argument default constructor. + */ + public StreamResult() { + } + + /** + * Construct a StreamResult from a byte stream. Normally, + * a stream should be used rather than a reader, so that + * the transformer may use instructions contained in the + * transformation instructions to control the encoding. + * + * @param outputStream A valid OutputStream reference. + */ + public StreamResult(OutputStream outputStream) { + setOutputStream(outputStream); + } + + /** + * Construct a StreamResult from a character stream. Normally, + * a stream should be used rather than a reader, so that + * the transformer may use instructions contained in the + * transformation instructions to control the encoding. However, + * there are times when it is useful to write to a character + * stream, such as when using a StringWriter. + * + * @param writer A valid Writer reference. + */ + public StreamResult(Writer writer) { + setWriter(writer); + } + + /** + * Construct a StreamResult from a URL. + * + * @param systemId Must be a String that conforms to the URI syntax. + */ + public StreamResult(String systemId) { + this.systemId = systemId; + } + + /** + * Construct a StreamResult from a File. + * + * @param f Must a non-null File reference. + */ + public StreamResult(File f) { + //convert file to appropriate URI, f.toURI().toASCIIString() + //converts the URI to string as per rule specified in + //RFC 2396, + setSystemId(f.toURI().toASCIIString()); + } + + /** + * Set the ByteStream that is to be written to. Normally, + * a stream should be used rather than a reader, so that + * the transformer may use instructions contained in the + * transformation instructions to control the encoding. + * + * @param outputStream A valid OutputStream reference. + */ + public void setOutputStream(OutputStream outputStream) { + this.outputStream = outputStream; + } + + /** + * Get the byte stream that was set with setOutputStream. + * + * @return The byte stream that was set with setOutputStream, or null + * if setOutputStream or the ByteStream constructor was not called. + */ + public OutputStream getOutputStream() { + return outputStream; + } + + /** + * Set the writer that is to receive the result. Normally, + * a stream should be used rather than a writer, so that + * the transformer may use instructions contained in the + * transformation instructions to control the encoding. However, + * there are times when it is useful to write to a writer, + * such as when using a StringWriter. + * + * @param writer A valid Writer reference. + */ + public void setWriter(Writer writer) { + this.writer = writer; + } + + /** + * Get the character stream that was set with setWriter. + * + * @return The character stream that was set with setWriter, or null + * if setWriter or the Writer constructor was not called. + */ + public Writer getWriter() { + return writer; + } + + /** + * Set the systemID that may be used in association + * with the byte or character stream, or, if neither is set, use + * this value as a writeable URI (probably a file name). + * + * @param systemId The system identifier as a URI string. + */ + public void setSystemId(String systemId) { + this.systemId = systemId; + } + + /** + *

      Set the system ID from a File reference.

      + * + * + * @param f Must a non-null File reference. + */ + public void setSystemId(File f) { + //convert file to appropriate URI, f.toURI().toASCIIString() + //converts the URI to string as per rule specified in + //RFC 2396, + this.systemId = f.toURI().toASCIIString(); + } + + /** + * Get the system identifier that was set with setSystemId. + * + * @return The system identifier that was set with setSystemId, or null + * if setSystemId was not called. + */ + public String getSystemId() { + return systemId; + } + + ////////////////////////////////////////////////////////////////////// + // Internal state. + ////////////////////////////////////////////////////////////////////// + + /** + * The systemID that may be used in association + * with the byte or character stream, or, if neither is set, use + * this value as a writeable URI (probably a file name). + */ + private String systemId; + + /** + * The byte stream that is to be written to. + */ + private OutputStream outputStream; + + /** + * The character stream that is to be written to. + */ + private Writer writer; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/transform/stream/StreamSource.java b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stream/StreamSource.java new file mode 100644 index 000000000..ad41b9d30 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/transform/stream/StreamSource.java @@ -0,0 +1,284 @@ +/* + * Copyright (c) 2000, 2005, 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 javax.xml.transform.stream; + +import java.io.File; +import java.io.InputStream; +import java.io.Reader; + +import javax.xml.transform.Source; + +/** + *

      Acts as an holder for a transformation Source in the form + * of a stream of XML markup.

      + * + *

      Note: Due to their internal use of either a {@link Reader} or {@link InputStream} instance, + * StreamSource instances may only be used once.

      + * + * @author Jeff Suttor + */ +public class StreamSource implements Source { + + /** If {@link javax.xml.transform.TransformerFactory#getFeature} + * returns true when passed this value as an argument, + * the Transformer supports Source input of this type. + */ + public static final String FEATURE = + "http://javax.xml.transform.stream.StreamSource/feature"; + + /** + *

      Zero-argument default constructor. If this constructor is used, and + * no Stream source is set using + * {@link #setInputStream(java.io.InputStream inputStream)} or + * {@link #setReader(java.io.Reader reader)}, then the + * Transformer will + * create an empty source {@link java.io.InputStream} using + * {@link java.io.InputStream#InputStream() new InputStream()}.

      + * + * @see javax.xml.transform.Transformer#transform(Source xmlSource, Result outputTarget) + */ + public StreamSource() { } + + /** + * Construct a StreamSource from a byte stream. Normally, + * a stream should be used rather than a reader, so + * the XML parser can resolve character encoding specified + * by the XML declaration. + * + *

      If this constructor is used to process a stylesheet, normally + * setSystemId should also be called, so that relative URI references + * can be resolved.

      + * + * @param inputStream A valid InputStream reference to an XML stream. + */ + public StreamSource(InputStream inputStream) { + setInputStream(inputStream); + } + + /** + * Construct a StreamSource from a byte stream. Normally, + * a stream should be used rather than a reader, so that + * the XML parser can resolve character encoding specified + * by the XML declaration. + * + *

      This constructor allows the systemID to be set in addition + * to the input stream, which allows relative URIs + * to be processed.

      + * + * @param inputStream A valid InputStream reference to an XML stream. + * @param systemId Must be a String that conforms to the URI syntax. + */ + public StreamSource(InputStream inputStream, String systemId) { + setInputStream(inputStream); + setSystemId(systemId); + } + + /** + * Construct a StreamSource from a character reader. Normally, + * a stream should be used rather than a reader, so that + * the XML parser can resolve character encoding specified + * by the XML declaration. However, in many cases the encoding + * of the input stream is already resolved, as in the case of + * reading XML from a StringReader. + * + * @param reader A valid Reader reference to an XML character stream. + */ + public StreamSource(Reader reader) { + setReader(reader); + } + + /** + * Construct a StreamSource from a character reader. Normally, + * a stream should be used rather than a reader, so that + * the XML parser may resolve character encoding specified + * by the XML declaration. However, in many cases the encoding + * of the input stream is already resolved, as in the case of + * reading XML from a StringReader. + * + * @param reader A valid Reader reference to an XML character stream. + * @param systemId Must be a String that conforms to the URI syntax. + */ + public StreamSource(Reader reader, String systemId) { + setReader(reader); + setSystemId(systemId); + } + + /** + * Construct a StreamSource from a URL. + * + * @param systemId Must be a String that conforms to the URI syntax. + */ + public StreamSource(String systemId) { + this.systemId = systemId; + } + + /** + * Construct a StreamSource from a File. + * + * @param f Must a non-null File reference. + */ + public StreamSource(File f) { + //convert file to appropriate URI, f.toURI().toASCIIString() + //converts the URI to string as per rule specified in + //RFC 2396, + setSystemId(f.toURI().toASCIIString()); + } + + /** + * Set the byte stream to be used as input. Normally, + * a stream should be used rather than a reader, so that + * the XML parser can resolve character encoding specified + * by the XML declaration. + * + *

      If this Source object is used to process a stylesheet, normally + * setSystemId should also be called, so that relative URL references + * can be resolved.

      + * + * @param inputStream A valid InputStream reference to an XML stream. + */ + public void setInputStream(InputStream inputStream) { + this.inputStream = inputStream; + } + + /** + * Get the byte stream that was set with setByteStream. + * + * @return The byte stream that was set with setByteStream, or null + * if setByteStream or the ByteStream constructor was not called. + */ + public InputStream getInputStream() { + return inputStream; + } + + /** + * Set the input to be a character reader. Normally, + * a stream should be used rather than a reader, so that + * the XML parser can resolve character encoding specified + * by the XML declaration. However, in many cases the encoding + * of the input stream is already resolved, as in the case of + * reading XML from a StringReader. + * + * @param reader A valid Reader reference to an XML CharacterStream. + */ + public void setReader(Reader reader) { + this.reader = reader; + } + + /** + * Get the character stream that was set with setReader. + * + * @return The character stream that was set with setReader, or null + * if setReader or the Reader constructor was not called. + */ + public Reader getReader() { + return reader; + } + + /** + * Set the public identifier for this Source. + * + *

      The public identifier is always optional: if the application + * writer includes one, it will be provided as part of the + * location information.

      + * + * @param publicId The public identifier as a string. + */ + public void setPublicId(String publicId) { + this.publicId = publicId; + } + + /** + * Get the public identifier that was set with setPublicId. + * + * @return The public identifier that was set with setPublicId, or null + * if setPublicId was not called. + */ + public String getPublicId() { + return publicId; + } + + /** + * Set the system identifier for this Source. + * + *

      The system identifier is optional if there is a byte stream + * or a character stream, but it is still useful to provide one, + * since the application can use it to resolve relative URIs + * and can include it in error messages and warnings (the parser + * will attempt to open a connection to the URI only if + * there is no byte stream or character stream specified).

      + * + * @param systemId The system identifier as a URL string. + */ + public void setSystemId(String systemId) { + this.systemId = systemId; + } + + /** + * Get the system identifier that was set with setSystemId. + * + * @return The system identifier that was set with setSystemId, or null + * if setSystemId was not called. + */ + public String getSystemId() { + return systemId; + } + + /** + * Set the system ID from a File reference. + * + * @param f Must a non-null File reference. + */ + public void setSystemId(File f) { + //convert file to appropriate URI, f.toURI().toASCIIString() + //converts the URI to string as per rule specified in + //RFC 2396, + this.systemId = f.toURI().toASCIIString(); + } + + ////////////////////////////////////////////////////////////////////// + // Internal state. + ////////////////////////////////////////////////////////////////////// + + /** + * The public identifier for this input source, or null. + */ + private String publicId; + + /** + * The system identifier as a URL string, or null. + */ + private String systemId; + + /** + * The byte stream for this Source, or null. + */ + private InputStream inputStream; + + /** + * The character stream for this Source, or null. + */ + private Reader reader; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/Schema.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/Schema.java new file mode 100644 index 000000000..05c445ac0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/Schema.java @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.validation; + +/** + * Immutable in-memory representation of grammar. + * + *

      + * This object represents a set of constraints that can be checked/ + * enforced against an XML document. + * + *

      + * A {@link Schema} object is thread safe and applications are + * encouraged to share it across many parsers in many threads. + * + *

      + * A {@link Schema} object is immutable in the sense that it shouldn't + * change the set of constraints once it is created. In other words, + * if an application validates the same document twice against the same + * {@link Schema}, it must always produce the same result. + * + *

      + * A {@link Schema} object is usually created from {@link SchemaFactory}. + * + *

      + * Two kinds of validators can be created from a {@link Schema} object. + * One is {@link Validator}, which provides highly-level validation + * operations that cover typical use cases. The other is + * {@link ValidatorHandler}, which works on top of SAX for better + * modularity. + * + *

      + * This specification does not refine + * the {@link java.lang.Object#equals(java.lang.Object)} method. + * In other words, if you parse the same schema twice, you may + * still get !schemaA.equals(schemaB). + * + * @author Kohsuke Kawaguchi + * @see XML Schema Part 1: Structures + * @see Extensible Markup Language (XML) 1.1 + * @see Extensible Markup Language (XML) 1.0 (Second Edition) + * @since 1.5 + */ +public abstract class Schema { + + /** + * Constructor for the derived class. + * + *

      + * The constructor does nothing. + */ + protected Schema() { + } + + /** + * Creates a new {@link Validator} for this {@link Schema}. + * + *

      A validator enforces/checks the set of constraints this object + * represents.

      + * + *

      Implementors should assure that the properties set on the + * {@link SchemaFactory} that created this {@link Schema} are also + * set on the {@link Validator} constructed.

      + * + * @return + * Always return a non-null valid object. + */ + public abstract Validator newValidator(); + + /** + * Creates a new {@link ValidatorHandler} for this {@link Schema}. + * + *

      Implementors should assure that the properties set on the + * {@link SchemaFactory} that created this {@link Schema} are also + * set on the {@link ValidatorHandler} constructed.

      + * + * @return + * Always return a non-null valid object. + */ + public abstract ValidatorHandler newValidatorHandler(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactory.java new file mode 100644 index 000000000..97b316540 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactory.java @@ -0,0 +1,753 @@ +/* + * Copyright (c) 2003, 2006, 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 javax.xml.validation; + +import java.io.File; +import java.net.URL; + +import javax.xml.transform.Source; +import javax.xml.transform.stream.StreamSource; + +import org.w3c.dom.ls.LSResourceResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + +/** + * Factory that creates {@link Schema} objects. Entry-point to + * the validation API. + * + *

      + * {@link SchemaFactory} is a schema compiler. It reads external + * representations of schemas and prepares them for validation. + * + *

      + * The {@link SchemaFactory} class is not thread-safe. In other words, + * it is the application's responsibility to ensure that at most + * one thread is using a {@link SchemaFactory} object at any + * given moment. Implementations are encouraged to mark methods + * as synchronized to protect themselves from broken clients. + * + *

      + * {@link SchemaFactory} is not re-entrant. While one of the + * newSchema methods is being invoked, applications + * may not attempt to recursively invoke the newSchema method, + * even from the same thread. + * + *

      Schema Language

      + *

      + * This spec uses a namespace URI to designate a schema language. + * The following table shows the values defined by this specification. + *

      + * To be compliant with the spec, the implementation + * is only required to support W3C XML Schema 1.0. However, + * if it chooses to support other schema languages listed here, + * it must conform to the relevant behaviors described in this spec. + * + *

      + * Schema languages not listed here are expected to + * introduce their own URIs to represent themselves. + * The {@link SchemaFactory} class is capable of locating other + * implementations for other schema languages at run-time. + * + *

      + * Note that because the XML DTD is strongly tied to the parsing process + * and has a significant effect on the parsing process, it is impossible + * to define the DTD validation as a process independent from parsing. + * For this reason, this specification does not define the semantics for + * the XML DTD. This doesn't prohibit implentors from implementing it + * in a way they see fit, but users are warned that any DTD + * validation implemented on this interface necessarily deviate from + * the XML DTD semantics as defined in the XML 1.0. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      valuelanguage
      {@link javax.xml.XMLConstants#W3C_XML_SCHEMA_NS_URI} ("http://www.w3.org/2001/XMLSchema")W3C XML Schema 1.0
      {@link javax.xml.XMLConstants#RELAXNG_NS_URI} ("http://relaxng.org/ns/structure/1.0")RELAX NG 1.0
      + * + * @author Kohsuke Kawaguchi + * @author Neeraj Bajaj + * + * @since 1.5 + */ +public abstract class SchemaFactory { + + private static SecuritySupport ss = new SecuritySupport(); + + /** + *

      Constructor for derived classes.

      + * + *

      The constructor does nothing.

      + * + *

      Derived classes must create {@link SchemaFactory} objects that have + * null {@link ErrorHandler} and + * null {@link LSResourceResolver}.

      + */ + protected SchemaFactory() { + } + + /** + *

      Lookup an implementation of the SchemaFactory that supports the specified + * schema language and return it.

      + * + *

      To find a SchemaFactory object for a given schema language, + * this method looks the following places in the following order + * where "the class loader" refers to the context class loader:

      + *
        + *
      1. + * If the system property + * "javax.xml.validation.SchemaFactory:schemaLanguage" + * is present (where schemaLanguage is the parameter + * to this method), then its value is read + * as a class name. The method will try to + * create a new instance of this class by using the class loader, + * and returns it if it is successfully created. + *
      2. + *
      3. + * $java.home/lib/jaxp.properties is read and + * the value associated with the key being the system property above + * is looked for. If present, the value is processed just like above. + *
      4. + *
      5. + *

        The class loader is asked for service provider provider-configuration files matching + * javax.xml.validation.SchemaFactory in the resource directory META-INF/services. + * See the JAR File Specification for file format and parsing rules. + * Each potential service provider is required to implement the method:

        + *
        +     *        {@link #isSchemaLanguageSupported(String schemaLanguage)}
        +     *     
        + * The first service provider found in class loader order that supports the specified schema language is returned. + *
      6. + *
      7. + * Platform default SchemaFactory is located + * in a implementation specific way. There must be a platform default + * SchemaFactory for W3C XML Schema. + *
      8. + *
      + * + *

      If everything fails, {@link IllegalArgumentException} will be thrown.

      + * + *

      Tip for Trouble-shooting:

      + *

      See {@link java.util.Properties#load(java.io.InputStream)} for + * exactly how a property file is parsed. In particular, colons ':' + * need to be escaped in a property file, so make sure schema language + * URIs are properly escaped in it. For example:

      + *
      +     * http\://www.w3.org/2001/XMLSchema=org.acme.foo.XSSchemaFactory
      +     * 
      + * + * @param schemaLanguage + * Specifies the schema language which the returned + * SchemaFactory will understand. See + * the list of available + * schema languages for the possible values. + * + * @return New instance of a SchemaFactory + * + * @throws IllegalArgumentException + * If no implementation of the schema language is available. + * @throws NullPointerException + * If the schemaLanguage parameter is null. + * + * @see #newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader) + */ + public static final SchemaFactory newInstance(String schemaLanguage) { + ClassLoader cl; + cl = ss.getContextClassLoader(); + + if (cl == null) { + //cl = ClassLoader.getSystemClassLoader(); + //use the current class loader + cl = SchemaFactory.class.getClassLoader(); + } + + SchemaFactory f = new SchemaFactoryFinder(cl).newFactory(schemaLanguage); + if (f == null) { + throw new IllegalArgumentException( + "No SchemaFactory" + + " that implements the schema language specified by: " + schemaLanguage + + " could be loaded"); + } + return f; + } + + /** + *

      Obtain a new instance of a SchemaFactory from class name. SchemaFactory + * is returned if specified factory class name supports the specified schema language. + * This function is useful when there are multiple providers in the classpath. + * It gives more control to the application as it can specify which provider + * should be loaded.

      + * + *

      Tip for Trouble-shooting

      + *

      Setting the jaxp.debug system property will cause + * this method to print a lot of debug messages + * to System.err about what it is doing and where it is looking at.

      + * + *

      If you have problems try:

      + *
      +     * java -Djaxp.debug=1 YourProgram ....
      +     * 
      + * + * @param schemaLanguage Specifies the schema language which the returned + * SchemaFactory will understand. See + * the list of available + * schema languages for the possible values. + * + * @param factoryClassName fully qualified factory class name that provides implementation of javax.xml.validation.SchemaFactory. + * + * @param classLoader ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * @return New instance of a SchemaFactory + * + * @throws IllegalArgumentException + * if factoryClassName is null, or + * the factory class cannot be loaded, instantiated or doesn't + * support the schema language specified in schemLanguage + * parameter. + * + * @throws NullPointerException + * If the schemaLanguage parameter is null. + * + * @see #newInstance(String schemaLanguage) + * + * @since 1.6 + */ + public static SchemaFactory newInstance(String schemaLanguage, String factoryClassName, ClassLoader classLoader){ + ClassLoader cl = classLoader; + + if (cl == null) { + cl = ss.getContextClassLoader(); + } + + SchemaFactory f = new SchemaFactoryFinder(cl).createInstance(factoryClassName); + if (f == null) { + throw new IllegalArgumentException( + "Factory " + factoryClassName + + " could not be loaded to implement the schema language specified by: " + schemaLanguage); + } + //if this factory supports the given schemalanguage return this factory else thrown exception + if(f.isSchemaLanguageSupported(schemaLanguage)){ + return f; + }else{ + throw new IllegalArgumentException( + "Factory " + f.getClass().getName() + + " does not implement the schema language specified by: " + schemaLanguage); + } + + } + + /** + *

      Is specified schema supported by this SchemaFactory?

      + * + * @param schemaLanguage Specifies the schema language which the returned SchemaFactory will understand. + * schemaLanguage must specify a valid schema language. + * + * @return true if SchemaFactory supports schemaLanguage, else false. + * + * @throws NullPointerException If schemaLanguage is null. + * @throws IllegalArgumentException If schemaLanguage.length() == 0 + * or schemaLanguage does not specify a valid schema language. + */ + public abstract boolean isSchemaLanguageSupported(String schemaLanguage); + + /** + * Look up the value of a feature flag. + * + *

      The feature name is any fully-qualified URI. It is + * possible for a {@link SchemaFactory} to recognize a feature name but + * temporarily be unable to return its value. + * + *

      Implementors are free (and encouraged) to invent their own features, + * using names built on their own URIs.

      + * + * @param name The feature name, which is a non-null fully-qualified URI. + * + * @return The current value of the feature (true or false). + * + * @throws SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link SchemaFactory} recognizes the feature name but + * cannot determine its value at this time. + * @throws NullPointerException If name is null. + * + * @see #setFeature(String, boolean) + */ + public boolean getFeature(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + throw new SAXNotRecognizedException(name); + } + + /** + *

      Set a feature for this SchemaFactory, + * {@link Schema}s created by this factory, and by extension, + * {@link Validator}s and {@link ValidatorHandler}s created by + * those {@link Schema}s. + *

      + * + *

      Implementors and developers should pay particular attention + * to how the special {@link Schema} object returned by {@link + * #newSchema()} is processed. In some cases, for example, when the + * SchemaFactory and the class actually loading the + * schema come from different implementations, it may not be possible + * for SchemaFactory features to be inherited automatically. + * Developers should + * make sure that features, such as secure processing, are explicitly + * set in both places.

      + * + *

      The feature name is any fully-qualified URI. It is + * possible for a {@link SchemaFactory} to expose a feature value but + * to be unable to change the current value.

      + * + *

      All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. + * When the feature is:

      + *
        + *
      • + * true: the implementation will limit XML processing to conform to implementation limits. + * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. + * If XML processing is limited for security reasons, it will be reported via a call to the registered + * {@link ErrorHandler#fatalError(SAXParseException exception)}. + * See {@link #setErrorHandler(ErrorHandler errorHandler)}. + *
      • + *
      • + * false: the implementation will processing XML according to the XML specifications without + * regard to possible implementation limits. + *
      • + *
      + * + * @param name The feature name, which is a non-null fully-qualified URI. + * @param value The requested value of the feature (true or false). + * + * @throws SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link SchemaFactory} recognizes the feature name but + * cannot set the requested value. + * @throws NullPointerException If name is null. + * + * @see #getFeature(String) + */ + public void setFeature(String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + throw new SAXNotRecognizedException(name); + } + + /** + * Set the value of a property. + * + *

      The property name is any fully-qualified URI. It is + * possible for a {@link SchemaFactory} to recognize a property name but + * to be unable to change the current value.

      + * + *

      {@link SchemaFactory}s are not required to recognize setting + * any specific property names.

      + * + * @param name The property name, which is a non-null fully-qualified URI. + * @param object The requested value for the property. + * + * @throws SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link SchemaFactory} recognizes the property name but + * cannot set the requested value. + * @throws NullPointerException If name is null. + */ + public void setProperty(String name, Object object) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + throw new SAXNotRecognizedException(name); + } + + /** + * Look up the value of a property. + * + *

      The property name is any fully-qualified URI. It is + * possible for a {@link SchemaFactory} to recognize a property name but + * temporarily be unable to return its value.

      + * + *

      {@link SchemaFactory}s are not required to recognize any specific + * property names.

      + * + *

      Implementors are free (and encouraged) to invent their own properties, + * using names built on their own URIs.

      + * + * @param name The property name, which is a non-null fully-qualified URI. + * + * @return The current value of the property. + * + * @throws SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * XMLReader recognizes the property name but + * cannot determine its value at this time. + * @throws NullPointerException If name is null. + * + * @see #setProperty(String, Object) + */ + public Object getProperty(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + throw new SAXNotRecognizedException(name); + } + + /** + * Sets the {@link ErrorHandler} to receive errors encountered + * during the newSchema method invocation. + * + *

      + * Error handler can be used to customize the error handling process + * during schema parsing. When an {@link ErrorHandler} is set, + * errors found during the parsing of schemas will be first sent + * to the {@link ErrorHandler}. + * + *

      + * The error handler can abort the parsing of a schema immediately + * by throwing {@link SAXException} from the handler. Or for example + * it can print an error to the screen and try to continue the + * processing by returning normally from the {@link ErrorHandler} + * + *

      + * If any {@link Throwable} (or instances of its derived classes) + * is thrown from an {@link ErrorHandler}, + * the caller of the newSchema method will be thrown + * the same {@link Throwable} object. + * + *

      + * {@link SchemaFactory} is not allowed to + * throw {@link SAXException} without first reporting it to + * {@link ErrorHandler}. + * + *

      + * Applications can call this method even during a {@link Schema} + * is being parsed. + * + *

      + * When the {@link ErrorHandler} is null, the implementation will + * behave as if the following {@link ErrorHandler} is set: + *

      +     * class DraconianErrorHandler implements {@link ErrorHandler} {
      +     *     public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
      +     *         throw e;
      +     *     }
      +     *     public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
      +     *         throw e;
      +     *     }
      +     *     public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
      +     *         // noop
      +     *     }
      +     * }
      +     * 
      + * + *

      + * When a new {@link SchemaFactory} object is created, initially + * this field is set to null. This field will NOT be + * inherited to {@link Schema}s, {@link Validator}s, or + * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. + * + * @param errorHandler A new error handler to be set. + * This parameter can be null. + */ + public abstract void setErrorHandler(ErrorHandler errorHandler); + + /** + * Gets the current {@link ErrorHandler} set to this {@link SchemaFactory}. + * + * @return + * This method returns the object that was last set through + * the {@link #setErrorHandler(ErrorHandler)} method, or null + * if that method has never been called since this {@link SchemaFactory} + * has created. + * + * @see #setErrorHandler(ErrorHandler) + */ + public abstract ErrorHandler getErrorHandler(); + + /** + * Sets the {@link LSResourceResolver} to customize + * resource resolution when parsing schemas. + * + *

      + * {@link SchemaFactory} uses a {@link LSResourceResolver} + * when it needs to locate external resources while parsing schemas, + * although exactly what constitutes "locating external resources" is + * up to each schema language. For example, for W3C XML Schema, + * this includes files <include>d or <import>ed, + * and DTD referenced from schema files, etc. + * + *

      + * Applications can call this method even during a {@link Schema} + * is being parsed. + * + *

      + * When the {@link LSResourceResolver} is null, the implementation will + * behave as if the following {@link LSResourceResolver} is set: + *

      +     * class DumbDOMResourceResolver implements {@link LSResourceResolver} {
      +     *     public {@link org.w3c.dom.ls.LSInput} resolveResource(
      +     *         String publicId, String systemId, String baseURI) {
      +     *
      +     *         return null; // always return null
      +     *     }
      +     * }
      +     * 
      + * + *

      + * If a {@link LSResourceResolver} throws a {@link RuntimeException} + * (or instances of its derived classes), + * then the {@link SchemaFactory} will abort the parsing and + * the caller of the newSchema method will receive + * the same {@link RuntimeException}. + * + *

      + * When a new {@link SchemaFactory} object is created, initially + * this field is set to null. This field will NOT be + * inherited to {@link Schema}s, {@link Validator}s, or + * {@link ValidatorHandler}s that are created from this {@link SchemaFactory}. + * + * @param resourceResolver + * A new resource resolver to be set. This parameter can be null. + */ + public abstract void setResourceResolver(LSResourceResolver resourceResolver); + + /** + * Gets the current {@link LSResourceResolver} set to this {@link SchemaFactory}. + * + * @return + * This method returns the object that was last set through + * the {@link #setResourceResolver(LSResourceResolver)} method, or null + * if that method has never been called since this {@link SchemaFactory} + * has created. + * + * @see #setErrorHandler(ErrorHandler) + */ + public abstract LSResourceResolver getResourceResolver(); + + /** + *

      Parses the specified source as a schema and returns it as a schema.

      + * + *

      This is a convenience method for {@link #newSchema(Source[] schemas)}.

      + * + * @param schema Source that represents a schema. + * + * @return New Schema from parsing schema. + * + * @throws SAXException If a SAX error occurs during parsing. + * @throws NullPointerException if schema is null. + */ + public Schema newSchema(Source schema) throws SAXException { + return newSchema(new Source[]{schema}); + } + + /** + *

      Parses the specified File as a schema and returns it as a Schema.

      + * + *

      This is a convenience method for {@link #newSchema(Source schema)}.

      + * + * @param schema File that represents a schema. + * + * @return New Schema from parsing schema. + * + * @throws SAXException If a SAX error occurs during parsing. + * @throws NullPointerException if schema is null. + */ + public Schema newSchema(File schema) throws SAXException { + return newSchema(new StreamSource(schema)); + } + + /** + *

      Parses the specified URL as a schema and returns it as a Schema.

      + * + *

      This is a convenience method for {@link #newSchema(Source schema)}.

      + * + * @param schema URL that represents a schema. + * + * @return New Schema from parsing schema. + * + * @throws SAXException If a SAX error occurs during parsing. + * @throws NullPointerException if schema is null. + */ + public Schema newSchema(URL schema) throws SAXException { + return newSchema(new StreamSource(schema.toExternalForm())); + } + + /** + * Parses the specified source(s) as a schema and returns it as a schema. + * + *

      + * The callee will read all the {@link Source}s and combine them into a + * single schema. The exact semantics of the combination depends on the schema + * language that this {@link SchemaFactory} object is created for. + * + *

      + * When an {@link ErrorHandler} is set, the callee will report all the errors + * found in sources to the handler. If the handler throws an exception, it will + * abort the schema compilation and the same exception will be thrown from + * this method. Also, after an error is reported to a handler, the callee is allowed + * to abort the further processing by throwing it. If an error handler is not set, + * the callee will throw the first error it finds in the sources. + * + *

      W3C XML Schema 1.0

      + *

      + * The resulting schema contains components from the specified sources. + * The same result would be achieved if all these sources were + * imported, using appropriate values for schemaLocation and namespace, + * into a single schema document with a different targetNamespace + * and no components of its own, if the import elements were given + * in the same order as the sources. Section 4.2.3 of the XML Schema + * recommendation describes the options processors have in this + * regard. While a processor should be consistent in its treatment of + * JAXP schema sources and XML Schema imports, the behaviour between + * JAXP-compliant parsers may vary; in particular, parsers may choose + * to ignore all but the first <import> for a given namespace, + * regardless of information provided in schemaLocation. + * + *

      + * If the parsed set of schemas includes error(s) as + * specified in the section 5.1 of the XML Schema spec, then + * the error must be reported to the {@link ErrorHandler}. + * + *

      RELAX NG

      + * + *

      For RELAX NG, this method must throw {@link UnsupportedOperationException} + * if schemas.length!=1. + * + * + * @param schemas + * inputs to be parsed. {@link SchemaFactory} is required + * to recognize {@link javax.xml.transform.sax.SAXSource}, + * {@link StreamSource}, + * {@link javax.xml.transform.stax.StAXSource}, + * and {@link javax.xml.transform.dom.DOMSource}. + * Input schemas must be XML documents or + * XML elements and must not be null. For backwards compatibility, + * the results of passing anything other than + * a document or element are implementation-dependent. + * Implementations must either recognize and process the input + * or thrown an IllegalArgumentException. + * + * @return + * Always return a non-null valid {@link Schema} object. + * Note that when an error has been reported, there is no + * guarantee that the returned {@link Schema} object is + * meaningful. + * + * @throws SAXException + * If an error is found during processing the specified inputs. + * When an {@link ErrorHandler} is set, errors are reported to + * there first. See {@link #setErrorHandler(ErrorHandler)}. + * @throws NullPointerException + * If the schemas parameter itself is null or + * any item in the array is null. + * @throws IllegalArgumentException + * If any item in the array is not recognized by this method. + * @throws UnsupportedOperationException + * If the schema language doesn't support this operation. + */ + public abstract Schema newSchema(Source[] schemas) throws SAXException; + + /** + * Creates a special {@link Schema} object. + * + *

      The exact semantics of the returned {@link Schema} object + * depend on the schema language for which this {@link SchemaFactory} + * is created. + * + *

      Also, implementations are allowed to use implementation-specific + * property/feature to alter the semantics of this method.

      + * + *

      Implementors and developers should pay particular attention + * to how the features set on this {@link SchemaFactory} are + * processed by this special {@link Schema}. + * In some cases, for example, when the + * {@link SchemaFactory} and the class actually loading the + * schema come from different implementations, it may not be possible + * for {@link SchemaFactory} features to be inherited automatically. + * Developers should + * make sure that features, such as secure processing, are explicitly + * set in both places.

      + * + *

      W3C XML Schema 1.0

      + *

      + * For XML Schema, this method creates a {@link Schema} object that + * performs validation by using location hints specified in documents. + * + *

      + * The returned {@link Schema} object assumes that if documents + * refer to the same URL in the schema location hints, + * they will always resolve to the same schema document. This + * asusmption allows implementations to reuse parsed results of + * schema documents so that multiple validations against the same + * schema will run faster. + * + *

      + * Note that the use of schema location hints introduces a + * vulnerability to denial-of-service attacks. + * + * + *

      RELAX NG

      + *

      + * RELAX NG does not support this operation. + * + * @return + * Always return non-null valid {@link Schema} object. + * + * @throws UnsupportedOperationException + * If this operation is not supported by the callee. + * @throws SAXException + * If this operation is supported but failed for some reason. + */ + public abstract Schema newSchema() throws SAXException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactoryFinder.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactoryFinder.java new file mode 100644 index 000000000..8157b6bd8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactoryFinder.java @@ -0,0 +1,571 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.validation; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Properties; + +/** + * Implementation of {@link SchemaFactory#newInstance(String)}. + * + * @author Kohsuke Kawaguchi + * @version $Revision: 1.8 $, $Date: 2010-11-01 04:36:13 $ + * @since 1.5 + */ +class SchemaFactoryFinder { + + /** debug support code. */ + private static boolean debug = false; + /** + *

      Take care of restrictions imposed by java security model

      + */ + private static SecuritySupport ss = new SecuritySupport(); + /** + *

      Cache properties for performance.

      + */ + private static Properties cacheProps = new Properties(); + + /** + *

      First time requires initialization overhead.

      + */ + private static volatile boolean firstTime = true; + + static { + // Use try/catch block to support applets + try { + debug = ss.getSystemProperty("jaxp.debug") != null; + } catch (Exception _) { + debug = false; + } + } + + /** + *

      Conditional debug printing.

      + * + * @param msg to print + */ + private static void debugPrintln(String msg) { + if (debug) { + System.err.println("JAXP: " + msg); + } + } + + /** + *

      ClassLoader to use to find SchemaFactory.

      + */ + private final ClassLoader classLoader; + + /** + *

      Constructor that specifies ClassLoader to use + * to find SchemaFactory.

      + * + * @param loader + * to be used to load resource, {@link SchemaFactory}, and + * {@link SchemaFactoryLoader} implementations during + * the resolution process. + * If this parameter is null, the default system class loader + * will be used. + */ + public SchemaFactoryFinder(ClassLoader loader) { + this.classLoader = loader; + if( debug ) { + debugDisplayClassLoader(); + } + } + + private void debugDisplayClassLoader() { + try { + if( classLoader == ss.getContextClassLoader() ) { + debugPrintln("using thread context class loader ("+classLoader+") for search"); + return; + } + } catch( Throwable _ ) { + ; // getContextClassLoader() undefined in JDK1.1 + } + + if( classLoader==ClassLoader.getSystemClassLoader() ) { + debugPrintln("using system class loader ("+classLoader+") for search"); + return; + } + + debugPrintln("using class loader ("+classLoader+") for search"); + } + + /** + *

      Creates a new {@link SchemaFactory} object for the specified + * schema language.

      + * + * @param schemaLanguage + * See {@link SchemaFactory Schema Language} table in SchemaFactory + * for the list of available schema languages. + * + * @return null if the callee fails to create one. + * + * @throws NullPointerException + * If the schemaLanguage parameter is null. + */ + public SchemaFactory newFactory(String schemaLanguage) { + if(schemaLanguage==null) throw new NullPointerException(); + SchemaFactory f = _newFactory(schemaLanguage); + if (f != null) { + debugPrintln("factory '" + f.getClass().getName() + "' was found for " + schemaLanguage); + } else { + debugPrintln("unable to find a factory for " + schemaLanguage); + } + return f; + } + + /** + *

      Lookup a SchemaFactory for the given schemaLanguage.

      + * + * @param schemaLanguage Schema language to lookup SchemaFactory for. + * + * @return SchemaFactory for the given schemaLanguage. + */ + private SchemaFactory _newFactory(String schemaLanguage) { + SchemaFactory sf; + + String propertyName = SERVICE_CLASS.getName() + ":" + schemaLanguage; + + // system property look up + try { + debugPrintln("Looking up system property '"+propertyName+"'" ); + String r = ss.getSystemProperty(propertyName); + if(r!=null) { + debugPrintln("The value is '"+r+"'"); + sf = createInstance(r, true); + if(sf!=null) return sf; + } else + debugPrintln("The property is undefined."); + } catch( Throwable t ) { + if( debug ) { + debugPrintln("failed to look up system property '"+propertyName+"'" ); + t.printStackTrace(); + } + } + + String javah = ss.getSystemProperty( "java.home" ); + String configFile = javah + File.separator + + "lib" + File.separator + "jaxp.properties"; + + String factoryClassName = null ; + + // try to read from $java.home/lib/jaxp.properties + try { + if(firstTime){ + synchronized(cacheProps){ + if(firstTime){ + File f=new File( configFile ); + firstTime = false; + if(ss.doesFileExist(f)){ + debugPrintln("Read properties file " + f); + cacheProps.load(ss.getFileInputStream(f)); + } + } + } + } + factoryClassName = cacheProps.getProperty(propertyName); + debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); + + if (factoryClassName != null) { + sf = createInstance(factoryClassName, true); + if(sf != null){ + return sf; + } + } + } catch (Exception ex) { + if (debug) { + ex.printStackTrace(); + } + } + + /** + // try to read from $java.home/lib/jaxp.properties + try { + String javah = ss.getSystemProperty( "java.home" ); + String configFile = javah + File.separator + + "lib" + File.separator + "jaxp.properties"; + File f = new File( configFile ); + if( ss.doesFileExist(f)) { + sf = loadFromProperty( + propertyName,f.getAbsolutePath(), new FileInputStream(f)); + if(sf!=null) return sf; + } else { + debugPrintln("Tried to read "+ f.getAbsolutePath()+", but it doesn't exist."); + } + } catch(Throwable e) { + if( debug ) { + debugPrintln("failed to read $java.home/lib/jaxp.properties"); + e.printStackTrace(); + } + } + */ + + // try META-INF/services files + Iterator sitr = createServiceFileIterator(); + while(sitr.hasNext()) { + URL resource = (URL)sitr.next(); + debugPrintln("looking into " + resource); + try { + sf = loadFromService(schemaLanguage,resource.toExternalForm(), + ss.getURLInputStream(resource)); + if(sf!=null) return sf; + } catch(IOException e) { + if( debug ) { + debugPrintln("failed to read "+resource); + e.printStackTrace(); + } + } + } + + // platform default + if(schemaLanguage.equals("http://www.w3.org/2001/XMLSchema")) { + debugPrintln("attempting to use the platform default XML Schema validator"); + return createInstance("com.sun.org.apache.xerces.internal.jaxp.validation.XMLSchemaFactory", true); + } + + debugPrintln("all things were tried, but none was found. bailing out."); + return null; + } + + /**

      Create class using appropriate ClassLoader.

      + * + * @param className Name of class to create. + * @return Created class or null. + */ + private Class createClass(String className) { + Class clazz; + + // use approprite ClassLoader + try { + if (classLoader != null) { + clazz = classLoader.loadClass(className); + } else { + clazz = Class.forName(className); + } + } catch (Throwable t) { + if(debug) t.printStackTrace(); + return null; + } + + return clazz; + } + + /** + *

      Creates an instance of the specified and returns it.

      + * + * @param className + * fully qualified class name to be instanciated. + * + * @return null + * if it fails. Error messages will be printed by this method. + */ + SchemaFactory createInstance( String className ) { + return createInstance( className, false ); + } + + SchemaFactory createInstance( String className, boolean useServicesMechanism ) { + SchemaFactory schemaFactory = null; + + debugPrintln("createInstance(" + className + ")"); + + // get Class from className + Class clazz = createClass(className); + if (clazz == null) { + debugPrintln("failed to getClass(" + className + ")"); + return null; + } + debugPrintln("loaded " + className + " from " + which(clazz)); + + // instantiate Class as a SchemaFactory + try { + if (!useServicesMechanism) { + schemaFactory = (SchemaFactory) newInstanceNoServiceLoader(clazz); + } + if (schemaFactory == null) { + schemaFactory = (SchemaFactory) clazz.newInstance(); + } + } catch (ClassCastException classCastException) { + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + classCastException.printStackTrace(); + } + return null; + } catch (IllegalAccessException illegalAccessException) { + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + illegalAccessException.printStackTrace(); + } + return null; + } catch (InstantiationException instantiationException) { + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + instantiationException.printStackTrace(); + } + return null; + } + + return schemaFactory; + } + /** + * Try to construct using newTransformerFactoryNoServiceLoader + * method if available. + */ + private static Object newInstanceNoServiceLoader( + Class providerClass + ) { + // Retain maximum compatibility if no security manager. + if (System.getSecurityManager() == null) { + return null; + } + try { + Method creationMethod = + providerClass.getDeclaredMethod( + "newXMLSchemaFactoryNoServiceLoader" + ); + return creationMethod.invoke(null, null); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { + return null; + } + } + + /** Iterator that lazily computes one value and returns it. */ + private static abstract class SingleIterator implements Iterator { + private boolean seen = false; + + public final void remove() { throw new UnsupportedOperationException(); } + public final boolean hasNext() { return !seen; } + public final Object next() { + if(seen) throw new NoSuchElementException(); + seen = true; + return value(); + } + + protected abstract Object value(); + } + + /** + * Looks up a value in a property file + * while producing all sorts of debug messages. + * + * @return null + * if there was an error. + */ + private SchemaFactory loadFromProperty( String keyName, String resourceName, InputStream in ) + throws IOException { + debugPrintln("Reading "+resourceName ); + + Properties props=new Properties(); + props.load(in); + in.close(); + String factoryClassName = props.getProperty(keyName); + if(factoryClassName != null){ + debugPrintln("found "+keyName+" = " + factoryClassName); + return createInstance(factoryClassName); + } else { + debugPrintln(keyName+" is not in the property file"); + return null; + } + } + + /** + *

      Look up a value in a property file.

      + * + *

      Set debug to true to trace property evaluation.

      + * + * @param schemaLanguage Schema Language to support. + * @param inputName Name of InputStream. + * @param in InputStream of properties. + * + * @return SchemaFactory as determined by keyName value or null if there was an error. + * + * @throws IOException If IO error reading from in. + */ + private SchemaFactory loadFromService( + String schemaLanguage, + String inputName, + InputStream in) + throws IOException { + + SchemaFactory schemaFactory = null; + final Class[] stringClassArray = {"".getClass()}; + final Object[] schemaLanguageObjectArray = {schemaLanguage}; + final String isSchemaLanguageSupportedMethod = "isSchemaLanguageSupported"; + + debugPrintln("Reading " + inputName); + + // read from InputStream until a match is found + BufferedReader configFile = new BufferedReader(new InputStreamReader(in)); + String line = null; + while ((line = configFile.readLine()) != null) { + // '#' is comment char + int comment = line.indexOf("#"); + switch (comment) { + case -1: break; // no comment + case 0: line = ""; break; // entire line is a comment + default: line = line.substring(0, comment); break; // trim comment + } + + // trim whitespace + line = line.trim(); + + // any content left on line? + if (line.length() == 0) { + continue; + } + + // line content is now the name of the class + Class clazz = createClass(line); + if (clazz == null) { + continue; + } + + // create an instance of the Class + try { + schemaFactory = (SchemaFactory) clazz.newInstance(); + } catch (ClassCastException classCastExcpetion) { + schemaFactory = null; + continue; + } catch (InstantiationException instantiationException) { + schemaFactory = null; + continue; + } catch (IllegalAccessException illegalAccessException) { + schemaFactory = null; + continue; + } + + // does this Class support desired Schema? + try { + Method isSchemaLanguageSupported = clazz.getMethod(isSchemaLanguageSupportedMethod, stringClassArray); + Boolean supported = (Boolean) isSchemaLanguageSupported.invoke(schemaFactory, schemaLanguageObjectArray); + if (supported.booleanValue()) { + break; + } + } catch (NoSuchMethodException noSuchMethodException) { + + } catch (IllegalAccessException illegalAccessException) { + + } catch (InvocationTargetException invocationTargetException) { + + } + schemaFactory = null; + } + + // clean up + configFile.close(); + + // return new instance of SchemaFactory or null + return schemaFactory; + } + + /** + * Returns an {@link Iterator} that enumerates all + * the META-INF/services files that we care. + */ + private Iterator createServiceFileIterator() { + if (classLoader == null) { + return new SingleIterator() { + protected Object value() { + ClassLoader classLoader = SchemaFactoryFinder.class.getClassLoader(); + //return (ClassLoader.getSystemResource( SERVICE_ID )); + return ss.getResourceAsURL(classLoader, SERVICE_ID); + } + }; + } else { + try { + //final Enumeration e = classLoader.getResources(SERVICE_ID); + final Enumeration e = ss.getResources(classLoader, SERVICE_ID); + if(!e.hasMoreElements()) { + debugPrintln("no "+SERVICE_ID+" file was found"); + } + + // wrap it into an Iterator. + return new Iterator() { + public void remove() { + throw new UnsupportedOperationException(); + } + + public boolean hasNext() { + return e.hasMoreElements(); + } + + public Object next() { + return e.nextElement(); + } + }; + } catch (IOException e) { + debugPrintln("failed to enumerate resources "+SERVICE_ID); + if(debug) e.printStackTrace(); + return new ArrayList().iterator(); // empty iterator + } + } + } + + private static final Class SERVICE_CLASS = SchemaFactory.class; + private static final String SERVICE_ID = "META-INF/services/" + SERVICE_CLASS.getName(); + + + + private static String which( Class clazz ) { + return which( clazz.getName(), clazz.getClassLoader() ); + } + + /** + *

      Search the specified classloader for the given classname.

      + * + * @param classname the fully qualified name of the class to search for + * @param loader the classloader to search + * + * @return the source location of the resource, or null if it wasn't found + */ + private static String which(String classname, ClassLoader loader) { + + String classnameAsResource = classname.replace('.', '/') + ".class"; + + if( loader==null ) loader = ClassLoader.getSystemClassLoader(); + + //URL it = loader.getResource(classnameAsResource); + URL it = ss.getResourceAsURL(loader, classnameAsResource); + if (it != null) { + return it.toString(); + } else { + return null; + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactoryLoader.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactoryLoader.java new file mode 100644 index 000000000..f617d99ae --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SchemaFactoryLoader.java @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2004, 2006, 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 javax.xml.validation; + +/** + *

      Factory that creates {@link SchemaFactory}.

      + * + *

      DO NOT USE THIS CLASS

      + * + *

      + * This class was introduced as a part of an early proposal during the + * JSR-206 standardization process. The proposal was eventually abandoned + * but this class accidentally remained in the source tree, and made its + * way into the final version. + *

      + * This class does not participate in any JAXP 1.3 or JAXP 1.4 processing. + * It must not be used by users or JAXP implementations. + *

      + * + * @author Kohsuke Kawaguchi + * @since 1.5 + */ +public abstract class SchemaFactoryLoader { + + /** + * A do-nothing constructor. + */ + protected SchemaFactoryLoader() { + } + + /** + * Creates a new {@link SchemaFactory} object for the specified + * schema language. + * + * @param schemaLanguage + * See + * the list of available schema languages. + * + * @throws NullPointerException + * If the schemaLanguage parameter is null. + * + * @return null if the callee fails to create one. + */ + public abstract SchemaFactory newFactory(String schemaLanguage); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/SecuritySupport.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SecuritySupport.java new file mode 100644 index 000000000..e11ff64f6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/SecuritySupport.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 2005, 2006, 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 javax.xml.validation; + +import java.io.IOException; +import java.net.URL; +import java.security.*; +import java.net.*; +import java.io.*; +import java.util.*; + +/** + * This class is duplicated for each JAXP subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of the JAXP + * API. + * + * Security related methods that only work on J2SE 1.2 and newer. + */ +class SecuritySupport { + + + ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + //try { + cl = Thread.currentThread().getContextClassLoader(); + //} catch (SecurityException ex) { } + if (cl == null) + cl = ClassLoader.getSystemClassLoader(); + return cl; + } + }); + } + + String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + FileInputStream getFileInputStream(final File file) + throws FileNotFoundException + { + try { + return (FileInputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws FileNotFoundException { + return new FileInputStream(file); + } + }); + } catch (PrivilegedActionException e) { + throw (FileNotFoundException)e.getException(); + } + } + + InputStream getURLInputStream(final URL url) + throws IOException + { + try { + return (InputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws IOException { + return url.openStream(); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException)e.getException(); + } + } + + URL getResourceAsURL(final ClassLoader cl, + final String name) + { + return (URL) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + URL url; + if (cl == null) { + url = Object.class.getResource(name); + } else { + url = cl.getResource(name); + } + return url; + } + }); + } + + Enumeration getResources(final ClassLoader cl, + final String name) throws IOException + { + try{ + return (Enumeration) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws IOException{ + Enumeration enumeration; + if (cl == null) { + enumeration = ClassLoader.getSystemResources(name); + } else { + enumeration = cl.getResources(name); + } + return enumeration; + } + }); + }catch(PrivilegedActionException e){ + throw (IOException)e.getException(); + } + } + + InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + boolean doesFileExist(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Boolean(f.exists()); + } + })).booleanValue(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/TypeInfoProvider.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/TypeInfoProvider.java new file mode 100644 index 000000000..6b4c7b4bb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/TypeInfoProvider.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.validation; + +import org.w3c.dom.TypeInfo; + +/** + * This class provides access to the type information determined + * by {@link ValidatorHandler}. + * + *

      + * Some schema languages, such as W3C XML Schema, encourages a validator + * to report the "type" it assigns to each attribute/element. + * Those applications who wish to access this type information can invoke + * methods defined on this "interface" to access such type information. + * + *

      + * Implementation of this "interface" can be obtained through the + * {@link ValidatorHandler#getTypeInfoProvider()} method. + * + * @author Kohsuke Kawaguchi + * @see org.w3c.dom.TypeInfo + * @since 1.5 + */ +public abstract class TypeInfoProvider { + + /** + * Constructor for the derived class. + * + *

      + * The constructor does nothing. + */ + protected TypeInfoProvider() { + } + + /** + *

      Returns the immutable {@link TypeInfo} object for the current + * element.

      + * + *

      The method may only be called by the startElement event + * or the endElement event + * of the {@link org.xml.sax.ContentHandler} that the application sets to + * the {@link ValidatorHandler}.

      + * + *

      When W3C XML Schema validation is being performed, in the + * case where an element has a union type, the {@link TypeInfo} + * returned by a call to getElementTypeInfo() from the + * startElement + * event will be the union type. The TypeInfo + * returned by a call + * from the endElement event will be the actual member type used + * to validate the element.

      + * + * @throws IllegalStateException + * If this method is called from other {@link org.xml.sax.ContentHandler} + * methods. + * @return + * An immutable {@link TypeInfo} object that represents the + * type of the current element. + * Note that the caller can keep references to the obtained + * {@link TypeInfo} longer than the callback scope. + * + * Otherwise, this method returns + * null if the validator is unable to + * determine the type of the current element for some reason + * (for example, if the validator is recovering from + * an earlier error.) + * + */ + public abstract TypeInfo getElementTypeInfo(); + + /** + * Returns the immutable {@link TypeInfo} object for the specified + * attribute of the current element. + * + *

      + * The method may only be called by the startElement event of + * the {@link org.xml.sax.ContentHandler} that the application sets to the + * {@link ValidatorHandler}.

      + * + * @param index + * The index of the attribute. The same index for + * the {@link org.xml.sax.Attributes} object passed to the + * startElement callback. + * + * @throws IndexOutOfBoundsException + * If the index is invalid. + * @throws IllegalStateException + * If this method is called from other {@link org.xml.sax.ContentHandler} + * methods. + * + * @return + * An immutable {@link TypeInfo} object that represents the + * type of the specified attribute. + * Note that the caller can keep references to the obtained + * {@link TypeInfo} longer than the callback scope. + * + * Otherwise, this method returns + * null if the validator is unable to + * determine the type. + */ + public abstract TypeInfo getAttributeTypeInfo(int index); + + /** + * Returns true if the specified attribute is determined + * to be ID. + * + *

      + * Exacly how an attribute is "determined to be ID" is up to the + * schema language. In case of W3C XML Schema, this means + * that the actual type of the attribute is the built-in ID type + * or its derived type. + * + *

      + * A {@link javax.xml.parsers.DocumentBuilder} uses this information + * to properly implement {@link org.w3c.dom.Attr#isId()}. + * + *

      + * The method may only be called by the startElement event of + * the {@link org.xml.sax.ContentHandler} that the application sets to the + * {@link ValidatorHandler}. + * + * @param index + * The index of the attribute. The same index for + * the {@link org.xml.sax.Attributes} object passed to the + * startElement callback. + * + * @throws IndexOutOfBoundsException + * If the index is invalid. + * @throws IllegalStateException + * If this method is called from other {@link org.xml.sax.ContentHandler} + * methods. + * + * @return true + * if the type of the specified attribute is ID. + */ + public abstract boolean isIdAttribute(int index); + + /** + * Returns false if the attribute was added by the validator. + * + *

      + * This method provides information necessary for + * a {@link javax.xml.parsers.DocumentBuilder} to determine what + * the DOM tree should return from the {@link org.w3c.dom.Attr#getSpecified()} method. + * + *

      + * The method may only be called by the startElement event of + * the {@link org.xml.sax.ContentHandler} that the application sets to the + * {@link ValidatorHandler}. + * + *

      + * A general guideline for validators is to return true if + * the attribute was originally present in the pipeline, and + * false if it was added by the validator. + * + * @param index + * The index of the attribute. The same index for + * the {@link org.xml.sax.Attributes} object passed to the + * startElement callback. + * + * @throws IndexOutOfBoundsException + * If the index is invalid. + * @throws IllegalStateException + * If this method is called from other {@link org.xml.sax.ContentHandler} + * methods. + * + * @return + * true if the attribute was present before the validator + * processes input. false if the attribute was added + * by the validator. + */ + public abstract boolean isSpecified(int index); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/Validator.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/Validator.java new file mode 100644 index 000000000..ee66a6d1f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/Validator.java @@ -0,0 +1,505 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.validation; + +import java.io.IOException; + +import javax.xml.transform.Result; +import javax.xml.transform.Source; + +import org.w3c.dom.ls.LSResourceResolver; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + +/** + *

      A processor that checks an XML document against {@link Schema}.

      + * + *

      + * A validator object is not thread-safe and not reentrant. + * In other words, it is the application's responsibility to make + * sure that one {@link Validator} object is not used from + * more than one thread at any given time, and while the validate + * method is invoked, applications may not recursively call + * the validate method. + *

      + * + * + * @author Kohsuke Kawaguchi + * @since 1.5 + */ +public abstract class Validator { + + /** + * Constructor for derived classes. + * + *

      The constructor does nothing.

      + * + *

      Derived classes must create {@link Validator} objects that have + * null {@link ErrorHandler} and + * null {@link LSResourceResolver}. + *

      + */ + protected Validator() { + } + + /** + *

      Reset this Validator to its original configuration.

      + * + *

      Validator is reset to the same state as when it was created with + * {@link Schema#newValidator()}. + * reset() is designed to allow the reuse of existing Validators + * thus saving resources associated with the creation of new Validators.

      + * + *

      The reset Validator is not guaranteed to have the same {@link LSResourceResolver} or {@link ErrorHandler} + * Objects, e.g. {@link Object#equals(Object obj)}. It is guaranteed to have a functionally equal + * LSResourceResolver and ErrorHandler.

      + */ + public abstract void reset(); + + /** + * Validates the specified input. + * + *

      This is just a convenience method for + * {@link #validate(Source source, Result result)} + * with result of null.

      + * + * @param source + * XML to be validated. Must be an XML document or + * XML element and must not be null. For backwards compatibility, + * the results of attempting to validate anything other than + * a document or element are implementation-dependent. + * Implementations must either recognize and process the input + * or throw an IllegalArgumentException. + * + * @throws IllegalArgumentException + * If the Source + * is an XML artifact that the implementation cannot + * validate (for example, a processing instruction). + * + * @throws SAXException + * If the {@link ErrorHandler} throws a {@link SAXException} or + * if a fatal error is found and the {@link ErrorHandler} returns + * normally. + * + * @throws IOException + * If the validator is processing a + * {@link javax.xml.transform.sax.SAXSource} and the + * underlying {@link org.xml.sax.XMLReader} throws an + * {@link IOException}. + * + * + * @throws NullPointerException If source is + * null. + * + * @see #validate(Source source, Result result) + */ + public void validate(Source source) + throws SAXException, IOException { + + validate(source, null); + } + + /** + *

      Validates the specified input and send the augmented validation + * result to the specified output.

      + * + *

      This method places the following restrictions on the types of + * the {@link Source}/{@link Result} accepted.

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      Source / Result Accepted
      {@link javax.xml.transform.stream.StreamSource}{@link javax.xml.transform.sax.SAXSource}{@link javax.xml.transform.dom.DOMSource}{@link javax.xml.transform.stax.StAXSource}
      nullOKOKOKOK
      {@link javax.xml.transform.stream.StreamResult}OKIllegalArgumentExceptionIllegalArgumentExceptionIllegalArgumentException
      {@link javax.xml.transform.sax.SAXResult}IllegalArgumentExceptionOKIllegalArgumentExceptionIllegalArgumentException
      {@link javax.xml.transform.dom.DOMResult}IllegalArgumentExceptionIllegalArgumentExceptionOKIllegalArgumentException
      {@link javax.xml.transform.stax.StAXResult}IllegalArgumentExceptionIllegalArgumentExceptionIllegalArgumentExceptionOK
      + * + *

      To validate one Source into another kind of + * Result, use the identity transformer (see + * {@link javax.xml.transform.TransformerFactory#newTransformer()}).

      + * + *

      Errors found during the validation is sent to the specified + * {@link ErrorHandler}.

      + * + *

      If a document is valid, or if a document contains some errors + * but none of them were fatal and the ErrorHandler didn't + * throw any exception, then the method returns normally.

      + * + * @param source + * XML to be validated. Must be an XML document or + * XML element and must not be null. For backwards compatibility, + * the results of attempting to validate anything other than + * a document or element are implementation-dependent. + * Implementations must either recognize and process the input + * or throw an IllegalArgumentException. + * + * @param result + * The Result object that receives (possibly augmented) + * XML. This parameter can be null if the caller is not interested + * in it. + * + * Note that when a DOMResult is used, + * a validator might just pass the same DOM node from + * DOMSource to DOMResult + * (in which case source.getNode()==result.getNode()), + * it might copy the entire DOM tree, or it might alter the + * node given by the source. + * + * @throws IllegalArgumentException + * If the Result type doesn't match the + * Source type of if the Source + * is an XML artifact that the implementation cannot + * validate (for example, a processing instruction). + * @throws SAXException + * If the ErrorHandler throws a + * SAXException or + * if a fatal error is found and the ErrorHandler returns + * normally. + * @throws IOException + * If the validator is processing a + * SAXSource and the + * underlying {@link org.xml.sax.XMLReader} throws an + * IOException. + * @throws NullPointerException + * If the source parameter is null. + * + * @see #validate(Source source) + */ + public abstract void validate(Source source, Result result) + throws SAXException, IOException; + + /** + * Sets the {@link ErrorHandler} to receive errors encountered + * during the validate method invocation. + * + *

      + * Error handler can be used to customize the error handling process + * during a validation. When an {@link ErrorHandler} is set, + * errors found during the validation will be first sent + * to the {@link ErrorHandler}. + * + *

      + * The error handler can abort further validation immediately + * by throwing {@link SAXException} from the handler. Or for example + * it can print an error to the screen and try to continue the + * validation by returning normally from the {@link ErrorHandler} + * + *

      + * If any {@link Throwable} is thrown from an {@link ErrorHandler}, + * the caller of the validate method will be thrown + * the same {@link Throwable} object. + * + *

      + * {@link Validator} is not allowed to + * throw {@link SAXException} without first reporting it to + * {@link ErrorHandler}. + * + *

      + * When the {@link ErrorHandler} is null, the implementation will + * behave as if the following {@link ErrorHandler} is set: + *

      +     * class DraconianErrorHandler implements {@link ErrorHandler} {
      +     *     public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
      +     *         throw e;
      +     *     }
      +     *     public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
      +     *         throw e;
      +     *     }
      +     *     public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link SAXException} {
      +     *         // noop
      +     *     }
      +     * }
      +     * 
      + * + *

      + * When a new {@link Validator} object is created, initially + * this field is set to null. + * + * @param errorHandler + * A new error handler to be set. This parameter can be null. + */ + public abstract void setErrorHandler(ErrorHandler errorHandler); + + /** + * Gets the current {@link ErrorHandler} set to this {@link Validator}. + * + * @return + * This method returns the object that was last set through + * the {@link #setErrorHandler(ErrorHandler)} method, or null + * if that method has never been called since this {@link Validator} + * has created. + * + * @see #setErrorHandler(ErrorHandler) + */ + public abstract ErrorHandler getErrorHandler(); + + /** + * Sets the {@link LSResourceResolver} to customize + * resource resolution while in a validation episode. + * + *

      + * {@link Validator} uses a {@link LSResourceResolver} + * when it needs to locate external resources while a validation, + * although exactly what constitutes "locating external resources" is + * up to each schema language. + * + *

      + * When the {@link LSResourceResolver} is null, the implementation will + * behave as if the following {@link LSResourceResolver} is set: + *

      +     * class DumbLSResourceResolver implements {@link LSResourceResolver} {
      +     *     public {@link org.w3c.dom.ls.LSInput} resolveResource(
      +     *         String publicId, String systemId, String baseURI) {
      +     *
      +     *         return null; // always return null
      +     *     }
      +     * }
      +     * 
      + * + *

      + * If a {@link LSResourceResolver} throws a {@link RuntimeException} + * (or instances of its derived classes), + * then the {@link Validator} will abort the parsing and + * the caller of the validate method will receive + * the same {@link RuntimeException}. + * + *

      + * When a new {@link Validator} object is created, initially + * this field is set to null. + * + * @param resourceResolver + * A new resource resolver to be set. This parameter can be null. + */ + public abstract void setResourceResolver(LSResourceResolver resourceResolver); + + /** + * Gets the current {@link LSResourceResolver} set to this {@link Validator}. + * + * @return + * This method returns the object that was last set through + * the {@link #setResourceResolver(LSResourceResolver)} method, or null + * if that method has never been called since this {@link Validator} + * has created. + * + * @see #setErrorHandler(ErrorHandler) + */ + public abstract LSResourceResolver getResourceResolver(); + + + + /** + * Look up the value of a feature flag. + * + *

      The feature name is any fully-qualified URI. It is + * possible for a {@link Validator} to recognize a feature name but + * temporarily be unable to return its value. + * Some feature values may be available only in specific + * contexts, such as before, during, or after a validation. + * + *

      Implementors are free (and encouraged) to invent their own features, + * using names built on their own URIs.

      + * + * @param name The feature name, which is a non-null fully-qualified URI. + * + * @return The current value of the feature (true or false). + * + * @throws SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link Validator} recognizes the feature name but + * cannot determine its value at this time. + * @throws NullPointerException + * When the name parameter is null. + * + * @see #setFeature(String, boolean) + */ + public boolean getFeature(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + + throw new SAXNotRecognizedException(name); + } + + /** + * Set the value of a feature flag. + * + *

      + * Feature can be used to control the way a {@link Validator} + * parses schemas, although {@link Validator}s are not required + * to recognize any specific feature names.

      + * + *

      The feature name is any fully-qualified URI. It is + * possible for a {@link Validator} to expose a feature value but + * to be unable to change the current value. + * Some feature values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a validation.

      + * + * @param name The feature name, which is a non-null fully-qualified URI. + * @param value The requested value of the feature (true or false). + * + * @throws SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link Validator} recognizes the feature name but + * cannot set the requested value. + * @throws NullPointerException + * When the name parameter is null. + * + * @see #getFeature(String) + */ + public void setFeature(String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + + throw new SAXNotRecognizedException(name); + } + + /** + * Set the value of a property. + * + *

      The property name is any fully-qualified URI. It is + * possible for a {@link Validator} to recognize a property name but + * to be unable to change the current value. + * Some property values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a validation.

      + * + *

      {@link Validator}s are not required to recognize setting + * any specific property names.

      + * + * @param name The property name, which is a non-null fully-qualified URI. + * @param object The requested value for the property. + * + * @throws SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link Validator} recognizes the property name but + * cannot set the requested value. + * @throws NullPointerException + * When the name parameter is null. + */ + public void setProperty(String name, Object object) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + + throw new SAXNotRecognizedException(name); + } + + /** + * Look up the value of a property. + * + *

      The property name is any fully-qualified URI. It is + * possible for a {@link Validator} to recognize a property name but + * temporarily be unable to return its value. + * Some property values may be available only in specific + * contexts, such as before, during, or after a validation.

      + * + *

      {@link Validator}s are not required to recognize any specific + * property names.

      + * + *

      Implementors are free (and encouraged) to invent their own properties, + * using names built on their own URIs.

      + * + * @param name The property name, which is a non-null fully-qualified URI. + * + * @return The current value of the property. + * + * @throws SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * XMLReader recognizes the property name but + * cannot determine its value at this time. + * @throws NullPointerException + * When the name parameter is null. + * + * @see #setProperty(String, Object) + */ + public Object getProperty(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException("the name parameter is null"); + } + + throw new SAXNotRecognizedException(name); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/validation/ValidatorHandler.java b/sources/net.sf.j2s.java.core/src/javax/xml/validation/ValidatorHandler.java new file mode 100644 index 000000000..2aa2cc147 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/validation/ValidatorHandler.java @@ -0,0 +1,485 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.validation; + +import org.w3c.dom.ls.LSResourceResolver; +import org.xml.sax.ContentHandler; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXNotRecognizedException; +import org.xml.sax.SAXNotSupportedException; + +/** + * Streaming validator that works on SAX stream. + * + *

      + * A {@link ValidatorHandler} object is not thread-safe and not reentrant. + * In other words, it is the application's responsibility to make + * sure that one {@link ValidatorHandler} object is not used from + * more than one thread at any given time. + * + *

      + * {@link ValidatorHandler} checks if the SAX events follow + * the set of constraints described in the associated {@link Schema}, + * and additionally it may modify the SAX events (for example + * by adding default values, etc.) + * + *

      + * {@link ValidatorHandler} extends from {@link ContentHandler}, + * but it refines the underlying {@link ContentHandler} in + * the following way: + *

        + *
      1. startElement/endElement events must receive non-null String + * for uri, localName, and qname, + * even though SAX allows some of them to be null. + * Similarly, the user-specified {@link ContentHandler} will receive non-null + * Strings for all three parameters. + * + *
      2. Applications must ensure that {@link ValidatorHandler}'s + * {@link ContentHandler#startPrefixMapping(String,String)} and + * {@link ContentHandler#endPrefixMapping(String)} are invoked + * properly. Similarly, the user-specified {@link ContentHandler} + * will receive startPrefixMapping/endPrefixMapping events. + * If the {@link ValidatorHandler} introduces additional namespace + * bindings, the user-specified {@link ContentHandler} will receive + * additional startPrefixMapping/endPrefixMapping events. + * + *
      3. {@link org.xml.sax.Attributes} for the + * {@link ContentHandler#startElement(String,String,String,Attributes)} method + * may or may not include xmlns* attributes. + *
      + * + *

      + * A {@link ValidatorHandler} is automatically reset every time + * the startDocument method is invoked. + * + *

      Recognized Properties and Features

      + *

      + * This spec defines the following feature that must be recognized + * by all {@link ValidatorHandler} implementations. + * + *

      http://xml.org/sax/features/namespace-prefixes

      + *

      + * This feature controls how a {@link ValidatorHandler} introduces + * namespace bindings that were not present in the original SAX event + * stream. + * When this feature is set to true, it must make + * sure that the user's {@link ContentHandler} will see + * the corresponding xmlns* attribute in + * the {@link org.xml.sax.Attributes} object of the + * {@link ContentHandler#startElement(String,String,String,Attributes)} + * callback. Otherwise, xmlns* attributes must not be + * added to {@link org.xml.sax.Attributes} that's passed to the + * user-specified {@link ContentHandler}. + *

      + * (Note that regardless of this switch, namespace bindings are + * always notified to applications through + * {@link ContentHandler#startPrefixMapping(String,String)} and + * {@link ContentHandler#endPrefixMapping(String)} methods of the + * {@link ContentHandler} specified by the user.) + * + *

      + * Note that this feature does NOT affect the way + * a {@link ValidatorHandler} receives SAX events. It merely + * changes the way it augments SAX events. + * + *

      This feature is set to false by default.

      + * + * @author Kohsuke Kawaguchi + * @since 1.5 + */ +public abstract class ValidatorHandler implements ContentHandler { + + /** + *

      Constructor for derived classes.

      + * + *

      The constructor does nothing.

      + * + *

      Derived classes must create {@link ValidatorHandler} objects that have + * null {@link ErrorHandler} and + * null {@link LSResourceResolver}.

      + */ + protected ValidatorHandler() { + } + + /** + * Sets the {@link ContentHandler} which receives + * the augmented validation result. + * + *

      + * When a {@link ContentHandler} is specified, a + * {@link ValidatorHandler} will work as a filter + * and basically copy the incoming events to the + * specified {@link ContentHandler}. + * + *

      + * In doing so, a {@link ValidatorHandler} may modify + * the events, for example by adding defaulted attributes. + * + *

      + * A {@link ValidatorHandler} may buffer events to certain + * extent, but to allow {@link ValidatorHandler} to be used + * by a parser, the following requirement has to be met. + * + *

        + *
      1. When + * {@link ContentHandler#startElement(String, String, String, Attributes)}, + * {@link ContentHandler#endElement(String, String, String)}, + * {@link ContentHandler#startDocument()}, or + * {@link ContentHandler#endDocument()} + * are invoked on a {@link ValidatorHandler}, + * the same method on the user-specified {@link ContentHandler} + * must be invoked for the same event before the callback + * returns. + *
      2. {@link ValidatorHandler} may not introduce new elements that + * were not present in the input. + * + *
      3. {@link ValidatorHandler} may not remove attributes that were + * present in the input. + *
      + * + *

      + * When a callback method on the specified {@link ContentHandler} + * throws an exception, the same exception object must be thrown + * from the {@link ValidatorHandler}. The {@link ErrorHandler} + * should not be notified of such an exception. + * + *

      + * This method can be called even during a middle of a validation. + * + * @param receiver + * A {@link ContentHandler} or a null value. + */ + public abstract void setContentHandler(ContentHandler receiver); + + /** + * Gets the {@link ContentHandler} which receives the + * augmented validation result. + * + * @return + * This method returns the object that was last set through + * the {@link #getContentHandler()} method, or null + * if that method has never been called since this {@link ValidatorHandler} + * has created. + * + * @see #setContentHandler(ContentHandler) + */ + public abstract ContentHandler getContentHandler(); + + /** + * Sets the {@link ErrorHandler} to receive errors encountered + * during the validation. + * + *

      + * Error handler can be used to customize the error handling process + * during a validation. When an {@link ErrorHandler} is set, + * errors found during the validation will be first sent + * to the {@link ErrorHandler}. + * + *

      + * The error handler can abort further validation immediately + * by throwing {@link org.xml.sax.SAXException} from the handler. Or for example + * it can print an error to the screen and try to continue the + * validation by returning normally from the {@link ErrorHandler} + * + *

      + * If any {@link Throwable} is thrown from an {@link ErrorHandler}, + * the same {@link Throwable} object will be thrown toward the + * root of the call stack. + * + *

      + * {@link ValidatorHandler} is not allowed to + * throw {@link org.xml.sax.SAXException} without first reporting it to + * {@link ErrorHandler}. + * + *

      + * When the {@link ErrorHandler} is null, the implementation will + * behave as if the following {@link ErrorHandler} is set: + *

      +     * class DraconianErrorHandler implements {@link ErrorHandler} {
      +     *     public void fatalError( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
      +     *         throw e;
      +     *     }
      +     *     public void error( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
      +     *         throw e;
      +     *     }
      +     *     public void warning( {@link org.xml.sax.SAXParseException} e ) throws {@link org.xml.sax.SAXException} {
      +     *         // noop
      +     *     }
      +     * }
      +     * 
      + * + *

      + * When a new {@link ValidatorHandler} object is created, initially + * this field is set to null. + * + * @param errorHandler + * A new error handler to be set. This parameter can be null. + */ + public abstract void setErrorHandler(ErrorHandler errorHandler); + + /** + * Gets the current {@link ErrorHandler} set to this {@link ValidatorHandler}. + * + * @return + * This method returns the object that was last set through + * the {@link #setErrorHandler(ErrorHandler)} method, or null + * if that method has never been called since this {@link ValidatorHandler} + * has created. + * + * @see #setErrorHandler(ErrorHandler) + */ + public abstract ErrorHandler getErrorHandler(); + + /** + * Sets the {@link LSResourceResolver} to customize + * resource resolution while in a validation episode. + * + *

      + * {@link ValidatorHandler} uses a {@link LSResourceResolver} + * when it needs to locate external resources while a validation, + * although exactly what constitutes "locating external resources" is + * up to each schema language. + * + *

      + * When the {@link LSResourceResolver} is null, the implementation will + * behave as if the following {@link LSResourceResolver} is set: + *

      +     * class DumbLSResourceResolver implements {@link LSResourceResolver} {
      +     *     public {@link org.w3c.dom.ls.LSInput} resolveResource(
      +     *         String publicId, String systemId, String baseURI) {
      +     *
      +     *         return null; // always return null
      +     *     }
      +     * }
      +     * 
      + * + *

      + * If a {@link LSResourceResolver} throws a {@link RuntimeException} + * (or instances of its derived classes), + * then the {@link ValidatorHandler} will abort the parsing and + * the caller of the validate method will receive + * the same {@link RuntimeException}. + * + *

      + * When a new {@link ValidatorHandler} object is created, initially + * this field is set to null. + * + * @param resourceResolver + * A new resource resolver to be set. This parameter can be null. + */ + public abstract void setResourceResolver(LSResourceResolver resourceResolver); + + /** + * Gets the current {@link LSResourceResolver} set to this {@link ValidatorHandler}. + * + * @return + * This method returns the object that was last set through + * the {@link #setResourceResolver(LSResourceResolver)} method, or null + * if that method has never been called since this {@link ValidatorHandler} + * has created. + * + * @see #setErrorHandler(ErrorHandler) + */ + public abstract LSResourceResolver getResourceResolver(); + + /** + * Obtains the {@link TypeInfoProvider} implementation of this + * {@link ValidatorHandler}. + * + *

      + * The obtained {@link TypeInfoProvider} can be queried during a parse + * to access the type information determined by the validator. + * + *

      + * Some schema languages do not define the notion of type, + * for those languages, this method may not be supported. + * However, to be compliant with this specification, implementations + * for W3C XML Schema 1.0 must support this operation. + * + * @return + * null if the validator / schema language does not support + * the notion of {@link org.w3c.dom.TypeInfo}. + * Otherwise a non-null valid {@link TypeInfoProvider}. + */ + public abstract TypeInfoProvider getTypeInfoProvider(); + + + /** + * Look up the value of a feature flag. + * + *

      The feature name is any fully-qualified URI. It is + * possible for a {@link ValidatorHandler} to recognize a feature name but + * temporarily be unable to return its value. + * Some feature values may be available only in specific + * contexts, such as before, during, or after a validation. + * + *

      Implementors are free (and encouraged) to invent their own features, + * using names built on their own URIs.

      + * + * @param name The feature name, which is a non-null fully-qualified URI. + * + * @return The current value of the feature (true or false). + * + * @throws SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link ValidatorHandler} recognizes the feature name but + * cannot determine its value at this time. + * @throws NullPointerException When name is null. + * + * @see #setFeature(String, boolean) + */ + public boolean getFeature(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException(); + } + + throw new SAXNotRecognizedException(name); + } + + /** + *

      Set a feature for this ValidatorHandler.

      + * + *

      Feature can be used to control the way a + * {@link ValidatorHandler} parses schemas. The feature name is + * any fully-qualified URI. It is possible for a + * {@link SchemaFactory} to + * expose a feature value but to be unable to change the current + * value. Some feature values may be immutable or mutable only in + * specific contexts, such as before, during, or after a + * validation.

      + * + *

      All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. + * When the feature is:

      + *
        + *
      • + * true: the implementation will limit XML processing to conform to implementation limits. + * Examples include enity expansion limits and XML Schema constructs that would consume large amounts of resources. + * If XML processing is limited for security reasons, it will be reported via a call to the registered + * {@link ErrorHandler#fatalError(SAXParseException exception)}. + * See {@link #setErrorHandler(ErrorHandler errorHandler)}. + *
      • + *
      • + * false: the implementation will processing XML according to the XML specifications without + * regard to possible implementation limits. + *
      • + *
      + * + * @param name The feature name, which is a non-null fully-qualified URI. + * @param value The requested value of the feature (true or false). + * + * @throws SAXNotRecognizedException If the feature + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link ValidatorHandler} recognizes the feature name but + * cannot set the requested value. + * @throws NullPointerException When name is null. + * + * @see #getFeature(String) + */ + public void setFeature(String name, boolean value) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException(); + } + + throw new SAXNotRecognizedException(name); + } + + /** + * Set the value of a property. + * + *

      The property name is any fully-qualified URI. It is + * possible for a {@link ValidatorHandler} to recognize a property name but + * to be unable to change the current value. + * Some property values may be immutable or mutable only + * in specific contexts, such as before, during, or after + * a validation.

      + * + *

      {@link ValidatorHandler}s are not required to recognize setting + * any specific property names.

      + * + * @param name The property name, which is a non-null fully-qualified URI. + * @param object The requested value for the property. + * + * @throws SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * {@link ValidatorHandler} recognizes the property name but + * cannot set the requested value. + * @throws NullPointerException When name is null. + */ + public void setProperty(String name, Object object) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException(); + } + + throw new SAXNotRecognizedException(name); + } + + /** + * Look up the value of a property. + * + *

      The property name is any fully-qualified URI. It is + * possible for a {@link ValidatorHandler} to recognize a property name but + * temporarily be unable to return its value. + * Some property values may be available only in specific + * contexts, such as before, during, or after a validation.

      + * + *

      {@link ValidatorHandler}s are not required to recognize any specific + * property names.

      + * + *

      Implementors are free (and encouraged) to invent their own properties, + * using names built on their own URIs.

      + * + * @param name The property name, which is a non-null fully-qualified URI. + * + * @return The current value of the property. + * + * @throws SAXNotRecognizedException If the property + * value can't be assigned or retrieved. + * @throws SAXNotSupportedException When the + * XMLReader recognizes the property name but + * cannot determine its value at this time. + * @throws NullPointerException When name is null. + * + * @see #setProperty(String, Object) + */ + public Object getProperty(String name) + throws SAXNotRecognizedException, SAXNotSupportedException { + + if (name == null) { + throw new NullPointerException(); + } + + throw new SAXNotRecognizedException(name); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/SecuritySupport.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/SecuritySupport.java new file mode 100644 index 000000000..5859c952c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/SecuritySupport.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2005, 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 javax.xml.xpath; + +import java.net.URL; +import java.security.*; +import java.net.*; +import java.io.*; +import java.util.*; + +/** + * This class is duplicated for each JAXP subpackage so keep it in sync. + * It is package private and therefore is not exposed as part of the JAXP + * API. + * + * Security related methods that only work on J2SE 1.2 and newer. + */ +class SecuritySupport { + + + ClassLoader getContextClassLoader() { + return (ClassLoader) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + ClassLoader cl = null; + try { + cl = Thread.currentThread().getContextClassLoader(); + } catch (SecurityException ex) { } + return cl; + } + }); + } + + String getSystemProperty(final String propName) { + return (String) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return System.getProperty(propName); + } + }); + } + + FileInputStream getFileInputStream(final File file) + throws FileNotFoundException + { + try { + return (FileInputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws FileNotFoundException { + return new FileInputStream(file); + } + }); + } catch (PrivilegedActionException e) { + throw (FileNotFoundException)e.getException(); + } + } + + InputStream getURLInputStream(final URL url) + throws IOException + { + try { + return (InputStream) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws IOException { + return url.openStream(); + } + }); + } catch (PrivilegedActionException e) { + throw (IOException)e.getException(); + } + } + + URL getResourceAsURL(final ClassLoader cl, + final String name) + { + return (URL) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + URL url; + if (cl == null) { + url = Object.class.getResource(name); + } else { + url = cl.getResource(name); + } + return url; + } + }); + } + + Enumeration getResources(final ClassLoader cl, + final String name) throws IOException + { + try{ + return (Enumeration) + AccessController.doPrivileged(new PrivilegedExceptionAction() { + public Object run() throws IOException{ + Enumeration enumeration; + if (cl == null) { + enumeration = ClassLoader.getSystemResources(name); + } else { + enumeration = cl.getResources(name); + } + return enumeration; + } + }); + }catch(PrivilegedActionException e){ + throw (IOException)e.getException(); + } + } + + InputStream getResourceAsStream(final ClassLoader cl, + final String name) + { + return (InputStream) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + InputStream ris; + if (cl == null) { + ris = Object.class.getResourceAsStream(name); + } else { + ris = cl.getResourceAsStream(name); + } + return ris; + } + }); + } + + boolean doesFileExist(final File f) { + return ((Boolean) + AccessController.doPrivileged(new PrivilegedAction() { + public Object run() { + return new Boolean(f.exists()); + } + })).booleanValue(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPath.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPath.java new file mode 100644 index 000000000..90ba4feac --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPath.java @@ -0,0 +1,319 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +import org.xml.sax.InputSource; +import javax.xml.namespace.QName; +import javax.xml.namespace.NamespaceContext; + +/** + *

      XPath provides access to the XPath evaluation environment and expressions.

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      Evaluation of XPath Expressions.
      context + * If a request is made to evaluate the expression in the absence + * of a context item, an empty document node will be used for the context. + * For the purposes of evaluating XPath expressions, a DocumentFragment + * is treated like a Document node. + *
      variables + * If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver} + * set with {@link #setXPathVariableResolver(XPathVariableResolver resolver)}. + * An {@link XPathExpressionException} is raised if the variable resolver is undefined or + * the resolver returns null for the variable. + * The value of a variable must be immutable through the course of any single evaluation.

      + *
      functions + * If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver} + * set with {@link #setXPathFunctionResolver(XPathFunctionResolver resolver)}. + * An {@link XPathExpressionException} is raised if the function resolver is undefined or + * the function resolver returns null for the function.

      + *
      QNames + * QNames in the expression are resolved against the XPath namespace context + * set with {@link #setNamespaceContext(NamespaceContext nsContext)}. + *
      result + * This result of evaluating an expression is converted to an instance of the desired return type. + * Valid return types are defined in {@link XPathConstants}. + * Conversion to the return type follows XPath conversion rules.

      + *
      + * + *

      An XPath object is not thread-safe and not reentrant. + * In other words, it is the application's responsibility to make + * sure that one {@link XPath} object is not used from + * more than one thread at any given time, and while the evaluate + * method is invoked, applications may not recursively call + * the evaluate method. + *

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @see XML Path Language (XPath) Version 1.0 + * @since 1.5 + */ +public interface XPath { + + /** + *

      Reset this XPath to its original configuration.

      + * + *

      XPath is reset to the same state as when it was created with + * {@link XPathFactory#newXPath()}. + * reset() is designed to allow the reuse of existing XPaths + * thus saving resources associated with the creation of new XPaths.

      + * + *

      The reset XPath is not guaranteed to have the same {@link XPathFunctionResolver}, {@link XPathVariableResolver} + * or {@link NamespaceContext} Objects, e.g. {@link Object#equals(Object obj)}. + * It is guaranteed to have a functionally equal XPathFunctionResolver, XPathVariableResolver + * and NamespaceContext.

      + */ + public void reset(); + + /** + *

      Establish a variable resolver.

      + * + *

      A NullPointerException is thrown if resolver is null.

      + * + * @param resolver Variable resolver. + * + * @throws NullPointerException If resolver is null. + */ + public void setXPathVariableResolver(XPathVariableResolver resolver); + + /** + *

      Return the current variable resolver.

      + * + *

      null is returned in no variable resolver is in effect.

      + * + * @return Current variable resolver. + */ + public XPathVariableResolver getXPathVariableResolver(); + + /** + *

      Establish a function resolver.

      + * + *

      A NullPointerException is thrown if resolver is null.

      + * + * @param resolver XPath function resolver. + * + * @throws NullPointerException If resolver is null. + */ + public void setXPathFunctionResolver(XPathFunctionResolver resolver); + + /** + *

      Return the current function resolver.

      + * + *

      null is returned in no function resolver is in effect.

      + * + * @return Current function resolver. + */ + public XPathFunctionResolver getXPathFunctionResolver(); + + /** + *

      Establish a namespace context.

      + * + *

      A NullPointerException is thrown if nsContext is null.

      + * + * @param nsContext Namespace context to use. + * + * @throws NullPointerException If nsContext is null. + */ + public void setNamespaceContext(NamespaceContext nsContext); + + /** + *

      Return the current namespace context.

      + * + *

      null is returned in no namespace context is in effect.

      + * + * @return Current Namespace context. + */ + public NamespaceContext getNamespaceContext(); + + /** + *

      Compile an XPath expression for later evaluation.

      + * + *

      If expression contains any {@link XPathFunction}s, + * they must be available via the {@link XPathFunctionResolver}. + * An {@link XPathExpressionException} will be thrown if the + * XPathFunction + * cannot be resovled with the XPathFunctionResolver.

      + * + *

      If expression contains any variables, the + * {@link XPathVariableResolver} in effect + * at compile time will be used to resolve them.

      + * + *

      If expression is null, a NullPointerException is thrown.

      + * + * @param expression The XPath expression. + * + * @return Compiled XPath expression. + + * @throws XPathExpressionException If expression cannot be compiled. + * @throws NullPointerException If expression is null. + */ + public XPathExpression compile(String expression) + throws XPathExpressionException; + + /** + *

      Evaluate an XPath expression in the specified context and return the result as the specified type.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If returnType is not one of the types defined in {@link XPathConstants} ( + * {@link XPathConstants#NUMBER NUMBER}, + * {@link XPathConstants#STRING STRING}, + * {@link XPathConstants#BOOLEAN BOOLEAN}, + * {@link XPathConstants#NODE NODE} or + * {@link XPathConstants#NODESET NODESET}) + * then an IllegalArgumentException is thrown.

      + * + *

      If a null value is provided for + * item, an empty document will be used for the + * context. + * If expression or returnType is null, then a + * NullPointerException is thrown.

      + * + * @param expression The XPath expression. + * @param item The starting context (a node, for example). + * @param returnType The desired return type. + * + * @return Result of evaluating an XPath expression as an Object of returnType. + * + * @throws XPathExpressionException If expression cannot be evaluated. + * @throws IllegalArgumentException If returnType is not one of the types defined in {@link XPathConstants}. + * @throws NullPointerException If expression or returnType is null. + */ + public Object evaluate(String expression, Object item, QName returnType) + throws XPathExpressionException; + + /** + *

      Evaluate an XPath expression in the specified context and return the result as a String.

      + * + *

      This method calls {@link #evaluate(String expression, Object item, QName returnType)} with a returnType of + * {@link XPathConstants#STRING}.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If a null value is provided for + * item, an empty document will be used for the + * context. + * If expression is null, then a NullPointerException is thrown.

      + * + * @param expression The XPath expression. + * @param item The starting context (a node, for example). + * + * @return The String that is the result of evaluating the expression and + * converting the result to a String. + * + * @throws XPathExpressionException If expression cannot be evaluated. + * @throws NullPointerException If expression is null. + */ + public String evaluate(String expression, Object item) + throws XPathExpressionException; + + /** + *

      Evaluate an XPath expression in the context of the specified InputSource + * and return the result as the specified type.

      + * + *

      This method builds a data model for the {@link InputSource} and calls + * {@link #evaluate(String expression, Object item, QName returnType)} on the resulting document object.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If returnType is not one of the types defined in {@link XPathConstants}, + * then an IllegalArgumentException is thrown.

      + * + *

      If expression, source or returnType is null, + * then a NullPointerException is thrown.

      + * + * @param expression The XPath expression. + * @param source The input source of the document to evaluate over. + * @param returnType The desired return type. + * + * @return The Object that encapsulates the result of evaluating the expression. + * + * @throws XPathExpressionException If expression cannot be evaluated. + * @throws IllegalArgumentException If returnType is not one of the types defined in {@link XPathConstants}. + * @throws NullPointerException If expression, source or returnType + * is null. + */ + public Object evaluate( + String expression, + InputSource source, + QName returnType) + throws XPathExpressionException; + + /** + *

      Evaluate an XPath expression in the context of the specified InputSource + * and return the result as a String.

      + * + *

      This method calls {@link #evaluate(String expression, InputSource source, QName returnType)} with a + * returnType of {@link XPathConstants#STRING}.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If expression or source is null, + * then a NullPointerException is thrown.

      + * + * @param expression The XPath expression. + * @param source The InputSource of the document to evaluate over. + * + * @return The String that is the result of evaluating the expression and + * converting the result to a String. + * + * @throws XPathExpressionException If expression cannot be evaluated. + * @throws NullPointerException If expression or source is null. + */ + public String evaluate(String expression, InputSource source) + throws XPathExpressionException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathConstants.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathConstants.java new file mode 100644 index 000000000..205e04171 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathConstants.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +import javax.xml.namespace.QName; + +/** + *

      XPath constants.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @see XML Path Language (XPath) Version 1.0 + * @since 1.5 + */ +public class XPathConstants { + + /** + *

      Private constructor to prevent instantiation.

      + */ + private XPathConstants() { } + + /** + *

      The XPath 1.0 number data type.

      + * + *

      Maps to Java {@link Double}.

      + */ + public static final QName NUMBER = new QName("http://www.w3.org/1999/XSL/Transform", "NUMBER"); + + /** + *

      The XPath 1.0 string data type.

      + * + *

      Maps to Java {@link String}.

      + */ + public static final QName STRING = new QName("http://www.w3.org/1999/XSL/Transform", "STRING"); + + /** + *

      The XPath 1.0 boolean data type.

      + * + *

      Maps to Java {@link Boolean}.

      + */ + public static final QName BOOLEAN = new QName("http://www.w3.org/1999/XSL/Transform", "BOOLEAN"); + + /** + *

      The XPath 1.0 NodeSet data type.

      + * + *

      Maps to Java {@link org.w3c.dom.NodeList}.

      + */ + public static final QName NODESET = new QName("http://www.w3.org/1999/XSL/Transform", "NODESET"); + + /** + *

      The XPath 1.0 NodeSet data type. + * + *

      Maps to Java {@link org.w3c.dom.Node}.

      + */ + public static final QName NODE = new QName("http://www.w3.org/1999/XSL/Transform", "NODE"); + + /** + *

      The URI for the DOM object model, "http://java.sun.com/jaxp/xpath/dom".

      + */ + public static final String DOM_OBJECT_MODEL = "http://java.sun.com/jaxp/xpath/dom"; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathException.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathException.java new file mode 100644 index 000000000..aca84e578 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathException.java @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +import java.io.PrintWriter; + +/** + * XPathException represents a generic XPath exception.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @since 1.5 + */ +public class XPathException extends Exception { + + private final Throwable cause; + + /** + *

      Stream Unique Identifier.

      + */ + private static final long serialVersionUID = -1837080260374986980L; + + /** + *

      Constructs a new XPathException + * with the specified detail message.

      + * + *

      The cause is not initialized.

      + * + *

      If message is null, + * then a NullPointerException is thrown.

      + * + * @param message The detail message. + * + * @throws NullPointerException When message is + * null. + */ + public XPathException(String message) { + super(message); + if ( message == null ) { + throw new NullPointerException ( "message can't be null"); + } + this.cause = null; + } + + /** + *

      Constructs a new XPathException + * with the specified cause.

      + * + *

      If cause is null, + * then a NullPointerException is thrown.

      + * + * @param cause The cause. + * + * @throws NullPointerException if cause is null. + */ + public XPathException(Throwable cause) { + super(); + this.cause = cause; + if ( cause == null ) { + throw new NullPointerException ( "cause can't be null"); + } + } + + /** + *

      Get the cause of this XPathException.

      + * + * @return Cause of this XPathException. + */ + public Throwable getCause() { + return cause; + } + + /** + *

      Print stack trace to specified PrintStream.

      + * + * @param s Print stack trace to this PrintStream. + */ + public void printStackTrace(java.io.PrintStream s) { + if (getCause() != null) { + getCause().printStackTrace(s); + s.println("--------------- linked to ------------------"); + } + + super.printStackTrace(s); + } + + /** + *

      Print stack trace to System.err.

      + */ + public void printStackTrace() { + printStackTrace(System.err); + } + + /** + *

      Print stack trace to specified PrintWriter.

      + * + * @param s Print stack trace to this PrintWriter. + */ + public void printStackTrace(PrintWriter s) { + + if (getCause() != null) { + getCause().printStackTrace(s); + s.println("--------------- linked to ------------------"); + } + + super.printStackTrace(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathExpression.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathExpression.java new file mode 100644 index 000000000..0f980f6ed --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathExpression.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +import org.xml.sax.InputSource; +import javax.xml.namespace.QName; + +/** + *

      XPathExpression provides access to compiled XPath expressions.

      + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
      Evaluation of XPath Expressions.
      context + * If a request is made to evaluate the expression in the absence + * of a context item, an empty document node will be used for the context. + * For the purposes of evaluating XPath expressions, a DocumentFragment + * is treated like a Document node. + *
      variables + * If the expression contains a variable reference, its value will be found through the {@link XPathVariableResolver}. + * An {@link XPathExpressionException} is raised if the variable resolver is undefined or + * the resolver returns null for the variable. + * The value of a variable must be immutable through the course of any single evaluation.

      + *
      functions + * If the expression contains a function reference, the function will be found through the {@link XPathFunctionResolver}. + * An {@link XPathExpressionException} is raised if the function resolver is undefined or + * the function resolver returns null for the function.

      + *
      QNames + * QNames in the expression are resolved against the XPath namespace context. + *
      result + * This result of evaluating an expression is converted to an instance of the desired return type. + * Valid return types are defined in {@link XPathConstants}. + * Conversion to the return type follows XPath conversion rules.

      + *
      + * + *

      An XPath expression is not thread-safe and not reentrant. + * In other words, it is the application's responsibility to make + * sure that one {@link XPathExpression} object is not used from + * more than one thread at any given time, and while the evaluate + * method is invoked, applications may not recursively call + * the evaluate method. + *

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @see XML Path Language (XPath) Version 1.0, Expressions + * @since 1.5 + */ +public interface XPathExpression { + + /** + *

      Evaluate the compiled XPath expression in the specified context and return the result as the specified type.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If returnType is not one of the types defined in {@link XPathConstants}, + * then an IllegalArgumentException is thrown.

      + * + *

      If a null value is provided for + * item, an empty document will be used for the + * context. + * If returnType is null, then a NullPointerException is thrown.

      + * + * @param item The starting context (a node, for example). + * @param returnType The desired return type. + * + * @return The Object that is the result of evaluating the expression and converting the result to + * returnType. + * + * @throws XPathExpressionException If the expression cannot be evaluated. + * @throws IllegalArgumentException If returnType is not one of the types defined in {@link XPathConstants}. + * @throws NullPointerException If returnType is null. + */ + public Object evaluate(Object item, QName returnType) + throws XPathExpressionException; + + /** + *

      Evaluate the compiled XPath expression in the specified context and return the result as a String.

      + * + *

      This method calls {@link #evaluate(Object item, QName returnType)} with a returnType of + * {@link XPathConstants#STRING}.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If a null value is provided for + * item, an empty document will be used for the + * context. + * + * @param item The starting context (a node, for example). + * + * @return The String that is the result of evaluating the expression and converting the result to a + * String. + * + * @throws XPathExpressionException If the expression cannot be evaluated. + */ + public String evaluate(Object item) + throws XPathExpressionException; + + /** + *

      Evaluate the compiled XPath expression in the context of the specified InputSource and return the result as the + * specified type.

      + * + *

      This method builds a data model for the {@link InputSource} and calls + * {@link #evaluate(Object item, QName returnType)} on the resulting document object.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If returnType is not one of the types defined in {@link XPathConstants}, + * then an IllegalArgumentException is thrown.

      + * + *

      If source or returnType is null, + * then a NullPointerException is thrown.

      + * + * @param source The InputSource of the document to evaluate over. + * @param returnType The desired return type. + * + * @return The Object that is the result of evaluating the expression and converting the result to + * returnType. + * + * @throws XPathExpressionException If the expression cannot be evaluated. + * @throws IllegalArgumentException If returnType is not one of the types defined in {@link XPathConstants}. + * @throws NullPointerException If source or returnType is null. + */ + public Object evaluate(InputSource source, QName returnType) + throws XPathExpressionException; + + /** + *

      Evaluate the compiled XPath expression in the context of the specified InputSource and return the result as a + * String.

      + * + *

      This method calls {@link #evaluate(InputSource source, QName returnType)} with a returnType of + * {@link XPathConstants#STRING}.

      + * + *

      See Evaluation of XPath Expressions for context item evaluation, + * variable, function and QName resolution and return type conversion.

      + * + *

      If source is null, then a NullPointerException is thrown.

      + * + * @param source The InputSource of the document to evaluate over. + * + * @return The String that is the result of evaluating the expression and converting the result to a + * String. + * + * @throws XPathExpressionException If the expression cannot be evaluated. + * @throws NullPointerException If source is null. + */ + public String evaluate(InputSource source) + throws XPathExpressionException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathExpressionException.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathExpressionException.java new file mode 100644 index 000000000..02190781f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathExpressionException.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +/** + * XPathExpressionException represents an error in an XPath expression.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @since 1.5 + */ +public class XPathExpressionException extends XPathException { + + /** + *

      Stream Unique Identifier.

      + */ + private static final long serialVersionUID = -1837080260374986980L; + + /** + *

      Constructs a new XPathExpressionException + * with the specified detail message.

      + * + *

      The cause is not initialized.

      + * + *

      If message is null, + * then a NullPointerException is thrown.

      + * + * @param message The detail message. + * + * @throws NullPointerException When message is + * null. + */ + public XPathExpressionException(String message) { + super(message); + } + + /** + *

      Constructs a new XPathExpressionException + * with the specified cause.

      + * + *

      If cause is null, + * then a NullPointerException is thrown.

      + * + * @param cause The cause. + * + * @throws NullPointerException if cause is null. + */ + public XPathExpressionException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactory.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactory.java new file mode 100644 index 000000000..1fd93a7a1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactory.java @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2003, 2006, 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 javax.xml.xpath; + +/** + *

      An XPathFactory instance can be used to create + * {@link javax.xml.xpath.XPath} objects.

      + * + *

      See {@link #newInstance(String uri)} for lookup mechanism.

      + * + *

      The {@link XPathFactory} class is not thread-safe. In other words, + * it is the application's responsibility to ensure that at most + * one thread is using a {@link XPathFactory} object at any + * given moment. Implementations are encouraged to mark methods + * as synchronized to protect themselves from broken clients. + * + *

      {@link XPathFactory} is not re-entrant. While one of the + * newInstance methods is being invoked, applications + * may not attempt to recursively invoke a newInstance method, + * even from the same thread. + * + * @author Norman Walsh + * @author Jeff Suttor + * + * @since 1.5 + */ +public abstract class XPathFactory { + + + /** + *

      The default property name according to the JAXP spec.

      + */ + public static final String DEFAULT_PROPERTY_NAME = "javax.xml.xpath.XPathFactory"; + + /** + *

      Default Object Model URI.

      + */ + public static final String DEFAULT_OBJECT_MODEL_URI = "http://java.sun.com/jaxp/xpath/dom"; + + /** + *

      Take care of restrictions imposed by java security model

      + */ + private static SecuritySupport ss = new SecuritySupport() ; + + /** + *

      Protected constructor as {@link #newInstance()} or {@link #newInstance(String uri)} + * or {@link #newInstance(String uri, String factoryClassName, ClassLoader classLoader)} + * should be used to create a new instance of an XPathFactory.

      + */ + protected XPathFactory() { + } + + /** + *

      Get a new XPathFactory instance using the default object model, + * {@link #DEFAULT_OBJECT_MODEL_URI}, + * the W3C DOM.

      + * + *

      This method is functionally equivalent to:

      + *
      +     *   newInstance(DEFAULT_OBJECT_MODEL_URI)
      +     * 
      + * + *

      Since the implementation for the W3C DOM is always available, this method will never fail.

      + * + * @return Instance of an XPathFactory. + * + * @throws RuntimeException When there is a failure in creating an + * XPathFactory for the default object model. + */ + public static final XPathFactory newInstance() { + + try { + return newInstance(DEFAULT_OBJECT_MODEL_URI); + } catch (XPathFactoryConfigurationException xpathFactoryConfigurationException) { + throw new RuntimeException( + "XPathFactory#newInstance() failed to create an XPathFactory for the default object model: " + + DEFAULT_OBJECT_MODEL_URI + + " with the XPathFactoryConfigurationException: " + + xpathFactoryConfigurationException.toString() + ); + } + } + + /** + *

      Get a new XPathFactory instance using the specified object model.

      + * + *

      To find a XPathFactory object, + * this method looks the following places in the following order where "the class loader" refers to the context class loader:

      + *
        + *
      1. + * If the system property {@link #DEFAULT_PROPERTY_NAME} + ":uri" is present, + * where uri is the parameter to this method, then its value is read as a class name. + * The method will try to create a new instance of this class by using the class loader, + * and returns it if it is successfully created. + *
      2. + *
      3. + * ${java.home}/lib/jaxp.properties is read and the value associated with the key being the system property above is looked for. + * If present, the value is processed just like above. + *
      4. + *
      5. + * The class loader is asked for service provider provider-configuration files matching javax.xml.xpath.XPathFactory + * in the resource directory META-INF/services. + * See the JAR File Specification for file format and parsing rules. + * Each potential service provider is required to implement the method: + *
        +    *       {@link #isObjectModelSupported(String objectModel)}
        +    *     
        + * The first service provider found in class loader order that supports the specified object model is returned. + *
      6. + *
      7. + * Platform default XPathFactory is located in a platform specific way. + * There must be a platform default XPathFactory for the W3C DOM, i.e. {@link #DEFAULT_OBJECT_MODEL_URI}. + *
      8. + *
      + *

      If everything fails, an XPathFactoryConfigurationException will be thrown.

      + * + *

      Tip for Trouble-shooting:

      + *

      See {@link java.util.Properties#load(java.io.InputStream)} for exactly how a property file is parsed. + * In particular, colons ':' need to be escaped in a property file, so make sure the URIs are properly escaped in it. + * For example:

      + *
      +    *   http\://java.sun.com/jaxp/xpath/dom=org.acme.DomXPathFactory
      +    * 
      + * + * @param uri Identifies the underlying object model. + * The specification only defines the URI {@link #DEFAULT_OBJECT_MODEL_URI}, + * http://java.sun.com/jaxp/xpath/dom for the W3C DOM, + * the org.w3c.dom package, and implementations are free to introduce other URIs for other object models. + * + * @return Instance of an XPathFactory. + * + * @throws XPathFactoryConfigurationException If the specified object model is unavailable. + * @throws NullPointerException If uri is null. + * @throws IllegalArgumentException If uri is null + * or uri.length() == 0. + */ + public static final XPathFactory newInstance(final String uri) + throws XPathFactoryConfigurationException { + + if (uri == null) { + throw new NullPointerException( + "XPathFactory#newInstance(String uri) cannot be called with uri == null" + ); + } + + if (uri.length() == 0) { + throw new IllegalArgumentException( + "XPathFactory#newInstance(String uri) cannot be called with uri == \"\"" + ); + } + + ClassLoader classLoader = ss.getContextClassLoader(); + + if (classLoader == null) { + //use the current class loader + classLoader = XPathFactory.class.getClassLoader(); + } + + XPathFactory xpathFactory = new XPathFactoryFinder(classLoader).newFactory(uri); + + if (xpathFactory == null) { + throw new XPathFactoryConfigurationException( + "No XPathFactory implementation found for the object model: " + + uri + ); + } + + return xpathFactory; + } + + /** + *

      Obtain a new instance of a XPathFactory from a factory class name. XPathFactory + * is returned if specified factory class supports the specified object model. + * This function is useful when there are multiple providers in the classpath. + * It gives more control to the application as it can specify which provider + * should be loaded.

      + * + * + *

      Tip for Trouble-shooting

      + *

      Setting the jaxp.debug system property will cause + * this method to print a lot of debug messages + * to System.err about what it is doing and where it is looking at.

      + * + *

      If you have problems try:

      + *
      +     * java -Djaxp.debug=1 YourProgram ....
      +     * 
      + * + * @param uri Identifies the underlying object model. The specification only defines the URI + * {@link #DEFAULT_OBJECT_MODEL_URI},http://java.sun.com/jaxp/xpath/dom + * for the W3C DOM, the org.w3c.dom package, and implementations are free to introduce + * other URIs for other object models. + * + * @param factoryClassName fully qualified factory class name that provides implementation of javax.xml.xpath.XPathFactory. + * + * @param classLoader ClassLoader used to load the factory class. If null + * current Thread's context classLoader is used to load the factory class. + * + * + * @return New instance of a XPathFactory + * + * @throws XPathFactoryConfigurationException + * if factoryClassName is null, or + * the factory class cannot be loaded, instantiated + * or the factory class does not support the object model specified + * in the uri parameter. + * + * @throws NullPointerException If uri is null. + * @throws IllegalArgumentException If uri is null + * or uri.length() == 0. + * + * @see #newInstance() + * @see #newInstance(String uri) + * + * @since 1.6 + */ + public static XPathFactory newInstance(String uri, String factoryClassName, ClassLoader classLoader) + throws XPathFactoryConfigurationException{ + ClassLoader cl = classLoader; + + if (uri == null) { + throw new NullPointerException( + "XPathFactory#newInstance(String uri) cannot be called with uri == null" + ); + } + + if (uri.length() == 0) { + throw new IllegalArgumentException( + "XPathFactory#newInstance(String uri) cannot be called with uri == \"\"" + ); + } + + if (cl == null) { + cl = ss.getContextClassLoader(); + } + + XPathFactory f = new XPathFactoryFinder(cl).createInstance(factoryClassName); + + if (f == null) { + throw new XPathFactoryConfigurationException( + "No XPathFactory implementation found for the object model: " + + uri + ); + } + //if this factory supports the given schemalanguage return this factory else thrown exception + if(f.isObjectModelSupported(uri)){ + return f; + }else{ + throw new XPathFactoryConfigurationException("Factory " + factoryClassName + " doesn't support given " + uri + " object model"); + } + + } + + /** + *

      Is specified object model supported by this XPathFactory?

      + * + * @param objectModel Specifies the object model which the returned XPathFactory will understand. + * + * @return true if XPathFactory supports objectModel, else false. + * + * @throws NullPointerException If objectModel is null. + * @throws IllegalArgumentException If objectModel.length() == 0. + */ + public abstract boolean isObjectModelSupported(String objectModel); + + /** + *

      Set a feature for this XPathFactory and + * XPaths created by this factory.

      + * + *

      + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * An {@link XPathFactoryConfigurationException} is thrown if this + * XPathFactory or the XPaths + * it creates cannot support the feature. + * It is possible for an XPathFactory to expose a feature value + * but be unable to change its state. + *

      + * + *

      + * All implementations are required to support the {@link javax.xml.XMLConstants#FEATURE_SECURE_PROCESSING} feature. + * When the feature is true, any reference to an external function is an error. + * Under these conditions, the implementation must not call the {@link XPathFunctionResolver} + * and must throw an {@link XPathFunctionException}. + *

      + * + * @param name Feature name. + * @param value Is feature state true or false. + * + * @throws XPathFactoryConfigurationException if this XPathFactory or the XPaths + * it creates cannot support this feature. + * @throws NullPointerException if name is null. + */ + public abstract void setFeature(String name, boolean value) + throws XPathFactoryConfigurationException; + + /** + *

      Get the state of the named feature.

      + * + *

      + * Feature names are fully qualified {@link java.net.URI}s. + * Implementations may define their own features. + * An {@link XPathFactoryConfigurationException} is thrown if this + * XPathFactory or the XPaths + * it creates cannot support the feature. + * It is possible for an XPathFactory to expose a feature value + * but be unable to change its state. + *

      + * + * @param name Feature name. + * + * @return State of the named feature. + * + * @throws XPathFactoryConfigurationException if this + * XPathFactory or the XPaths + * it creates cannot support this feature. + * @throws NullPointerException if name is null. + */ + public abstract boolean getFeature(String name) + throws XPathFactoryConfigurationException; + + /** + *

      Establish a default variable resolver.

      + * + *

      Any XPath objects constructed from this factory will use + * the specified resolver by default.

      + * + *

      A NullPointerException is thrown if resolver + * is null.

      + * + * @param resolver Variable resolver. + * + * @throws NullPointerException If resolver is + * null. + */ + public abstract void setXPathVariableResolver(XPathVariableResolver resolver); + + /** + *

      Establish a default function resolver.

      + * + *

      Any XPath objects constructed from this factory will + * use the specified resolver by default.

      + * + *

      A NullPointerException is thrown if + * resolver is null.

      + * + * @param resolver XPath function resolver. + * + * @throws NullPointerException If resolver is + * null. + */ + public abstract void setXPathFunctionResolver(XPathFunctionResolver resolver); + + /** + *

      Return a new XPath using the underlying object + * model determined when the XPathFactory was instantiated.

      + * + * @return New instance of an XPath. + */ + public abstract XPath newXPath(); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactoryConfigurationException.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactoryConfigurationException.java new file mode 100644 index 000000000..cd3ebdf49 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactoryConfigurationException.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +/** + * XPathFactoryConfigurationException represents a configuration error in a XPathFactory environment.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @since 1.5 + */ +public class XPathFactoryConfigurationException extends XPathException { + + /** + *

      Stream Unique Identifier.

      + */ + private static final long serialVersionUID = -1837080260374986980L; + + /** + *

      Constructs a new XPathFactoryConfigurationException with the specified detail message.

      + * + *

      The cause is not initialized.

      + * + *

      If message is null, + * then a NullPointerException is thrown.

      + * + * @param message The detail message. + * + * @throws NullPointerException When message is + * null. + */ + public XPathFactoryConfigurationException(String message) { + super(message); + } + + /** + *

      Constructs a new XPathFactoryConfigurationException + * with the specified cause.

      + * + *

      If cause is null, + * then a NullPointerException is thrown.

      + * + * @param cause The cause. + * + * @throws NullPointerException if cause is null. + */ + public XPathFactoryConfigurationException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactoryFinder.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactoryFinder.java new file mode 100644 index 000000000..2833a5880 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFactoryFinder.java @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2004, 2005, 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 javax.xml.xpath; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.lang.reflect.Method; +import java.lang.reflect.InvocationTargetException; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Properties; + +/** + * Implementation of {@link XPathFactory#newInstance(String)}. + * + * @author Kohsuke Kawaguchi + * @version $Revision: 1.7 $, $Date: 2010-11-01 04:36:14 $ + * @since 1.5 + */ +class XPathFactoryFinder { + + private static SecuritySupport ss = new SecuritySupport() ; + /** debug support code. */ + private static boolean debug = false; + static { + // Use try/catch block to support applets + try { + debug = ss.getSystemProperty("jaxp.debug") != null; + } catch (Exception _) { + debug = false; + } + } + + /** + *

      Cache properties for performance.

      + */ + private static Properties cacheProps = new Properties(); + + /** + *

      First time requires initialization overhead.

      + */ + private volatile static boolean firstTime = true; + + /** + *

      Conditional debug printing.

      + * + * @param msg to print + */ + private static void debugPrintln(String msg) { + if (debug) { + System.err.println("JAXP: " + msg); + } + } + + /** + *

      ClassLoader to use to find XPathFactory.

      + */ + private final ClassLoader classLoader; + + /** + *

      Constructor that specifies ClassLoader to use + * to find XPathFactory.

      + * + * @param loader + * to be used to load resource, {@link XPathFactory}, and + * {@link SchemaFactoryLoader} implementations during + * the resolution process. + * If this parameter is null, the default system class loader + * will be used. + */ + public XPathFactoryFinder(ClassLoader loader) { + this.classLoader = loader; + if( debug ) { + debugDisplayClassLoader(); + } + } + + private void debugDisplayClassLoader() { + try { + if( classLoader == ss.getContextClassLoader() ) { + debugPrintln("using thread context class loader ("+classLoader+") for search"); + return; + } + } catch( Throwable _ ) { + ; // getContextClassLoader() undefined in JDK1.1 + } + + if( classLoader==ClassLoader.getSystemClassLoader() ) { + debugPrintln("using system class loader ("+classLoader+") for search"); + return; + } + + debugPrintln("using class loader ("+classLoader+") for search"); + } + + /** + *

      Creates a new {@link XPathFactory} object for the specified + * schema language.

      + * + * @param uri + * Identifies the underlying object model. + * + * @return null if the callee fails to create one. + * + * @throws NullPointerException + * If the parameter is null. + */ + public XPathFactory newFactory(String uri) { + if(uri==null) throw new NullPointerException(); + XPathFactory f = _newFactory(uri); + if (f != null) { + debugPrintln("factory '" + f.getClass().getName() + "' was found for " + uri); + } else { + debugPrintln("unable to find a factory for " + uri); + } + return f; + } + + /** + *

      Lookup a {@link XPathFactory} for the given object model.

      + * + * @param uri identifies the object model. + * + * @return {@link XPathFactory} for the given object model. + */ + private XPathFactory _newFactory(String uri) { + XPathFactory xpathFactory; + + String propertyName = SERVICE_CLASS.getName() + ":" + uri; + + // system property look up + try { + debugPrintln("Looking up system property '"+propertyName+"'" ); + String r = ss.getSystemProperty(propertyName); + if(r!=null) { + debugPrintln("The value is '"+r+"'"); + xpathFactory = createInstance(r, true); + if(xpathFactory != null) return xpathFactory; + } else + debugPrintln("The property is undefined."); + } catch( Throwable t ) { + if( debug ) { + debugPrintln("failed to look up system property '"+propertyName+"'" ); + t.printStackTrace(); + } + } + + String javah = ss.getSystemProperty( "java.home" ); + String configFile = javah + File.separator + + "lib" + File.separator + "jaxp.properties"; + + String factoryClassName = null ; + + // try to read from $java.home/lib/jaxp.properties + try { + if(firstTime){ + synchronized(cacheProps){ + if(firstTime){ + File f=new File( configFile ); + firstTime = false; + if(ss.doesFileExist(f)){ + debugPrintln("Read properties file " + f); + cacheProps.load(ss.getFileInputStream(f)); + } + } + } + } + factoryClassName = cacheProps.getProperty(propertyName); + debugPrintln("found " + factoryClassName + " in $java.home/jaxp.properties"); + + if (factoryClassName != null) { + xpathFactory = createInstance(factoryClassName, true); + if(xpathFactory != null){ + return xpathFactory; + } + } + } catch (Exception ex) { + if (debug) { + ex.printStackTrace(); + } + } + + // try META-INF/services files + Iterator sitr = createServiceFileIterator(); + while(sitr.hasNext()) { + URL resource = (URL)sitr.next(); + debugPrintln("looking into " + resource); + try { + xpathFactory = loadFromService(uri, resource.toExternalForm(), + ss.getURLInputStream(resource)); + if (xpathFactory != null) { + return xpathFactory; + } + } catch(IOException e) { + if( debug ) { + debugPrintln("failed to read "+resource); + e.printStackTrace(); + } + } + } + + // platform default + if(uri.equals(XPathFactory.DEFAULT_OBJECT_MODEL_URI)) { + debugPrintln("attempting to use the platform default W3C DOM XPath lib"); + return createInstance("com.sun.org.apache.xpath.internal.jaxp.XPathFactoryImpl", true); + } + + debugPrintln("all things were tried, but none was found. bailing out."); + return null; + } + + /**

      Create class using appropriate ClassLoader.

      + * + * @param className Name of class to create. + * @return Created class or null. + */ + private Class createClass(String className) { + Class clazz; + + // use approprite ClassLoader + try { + if (classLoader != null) { + clazz = classLoader.loadClass(className); + } else { + clazz = Class.forName(className); + } + } catch (Throwable t) { + if(debug) t.printStackTrace(); + return null; + } + + return clazz; + } + + /** + *

      Creates an instance of the specified and returns it.

      + * + * @param className + * fully qualified class name to be instanciated. + * + * @return null + * if it fails. Error messages will be printed by this method. + */ + XPathFactory createInstance( String className ) { + return createInstance( className, false ); + } + XPathFactory createInstance( String className, boolean useServicesMechanism ) { + XPathFactory xPathFactory = null; + + debugPrintln("createInstance(" + className + ")"); + + // get Class from className + Class clazz = createClass(className); + if (clazz == null) { + debugPrintln("failed to getClass(" + className + ")"); + return null; + } + debugPrintln("loaded " + className + " from " + which(clazz)); + + // instantiate Class as a XPathFactory + try { + if (!useServicesMechanism) { + xPathFactory = (XPathFactory) newInstanceNoServiceLoader(clazz); + } + if (xPathFactory == null) { + xPathFactory = (XPathFactory) clazz.newInstance(); + } + } catch (ClassCastException classCastException) { + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + classCastException.printStackTrace(); + } + return null; + } catch (IllegalAccessException illegalAccessException) { + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + illegalAccessException.printStackTrace(); + } + return null; + } catch (InstantiationException instantiationException) { + debugPrintln("could not instantiate " + clazz.getName()); + if (debug) { + instantiationException.printStackTrace(); + } + return null; + } + + return xPathFactory; + } + /** + * Try to construct using newXPathFactoryNoServiceLoader + * method if available. + */ + private static Object newInstanceNoServiceLoader( + Class providerClass + ) { + // Retain maximum compatibility if no security manager. + if (System.getSecurityManager() == null) { + return null; + } + try { + Method creationMethod = + providerClass.getDeclaredMethod( + "newXPathFactoryNoServiceLoader" + ); + return creationMethod.invoke(null, null); + } catch (NoSuchMethodException exc) { + return null; + } catch (Exception exc) { + return null; + } + } + + /** + *

      Look up a value in a property file.

      + * + *

      Set debug to true to trace property evaluation.

      + * + * @param objectModel URI of object model to support. + * @param inputName Name of InputStream. + * @param in InputStream of properties. + * + * @return XPathFactory as determined by keyName value or null if there was an error. + * + * @throws IOException If IO error reading from in. + */ + private XPathFactory loadFromService( + String objectModel, + String inputName, + InputStream in) + throws IOException { + + XPathFactory xPathFactory = null; + final Class[] stringClassArray = {"".getClass()}; + final Object[] objectModelObjectArray = {objectModel}; + final String isObjectModelSupportedMethod = "isObjectModelSupported"; + + debugPrintln("Reading " + inputName); + + // read from InputStream until a match is found + BufferedReader configFile = new BufferedReader(new InputStreamReader(in)); + String line = null; + while ((line = configFile.readLine()) != null) { + // '#' is comment char + int comment = line.indexOf("#"); + switch (comment) { + case -1: break; // no comment + case 0: line = ""; break; // entire line is a comment + default: line = line.substring(0, comment); break; // trim comment + } + + // trim whitespace + line = line.trim(); + + // any content left on line? + if (line.length() == 0) { + continue; + } + + // line content is now the name of the class + Class clazz = createClass(line); + if (clazz == null) { + continue; + } + + // create an instance of the Class + try { + xPathFactory = (XPathFactory) clazz.newInstance(); + } catch (ClassCastException classCastExcpetion) { + xPathFactory = null; + continue; + } catch (InstantiationException instantiationException) { + xPathFactory = null; + continue; + } catch (IllegalAccessException illegalAccessException) { + xPathFactory = null; + continue; + } + + // does this Class support desired object model? + try { + Method isObjectModelSupported = clazz.getMethod(isObjectModelSupportedMethod, stringClassArray); + Boolean supported = (Boolean) isObjectModelSupported.invoke(xPathFactory, objectModelObjectArray); + if (supported.booleanValue()) { + break; + } + + } catch (NoSuchMethodException noSuchMethodException) { + + } catch (IllegalAccessException illegalAccessException) { + + } catch (InvocationTargetException invocationTargetException) { + + } + xPathFactory = null; + } + + // clean up + configFile.close(); + + // return new instance of XPathFactory or null + return xPathFactory; + } + + /** Iterator that lazily computes one value and returns it. */ + private static abstract class SingleIterator implements Iterator { + private boolean seen = false; + + public final void remove() { throw new UnsupportedOperationException(); } + public final boolean hasNext() { return !seen; } + public final Object next() { + if(seen) throw new NoSuchElementException(); + seen = true; + return value(); + } + + protected abstract Object value(); + } + + /** + * Looks up a value in a property file + * while producing all sorts of debug messages. + * + * @return null + * if there was an error. + */ + private XPathFactory loadFromProperty( String keyName, String resourceName, InputStream in ) + throws IOException { + debugPrintln("Reading "+resourceName ); + + Properties props = new Properties(); + props.load(in); + in.close(); + String factoryClassName = props.getProperty(keyName); + if(factoryClassName != null){ + debugPrintln("found "+keyName+" = " + factoryClassName); + return createInstance(factoryClassName, true); + } else { + debugPrintln(keyName+" is not in the property file"); + return null; + } + } + + /** + * Returns an {@link Iterator} that enumerates all + * the META-INF/services files that we care. + */ + private Iterator createServiceFileIterator() { + if (classLoader == null) { + return new SingleIterator() { + protected Object value() { + ClassLoader classLoader = XPathFactoryFinder.class.getClassLoader(); + return ss.getResourceAsURL(classLoader, SERVICE_ID); + //return (ClassLoader.getSystemResource( SERVICE_ID )); + } + }; + } else { + try { + //final Enumeration e = classLoader.getResources(SERVICE_ID); + final Enumeration e = ss.getResources(classLoader, SERVICE_ID); + if(!e.hasMoreElements()) { + debugPrintln("no "+SERVICE_ID+" file was found"); + } + + // wrap it into an Iterator. + return new Iterator() { + public void remove() { + throw new UnsupportedOperationException(); + } + + public boolean hasNext() { + return e.hasMoreElements(); + } + + public Object next() { + return e.nextElement(); + } + }; + } catch (IOException e) { + debugPrintln("failed to enumerate resources "+SERVICE_ID); + if(debug) e.printStackTrace(); + return new ArrayList().iterator(); // empty iterator + } + } + } + + private static final Class SERVICE_CLASS = XPathFactory.class; + private static final String SERVICE_ID = "META-INF/services/" + SERVICE_CLASS.getName(); + + + + private static String which( Class clazz ) { + return which( clazz.getName(), clazz.getClassLoader() ); + } + + /** + *

      Search the specified classloader for the given classname.

      + * + * @param classname the fully qualified name of the class to search for + * @param loader the classloader to search + * + * @return the source location of the resource, or null if it wasn't found + */ + private static String which(String classname, ClassLoader loader) { + + String classnameAsResource = classname.replace('.', '/') + ".class"; + + if( loader==null ) loader = ClassLoader.getSystemClassLoader(); + + //URL it = loader.getResource(classnameAsResource); + URL it = ss.getResourceAsURL(loader, classnameAsResource); + if (it != null) { + return it.toString(); + } else { + return null; + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunction.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunction.java new file mode 100644 index 000000000..bc3b544ad --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunction.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +import java.util.List; + +/** + *

      XPathFunction provides access to XPath functions.

      + * + *

      Functions are identified by QName and arity in XPath.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @since 1.5 + */ +public interface XPathFunction { + /** + *

      Evaluate the function with the specified arguments.

      + * + *

      To the greatest extent possible, side-effects should be avoided in the + * definition of extension functions. The implementation evaluating an + * XPath expression is under no obligation to call extension functions in + * any particular order or any particular number of times.

      + * + * @param args The arguments, null is a valid value. + * + * @return The result of evaluating the XPath function as an Object. + * + * @throws XPathFunctionException If args cannot be evaluated with this XPath function. + */ + public Object evaluate(List args) + throws XPathFunctionException; +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunctionException.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunctionException.java new file mode 100644 index 000000000..398fe7c38 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunctionException.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +/** + * XPathFunctionException represents an error with an XPath function.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @since 1.5 + */ +public class XPathFunctionException extends XPathExpressionException { + + /** + *

      Stream Unique Identifier.

      + */ + private static final long serialVersionUID = -1837080260374986980L; + + /** + *

      Constructs a new XPathFunctionException with the specified detail message.

      + * + *

      The cause is not initialized.

      + * + *

      If message is null, + * then a NullPointerException is thrown.

      + * + * @param message The detail message. + * + * @throws NullPointerException When message is + * null. + */ + public XPathFunctionException(String message) { + super(message); + } + + /** + *

      Constructs a new XPathFunctionException with the specified cause.

      + * + *

      If cause is null, + * then a NullPointerException is thrown.

      + * + * @param cause The cause. + * + * @throws NullPointerException if cause is null. + */ + public XPathFunctionException(Throwable cause) { + super(cause); + } +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunctionResolver.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunctionResolver.java new file mode 100644 index 000000000..0c3786b27 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathFunctionResolver.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +import javax.xml.namespace.QName; + +/** + *

      XPathFunctionResolver provides access to the set of user defined XPathFunctions.

      + * + *

      XPath functions are resolved by name and arity. + * The resolver is not needed for XPath built-in functions and the resolver + * cannot be used to override those functions.

      + * + *

      In particular, the resolver is only called for functions in an another + * namespace (functions with an explicit prefix). This means that you cannot + * use the XPathFunctionResolver to implement specifications + * like XML-Signature Syntax + * and Processing which extend the function library of XPath 1.0 in the + * same namespace. This is a consequence of the design of the resolver.

      + * + *

      If you wish to implement additional built-in functions, you will have to + * extend the underlying implementation directly.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @see XML Path Language (XPath) Version 1.0, Core Function Library + * @since 1.5 + */ +public interface XPathFunctionResolver { + /** + *

      Find a function in the set of available functions.

      + * + *

      If functionName or arity is null, then a NullPointerException is thrown.

      + * + * @param functionName The function name. + * @param arity The number of arguments that the returned function must accept. + * + * @return The function or null if no function named functionName with arity arguments exists. + * + * @throws NullPointerException If functionName or arity is null. + */ + public XPathFunction resolveFunction(QName functionName, int arity); +} diff --git a/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathVariableResolver.java b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathVariableResolver.java new file mode 100644 index 000000000..0957c28e6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/javax/xml/xpath/XPathVariableResolver.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2003, 2005, 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 javax.xml.xpath; + +import javax.xml.namespace.QName; + +/** + *

      XPathVariableResolver provides access to the set of user defined XPath variables.

      + * + *

      The XPathVariableResolver and the XPath evaluator must adhere to a contract that + * cannot be directly enforced by the API. Although variables may be mutable, + * that is, an application may wish to evaluate the same XPath expression more + * than once with different variable values, in the course of evaluating any + * single XPath expression, a variable's value must + * not change.

      + * + * @author Norman Walsh + * @author Jeff Suttor + * @since 1.5 + */ +public interface XPathVariableResolver { + /** + *

      Find a variable in the set of available variables.

      + * + *

      If variableName is null, then a NullPointerException is thrown.

      + * + * @param variableName The QName of the variable name. + * + * @return The variables value, or null if no variable named variableName + * exists. The value returned must be of a type appropriate for the underlying object model. + * + * @throws NullPointerException If variableName is null. + */ + public Object resolveVariable(QName variableName); +} diff --git a/sources/net.sf.j2s.java.core/src/org/json/JSONObject.java b/sources/net.sf.j2s.java.core/src/org/json/JSONObject.java index d07854197..68c3a9a01 100644 --- a/sources/net.sf.j2s.java.core/src/org/json/JSONObject.java +++ b/sources/net.sf.j2s.java.core/src/org/json/JSONObject.java @@ -1375,8 +1375,10 @@ private void populateMap(Object bean) { Method[] methods = includeSuperClass ? klass.getMethods() : klass.getDeclaredMethods(); for (final Method method : methods) { final int modifiers = method.getModifiers(); - if (Modifier.isPublic(modifiers) && !Modifier.isStatic(modifiers) && method.getParameterTypes().length == 0 - && !method.isBridge() && method.getReturnType() != Void.TYPE + if (Modifier.isPublic(modifiers) && + !Modifier.isStatic(modifiers) && method.getParameterTypes().length == 0 + && !method.isBridge() + //&& method.getReturnType() != Void.TYPE && isValidMethodName(method.getName())) { final String key = getKeyNameFromMethod(method); if (key != null && !key.isEmpty()) { diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Attr.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Attr.java new file mode 100644 index 000000000..b19574156 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Attr.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The Attr interface represents an attribute in an + * Element object. Typically the allowable values for the + * attribute are defined in a document type definition. + *

      Attr objects inherit the Node interface, but + * since they are not actually child nodes of the element they describe, the + * DOM does not consider them part of the document tree. Thus, the + * Node attributes parentNode , + * previousSibling , and nextSibling have a + * null value for Attr objects. The DOM takes the + * view that attributes are properties of elements rather than having a + * separate identity from the elements they are associated with; this should + * make it more efficient to implement such features as default attributes + * associated with all elements of a given type. Furthermore, + * Attr nodes may not be immediate children of a + * DocumentFragment . However, they can be associated with + * Element nodes contained within a DocumentFragment + * . In short, users and implementors of the DOM need to be aware that + * Attr nodes have some things in common with other objects + * inheriting the Node interface, but they also are quite + * distinct. + *

      The attribute's effective value is determined as follows: if this + * attribute has been explicitly assigned any value, that value is the + * attribute's effective value; otherwise, if there is a declaration for + * this attribute, and that declaration includes a default value, then that + * default value is the attribute's effective value; otherwise, the + * attribute does not exist on this element in the structure model until it + * has been explicitly added. Note that the nodeValue + * attribute on the Attr instance can also be used to retrieve + * the string version of the attribute's value(s). + *

      In XML, where the value of an attribute can contain entity references, + * the child nodes of the Attr node provide a representation in + * which entity references are not expanded. These child nodes may be either + * Text or EntityReference nodes. Because the + * attribute type may be unknown, there are no tokenized attribute values. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Attr extends Node { + /** + * Returns the name of this attribute. + */ + public String getName(); + + /** + * If this attribute was explicitly given a value in the original + * document, this is true ; otherwise, it is + * false . Note that the implementation is in charge of this + * attribute, not the user. If the user changes the value of the + * attribute (even if it ends up having the same value as the default + * value) then the specified flag is automatically flipped + * to true . To re-specify the attribute as the default + * value from the DTD, the user must delete the attribute. The + * implementation will then make a new attribute available with + * specified set to false and the default value + * (if one exists). + *
      In summary: If the attribute has an assigned value in the document + * then specified is true , and the value is + * the assigned value. If the attribute has no assigned value in the + * document and has a default value in the DTD, then + * specified is false , and the value is the + * default value in the DTD. If the attribute has no assigned value in + * the document and has a value of #IMPLIED in the DTD, then the + * attribute does not appear in the structure model of the document. If + * the ownerElement attribute is null (i.e. + * because it was just created or was set to null by the + * various removal and cloning operations) specified is + * true . + */ + public boolean getSpecified(); + + /** + * On retrieval, the value of the attribute is returned as a string. + * Character and general entity references are replaced with their + * values. See also the method getAttribute on the + * Element interface. + *
      On setting, this creates a Text node with the unparsed + * contents of the string. I.e. any characters that an XML processor + * would recognize as markup are instead treated as literal text. See + * also the method setAttribute on the Element + * interface. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + */ + public String getValue(); + public void setValue(String value) + throws DOMException; + + /** + * The Element node this attribute is attached to or + * null if this attribute is not in use. + * @since DOM Level 2 + */ + public Element getOwnerElement(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/CDATASection.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/CDATASection.java new file mode 100644 index 000000000..2ead5b739 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/CDATASection.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * CDATA sections are used to escape blocks of text containing characters + * that would otherwise be regarded as markup. The only delimiter that is + * recognized in a CDATA section is the "]]>" string that ends the CDATA + * section. CDATA sections cannot be nested. Their primary purpose is for + * including material such as XML fragments, without needing to escape all + * the delimiters. + *

      The DOMString attribute of the Text node + * holds the text that is contained by the CDATA section. Note that this may + * contain characters that need to be escaped outside of CDATA sections and + * that, depending on the character encoding ("charset") chosen for + * serialization, it may be impossible to write out some characters as part + * of a CDATA section. + *

      The CDATASection interface inherits from the + * CharacterData interface through the Text + * interface. Adjacent CDATASections nodes are not merged by use + * of the normalize method of the Node interface. + * Because no markup is recognized within a CDATASection , + * character numeric references cannot be used as an escape mechanism when + * serializing. Therefore, action needs to be taken when serializing a + * CDATASection with a character encoding where some of the + * contained characters cannot be represented. Failure to do so would not + * produce well-formed XML. One potential solution in the serialization + * process is to end the CDATA section before the character, output the + * character using a character reference or entity reference, and open a new + * CDATA section for any further characters in the text node. Note, however, + * that some code conversion libraries at the time of writing do not return + * an error or exception when a character is missing from the encoding, + * making the task of ensuring that data is not corrupted on serialization + * more difficult. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface CDATASection extends Text { +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/CharacterData.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/CharacterData.java new file mode 100644 index 000000000..2711bf5d7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/CharacterData.java @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The CharacterData interface extends Node with a set of + * attributes and methods for accessing character data in the DOM. For + * clarity this set is defined here rather than on each object that uses + * these attributes and methods. No DOM objects correspond directly to + * CharacterData , though Text and others do + * inherit the interface from it. All offsets in this interface + * start from 0. + *

      As explained in the DOMString interface, text strings in + * the DOM are represented in UTF-16, i.e. as a sequence of 16-bit units. In + * the following, the term 16-bit units is used whenever necessary to + * indicate that indexing on CharacterData is done in 16-bit units. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface CharacterData extends Node { + /** + * The character data of the node that implements this interface. The DOM + * implementation may not put arbitrary limits on the amount of data that + * may be stored in a CharacterData node. However, + * implementation limits may mean that the entirety of a node's data may + * not fit into a single DOMString . In such cases, the user + * may call substringData to retrieve the data in + * appropriately sized pieces. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters + * than fit in a DOMString variable on the implementation + * platform. + */ + public String getData() + throws DOMException; + public void setData(String data) + throws DOMException; + + /** + * The number of 16-bit units that are available through + * data and the substringData method below. + * This may have the value zero, i.e., CharacterData nodes + * may be empty. + */ + public int getLength(); + + /** + * Extracts a range of data from the node. + * @param offset Start offset of substring to extract. + * @param count The number of 16-bit units to extract. + * @return The specified substring. If the sum of offset and + * count exceeds the length , then all 16-bit + * units to the end of the data are returned. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified offset is + * negative or greater than the number of 16-bit units in + * data , or if the specified count is + * negative. + *
      DOMSTRING_SIZE_ERR: Raised if the specified range of text does + * not fit into a DOMString . + */ + public String substringData(int offset, + int count) + throws DOMException; + + /** + * Append the string to the end of the character data of the node. Upon + * success, data provides access to the concatenation of + * data and the DOMString specified. + * @param arg The DOMString to append. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void appendData(String arg) + throws DOMException; + + /** + * Insert a string at the specified character offset. + * @param offset The character offset at which to insert. + * @param arg The DOMString to insert. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified offset is + * negative or greater than the number of 16-bit units in + * data . + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void insertData(int offset, + String arg) + throws DOMException; + + /** + * Remove a range of 16-bit units from the node. Upon success, + * data and length reflect the change. + * @param offset The offset from which to start removing. + * @param count The number of 16-bit units to delete. If the sum of + * offset and count exceeds + * length then all 16-bit units from offset + * to the end of the data are deleted. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified offset is + * negative or greater than the number of 16-bit units in + * data , or if the specified count is + * negative. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void deleteData(int offset, + int count) + throws DOMException; + + /** + * Replace the characters starting at the specified 16-bit unit offset + * with the specified string. + * @param offset The offset from which to start replacing. + * @param count The number of 16-bit units to replace. If the sum of + * offset and count exceeds + * length , then all 16-bit units to the end of the data + * are replaced; (i.e., the effect is the same as a remove + * method call with the same range, followed by an append + * method invocation). + * @param arg The DOMString with which the range must be + * replaced. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified offset is + * negative or greater than the number of 16-bit units in + * data , or if the specified count is + * negative. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void replaceData(int offset, + int count, + String arg) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Comment.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Comment.java new file mode 100644 index 000000000..fc1e81381 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Comment.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * This interface inherits from CharacterData and represents the + * content of a comment, i.e., all the characters between the starting ' + * <!-- ' and ending '--> '. Note that this + * is the definition of a comment in XML, and, in practice, HTML, although + * some HTML tools may implement the full SGML comment structure. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Comment extends CharacterData { +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/DOMException.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DOMException.java new file mode 100644 index 000000000..7dac52e0f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DOMException.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * DOM operations only raise exceptions in "exceptional" circumstances, + * i.e., when an operation is impossible to perform (either for logical + * reasons, because data is lost, or because the implementation has become + * unstable). In general, DOM methods return specific error values in ordinary + * processing situations, such as out-of-bound errors when using + * NodeList . + *

      Implementations may raise other exceptions under other circumstances. + * For example, implementations may raise an implementation-dependent + * exception if a null argument is passed. + *

      Some languages and object systems do not support the concept of + * exceptions. For such systems, error conditions may be indicated using + * native error reporting mechanisms. For some bindings, for example, methods + * may return error codes similar to those listed in the corresponding method + * descriptions. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public class DOMException extends RuntimeException { + public DOMException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // ExceptionCode + public static final short INDEX_SIZE_ERR = 1; + public static final short DOMSTRING_SIZE_ERR = 2; + public static final short HIERARCHY_REQUEST_ERR = 3; + public static final short WRONG_DOCUMENT_ERR = 4; + public static final short INVALID_CHARACTER_ERR = 5; + public static final short NO_DATA_ALLOWED_ERR = 6; + public static final short NO_MODIFICATION_ALLOWED_ERR = 7; + public static final short NOT_FOUND_ERR = 8; + public static final short NOT_SUPPORTED_ERR = 9; + public static final short INUSE_ATTRIBUTE_ERR = 10; + /** + * @since DOM Level 2 + */ + public static final short INVALID_STATE_ERR = 11; + /** + * @since DOM Level 2 + */ + public static final short SYNTAX_ERR = 12; + /** + * @since DOM Level 2 + */ + public static final short INVALID_MODIFICATION_ERR = 13; + /** + * @since DOM Level 2 + */ + public static final short NAMESPACE_ERR = 14; + /** + * @since DOM Level 2 + */ + public static final short INVALID_ACCESS_ERR = 15; + + public static final short TYPE_MISMATCH_ERR = 17; + public static final short VALIDATION_ERR = 16; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/DOMImplementation.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DOMImplementation.java new file mode 100644 index 000000000..24493b2e8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DOMImplementation.java @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The DOMImplementation interface provides a number of methods + * for performing operations that are independent of any particular instance + * of the document object model. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface DOMImplementation { + /** + * Test if the DOM implementation implements a specific feature. + * @param feature The name of the feature to test (case-insensitive). The + * values used by DOM features are defined throughout this + * specification and listed in the section. The name must be an XML + * name . To avoid possible conflicts, as a convention, names referring + * to features defined outside the DOM specification should be made + * unique by reversing the name of the Internet domain name of the + * person (or the organization that the person belongs to) who defines + * the feature, component by component, and using this as a prefix. For + * instance, the W3C SYMM Working Group defines the feature + * "org.w3c.dom.smil". + * @param version This is the version number of the feature to test. In + * Level 2, this is the string "2.0". If the version is not specified, + * supporting any version of the feature causes the method to return + * true . + * @return true if the feature is implemented in the + * specified version, false otherwise. + */ + public boolean hasFeature(String feature, + String version); + + /** + * Creates an empty DocumentType node. Entity declarations + * and notations are not made available. Entity reference expansions and + * default attribute additions do not occur. It is expected that a future + * version of the DOM will provide a way for populating a + * DocumentType . + *
      HTML-only DOM implementations do not need to implement this method. + * @param qualifiedName The qualified name of the document type to be + * created. + * @param publicId The external subset public identifier. + * @param systemId The external subset system identifier. + * @return A new DocumentType node with + * Node.ownerDocument set to null . + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name + * contains an illegal character. + *
      NAMESPACE_ERR: Raised if the qualifiedName is + * malformed. + * @since DOM Level 2 + */ + public DocumentType createDocumentType(String qualifiedName, + String publicId, + String systemId) + throws DOMException; + + /** + * Creates an XML Document object of the specified type with + * its document element. HTML-only DOM implementations do not need to + * implement this method. + * @param namespaceURI The namespace URI of the document element to + * create. + * @param qualifiedName The qualified name of the document element to be + * created. + * @param doctype The type of document to be created or null + * . When doctype is not null , its + * Node.ownerDocument attribute is set to the document + * being created. + * @return A new Document object. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name + * contains an illegal character. + *
      NAMESPACE_ERR: Raised if the qualifiedName is + * malformed, if the qualifiedName has a prefix and the + * namespaceURI is null or an empty string, + * or if the qualifiedName has a prefix that is "xml" and + * the namespaceURI is different from " + * http://www.w3.org/XML/1998/namespace " . + *
      WRONG_DOCUMENT_ERR: Raised if doctype has already + * been used with a different document or was created from a different + * implementation. + * @since DOM Level 2 + */ + public Document createDocument(String namespaceURI, + String qualifiedName, + DocumentType doctype) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Document.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Document.java new file mode 100644 index 000000000..798e64265 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Document.java @@ -0,0 +1,498 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The Document interface represents the entire HTML or XML + * document. Conceptually, it is the root of the document tree, and provides + * the primary access to the document's data. + *

      Since elements, text nodes, comments, processing instructions, etc. + * cannot exist outside the context of a Document , the + * Document interface also contains the factory methods needed + * to create these objects. The Node objects created have a + * ownerDocument attribute which associates them with the + * Document within whose context they were created. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Document extends Node { + /** + * The Document Type Declaration (see DocumentType ) + * associated with this document. For HTML documents as well as XML + * documents without a document type declaration this returns + * null . The DOM Level 2 does not support editing the + * Document Type Declaration, therefore docType cannot be + * altered in any way, including through the use of methods, such as + * insertNode or removeNode , which are + * inherited from the Node interface. + */ + public DocumentType getDoctype(); + + /** + * The DOMImplementation object that handles this document. + * A DOM application may use objects from multiple implementations. + */ + public DOMImplementation getImplementation(); + + /** + * This is a convenience attribute that allows direct access to the child + * node that is the root element of the document. For HTML documents, + * this is the element with the tagName "HTML". + */ + public Element getDocumentElement(); + + /** + * Creates an element of the type specified. Note that the instance + * returned implements the Element interface, so attributes + * can be specified directly on the returned object. + *
      In addition, if there are known attributes with default values, + * Attr nodes representing them are automatically created and + * attached to the element. + *
      To create an element with a qualified name and namespace URI, use + * the createElementNS method. + * @param tagName The name of the element type to instantiate. For XML, + * this is case-sensitive. For HTML, the tagName + * parameter may be provided in any case, but it must be mapped to the + * canonical uppercase form by the DOM implementation. + * @return A new Element object with the + * nodeName attribute set to tagName , and + * localName , prefix , and + * namespaceURI set to null . + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name contains an + * illegal character. + */ + public Element createElement(String tagName) + throws DOMException; + + /** + * Creates an empty DocumentFragment object. + * @return A new DocumentFragment . + */ + public DocumentFragment createDocumentFragment(); + + /** + * Creates a Text node given the specified string. + * @param data The data for the node. + * @return The new Text object. + */ + public Text createTextNode(String data); + + /** + * Creates a Comment node given the specified string. + * @param data The data for the node. + * @return The new Comment object. + */ + public Comment createComment(String data); + + /** + * Creates a CDATASection node whose value is the specified + * string. + * @param data The data for the CDATASection contents. + * @return The new CDATASection object. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if this document is an HTML document. + */ + public CDATASection createCDATASection(String data) + throws DOMException; + + /** + * Creates a ProcessingInstruction node given the specified + * name and data strings. + * @param target The target part of the processing instruction. + * @param data The data for the node. + * @return The new ProcessingInstruction object. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified target contains an + * illegal character. + *
      NOT_SUPPORTED_ERR: Raised if this document is an HTML document. + */ + public ProcessingInstruction createProcessingInstruction(String target, + String data) + throws DOMException; + + /** + * Creates an Attr of the given name. Note that the + * Attr instance can then be set on an Element + * using the setAttributeNode method. + *
      To create an attribute with a qualified name and namespace URI, use + * the createAttributeNS method. + * @param name The name of the attribute. + * @return A new Attr object with the nodeName + * attribute set to name , and localName , + * prefix , and namespaceURI set to + * null . + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name contains an + * illegal character. + */ + public Attr createAttribute(String name) + throws DOMException; + + /** + * Creates an EntityReference object. In addition, if the + * referenced entity is known, the child list of the + * EntityReference node is made the same as that of the + * corresponding Entity node. If any descendant of the + * Entity node has an unbound namespace prefix , the + * corresponding descendant of the created EntityReference + * node is also unbound; (its namespaceURI is + * null ). The DOM Level 2 does not support any mechanism to + * resolve namespace prefixes. + * @param name The name of the entity to reference. + * @return The new EntityReference object. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name contains an + * illegal character. + *
      NOT_SUPPORTED_ERR: Raised if this document is an HTML document. + */ + public EntityReference createEntityReference(String name) + throws DOMException; + + /** + * Returns a NodeList of all the Elements with + * a given tag name in the order in which they are encountered in a + * preorder traversal of the Document tree. + * @param tagname The name of the tag to match on. The special value "*" + * matches all tags. + * @return A new NodeList object containing all the matched + * Elements . + */ + public NodeList getElementsByTagName(String tagname); + + /** + * Imports a node from another document to this document. The returned + * node has no parent; (parentNode is null ). + * The source node is not altered or removed from the original document; + * this method creates a new copy of the source node. + *
      For all nodes, importing a node creates a node object owned by the + * importing document, with attribute values identical to the source + * node's nodeName and nodeType , plus the + * attributes related to namespaces (prefix , + * localName , and namespaceURI ). As in the + * cloneNode operation on a Node , the source + * node is not altered. + *
      Additional information is copied as appropriate to the + * nodeType , attempting to mirror the behavior expected if a + * fragment of XML or HTML source was copied from one document to + * another, recognizing that the two documents may have different DTDs in + * the XML case. The following list describes the specifics for each type + * of node. + *

      + *
      ATTRIBUTE_NODE
      + *
      The ownerElement attribute is + * set to null and the specified flag is set to + * true on the generated Attr . The descendants + * of the source Attr are recursively imported and the + * resulting nodes reassembled to form the corresponding subtree. Note + * that the deep parameter has no effect on + * Attr nodes; they always carry their children with them + * when imported.
      + *
      DOCUMENT_FRAGMENT_NODE
      + *
      If the deep option + * was set to true , the descendants of the source element + * will be recursively imported and the resulting nodes reassembled to + * form the corresponding subtree. Otherwise, this simply generates an + * empty DocumentFragment .
      + *
      DOCUMENT_NODE
      + *
      + * Document nodes cannot be imported.
      + *
      DOCUMENT_TYPE_NODE
      + *
      + * DocumentType nodes cannot be imported.
      + *
      ELEMENT_NODE
      + *
      + * Specified attribute nodes of the source element are imported, and the + * generated Attr nodes are attached to the generated + * Element . Default attributes are not copied, though if + * the document being imported into defines default attributes for this + * element name, those are assigned. If the importNode + * deep parameter was set to true , the + * descendants of the source element will be recursively imported and the + * resulting nodes reassembled to form the corresponding subtree.
      + *
      + * ENTITY_NODE
      + *
      Entity nodes can be imported, however in the + * current release of the DOM the DocumentType is readonly. + * Ability to add these imported nodes to a DocumentType + * will be considered for addition to a future release of the DOM. On + * import, the publicId , systemId , and + * notationName attributes are copied. If a deep + * import is requested, the descendants of the the source + * Entity is recursively imported and the resulting nodes + * reassembled to form the corresponding subtree.
      + *
      ENTITY_REFERENCE_NODE
      + *
      + * Only the EntityReference itself is copied, even if a + * deep import is requested, since the source and + * destination documents might have defined the entity differently. If + * the document being imported into provides a definition for this entity + * name, its value is assigned.
      + *
      NOTATION_NODE
      + *
      Notation nodes + * can be imported, however in the current release of the DOM the + * DocumentType is readonly. Ability to add these imported + * nodes to a DocumentType will be considered for addition + * to a future release of the DOM. On import, the publicId + * and systemId attributes are copied. Note that the + * deep parameter has no effect on Notation + * nodes since they never have any children.
      + *
      PROCESSING_INSTRUCTION_NODE
      + *
      + * The imported node copies its target and data + * values from those of the source node.
      + *
      TEXT_NODE, CDATA_SECTION_NODE, + * COMMENT_NODE
      + *
      These three types of nodes inheriting from + * CharacterData copy their data and + * length attributes from those of the source node.
      + *
      + * @param importedNode The node to import. + * @param deep If true , recursively import the subtree + * under the specified node; if false , import only the + * node itself, as explained above. This has no effect on + * Attr , EntityReference , and + * Notation nodes. + * @return The imported node that belongs to this Document . + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the type of node being imported is not + * supported. + * @since DOM Level 2 + */ + public Node importNode(Node importedNode, + boolean deep) + throws DOMException; + + /** + * Creates an element of the given qualified name and namespace URI. + * HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the element to create. + * @param qualifiedName The qualified name of the element type to + * instantiate. + * @return A new Element object with the following + * attributes: Attribute ValueNode.nodeName + * qualifiedNameNode.namespaceURI + * namespaceURINode.prefix prefix, extracted + * from qualifiedName , or null if there is no + * prefixNode.localName local name , extracted from + * qualifiedNameElement.tagName + * qualifiedName + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name + * contains an illegal character. + *
      NAMESPACE_ERR: Raised if the qualifiedName is + * malformed, if the qualifiedName has a prefix and the + * namespaceURI is null or an empty string, + * or if the qualifiedName has a prefix that is "xml" and + * the namespaceURI is different from " + * http://www.w3.org/XML/1998/namespace " . + * @since DOM Level 2 + */ + public Element createElementNS(String namespaceURI, + String qualifiedName) + throws DOMException; + + /** + * Creates an attribute of the given qualified name and namespace URI. + * HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the attribute to create. + * @param qualifiedName The qualified name of the attribute to + * instantiate. + * @return A new Attr object with the following attributes: + * Attribute ValueNode.nodeName qualifiedName + * Node.namespaceURInamespaceURI + * Node.prefix prefix, extracted from + * qualifiedName , or null if there is no + * prefixNode.localName local name , extracted from + * qualifiedNameAttr.name + * qualifiedName + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name + * contains an illegal character. + *
      NAMESPACE_ERR: Raised if the qualifiedName is + * malformed, if the qualifiedName has a prefix and the + * namespaceURI is null or an empty string, + * if the qualifiedName has a prefix that is "xml" and the + * namespaceURI is different from " + * http://www.w3.org/XML/1998/namespace ", or if the + * qualifiedName is "xmlns" and the + * namespaceURI is different from " + * http://www.w3.org/2000/xmlns/ ". + * @since DOM Level 2 + */ + public Attr createAttributeNS(String namespaceURI, + String qualifiedName) + throws DOMException; + + /** + * Returns a NodeList of all the Elements with + * a given local name and namespace URI in the order in which they are + * encountered in a preorder traversal of the Document tree. + * @param namespaceURI The namespace URI of the elements to match on. + * The special value "*" matches all namespaces. + * @param localName The local name of the elements to match on. The + * special value "*" matches all local names. + * @return A new NodeList object containing all the matched + * Elements . + * @since DOM Level 2 + */ + public NodeList getElementsByTagNameNS(String namespaceURI, + String localName); + + /** + * Returns the Element whose ID is given by + * elementId . If no such element exists, returns + * null . Behavior is not defined if more than one element + * has this ID . The DOM implementation must have + * information that says which attributes are of type ID. Attributes with + * the name "ID" are not of type ID unless so defined. Implementations + * that do not know whether attributes are of type ID or not are expected + * to return null . + * @param elementId The unique id value for an element. + * @return The matching element. + * @since DOM Level 2 + */ + public Element getElementById(String elementId); + + /** + * An attribute specifying the actual encoding of this document. This is + * null otherwise. + */ + public String getActualEncoding(); + public void setActualEncoding(String actualEncoding); + + /** + * An attribute specifying, as part of the XML declaration, the encoding + * of this document. This is null when unspecified. + */ + public String getEncoding(); + public void setEncoding(String encoding); + + /** + * An attribute specifying, as part of the XML declaration, whether this + * document is standalone. + */ + public boolean getStandalone(); + public void setStandalone(boolean standalone); + + /** + * An attribute specifying whether errors checking is enforced or not. + * When set to false, the implementation is free to not + * test every possible error case normally defined on DOM operations, + * and not raise any DOMException. In case of error, the + * behavior is undefined. This attribute is true by + * defaults. + */ + public boolean getStrictErrorChecking(); + public void setStrictErrorChecking(boolean strictErrorChecking); + + /** + * An attribute specifying, as part of the XML declaration, the version + * number of this document. This is null when unspecified. + */ + public String getVersion(); + public void setVersion(String version); + + /** + * Changes the ownerDocument of a node, its children, as well + * as the attached attribute nodes if there are any. If the node has a + * parent it is first removed from its parent child list. This + * effectively allows moving a subtree from one document to another. The + * following list describes the specifics for each type of node. + *
      + *
      + * ATTRIBUTE_NODE
      + *
      The ownerElement attribute is set to + * null and the specified flag is set to + * true on the adopted Attr. The descendants + * of the source Attr are recursively adopted.
      + *
      + * DOCUMENT_FRAGMENT_NODE
      + *
      The descendants of the source node are + * recursively adopted.
      + *
      DOCUMENT_NODE
      + *
      Document nodes cannot + * be adopted.
      + *
      DOCUMENT_TYPE_NODE
      + *
      DocumentType nodes cannot + * be adopted.
      + *
      ELEMENT_NODE
      + *
      Specified attribute nodes of the source + * element are adopted, and the generated Attr nodes. + * Default attributes are discarded, though if the document being + * adopted into defines default attributes for this element name, those + * are assigned. The descendants of the source element are recursively + * adopted.
      + *
      ENTITY_NODE
      + *
      Entity nodes can be adopted, however + * in the current release of the DOM the DocumentType is + * readonly. Ability to add these adopted nodes to a + * DocumentType will be considered for addition to a future + * release of the DOM. The descendants of the the source entity are + * recursively adopted.
      + *
      ENTITY_REFERENCE_NODE
      + *
      Only the + * EntityReference node itself is adopted, the descendants + * are discarded, since the source and destination documents might have + * defined the entity differently. If the document being imported into + * provides a definition for this entity name, its value is assigned.
      + *
      + * NOTATION_NODE
      + *
      Notation nodes can be adopted, however in + * the current release of the DOM the DocumentType is + * readonly. Ability to add these adopted nodes to a + * DocumentType will be considered for addition to a future + * release of the DOM.
      + *
      PROCESSING_INSTRUCTION_NODE, TEXT_NODE, + * CDATA_SECTION_NODE, COMMENT_NODE
      + *
      These nodes can all be adopted. No + * specifics.
      + * Should this method simply return null when it fails? How + * "exceptional" is failure for this method?Stick with raising + * exceptions only in exceptional circumstances, return null on failure + * (F2F 19 Jun 2000).Can an entity node really be adopted? + * @param sourceThe node to move into this document. + * @return The adopted node, or null if this operation + * fails, such as when the source node comes from a different + * implementation. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the source node is of type + * DOCUMENT, DOCUMENT_TYPE. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised when the source node is + * readonly. + */ + public Node adoptNode(Node source) + throws DOMException; + + /** + * Get a list of all the elements which have a specific attribute.Anyone + * still lobbying for this?No, killed! (F2F 1 Aug 2000)Should we have + * getElementsByAttributeValue and getElementsByAttributeValueNS?Yes, + * but irrelevant, see above. (F2F 1 Aug 2000)Should we have this on + * Element as well? We have getElementsByTagName there.Irrelevant, see + * above. (F2F 1 Aug 2000) + * @param namespaceURIThe namespace URI of the attribute to look for. + * @param localNameThe local name of the attribute to look for. + * @param valueThe value of the attribute to look for. + * @return Returns a list containing the elements that have an attribute + * that matches the given namespace URI, local name, and value. + */ + public NodeList getElementsByAttributeValue(String namespaceURI, + String localName, + String value); + + public String getDocumentURI(); + + + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Document3.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Document3.java new file mode 100644 index 000000000..1274f3c9d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Document3.java @@ -0,0 +1,148 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom; + +/** + * This interface extends the Document interface with additional + * attributes and methods. + *

      See also the Document Object Model (DOM) Level 3 Core Specification. + */ +public interface Document3 extends Document { +// /** +// * An attribute specifying the actual encoding of this document. This is +// * null otherwise. +// */ +// public String getActualEncoding(); +// public void setActualEncoding(String actualEncoding); +// +// /** +// * An attribute specifying, as part of the XML declaration, the encoding +// * of this document. This is null when unspecified. +// */ +// public String getEncoding(); +// public void setEncoding(String encoding); +// +// /** +// * An attribute specifying, as part of the XML declaration, whether this +// * document is standalone. +// */ +// public boolean getStandalone(); +// public void setStandalone(boolean standalone); +// +// /** +// * An attribute specifying whether errors checking is enforced or not. +// * When set to false, the implementation is free to not +// * test every possible error case normally defined on DOM operations, +// * and not raise any DOMException. In case of error, the +// * behavior is undefined. This attribute is true by +// * defaults. +// */ +// public boolean getStrictErrorChecking(); +// public void setStrictErrorChecking(boolean strictErrorChecking); +// +// /** +// * An attribute specifying, as part of the XML declaration, the version +// * number of this document. This is null when unspecified. +// */ +// public String getVersion(); +// public void setVersion(String version); +// +// /** +// * Changes the ownerDocument of a node, its children, as well +// * as the attached attribute nodes if there are any. If the node has a +// * parent it is first removed from its parent child list. This +// * effectively allows moving a subtree from one document to another. The +// * following list describes the specifics for each type of node. +// *

      +// *
      +// * ATTRIBUTE_NODE
      +// *
      The ownerElement attribute is set to +// * null and the specified flag is set to +// * true on the adopted Attr. The descendants +// * of the source Attr are recursively adopted.
      +// *
      +// * DOCUMENT_FRAGMENT_NODE
      +// *
      The descendants of the source node are +// * recursively adopted.
      +// *
      DOCUMENT_NODE
      +// *
      Document nodes cannot +// * be adopted.
      +// *
      DOCUMENT_TYPE_NODE
      +// *
      DocumentType nodes cannot +// * be adopted.
      +// *
      ELEMENT_NODE
      +// *
      Specified attribute nodes of the source +// * element are adopted, and the generated Attr nodes. +// * Default attributes are discarded, though if the document being +// * adopted into defines default attributes for this element name, those +// * are assigned. The descendants of the source element are recursively +// * adopted.
      +// *
      ENTITY_NODE
      +// *
      Entity nodes can be adopted, however +// * in the current release of the DOM the DocumentType is +// * readonly. Ability to add these adopted nodes to a +// * DocumentType will be considered for addition to a future +// * release of the DOM. The descendants of the the source entity are +// * recursively adopted.
      +// *
      ENTITY_REFERENCE_NODE
      +// *
      Only the +// * EntityReference node itself is adopted, the descendants +// * are discarded, since the source and destination documents might have +// * defined the entity differently. If the document being imported into +// * provides a definition for this entity name, its value is assigned.
      +// *
      +// * NOTATION_NODE
      +// *
      Notation nodes can be adopted, however in +// * the current release of the DOM the DocumentType is +// * readonly. Ability to add these adopted nodes to a +// * DocumentType will be considered for addition to a future +// * release of the DOM.
      +// *
      PROCESSING_INSTRUCTION_NODE, TEXT_NODE, +// * CDATA_SECTION_NODE, COMMENT_NODE
      +// *
      These nodes can all be adopted. No +// * specifics.
      +// * Should this method simply return null when it fails? How +// * "exceptional" is failure for this method?Stick with raising +// * exceptions only in exceptional circumstances, return null on failure +// * (F2F 19 Jun 2000).Can an entity node really be adopted? +// * @param sourceThe node to move into this document. +// * @return The adopted node, or null if this operation +// * fails, such as when the source node comes from a different +// * implementation. +// * @exception DOMException +// * NOT_SUPPORTED_ERR: Raised if the source node is of type +// * DOCUMENT, DOCUMENT_TYPE. +// *
      NO_MODIFICATION_ALLOWED_ERR: Raised when the source node is +// * readonly. +// */ +// public Node adoptNode(Node source) +// throws DOMException; +// +// /** +// * Get a list of all the elements which have a specific attribute.Anyone +// * still lobbying for this?No, killed! (F2F 1 Aug 2000)Should we have +// * getElementsByAttributeValue and getElementsByAttributeValueNS?Yes, +// * but irrelevant, see above. (F2F 1 Aug 2000)Should we have this on +// * Element as well? We have getElementsByTagName there.Irrelevant, see +// * above. (F2F 1 Aug 2000) +// * @param namespaceURIThe namespace URI of the attribute to look for. +// * @param localNameThe local name of the attribute to look for. +// * @param valueThe value of the attribute to look for. +// * @return Returns a list containing the elements that have an attribute +// * that matches the given namespace URI, local name, and value. +// */ +// public NodeList getElementsByAttributeValue(String namespaceURI, +// String localName, +// String value); + +} diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/DocumentFragment.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DocumentFragment.java new file mode 100644 index 000000000..4268f61b3 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DocumentFragment.java @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * DocumentFragment is a "lightweight" or "minimal" + * Document object. It is very common to want to be able to + * extract a portion of a document's tree or to create a new fragment of a + * document. Imagine implementing a user command like cut or rearranging a + * document by moving fragments around. It is desirable to have an object + * which can hold such fragments and it is quite natural to use a Node for + * this purpose. While it is true that a Document object could + * fulfill this role, a Document object can potentially be a + * heavyweight object, depending on the underlying implementation. What is + * really needed for this is a very lightweight object. + * DocumentFragment is such an object. + *

      Furthermore, various operations -- such as inserting nodes as children + * of another Node -- may take DocumentFragment + * objects as arguments; this results in all the child nodes of the + * DocumentFragment being moved to the child list of this node. + *

      The children of a DocumentFragment node are zero or more + * nodes representing the tops of any sub-trees defining the structure of the + * document. DocumentFragment nodes do not need to be + * well-formed XML documents (although they do need to follow the rules + * imposed upon well-formed XML parsed entities, which can have multiple top + * nodes). For example, a DocumentFragment might have only one + * child and that child node could be a Text node. Such a + * structure model represents neither an HTML document nor a well-formed XML + * document. + *

      When a DocumentFragment is inserted into a + * Document (or indeed any other Node that may take + * children) the children of the DocumentFragment and not the + * DocumentFragment itself are inserted into the + * Node . This makes the DocumentFragment very + * useful when the user wishes to create nodes that are siblings; the + * DocumentFragment acts as the parent of these nodes so that + * the user can use the standard methods from the Node + * interface, such as insertBefore and appendChild . + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface DocumentFragment extends Node { +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/DocumentType.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DocumentType.java new file mode 100644 index 000000000..93ecbdf72 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/DocumentType.java @@ -0,0 +1,48 @@ +package org.w3c.dom; + +/** + * Each Document has a doctype attribute whose value + * is either null or a DocumentType object. The + * DocumentType interface in the DOM Level 1 Core provides an + * interface to the list of entities that are defined for the document, and + * little else because the effect of namespaces and the various XML scheme + * efforts on DTD representation are not clearly understood as of this + * writing. + *

      The DOM Level 1 doesn't support editing DocumentType nodes. + */ +public interface DocumentType extends Node { + /** + * The name of DTD; i.e., the name immediately following the + * DOCTYPE keyword. + */ + public String getName(); + /** + * A NamedNodeMap containing the general entities, both + * external and internal, declared in the DTD. Duplicates are discarded. + * For example in:<!DOCTYPE ex SYSTEM "ex.dtd" [ <!ENTITY foo + * "foo"> <!ENTITY bar "bar"> <!ENTITY % baz "baz">]> + * <ex/> the interface provides access to foo and + * bar but not baz. Every node in this map also + * implements the Entity interface. + *
      The DOM Level 1 does not support editing entities, therefore + * entities cannot be altered in any way. + */ + public NamedNodeMap getEntities(); + /** + * A NamedNodeMap containing the notations declared in the + * DTD. Duplicates are discarded. Every node in this map also implements + * the Notation interface. + *
      The DOM Level 1 does not support editing notations, therefore + * notations cannot be altered in any way. + */ + public NamedNodeMap getNotations(); + +// not mentioned + public String getInternalSubset(); + +public String getSystemId(); +public String getPublicId(); + + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Element.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Element.java new file mode 100644 index 000000000..a99c48a95 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Element.java @@ -0,0 +1,310 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The Element interface represents an element in an HTML or XML + * document. Elements may have attributes associated with them; since the + * Element interface inherits from Node , the + * generic Node interface attribute attributes may + * be used to retrieve the set of all attributes for an element. There are + * methods on the Element interface to retrieve either an + * Attr object by name or an attribute value by name. In XML, + * where an attribute value may contain entity references, an + * Attr object should be retrieved to examine the possibly + * fairly complex sub-tree representing the attribute value. On the other + * hand, in HTML, where all attributes have simple string values, methods to + * directly access an attribute value can safely be used as a convenience. In + * DOM Level 2, the method normalize is inherited from the + * Node interface where it was moved. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Element extends Node { + /** + * The name of the element. For example, in: + *

      +     * <elementExample id="demo"> 
      +     *         ... 
      +     * </elementExample> ,
      + * tagName has + * the value "elementExample" . Note that this is + * case-preserving in XML, as are all of the operations of the DOM. The + * HTML DOM returns the tagName of an HTML element in the + * canonical uppercase form, regardless of the case in the source HTML + * document. + */ + public String getTagName(); + + /** + * Retrieves an attribute value by name. + * @param name The name of the attribute to retrieve. + * @return The Attr value as a string, or the empty string if + * that attribute does not have a specified or default value. + */ + public String getAttribute(String name); + + /** + * Adds a new attribute. If an attribute with that name is already + * present in the element, its value is changed to be that of the value + * parameter. This value is a simple string; it is not parsed as it is + * being set. So any markup (such as syntax to be recognized as an entity + * reference) is treated as literal text, and needs to be appropriately + * escaped by the implementation when it is written out. In order to + * assign an attribute value that contains entity references, the user + * must create an Attr node plus any Text and + * EntityReference nodes, build the appropriate subtree, and + * use setAttributeNode to assign it as the value of an + * attribute. + *
      To set an attribute with a qualified name and namespace URI, use + * the setAttributeNS method. + * @param name The name of the attribute to create or alter. + * @param value Value to set in string form. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified name contains an + * illegal character. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void setAttribute(String name, + String value) + throws DOMException; + + /** + * Removes an attribute by name. If the removed attribute is known to + * have a default value, an attribute immediately appears containing the + * default value as well as the corresponding namespace URI, local name, + * and prefix when applicable. + *
      To remove an attribute by local name and namespace URI, use the + * removeAttributeNS method. + * @param name The name of the attribute to remove. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public void removeAttribute(String name) + throws DOMException; + + /** + * Retrieves an attribute node by name. + *
      To retrieve an attribute node by qualified name and namespace URI, + * use the getAttributeNodeNS method. + * @param name The name (nodeName ) of the attribute to + * retrieve. + * @return The Attr node with the specified name ( + * nodeName ) or null if there is no such + * attribute. + */ + public Attr getAttributeNode(String name); + + /** + * Adds a new attribute node. If an attribute with that name ( + * nodeName ) is already present in the element, it is + * replaced by the new one. + *
      To add a new attribute node with a qualified name and namespace + * URI, use the setAttributeNodeNS method. + * @param newAttr The Attr node to add to the attribute list. + * @return If the newAttr attribute replaces an existing + * attribute, the replaced Attr node is returned, + * otherwise null is returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if newAttr was created from + * a different document than the one that created the element. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + *
      INUSE_ATTRIBUTE_ERR: Raised if newAttr is already + * an attribute of another Element object. The DOM user + * must explicitly clone Attr nodes to re-use them in + * other elements. + */ + public Attr setAttributeNode(Attr newAttr) + throws DOMException; + + /** + * Removes the specified attribute node. If the removed Attr + * has a default value it is immediately replaced. The replacing + * attribute has the same namespace URI and local name, as well as the + * original prefix, when applicable. + * @param oldAttr The Attr node to remove from the attribute + * list. + * @return The Attr node that was removed. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + *
      NOT_FOUND_ERR: Raised if oldAttr is not an + * attribute of the element. + */ + public Attr removeAttributeNode(Attr oldAttr) + throws DOMException; + + /** + * Returns a NodeList of all descendant Elements + * with a given tag name, in the order in which they are encountered in + * a preorder traversal of this Element tree. + * @param name The name of the tag to match on. The special value "*" + * matches all tags. + * @return A list of matching Element nodes. + */ + public NodeList getElementsByTagName(String name); + + /** + * Retrieves an attribute value by local name and namespace URI. + * HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the attribute to retrieve. + * @param localName The local name of the attribute to retrieve. + * @return The Attr value as a string, or the empty string if + * that attribute does not have a specified or default value. + * @since DOM Level 2 + */ + public String getAttributeNS(String namespaceURI, + String localName); + + /** + * Adds a new attribute. If an attribute with the same local name and + * namespace URI is already present on the element, its prefix is changed + * to be the prefix part of the qualifiedName , and its + * value is changed to be the value parameter. This value is + * a simple string; it is not parsed as it is being set. So any markup + * (such as syntax to be recognized as an entity reference) is treated as + * literal text, and needs to be appropriately escaped by the + * implementation when it is written out. In order to assign an attribute + * value that contains entity references, the user must create an + * Attr node plus any Text and + * EntityReference nodes, build the appropriate subtree, and + * use setAttributeNodeNS or setAttributeNode to + * assign it as the value of an attribute. + *
      HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the attribute to create or + * alter. + * @param qualifiedName The qualified name of the attribute to create or + * alter. + * @param value The value to set in string form. + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified qualified name + * contains an illegal character. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + *
      NAMESPACE_ERR: Raised if the qualifiedName is + * malformed, if the qualifiedName has a prefix and the + * namespaceURI is null or an empty string, + * if the qualifiedName has a prefix that is "xml" and the + * namespaceURI is different from " + * http://www.w3.org/XML/1998/namespace ", or if the + * qualifiedName is "xmlns" and the + * namespaceURI is different from " + * http://www.w3.org/2000/xmlns/ ". + * @since DOM Level 2 + */ + public void setAttributeNS(String namespaceURI, + String qualifiedName, + String value) + throws DOMException; + + /** + * Removes an attribute by local name and namespace URI. If the removed + * attribute has a default value it is immediately replaced. The + * replacing attribute has the same namespace URI and local name, as well + * as the original prefix. + *
      HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the attribute to remove. + * @param localName The local name of the attribute to remove. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + * @since DOM Level 2 + */ + public void removeAttributeNS(String namespaceURI, + String localName) + throws DOMException; + + /** + * Retrieves an Attr node by local name and namespace URI. + * HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the attribute to retrieve. + * @param localName The local name of the attribute to retrieve. + * @return The Attr node with the specified attribute local + * name and namespace URI or null if there is no such + * attribute. + * @since DOM Level 2 + */ + public Attr getAttributeNodeNS(String namespaceURI, + String localName); + + /** + * Adds a new attribute. If an attribute with that local name and that + * namespace URI is already present in the element, it is replaced by the + * new one. + *
      HTML-only DOM implementations do not need to implement this method. + * @param newAttr The Attr node to add to the attribute list. + * @return If the newAttr attribute replaces an existing + * attribute with the same local name and namespace URI , the + * replaced Attr node is returned, otherwise + * null is returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if newAttr was created from + * a different document than the one that created the element. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + *
      INUSE_ATTRIBUTE_ERR: Raised if newAttr is already + * an attribute of another Element object. The DOM user + * must explicitly clone Attr nodes to re-use them in + * other elements. + * @since DOM Level 2 + */ + public Attr setAttributeNodeNS(Attr newAttr) + throws DOMException; + + /** + * Returns a NodeList of all the descendant + * Elements with a given local name and namespace URI in the + * order in which they are encountered in a preorder traversal of this + * Element tree. + *
      HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the elements to match on. + * The special value "*" matches all namespaces. + * @param localName The local name of the elements to match on. The + * special value "*" matches all local names. + * @return A new NodeList object containing all the matched + * Elements . + * @since DOM Level 2 + */ + public NodeList getElementsByTagNameNS(String namespaceURI, + String localName); + + /** + * Returns true when an attribute with a given name is + * specified on this element or has a default value, false + * otherwise. + * @param name The name of the attribute to look for. + * @return true if an attribute with the given name is + * specified on this element or has a default value, false + * otherwise. + * @since DOM Level 2 + */ + public boolean hasAttribute(String name); + + /** + * Returns true when an attribute with a given local name + * and namespace URI is specified on this element or has a default value, + * false otherwise. HTML-only DOM implementations do not + * need to implement this method. + * @param namespaceURI The namespace URI of the attribute to look for. + * @param localName The local name of the attribute to look for. + * @return true if an attribute with the given local name and + * namespace URI is specified or has a default value on this element, + * false otherwise. + * @since DOM Level 2 + */ + public boolean hasAttributeNS(String namespaceURI, + String localName); + + public boolean hasAttributes(); + + public boolean isDefaultNamespace(String namespaceURI); + + public String lookupPrefix(String namespaceURI); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/ElementTraversal.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ElementTraversal.java new file mode 100644 index 000000000..80882c717 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ElementTraversal.java @@ -0,0 +1,19 @@ +package org.w3c.dom; +// (version 1.1 : 45.3, no super bit) +public abstract interface ElementTraversal { + + // Method descriptor #4 ()Lorg/w3c/dom/Element; + public abstract Element getFirstElementChild(); + + // Method descriptor #4 ()Lorg/w3c/dom/Element; + public abstract Element getLastElementChild(); + + // Method descriptor #4 ()Lorg/w3c/dom/Element; + public abstract Element getPreviousElementSibling(); + + // Method descriptor #4 ()Lorg/w3c/dom/Element; + public abstract Element getNextElementSibling(); + + // Method descriptor #9 ()I + public abstract int getChildElementCount(); +} \ No newline at end of file diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Entity.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Entity.java new file mode 100644 index 000000000..e170f65d2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Entity.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * This interface represents an entity, either parsed or unparsed, in an XML + * document. Note that this models the entity itself not the entity + * declaration. Entity declaration modeling has been left for a + * later Level of the DOM specification. + *

      The nodeName attribute that is inherited from + * Node contains the name of the entity. + *

      An XML processor may choose to completely expand entities before the + * structure model is passed to the DOM; in this case there will be no + * EntityReference nodes in the document tree. + *

      XML does not mandate that a non-validating XML processor read and + * process entity declarations made in the external subset or declared in + * external parameter entities. This means that parsed entities declared in + * the external subset need not be expanded by some classes of applications, + * and that the replacement value of the entity may not be available. When the + * replacement value is available, the corresponding Entity + * node's child list represents the structure of that replacement text. + * Otherwise, the child list is empty. + *

      The DOM Level 2 does not support editing Entity nodes; if + * a user wants to make changes to the contents of an Entity , + * every related EntityReference node has to be replaced in the + * structure model by a clone of the Entity 's contents, and + * then the desired changes must be made to each of those clones instead. + * Entity nodes and all their descendants are readonly . + *

      An Entity node does not have any parent. If the entity + * contains an unbound namespace prefix , the namespaceURI of + * the corresponding node in the Entity node subtree is + * null . The same is true for EntityReference + * nodes that refer to this entity, when they are created using the + * createEntityReference method of the Document + * interface. The DOM Level 2 does not support any mechanism to resolve + * namespace prefixes. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Entity extends Node { + /** + * The public identifier associated with the entity, if specified. If the + * public identifier was not specified, this is null . + */ + public String getPublicId(); + + /** + * The system identifier associated with the entity, if specified. If the + * system identifier was not specified, this is null . + */ + public String getSystemId(); + + /** + * For unparsed entities, the name of the notation for the entity. For + * parsed entities, this is null . + */ + public String getNotationName(); + + /** + * An attribute specifying the actual encoding of this entity, when it is + * an external parsed entity. This is null otherwise. + */ + public String getActualEncoding(); + public void setActualEncoding(String actualEncoding); + + /** + * An attribute specifying, as part of the text declaration, the encoding + * of this entity, when it is an external parsed entity. This is + * null otherwise. + */ + public String getEncoding(); + public void setEncoding(String encoding); + + /** + * An attribute specifying, as part of the text declaration, the version + * number of this entity, when it is an external parsed entity. This is + * null otherwise. + */ + public String getVersion(); + public void setVersion(String version); + + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Entity3.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Entity3.java new file mode 100644 index 000000000..a8d56581c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Entity3.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom; + +/** + * This interface extends the Entity interface with additional + * attributes to provide information on the text declaration of external + * parsed entities. + *

      See also the Document Object Model (DOM) Level 3 Core Specification. + */ +public interface Entity3 extends Entity { +// /** +// * An attribute specifying the actual encoding of this entity, when it is +// * an external parsed entity. This is null otherwise. +// */ +// public String getActualEncoding(); +// public void setActualEncoding(String actualEncoding); +// +// /** +// * An attribute specifying, as part of the text declaration, the encoding +// * of this entity, when it is an external parsed entity. This is +// * null otherwise. +// */ +// public String getEncoding(); +// public void setEncoding(String encoding); +// +// /** +// * An attribute specifying, as part of the text declaration, the version +// * number of this entity, when it is an external parsed entity. This is +// * null otherwise. +// */ +// public String getVersion(); +// public void setVersion(String version); + +} diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/EntityReference.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/EntityReference.java new file mode 100644 index 000000000..1f92a156e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/EntityReference.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * EntityReference objects may be inserted into the structure + * model when an entity reference is in the source document, or when the user + * wishes to insert an entity reference. Note that character references and + * references to predefined entities are considered to be expanded by the + * HTML or XML processor so that characters are represented by their Unicode + * equivalent rather than by an entity reference. Moreover, the XML processor + * may completely expand references to entities while building the structure + * model, instead of providing EntityReference objects. If it + * does provide such objects, then for a given EntityReference + * node, it may be that there is no Entity node representing the + * referenced entity. If such an Entity exists, then the subtree + * of the EntityReference node is in general a copy of the + * Entity node subtree. However, this may not be true when an + * entity contains an unbound namespace prefix . In such a case, because the + * namespace prefix resolution depends on where the entity reference is, the + * descendants of the EntityReference node may be bound to + * different namespace URIs . + *

      As for Entity nodes, EntityReference nodes and + * all their descendants are readonly . + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface EntityReference extends Node { +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/NamedNodeMap.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/NamedNodeMap.java new file mode 100644 index 000000000..0672e1c80 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/NamedNodeMap.java @@ -0,0 +1,158 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * Objects implementing the NamedNodeMap interface are used to + * represent collections of nodes that can be accessed by name. Note that + * NamedNodeMap does not inherit from NodeList ; + * NamedNodeMaps are not maintained in any particular order. + * Objects contained in an object implementing NamedNodeMap may + * also be accessed by an ordinal index, but this is simply to allow + * convenient enumeration of the contents of a NamedNodeMap , + * and does not imply that the DOM specifies an order to these Nodes. + *

      NamedNodeMap objects in the DOM are live . + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface NamedNodeMap { + /** + * Retrieves a node specified by name. + * @param name The nodeName of a node to retrieve. + * @return A Node (of any type) with the specified + * nodeName , or null if it does not identify + * any node in this map. + */ + public Node getNamedItem(String name); + + /** + * Adds a node using its nodeName attribute. If a node with + * that name is already present in this map, it is replaced by the new + * one. + *
      As the nodeName attribute is used to derive the name + * which the node must be stored under, multiple nodes of certain types + * (those that have a "special" string value) cannot be stored as the + * names would clash. This is seen as preferable to allowing nodes to be + * aliased. + * @param arg A node to store in this map. The node will later be + * accessible using the value of its nodeName attribute. + * @return If the new Node replaces an existing node the + * replaced Node is returned, otherwise null + * is returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if arg was created from a + * different document than the one that created this map. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + *
      INUSE_ATTRIBUTE_ERR: Raised if arg is an + * Attr that is already an attribute of another + * Element object. The DOM user must explicitly clone + * Attr nodes to re-use them in other elements. + */ + public Node setNamedItem(Node arg) + throws DOMException; + + /** + * Removes a node specified by name. A removed attribute may be known to + * have a default value when this map contains the attributes attached to + * an element, as returned by the attributes attribute of the + * Node interface. If so, an attribute immediately appears + * containing the default value as well as the corresponding namespace + * URI, local name, and prefix when applicable. + * @param name The nodeName of the node to remove. + * @return The node removed from this map if a node with such a name + * exists. + * @exception DOMException + * NOT_FOUND_ERR: Raised if there is no node named name + * in this map. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + */ + public Node removeNamedItem(String name) + throws DOMException; + + /** + * Returns the index th item in the map. If + * index is greater than or equal to the number of nodes in + * this map, this returns null . + * @param index Index into this map. + * @return The node at the index th position in the map, or + * null if that is not a valid index. + */ + public Node item(int index); + + /** + * The number of nodes in this map. The range of valid child node indices + * is 0 to length-1 inclusive. + */ + public int getLength(); + + /** + * Retrieves a node specified by local name and namespace URI. HTML-only + * DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the node to retrieve. + * @param localName The local name of the node to retrieve. + * @return A Node (of any type) with the specified local + * name and namespace URI, or null if they do not identify + * any node in this map. + * @since DOM Level 2 + */ + public Node getNamedItemNS(String namespaceURI, + String localName); + + /** + * Adds a node using its namespaceURI and + * localName . If a node with that namespace URI and that + * local name is already present in this map, it is replaced by the new + * one. + *
      HTML-only DOM implementations do not need to implement this method. + * @param arg A node to store in this map. The node will later be + * accessible using the value of its namespaceURI and + * localName attributes. + * @return If the new Node replaces an existing node the + * replaced Node is returned, otherwise null + * is returned. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if arg was created from a + * different document than the one that created this map. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + *
      INUSE_ATTRIBUTE_ERR: Raised if arg is an + * Attr that is already an attribute of another + * Element object. The DOM user must explicitly clone + * Attr nodes to re-use them in other elements. + * @since DOM Level 2 + */ + public Node setNamedItemNS(Node arg) + throws DOMException; + + /** + * Removes a node specified by local name and namespace URI. A removed + * attribute may be known to have a default value when this map contains + * the attributes attached to an element, as returned by the attributes + * attribute of the Node interface. If so, an attribute + * immediately appears containing the default value as well as the + * corresponding namespace URI, local name, and prefix when applicable. + *
      HTML-only DOM implementations do not need to implement this method. + * @param namespaceURI The namespace URI of the node to remove. + * @param localName The local name of the node to remove. + * @return The node removed from this map if a node with such a local + * name and namespace URI exists. + * @exception DOMException + * NOT_FOUND_ERR: Raised if there is no node with the specified + * namespaceURI and localName in this map. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this map is readonly. + * @since DOM Level 2 + */ + public Node removeNamedItemNS(String namespaceURI, + String localName) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Node.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Node.java new file mode 100644 index 000000000..b244d99c5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Node.java @@ -0,0 +1,520 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The Node interface is the primary datatype for the entire + * Document Object Model. It represents a single node in the document tree. + * While all objects implementing the Node interface expose + * methods for dealing with children, not all objects implementing the + * Node interface may have children. For example, + * Text nodes may not have children, and adding children to such + * nodes results in a DOMException being raised. + *

      The attributes nodeName , nodeValue and + * attributes are included as a mechanism to get at node + * information without casting down to the specific derived interface. In + * cases where there is no obvious mapping of these attributes for a specific + * nodeType (e.g., nodeValue for an + * Element or attributes for a Comment + * ), this returns null . Note that the specialized interfaces + * may contain additional and more convenient mechanisms to get and set the + * relevant information. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Node { + // NodeType + public static final short ELEMENT_NODE = 1; + public static final short ATTRIBUTE_NODE = 2; + public static final short TEXT_NODE = 3; + public static final short CDATA_SECTION_NODE = 4; + public static final short ENTITY_REFERENCE_NODE = 5; + public static final short ENTITY_NODE = 6; + public static final short PROCESSING_INSTRUCTION_NODE = 7; + public static final short COMMENT_NODE = 8; + public static final short DOCUMENT_NODE = 9; + public static final short DOCUMENT_TYPE_NODE = 10; + public static final short DOCUMENT_FRAGMENT_NODE = 11; + public static final short NOTATION_NODE = 12; + + /** + * The name of this node, depending on its type; see the table above. + */ + public String getNodeName(); + + /** + * The value of this node, depending on its type; see the table above. + * When it is defined to be null , setting it has no effect. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + * @exception DOMException + * DOMSTRING_SIZE_ERR: Raised when it would return more characters + * than fit in a DOMString variable on the implementation + * platform. + */ + public String getNodeValue() + throws DOMException; + public void setNodeValue(String nodeValue) + throws DOMException; + + /** + * A code representing the type of the underlying object, as defined + * above. + */ + public short getNodeType(); + + /** + * The parent of this node. All nodes, except Attr , + * Document , DocumentFragment , + * Entity , and Notation may have a parent. + * However, if a node has just been created and not yet added to the + * tree, or if it has been removed from the tree, this is + * null . + */ + public Node getParentNode(); + + /** + * A NodeList that contains all children of this node. If + * there are no children, this is a NodeList containing no + * nodes. + */ + public NodeList getChildNodes(); + + /** + * The first child of this node. If there is no such node, this returns + * null . + */ + public Node getFirstChild(); + + /** + * The last child of this node. If there is no such node, this returns + * null . + */ + public Node getLastChild(); + + /** + * The node immediately preceding this node. If there is no such node, + * this returns null . + */ + public Node getPreviousSibling(); + + /** + * The node immediately following this node. If there is no such node, + * this returns null . + */ + public Node getNextSibling(); + + /** + * A NamedNodeMap containing the attributes of this node (if + * it is an Element ) or null otherwise. + */ + public NamedNodeMap getAttributes(); + + /** + * The Document object associated with this node. This is + * also the Document object used to create new nodes. When + * this node is a Document or a DocumentType + * which is not used with any Document yet, this is + * null . + * @version DOM Level 2 + */ + public Document getOwnerDocument(); + + /** + * Inserts the node newChild before the existing child node + * refChild . If refChild is null + * , insert newChild at the end of the list of children. + *
      If newChild is a DocumentFragment + * object, all of its children are inserted, in the same order, before + * refChild . If the newChild is already in the + * tree, it is first removed. + * @param newChild The node to insert. + * @param refChild The reference node, i.e., the node before which the + * new node must be inserted. + * @return The node being inserted. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does + * not allow children of the type of the newChild node, or + * if the node to insert is one of this node's ancestors. + *
      WRONG_DOCUMENT_ERR: Raised if newChild was created + * from a different document than the one that created this node. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly or + * if the parent of the node being inserted is readonly. + *
      NOT_FOUND_ERR: Raised if refChild is not a child + * of this node. + */ + public Node insertBefore(Node newChild, + Node refChild) + throws DOMException; + + /** + * Replaces the child node oldChild with + * newChild in the list of children, and returns the + * oldChild node. + *
      If newChild is a DocumentFragment object, + * oldChild is replaced by all of the + * DocumentFragment children, which are inserted in the same + * order. If the newChild is already in the tree, it is + * first removed. + * @param newChild The new node to put in the child list. + * @param oldChild The node being replaced in the list. + * @return The node replaced. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does + * not allow children of the type of the newChild node, or + * if the node to put in is one of this node's ancestors. + *
      WRONG_DOCUMENT_ERR: Raised if newChild was created + * from a different document than the one that created this node. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node or the parent + * of the new node is readonly. + *
      NOT_FOUND_ERR: Raised if oldChild is not a child + * of this node. + */ + public Node replaceChild(Node newChild, + Node oldChild) + throws DOMException; + + /** + * Removes the child node indicated by oldChild from the + * list of children, and returns it. + * @param oldChild The node being removed. + * @return The node removed. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + *
      NOT_FOUND_ERR: Raised if oldChild is not a child + * of this node. + */ + public Node removeChild(Node oldChild) + throws DOMException; + + /** + * Adds the node newChild to the end of the list of children + * of this node. If the newChild is already in the tree, it + * is first removed. + * @param newChild The node to add. If it is a + * DocumentFragment object, the entire contents of the + * document fragment are moved into the child list of this node + * @return The node added. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if this node is of a type that does + * not allow children of the type of the newChild node, or + * if the node to append is one of this node's ancestors. + *
      WRONG_DOCUMENT_ERR: Raised if newChild was created + * from a different document than the one that created this node. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public Node appendChild(Node newChild) + throws DOMException; + + /** + * This is a convenience method to allow easy determination of whether a + * node has any children. + * @return true if the node has any children, + * false if the node has no children. + */ + public boolean hasChildNodes(); + + /** + * Returns a duplicate of this node, i.e., serves as a generic copy + * constructor for nodes. The duplicate node has no parent; ( + * parentNode is null .). + *
      Cloning an Element copies all attributes and their + * values, including those generated by the XML processor to represent + * defaulted attributes, but this method does not copy any text it + * contains unless it is a deep clone, since the text is contained in a + * child Text node. Cloning an Attribute + * directly, as opposed to be cloned as part of an Element + * cloning operation, returns a specified attribute ( + * specified is true ). Cloning any other type + * of node simply returns a copy of this node. + *
      Note that cloning an immutable subtree results in a mutable copy, + * but the children of an EntityReference clone are + * readonly . In addition, clones of unspecified Attr nodes + * are specified. And, cloning Document , + * DocumentType , Entity , and + * Notation nodes is implementation dependent. + * @param deep If true , recursively clone the subtree under + * the specified node; if false , clone only the node + * itself (and its attributes, if it is an Element ). + * @return The duplicate node. + */ + public Node cloneNode(boolean deep); + + /** + * Puts all Text nodes in the full depth of the sub-tree + * underneath this Node , including attribute nodes, into a + * "normal" form where only structure (e.g., elements, comments, + * processing instructions, CDATA sections, and entity references) + * separates Text nodes, i.e., there are neither adjacent + * Text nodes nor empty Text nodes. This can be + * used to ensure that the DOM view of a document is the same as if it + * were saved and re-loaded, and is useful when operations (such as + * XPointer lookups) that depend on a particular document tree structure + * are to be used. In cases where the document contains + * CDATASections , the normalize operation alone may not be + * sufficient, since XPointers do not differentiate between + * Text nodes and CDATASection nodes. + * @since DOM Level 2 + */ + public void normalize(); + + /** + * Tests whether the DOM implementation implements a specific feature and + * that feature is supported by this node. + * @param feature The name of the feature to test. This is the same name + * which can be passed to the method hasFeature on + * DOMImplementation . + * @param version This is the version number of the feature to test. In + * Level 2, version 1, this is the string "2.0". If the version is not + * specified, supporting any version of the feature will cause the + * method to return true . + * @return Returns true if the specified feature is supported + * on this node, false otherwise. + * @since DOM Level 2 + */ + public boolean supports(String feature, + String version); + + /** + * The namespace URI of this node, or null if it is + * unspecified. + *
      This is not a computed value that is the result of a namespace + * lookup based on an examination of the namespace declarations in scope. + * It is merely the namespace URI given at creation time. + *
      For nodes of any type other than ELEMENT_NODE and + * ATTRIBUTE_NODE and nodes created with a DOM Level 1 + * method, such as createElement from the + * Document interface, this is always null . + * Per the Namespaces in XML Specification an attribute does not + * inherit its namespace from the element it is attached to. If an + * attribute is not explicitly given a namespace, it simply has no + * namespace. + * @since DOM Level 2 + */ + public String getNamespaceURI(); + + /** + * The namespace prefix of this node, or null if it is + * unspecified. + *
      Note that setting this attribute, when permitted, changes the + * nodeName attribute, which holds the qualified name , as + * well as the tagName and name attributes of + * the Element and Attr interfaces, when + * applicable. + *
      Note also that changing the prefix of an attribute that is known to + * have a default value, does not make a new attribute with the default + * value and the original prefix appear, since the + * namespaceURI and localName do not change. + *
      For nodes of any type other than ELEMENT_NODE and + * ATTRIBUTE_NODE and nodes created with a DOM Level 1 + * method, such as createElement from the + * Document interface, this is always null . + * @exception DOMException + * INVALID_CHARACTER_ERR: Raised if the specified prefix contains an + * illegal character. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + *
      NAMESPACE_ERR: Raised if the specified prefix is + * malformed, if the namespaceURI of this node is + * null , if the specified prefix is "xml" and the + * namespaceURI of this node is different from " + * http://www.w3.org/XML/1998/namespace ", if this node is an attribute + * and the specified prefix is "xmlns" and the namespaceURI + * of this node is different from " http://www.w3.org/2000/xmlns/ ", + * or if this node is an attribute and the qualifiedName + * of this node is "xmlns" . + * @since DOM Level 2 + */ + public String getPrefix(); + public void setPrefix(String prefix) + throws DOMException; + + /** + * Returns the local part of the qualified name of this node. + *
      For nodes of any type other than ELEMENT_NODE and + * ATTRIBUTE_NODE and nodes created with a DOM Level 1 + * method, such as createElement from the + * Document interface, this is always null . + * @since DOM Level 2 + */ + public String getLocalName(); + + /** + * Returns the absolute base URI of this node.How will this be affected by + * resolution of relative namespace URIs issue?Should this only be on + * Document, Element, ProcessingInstruction, Entity, and Notation nodes, + * according to the infoset? If not, what is it equal to on other nodes? + * Null? An empty string?Should this be read-only and computed or and + * actual read-write attribute?The former (F2F 19 Jun 2000). + */ + public String getBaseURI(); + + + /** + * Compares a node with this node with regard to document order.Should an + * exception be raised when comparing attributes? Entities and + * notations? An element against an attribute? If yes, which one? + * HIERARCHY_REQUEST_ERR? Should the enum value "unordered" be killed + * then?No, return unordered for attributes (F2F 19 Jun 2000).Should + * this method be moved to Node and take only one node in argument?Yes + * (F2F 19 Jun 2000). + * @param otherThe node to compare against this node. + * @return Returns how the given node compares with this node in document + * order. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if the given node does not belong to the + * same document as this node. + */ + public int compareDocumentOrder(Node other) + throws DOMException; + + + public static final int PRECEDING = 1; + public static final int FOLLOWING = 2; + public static final int ANCESTOR = 3; + public static final int DESCENDANT = 4; + public static final int SAME = 5; + public static final int UNORDERED = 6; + + +public static final short DOCUMENT_POSITION_DISCONNECTED = 1; +public static final short DOCUMENT_POSITION_PRECEDING = 2; +public static final short DOCUMENT_POSITION_FOLLOWING = 4; +public static final short DOCUMENT_POSITION_CONTAINS = 8; +public static final short DOCUMENT_POSITION_CONTAINED_BY = 16; +public static final short DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC = 32; + +public short compareDocumentPosition(Node other) throws DOMException; + + /** + * Compares a node with this node with regard to their position in the + * tree. + * @param otherThe node to compare against this node. + * @return Returns how the given node is positioned relatively to this + * node. + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if the given node does not belong to the + * same document as this node. + */ + public int compareTreePosition(Node other) + throws DOMException; + + /** + * This attribute returns the text content of this node and its + * descendants. When set, any possible children this node may have are + * removed and replaced by a single Text node containing + * the string this attribute is set to. On getting, no serialization is + * performed, the returned string does not contain any markup. + * Similarly, on setting, no parsing is performed either, the input + * string is taken as pure textual content. + *
      The string returned is made of the text content of this node + * depending on its type, as defined below: Node typeContent + * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, DOCUMENT_NODE, + * DOCUMENT_FRAGMENT_NODEconcatenation of the textContent + * of the child nodes, excluding COMMENT_NODE and + * PROCESSING_INSTRUCTION_NODE nodesATTRIBUTE_NODE, TEXT_NODE, + * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE + * nodeValueDOCUMENT_TYPE_NODE, NOTATION_NODEempty string + * Should any whitespace normalization be performed?Should this be two + * methods instead?What about the name? + */ + public String getTextContent(); + public void setTextContent(String textContent); + + /** + * Returns whether this node is the same node as the given one. Do we + * really want to make this different from equals?Yes, change name from + * isIdentical to isSameNode. (Telcon 4 Jul 2000). + * @param otherThe node to test against. + * @return Returns true if the nodes are the same, + * false otherwise. + */ + public boolean isSameNode(Node other); + + /** + * Look up the prefix associated to the given namespace URI, starting from + * this node. + * @param namespaceURIThe namespace URI to look for. + * @return Returns the associated namespace prefix or null + * if none is found. + */ + public String lookupNamespacePrefix(String namespaceURI); + + /** + * Look up the namespace URI associated to the given prefix, starting from + * this node.Name? May need to change depending on ending of the + * relative namespace URI reference nightmare. + * @param prefixThe prefix to look for. + * @return Returns the associated namespace URI or null if + * none is found. + */ + public String lookupNamespaceURI(String prefix); + + /** + * This method walks down the tree, starting from this node, and adds + * namespace declarations where needed so that every namespace being + * used is properly declared. It also changes or assign prefixes when + * needed. This effectively makes this node subtree is "namespace + * wellformed". + *
      What the generated prefixes are and/or how prefixes are changed to + * achieve this is implementation dependent.Any other name?How specific + * should this be? Should we not even specify that this should be done + * by walking down the tree?What does this do on attribute nodes?Doesn't + * do anything (F2F 1 Aug 2000).How does it work with entity reference + * subtree which may be broken?This doesn't affect entity references + * which are not visited in this operation (F2F 1 Aug 2000).Should this + * be really be on Node?Yes, but this only works on Document, Element, + * and DocumentFragment. On other types it is a no-op. (F2F 1 Aug 2000). + * What happens with read-only nodes?What/how errors should be reported? + * Are there any? + */ + public void normalizeNS(); + + /** + * This method allows to attach a user object to a Node. This object can + * then be retreived using getUserData.Is this really worth + * it?Could we live without a key?What happens if the node is cloned, + * imported, adopted? Should some event mechanism be specified to notify + * the application?What happens if the node is cloned?What should Object + * be mapped to in ECMAScript? For IDL we need to define this type + * somehow. + * @param dataThe piece of data to attach to this node. + * @param keyThe key to associate this data to. + * @return The object previously associated to this node and the given + * key or null. + */ + public Object setUserData(Object data, + String key); + + /** + * This method allows to retreive a user object previously attached to a + * Node with setUserData. + * @param keyThe key to look for. + * @return The object associated to this node and the given key or + * null. + */ + public Object getUserData(String key); + + /** + * This attribute returns a unique key identifying this node.What type + * should this really be?In what space is this key unique (Document, + * DOMImplementation)?What is the lifetime of the uniqueness of this key + * (Node, Document, ...)? + */ + public Object getKey(); + + public boolean isEqualNode(Node child2); + + public boolean hasAttributes(); + +} + + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Node3.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Node3.java new file mode 100644 index 000000000..79b286471 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Node3.java @@ -0,0 +1,184 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom; + +/** + * This interface extends the Node interface with several new + * methods. One allows to compare a node against another with regard to + * document order. Another methode allows to retrieve the content of a node + * and its descendants as a single DOMString. One allows to test whether two + * nodes are the same. Two methods provide for searching the namespace URI + * associated to a given prefix and to ensure the document is "namespace + * wellformed". Finally, a method allows to attach some user data to a Node. + * It also provides a new attribute to get the base URI of a node, as + * defined in the XML Infoset.The term namespace wellformed needs to be + * defined.Define it as "being conformant to the Namespaces in XML spec" in + * the glossary (Telcon 4 Jul 2000). + *

      See also the Document Object Model (DOM) Level 3 Core Specification. + */ +public interface Node3 { +// /** +// * Returns the absolute base URI of this node.How will this be affected by +// * resolution of relative namespace URIs issue?Should this only be on +// * Document, Element, ProcessingInstruction, Entity, and Notation nodes, +// * according to the infoset? If not, what is it equal to on other nodes? +// * Null? An empty string?Should this be read-only and computed or and +// * actual read-write attribute?The former (F2F 19 Jun 2000). +// */ +// public String getBaseURI(); +// +// +// /** +// * Compares a node with this node with regard to document order.Should an +// * exception be raised when comparing attributes? Entities and +// * notations? An element against an attribute? If yes, which one? +// * HIERARCHY_REQUEST_ERR? Should the enum value "unordered" be killed +// * then?No, return unordered for attributes (F2F 19 Jun 2000).Should +// * this method be moved to Node and take only one node in argument?Yes +// * (F2F 19 Jun 2000). +// * @param otherThe node to compare against this node. +// * @return Returns how the given node compares with this node in document +// * order. +// * @exception DOMException +// * WRONG_DOCUMENT_ERR: Raised if the given node does not belong to the +// * same document as this node. +// */ +// public int compareDocumentOrder(Node other) +// throws DOMException; +// +// +// public static final int PRECEDING = 1; +// public static final int FOLLOWING = 2; +// public static final int ANCESTOR = 3; +// public static final int DESCENDANT = 4; +// public static final int SAME = 5; +// public static final int UNORDERED = 6; +// +// /** +// * Compares a node with this node with regard to their position in the +// * tree. +// * @param otherThe node to compare against this node. +// * @return Returns how the given node is positioned relatively to this +// * node. +// * @exception DOMException +// * WRONG_DOCUMENT_ERR: Raised if the given node does not belong to the +// * same document as this node. +// */ +// public int compareTreePosition(Node other) +// throws DOMException; +// +// /** +// * This attribute returns the text content of this node and its +// * descendants. When set, any possible children this node may have are +// * removed and replaced by a single Text node containing +// * the string this attribute is set to. On getting, no serialization is +// * performed, the returned string does not contain any markup. +// * Similarly, on setting, no parsing is performed either, the input +// * string is taken as pure textual content. +// *
      The string returned is made of the text content of this node +// * depending on its type, as defined below: Node typeContent +// * ELEMENT_NODE, ENTITY_NODE, ENTITY_REFERENCE_NODE, DOCUMENT_NODE, +// * DOCUMENT_FRAGMENT_NODEconcatenation of the textContent +// * of the child nodes, excluding COMMENT_NODE and +// * PROCESSING_INSTRUCTION_NODE nodesATTRIBUTE_NODE, TEXT_NODE, +// * CDATA_SECTION_NODE, COMMENT_NODE, PROCESSING_INSTRUCTION_NODE +// * nodeValueDOCUMENT_TYPE_NODE, NOTATION_NODEempty string +// * Should any whitespace normalization be performed?Should this be two +// * methods instead?What about the name? +// */ +// public String getTextContent(); +// public void setTextContent(String textContent); +// +// /** +// * Returns whether this node is the same node as the given one. Do we +// * really want to make this different from equals?Yes, change name from +// * isIdentical to isSameNode. (Telcon 4 Jul 2000). +// * @param otherThe node to test against. +// * @return Returns true if the nodes are the same, +// * false otherwise. +// */ +// public boolean isSameNode(Node other); +// +// /** +// * Look up the prefix associated to the given namespace URI, starting from +// * this node. +// * @param namespaceURIThe namespace URI to look for. +// * @return Returns the associated namespace prefix or null +// * if none is found. +// */ +// public String lookupNamespacePrefix(String namespaceURI); +// +// /** +// * Look up the namespace URI associated to the given prefix, starting from +// * this node.Name? May need to change depending on ending of the +// * relative namespace URI reference nightmare. +// * @param prefixThe prefix to look for. +// * @return Returns the associated namespace URI or null if +// * none is found. +// */ +// public String lookupNamespaceURI(String prefix); +// +// /** +// * This method walks down the tree, starting from this node, and adds +// * namespace declarations where needed so that every namespace being +// * used is properly declared. It also changes or assign prefixes when +// * needed. This effectively makes this node subtree is "namespace +// * wellformed". +// *
      What the generated prefixes are and/or how prefixes are changed to +// * achieve this is implementation dependent.Any other name?How specific +// * should this be? Should we not even specify that this should be done +// * by walking down the tree?What does this do on attribute nodes?Doesn't +// * do anything (F2F 1 Aug 2000).How does it work with entity reference +// * subtree which may be broken?This doesn't affect entity references +// * which are not visited in this operation (F2F 1 Aug 2000).Should this +// * be really be on Node?Yes, but this only works on Document, Element, +// * and DocumentFragment. On other types it is a no-op. (F2F 1 Aug 2000). +// * What happens with read-only nodes?What/how errors should be reported? +// * Are there any? +// */ +// public void normalizeNS(); +// +// /** +// * This method allows to attach a user object to a Node. This object can +// * then be retreived using getUserData.Is this really worth +// * it?Could we live without a key?What happens if the node is cloned, +// * imported, adopted? Should some event mechanism be specified to notify +// * the application?What happens if the node is cloned?What should Object +// * be mapped to in ECMAScript? For IDL we need to define this type +// * somehow. +// * @param dataThe piece of data to attach to this node. +// * @param keyThe key to associate this data to. +// * @return The object previously associated to this node and the given +// * key or null. +// */ +// public Object setUserData(Object data, +// String key); +// +// /** +// * This method allows to retreive a user object previously attached to a +// * Node with setUserData. +// * @param keyThe key to look for. +// * @return The object associated to this node and the given key or +// * null. +// */ +// public Object getUserData(String key); +// +// /** +// * This attribute returns a unique key identifying this node.What type +// * should this really be?In what space is this key unique (Document, +// * DOMImplementation)?What is the lifetime of the uniqueness of this key +// * (Node, Document, ...)? +// */ +// public Object getKey(); + +} diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/NodeList.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/NodeList.java new file mode 100644 index 000000000..e63533e33 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/NodeList.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The NodeList interface provides the abstraction of an ordered + * collection of nodes, without defining or constraining how this collection + * is implemented. NodeList objects in the DOM are live . + *

      The items in the NodeList are accessible via an integral + * index, starting from 0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface NodeList { + /** + * Returns the index th item in the collection. If + * index is greater than or equal to the number of nodes in + * the list, this returns null . + * @param index Index into the collection. + * @return The node at the index th position in the + * NodeList , or null if that is not a valid + * index. + */ + public Node item(int index); + + /** + * The number of nodes in the list. The range of valid child node indices + * is 0 to length-1 inclusive. + */ + public int getLength(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Notation.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Notation.java new file mode 100644 index 000000000..ff7830c59 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Notation.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * This interface represents a notation declared in the DTD. A notation + * either declares, by name, the format of an unparsed entity (see section 4.7 + * of the XML 1.0 specification), or is used for formal declaration of + * processing instruction targets (see section 2.6 of the XML 1.0 + * specification). The nodeName attribute inherited from + * Node is set to the declared name of the notation. + *

      The DOM Level 1 does not support editing Notation nodes; + * they are therefore readonly . + *

      A Notation node does not have any parent. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Notation extends Node { + /** + * The public identifier of this notation. If the public identifier was + * not specified, this is null . + */ + public String getPublicId(); + + /** + * The system identifier of this notation. If the system identifier was + * not specified, this is null . + */ + public String getSystemId(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/ProcessingInstruction.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ProcessingInstruction.java new file mode 100644 index 000000000..9cdc59a27 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ProcessingInstruction.java @@ -0,0 +1,25 @@ +package org.w3c.dom; + +/** + * The ProcessingInstruction interface represents a "processing + * instruction", used in XML as a way to keep processor-specific information + * in the text of the document. + */ +public interface ProcessingInstruction extends Node { + /** + * The target of this processing instruction. XML defines this as being the + * first token following the markup that begins the processing instruction. + */ + public String getTarget(); + /** + * The content of this processing instruction. This is from the first non + * white space character after the target to the character immediately + * preceding the ?>. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised when the node is readonly. + */ + public String getData(); + public void setData(String data) + throws DOMException; +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Text.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Text.java new file mode 100644 index 000000000..bf87cd255 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Text.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom; + +/** + * The Text interface inherits from CharacterData + * and represents the textual content (termed character data in XML) of an + * Element or Attr . If there is no markup inside + * an element's content, the text is contained in a single object + * implementing the Text interface that is the only child of the + * element. If there is markup, it is parsed into the information items + * (elements, comments, etc.) and Text nodes that form the + * list of children of the element. + *

      When a document is first made available via the DOM, there is only one + * Text node for each block of text. Users may create adjacent + * Text nodes that represent the contents of a given element + * without any intervening markup, but should be aware that there is no way + * to represent the separations between these nodes in XML or HTML, so they + * will not (in general) persist between DOM editing sessions. The + * normalize() method on Node merges any such + * adjacent Text objects into a single node for each block of + * text. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface Text extends CharacterData { + /** + * Breaks this node into two nodes at the specified offset + * , keeping both in the tree as siblings. This node then only contains + * all the content up to the offset point. A new node of the + * same type, which is inserted as the next sibling of this node, + * contains all the content at and after the offset point. + * When the offset is equal to the length of this node, the + * new node has no data. + * @param offset The 16-bit unit offset at which to split, starting from + * 0 . + * @return The new node, of the same type as this node. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified offset is negative or + * greater than the number of 16-bit units in data . + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this node is readonly. + */ + public Text splitText(int offset) + throws DOMException; + + /** + * Returns whether this text node contains whitespace in element content, + * often abusively called "ignorable whitespace".An implementation can + * only return true if, one way or another, it has access + * to the relevant information (e.g., the DTD or schema). + */ + public boolean getIsWhitespaceInElementContent(); + + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/Text3.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Text3.java new file mode 100644 index 000000000..373157db9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/Text3.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more details. + */ + +package org.w3c.dom; + + + +/** + * This interface extends the Text interface with a new attribute + * that allows one to find out whether a Text node only + * contains whitespace in element content. + *

      See also the Document Object Model (DOM) Level 3 Core Specification. + */ +public interface Text3 extends Text { +// /** +// * Returns whether this text node contains whitespace in element content, +// * often abusively called "ignorable whitespace".An implementation can +// * only return true if, one way or another, it has access +// * to the relevant information (e.g., the DTD or schema). +// */ +// public boolean getIsWhitespaceInElementContent(); + +} diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Azimuth.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Azimuth.java new file mode 100644 index 000000000..de9016ec0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Azimuth.java @@ -0,0 +1,94 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2Azimuth interface represents the azimuth CSS Level 2 + * property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2Azimuth extends CSSValue { + /** + * A code defining the type of the value as defined in + * CSSValue . It would be one of CSS_DEG , + * CSS_RAD , CSS_GRAD or CSS_IDENT + * . + */ + public short getAzimuthType(); + + /** + * If azimuthType is CSS_IDENT , + * identifier contains one of left-side, far-left, left, + * center-left, center, center-right, right, far-right, right-side, + * leftwards, rightwards. The empty string if none is set. + */ + public String getIdentifier(); + + /** + * behind indicates whether the behind identifier has been + * set. + */ + public boolean getBehind(); + + /** + * A method to set the angle value with a specified unit. This method + * will unset any previously set identifier value. + * @param uType The unitType could only be one of CSS_DEG , + * CSS_RAD or CSS_GRAD ). + * @param fValue The new float value of the angle. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the unit type is invalid. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setAngleValue(short uType, + float fValue) + throws DOMException; + + /** + * Used to retrieved the float value of the azimuth property. + * @param uType The unit type can be only an angle unit type ( + * CSS_DEG , CSS_RAD or CSS_GRAD + * ). + * @return The float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the unit type is invalid. + */ + public float getAngleValue(short uType) + throws DOMException; + + /** + * Setting the identifier for the azimuth property will unset any + * previously set angle value. The value of azimuthType is + * set to CSS_IDENT + * @param ident The new identifier. If the identifier is "leftwards" or + * "rightward", the behind attribute is ignored. + * @param b The new value for behind. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified identifier has a + * syntax error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setIdentifier(String ident, + boolean b) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2BackgroundPosition.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2BackgroundPosition.java new file mode 100644 index 000000000..159504353 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2BackgroundPosition.java @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2BackgroundPosition interface represents the + * background-position CSS Level 2 property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2BackgroundPosition extends CSSValue { + /** + * A code defining the type of the horizontal value. It would be one of + * CSS_PERCENTAGE , CSS_EMS , + * CSS_EXS , CSS_PX , CSS_CM , + * CSS_MM , CSS_IN , CSS_PT , + * CSS_PC or CSS_IDENT . If one of horizontal or + * vertical is CSS_IDENT , it's guaranteed that the other is + * the same. + */ + public short getHorizontalType(); + + /** + * A code defining the type of the horizontal value. The code can be one + * of the following units : CSS_PERCENTAGE , + * CSS_EMS , CSS_EXS , CSS_PX , + * CSS_CM , CSS_MM , CSS_IN , + * CSS_PT , CSS_PC , CSS_IDENT , + * CSS_INHERIT . If one of horizontal or vertical is + * CSS_IDENT or CSS_INHERIT , it's guaranteed + * that the other is the same. + */ + public short getVerticalType(); + + /** + * If horizontalType is CSS_IDENT or + * CSS_INHERIT , this attribute contains the string + * representation of the ident, otherwise it contains an empty string. + */ + public String getHorizontalIdentifier(); + + /** + * If verticalType is CSS_IDENT or + * CSS_INHERIT , this attribute contains the string + * representation of the ident, otherwise it contains an empty string. The + * value is "center" if only the horizontalIdentifier has + * been set. + */ + public String getVerticalIdentifier(); + + /** + * This method is used to get the float value in a specified unit if the + * horizontalPosition represents a length or a percentage. If + * the float doesn't contain a float value or can't be converted into the + * specified unit, a DOMException is raised. + * @param hType The horizontal unit. + * @return The float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the property doesn't contain a float + * or the value can't be converted. + */ + public float getHorizontalPosition(float hType) + throws DOMException; + + /** + * This method is used to get the float value in a specified unit if the + * verticalPosition represents a length or a percentage. If + * the float doesn't contain a float value or can't be converted into the + * specified unit, a DOMException is raised. The value is + * 50% if only the horizontal value has been specified. + * @param vType The vertical unit. + * @return The float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the property doesn't contain a float + * or the value can't be converted. + */ + public float getVerticalPosition(float vType) + throws DOMException; + + /** + * This method is used to set the horizontal position with a specified + * unit. If the vertical value is not a percentage or a length, it sets + * the vertical position to 50% . + * @param hType The specified unit (a length or a percentage). + * @param value The new value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the specified unit is not a length or + * a percentage. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setHorizontalPosition(short hType, + float value) + throws DOMException; + + /** + * This method is used to set the vertical position with a specified + * unit. If the horizontal value is not a percentage or a length, it sets + * the vertical position to 50% . + * @param vType The specified unit (a length or a percentage). + * @param value The new value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the specified unit is not a length or + * a percentage. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setVerticalPosition(short vType, + float value) + throws DOMException; + + /** + * Sets the identifiers. If the second identifier is the empty string, + * the vertical identifier is set to its default value ( + * "center" ). + * @param hIdentifier The new horizontal identifier. + * @param vIdentifier The new vertical identifier. + * @exception DOMException + * SYNTAX_ERR: Raised if the identifiers have a syntax error and are + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setPositionIdentifier(String hIdentifier, + String vIdentifier) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2BorderSpacing.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2BorderSpacing.java new file mode 100644 index 000000000..920ebb2b3 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2BorderSpacing.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2BorderSpacing interface represents the border-spacing + * CSS Level 2 property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2BorderSpacing extends CSSValue { + /** + * The A code defining the type of the value as defined in + * CSSValue . It would be one of CSS_EMS , + * CSS_EXS , CSS_PX , CSS_CM , + * CSS_MM , CSS_IN , CSS_PT or + * CSS_PC . + */ + public short getHorizontalType(); + + /** + * The A code defining the type of the value as defined in + * CSSValue . It would be one of CSS_EMS , + * CSS_EXS , CSS_PX , CSS_CM , + * CSS_MM , CSS_IN , CSS_PT , + * CSS_PC or CSS_INHERIT . + */ + public short getVerticalType(); + + /** + * This method is used to get the float value in a specified unit if the + * horizontalSpacing represents a length. If the float + * doesn't contain a float value or can't be converted into the specified + * unit, a DOMException is raised. + * @param hType The horizontal unit. + * @return The float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the property doesn't contain a float + * or the value can't be converted. + */ + public float getHorizontalSpacing(float hType) + throws DOMException; + + /** + * This method is used to get the float value in a specified unit if the + * verticalSpacing represents a length. If the float doesn't + * contain a float value or can't be converted into the specified unit, a + * DOMException is raised. The value is 0 if + * only the horizontal value has been specified. + * @param vType The vertical unit. + * @return The float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the property doesn't contain a float + * or the value can't be converted. + */ + public float getVerticalSpacing(float vType) + throws DOMException; + + /** + * This method is used to set the horizontal spacing with a specified + * unit. If the vertical value is a length, it sets the vertical spacing + * to 0 . + * @param hType The horizontal unit. + * @param value The new value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the specified unit is not a length. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setHorizontalSpacing(short hType, + float value) + throws DOMException; + + /** + * This method is used to set the vertical spacing with a specified unit. + * If the horizontal value is not a length, it sets the vertical spacing + * to 0 . + * @param vType The vertical unit. + * @param value The new value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the specified unit is not a length or + * a percentage. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setVerticalSpacing(short vType, + float value) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2CounterIncrement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2CounterIncrement.java new file mode 100644 index 000000000..f1bd26ba1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2CounterIncrement.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2CounterIncrement interface represents a simple value + * for the counter-increment CSS Level 2 property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2CounterIncrement extends CSSValue { + /** + * The element name. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified identifier has a syntax error + * and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this identifier is + * readonly. + */ + public String getIdentifier(); + public void setIdentifier(String identifier) + throws DOMException; + + /** + * The increment. (Default value is 1.) + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this identifier is readonly. + */ + public short getIncrement(); + public void setIncrement(short increment) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2CounterReset.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2CounterReset.java new file mode 100644 index 000000000..5c665f5da --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2CounterReset.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2CounterReset interface represents a simple value for + * the counter-reset CSS Level 2 property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2CounterReset extends CSSValue { + /** + * The element name. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified identifier has a syntax error + * and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this identifier is + * readonly. + */ + public String getIdentifier(); + public void setIdentifier(String identifier) + throws DOMException; + + /** + * The reset (default value is 0). + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this identifier is readonly. + */ + public short getReset(); + public void setReset(short reset) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Cursor.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Cursor.java new file mode 100644 index 000000000..298565d88 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Cursor.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2Cursor interface represents the cursor CSS Level 2 + * property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2Cursor extends CSSValue { + /** + * uris represents the list of URIs (CSS_URI ) + * on the cursor property. The list can be empty. + */ + public CSSValueList getUris(); + + /** + * This identifier represents a generic cursor name or an empty string. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly. + */ + public String getPredefinedCursor(); + public void setPredefinedCursor(String predefinedCursor) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2FontFaceSrc.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2FontFaceSrc.java new file mode 100644 index 000000000..1385e9357 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2FontFaceSrc.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2FontFaceSrc interface represents the src CSS Level 2 + * descriptor. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2FontFaceSrc extends CSSValue { + /** + * Specifies the source of the font, empty string otherwise. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly. + */ + public String getUri(); + public void setUri(String uri) + throws DOMException; + + /** + * This attribute contains a list of strings for the format CSS function. + */ + public CSSValueList getFormat(); + + /** + * Specifies the full font name of a locally installed font. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly. + */ + public String getFontFaceName(); + public void setFontFaceName(String fontFaceName) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2FontFaceWidths.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2FontFaceWidths.java new file mode 100644 index 000000000..e4ad5e82c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2FontFaceWidths.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2FontFaceWidths interface represents a simple value + * for the widths CSS Level 2 descriptor. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2FontFaceWidths extends CSSValue { + /** + * The range for the characters. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly. + */ + public String getUrange(); + public void setUrange(String urange) + throws DOMException; + + /** + * A list of numbers representing the glyph widths. + */ + public CSSValueList getNumbers(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2PageSize.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2PageSize.java new file mode 100644 index 000000000..d27ec909e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2PageSize.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2PageSize interface represents the size CSS Level 2 + * descriptor. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2PageSize extends CSSValue { + /** + * A code defining the type of the width of the page. It would be one of + * CSS_EMS , CSS_EXS , CSS_PX , + * CSS_CM , CSS_MM , CSS_IN , + * CSS_PT , CSS_PC or CSS_IDENT . + */ + public short getWidthType(); + + /** + * A code defining the type of the height of the page. It would be one of + * CSS_EMS , CSS_EXS , CSS_PX , + * CSS_CM , CSS_MM , CSS_IN , + * CSS_PT , CSS_PC or CSS_IDENT . + * If one of width or height is CSS_IDENT , it's guaranteed + * that the other is the same. + */ + public short getHeightType(); + + /** + * If width is CSS_IDENT , this attribute + * contains the string representation of the ident, otherwise it contains + * an empty string. + */ + public String getIdentifier(); + + /** + * This method is used to get the float value in a specified unit if the + * widthType represents a length. If the float doesn't + * contain a float value or can't be converted into the specified unit, a + * DOMException is raised. + * @param wType The width unit. + * @return The float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the property doesn't contain a float + * or the value can't be converted. + */ + public float getWidth(float wType) + throws DOMException; + + /** + * This method is used to get the float value in a specified unit if the + * heightType represents a length. If the float doesn't + * contain a float value or can't be converted into the specified unit, a + * DOMException is raised. If only the width value has been + * specified, the height value is the same. + * @param hType The height unit. + * @return The float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the property doesn't contain a float + * or the value can't be converted. + */ + public float getHeightSize(float hType) + throws DOMException; + + /** + * This method is used to set the width position with a specified unit. + * If the heightType is not a length, it sets the height + * position to the same value. + * @param wType The width unit. + * @param value The new value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the specified unit is not a length or + * a percentage. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setWidthSize(short wType, + float value) + throws DOMException; + + /** + * This method is used to set the height position with a specified unit. + * If the widthType is not a length, it sets the width + * position to the same value. + * @param hType The height unit. + * @param value The new value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the specified unit is not a length or + * a percentage. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setHeightSize(short hType, + float value) + throws DOMException; + + /** + * Sets the identifier. + * @param ident The new identifier. + * @exception DOMException + * SYNTAX_ERR: Raised if the identifier has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setIdentifier(String ident) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2PlayDuring.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2PlayDuring.java new file mode 100644 index 000000000..4034cc4e5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2PlayDuring.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2PlayDuring interface represents the play-during CSS + * Level 2 property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2PlayDuring extends CSSValue { + /** + * A code defining the type of the value as defined in + * CSSvalue . It would be one of CSS_UNKNOWN or + * CSS_IDENT . + */ + public short getPlayDuringType(); + + /** + * One of "inherit" , "auto" , + * "none" or the empty string if the + * playDuringType is CSS_UNKNOWN . On setting, + * it will set the uri to the empty string and + * mix and repeat to false . + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly. + */ + public String getPlayDuringIdentifier(); + public void setPlayDuringIdentifier(String playDuringIdentifier) + throws DOMException; + + /** + * The sound specified by the uri . It will set the + * playDuringType attribute to CSS_UNKNOWN . + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly. + */ + public String getUri(); + public void setUri(String uri) + throws DOMException; + + /** + * true if the sound should be mixed. It will be ignored if + * the attribute doesn't contain a uri . + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is readonly. + */ + public boolean getMix(); + public void setMix(boolean mix) + throws DOMException; + + /** + * true if the sound should be repeated. It will be ignored + * if the attribute doesn't contain a uri . + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is readonly. + */ + public boolean getRepeat(); + public void setRepeat(boolean repeat) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Properties.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Properties.java new file mode 100644 index 000000000..a1195adc0 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2Properties.java @@ -0,0 +1,1533 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSS2Properties interface represents a convenience + * mechanism for retrieving and setting properties within a + * CSSStyleDeclaration . The attributes of this interface + * correspond to all the properties specified in CSS2 . Getting an attribute + * of this interface is equivalent to calling the + * getPropertyValue method of the + * CSSStyleDeclaration interface. Setting an attribute of this + * interface is equivalent to calling the setProperty method of + * the CSSStyleDeclaration interface. + *

      A compliant implementation is not required to implement the + * CSS2Properties interface. If an implementation does implement + * this interface, the expectation is that language-specific methods can be + * used to cast from an instance of the CSSStyleDeclaration + * interface to the CSS2Properties interface. + *

      If an implementation does implement this interface, it is expected to + * understand the specific syntax of the shorthand properties, and apply + * their semantics; when the margin property is set, for + * example, the marginTop , marginRight , + * marginBottom and marginLeft properties are + * actually being set by the underlying implementation. + *

      When dealing with CSS "shorthand" properties, the shorthand properties + * should be decomposed into their component longhand properties as + * appropriate, and when querying for their value, the form returned should + * be the shortest form exactly equivalent to the declarations made in the + * ruleset. However, if there is no shorthand declaration that could be + * added to the ruleset without changing in any way the rules already + * declared in the ruleset (i.e., by adding longhand rules that were + * previously not declared in the ruleset), then the empty string should be + * returned for the shorthand property. + *

      For example, querying for the font property should not + * return "normal normal normal 14pt/normal Arial, sans-serif", when "14pt + * Arial, sans-serif" suffices. (The normals are initial values, and are + * implied by use of the longhand property.) + *

      If the values for all the longhand properties that compose a particular + * string are the initial values, then a string consisting of all the initial + * values should be returned (e.g. a border-width value of + * "medium" should be returned as such, not as ""). + *

      For some shorthand properties that take missing values from other + * sides, such as the margin , padding , and + * border-[width|style|color] properties, the minimum number of + * sides possible should be used; i.e., "0px 10px" will be returned instead + * of "0px 10px 0px 10px". + *

      If the value of a shorthand property can not be decomposed into its + * component longhand properties, as is the case for the font + * property with a value of "menu", querying for the values of the component + * longhand properties should return the empty string. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2Properties { + /** + * See the azimuth property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getAzimuth(); + public void setAzimuth(String azimuth) + throws DOMException; + + /** + * See the background property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBackground(); + public void setBackground(String background) + throws DOMException; + + /** + * See the background-attachment property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBackgroundAttachment(); + public void setBackgroundAttachment(String backgroundAttachment) + throws DOMException; + + /** + * See the background-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBackgroundColor(); + public void setBackgroundColor(String backgroundColor) + throws DOMException; + + /** + * See the background-image property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBackgroundImage(); + public void setBackgroundImage(String backgroundImage) + throws DOMException; + + /** + * See the background-position property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBackgroundPosition(); + public void setBackgroundPosition(String backgroundPosition) + throws DOMException; + + /** + * See the background-repeat property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBackgroundRepeat(); + public void setBackgroundRepeat(String backgroundRepeat) + throws DOMException; + + /** + * See the border property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorder(); + public void setBorder(String border) + throws DOMException; + + /** + * See the border-collapse property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderCollapse(); + public void setBorderCollapse(String borderCollapse) + throws DOMException; + + /** + * See the border-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderColor(); + public void setBorderColor(String borderColor) + throws DOMException; + + /** + * See the border-spacing property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderSpacing(); + public void setBorderSpacing(String borderSpacing) + throws DOMException; + + /** + * See the border-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderStyle(); + public void setBorderStyle(String borderStyle) + throws DOMException; + + /** + * See the border-top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderTop(); + public void setBorderTop(String borderTop) + throws DOMException; + + /** + * See the border-right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderRight(); + public void setBorderRight(String borderRight) + throws DOMException; + + /** + * See the border-bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderBottom(); + public void setBorderBottom(String borderBottom) + throws DOMException; + + /** + * See the border-left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderLeft(); + public void setBorderLeft(String borderLeft) + throws DOMException; + + /** + * See the border-top-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderTopColor(); + public void setBorderTopColor(String borderTopColor) + throws DOMException; + + /** + * See the border-right-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderRightColor(); + public void setBorderRightColor(String borderRightColor) + throws DOMException; + + /** + * See the border-bottom-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderBottomColor(); + public void setBorderBottomColor(String borderBottomColor) + throws DOMException; + + /** + * See the border-left-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderLeftColor(); + public void setBorderLeftColor(String borderLeftColor) + throws DOMException; + + /** + * See the border-top-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderTopStyle(); + public void setBorderTopStyle(String borderTopStyle) + throws DOMException; + + /** + * See the border-right-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderRightStyle(); + public void setBorderRightStyle(String borderRightStyle) + throws DOMException; + + /** + * See the border-bottom-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderBottomStyle(); + public void setBorderBottomStyle(String borderBottomStyle) + throws DOMException; + + /** + * See the border-left-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderLeftStyle(); + public void setBorderLeftStyle(String borderLeftStyle) + throws DOMException; + + /** + * See the border-top-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderTopWidth(); + public void setBorderTopWidth(String borderTopWidth) + throws DOMException; + + /** + * See the border-right-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderRightWidth(); + public void setBorderRightWidth(String borderRightWidth) + throws DOMException; + + /** + * See the border-bottom-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderBottomWidth(); + public void setBorderBottomWidth(String borderBottomWidth) + throws DOMException; + + /** + * See the border-left-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderLeftWidth(); + public void setBorderLeftWidth(String borderLeftWidth) + throws DOMException; + + /** + * See the border-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBorderWidth(); + public void setBorderWidth(String borderWidth) + throws DOMException; + + /** + * See the bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getBottom(); + public void setBottom(String bottom) + throws DOMException; + + /** + * See the caption-side property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCaptionSide(); + public void setCaptionSide(String captionSide) + throws DOMException; + + /** + * See the clear property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getClear(); + public void setClear(String clear) + throws DOMException; + + /** + * See the clip property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getClip(); + public void setClip(String clip) + throws DOMException; + + /** + * See the color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getColor(); + public void setColor(String color) + throws DOMException; + + /** + * See the content property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getContent(); + public void setContent(String content) + throws DOMException; + + /** + * See the counter-increment property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCounterIncrement(); + public void setCounterIncrement(String counterIncrement) + throws DOMException; + + /** + * See the counter-reset property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCounterReset(); + public void setCounterReset(String counterReset) + throws DOMException; + + /** + * See the cue property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCue(); + public void setCue(String cue) + throws DOMException; + + /** + * See the cue-after property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCueAfter(); + public void setCueAfter(String cueAfter) + throws DOMException; + + /** + * See the cue-before property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCueBefore(); + public void setCueBefore(String cueBefore) + throws DOMException; + + /** + * See the cursor property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCursor(); + public void setCursor(String cursor) + throws DOMException; + + /** + * See the direction property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getDirection(); + public void setDirection(String direction) + throws DOMException; + + /** + * See the display property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getDisplay(); + public void setDisplay(String display) + throws DOMException; + + /** + * See the elevation property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getElevation(); + public void setElevation(String elevation) + throws DOMException; + + /** + * See the empty-cells property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getEmptyCells(); + public void setEmptyCells(String emptyCells) + throws DOMException; + + /** + * See the float property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getCssFloat(); + public void setCssFloat(String cssFloat) + throws DOMException; + + /** + * See the font property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFont(); + public void setFont(String font) + throws DOMException; + + /** + * See the font-family property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFontFamily(); + public void setFontFamily(String fontFamily) + throws DOMException; + + /** + * See the font-size property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFontSize(); + public void setFontSize(String fontSize) + throws DOMException; + + /** + * See the font-size-adjust property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFontSizeAdjust(); + public void setFontSizeAdjust(String fontSizeAdjust) + throws DOMException; + + /** + * See the font-stretch property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFontStretch(); + public void setFontStretch(String fontStretch) + throws DOMException; + + /** + * See the font-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFontStyle(); + public void setFontStyle(String fontStyle) + throws DOMException; + + /** + * See the font-variant property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFontVariant(); + public void setFontVariant(String fontVariant) + throws DOMException; + + /** + * See the font-weight property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getFontWeight(); + public void setFontWeight(String fontWeight) + throws DOMException; + + /** + * See the height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getHeight(); + public void setHeight(String height) + throws DOMException; + + /** + * See the left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getLeft(); + public void setLeft(String left) + throws DOMException; + + /** + * See the letter-spacing property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getLetterSpacing(); + public void setLetterSpacing(String letterSpacing) + throws DOMException; + + /** + * See the line-height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getLineHeight(); + public void setLineHeight(String lineHeight) + throws DOMException; + + /** + * See the list-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getListStyle(); + public void setListStyle(String listStyle) + throws DOMException; + + /** + * See the list-style-image property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getListStyleImage(); + public void setListStyleImage(String listStyleImage) + throws DOMException; + + /** + * See the list-style-position property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getListStylePosition(); + public void setListStylePosition(String listStylePosition) + throws DOMException; + + /** + * See the list-style-type property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getListStyleType(); + public void setListStyleType(String listStyleType) + throws DOMException; + + /** + * See the margin property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMargin(); + public void setMargin(String margin) + throws DOMException; + + /** + * See the margin-top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMarginTop(); + public void setMarginTop(String marginTop) + throws DOMException; + + /** + * See the margin-right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMarginRight(); + public void setMarginRight(String marginRight) + throws DOMException; + + /** + * See the margin-bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMarginBottom(); + public void setMarginBottom(String marginBottom) + throws DOMException; + + /** + * See the margin-left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMarginLeft(); + public void setMarginLeft(String marginLeft) + throws DOMException; + + /** + * See the marker-offset property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMarkerOffset(); + public void setMarkerOffset(String markerOffset) + throws DOMException; + + /** + * See the marks property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMarks(); + public void setMarks(String marks) + throws DOMException; + + /** + * See the max-height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMaxHeight(); + public void setMaxHeight(String maxHeight) + throws DOMException; + + /** + * See the max-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMaxWidth(); + public void setMaxWidth(String maxWidth) + throws DOMException; + + /** + * See the min-height property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMinHeight(); + public void setMinHeight(String minHeight) + throws DOMException; + + /** + * See the min-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getMinWidth(); + public void setMinWidth(String minWidth) + throws DOMException; + + /** + * See the orphans property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getOrphans(); + public void setOrphans(String orphans) + throws DOMException; + + /** + * See the outline property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getOutline(); + public void setOutline(String outline) + throws DOMException; + + /** + * See the outline-color property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getOutlineColor(); + public void setOutlineColor(String outlineColor) + throws DOMException; + + /** + * See the outline-style property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getOutlineStyle(); + public void setOutlineStyle(String outlineStyle) + throws DOMException; + + /** + * See the outline-width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getOutlineWidth(); + public void setOutlineWidth(String outlineWidth) + throws DOMException; + + /** + * See the overflow property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getOverflow(); + public void setOverflow(String overflow) + throws DOMException; + + /** + * See the padding property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPadding(); + public void setPadding(String padding) + throws DOMException; + + /** + * See the padding-top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPaddingTop(); + public void setPaddingTop(String paddingTop) + throws DOMException; + + /** + * See the padding-right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPaddingRight(); + public void setPaddingRight(String paddingRight) + throws DOMException; + + /** + * See the padding-bottom property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPaddingBottom(); + public void setPaddingBottom(String paddingBottom) + throws DOMException; + + /** + * See the padding-left property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPaddingLeft(); + public void setPaddingLeft(String paddingLeft) + throws DOMException; + + /** + * See the page property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPage(); + public void setPage(String page) + throws DOMException; + + /** + * See the page-break-after property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPageBreakAfter(); + public void setPageBreakAfter(String pageBreakAfter) + throws DOMException; + + /** + * See the page-break-before property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPageBreakBefore(); + public void setPageBreakBefore(String pageBreakBefore) + throws DOMException; + + /** + * See the page-break-inside property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPageBreakInside(); + public void setPageBreakInside(String pageBreakInside) + throws DOMException; + + /** + * See the pause property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPause(); + public void setPause(String pause) + throws DOMException; + + /** + * See the pause-after property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPauseAfter(); + public void setPauseAfter(String pauseAfter) + throws DOMException; + + /** + * See the pause-before property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPauseBefore(); + public void setPauseBefore(String pauseBefore) + throws DOMException; + + /** + * See the pitch property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPitch(); + public void setPitch(String pitch) + throws DOMException; + + /** + * See the pitch-range property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPitchRange(); + public void setPitchRange(String pitchRange) + throws DOMException; + + /** + * See the play-during property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPlayDuring(); + public void setPlayDuring(String playDuring) + throws DOMException; + + /** + * See the position property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getPosition(); + public void setPosition(String position) + throws DOMException; + + /** + * See the quotes property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getQuotes(); + public void setQuotes(String quotes) + throws DOMException; + + /** + * See the richness property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getRichness(); + public void setRichness(String richness) + throws DOMException; + + /** + * See the right property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getRight(); + public void setRight(String right) + throws DOMException; + + /** + * See the size property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getSize(); + public void setSize(String size) + throws DOMException; + + /** + * See the speak property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getSpeak(); + public void setSpeak(String speak) + throws DOMException; + + /** + * See the speak-header property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getSpeakHeader(); + public void setSpeakHeader(String speakHeader) + throws DOMException; + + /** + * See the speak-numeral property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getSpeakNumeral(); + public void setSpeakNumeral(String speakNumeral) + throws DOMException; + + /** + * See the speak-punctuation property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getSpeakPunctuation(); + public void setSpeakPunctuation(String speakPunctuation) + throws DOMException; + + /** + * See the speech-rate property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getSpeechRate(); + public void setSpeechRate(String speechRate) + throws DOMException; + + /** + * See the stress property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getStress(); + public void setStress(String stress) + throws DOMException; + + /** + * See the table-layout property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getTableLayout(); + public void setTableLayout(String tableLayout) + throws DOMException; + + /** + * See the text-align property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getTextAlign(); + public void setTextAlign(String textAlign) + throws DOMException; + + /** + * See the text-decoration property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getTextDecoration(); + public void setTextDecoration(String textDecoration) + throws DOMException; + + /** + * See the text-indent property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getTextIndent(); + public void setTextIndent(String textIndent) + throws DOMException; + + /** + * See the text-shadow property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getTextShadow(); + public void setTextShadow(String textShadow) + throws DOMException; + + /** + * See the text-transform property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getTextTransform(); + public void setTextTransform(String textTransform) + throws DOMException; + + /** + * See the top property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getTop(); + public void setTop(String top) + throws DOMException; + + /** + * See the unicode-bidi property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getUnicodeBidi(); + public void setUnicodeBidi(String unicodeBidi) + throws DOMException; + + /** + * See the vertical-align property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getVerticalAlign(); + public void setVerticalAlign(String verticalAlign) + throws DOMException; + + /** + * See the visibility property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getVisibility(); + public void setVisibility(String visibility) + throws DOMException; + + /** + * See the voice-family property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getVoiceFamily(); + public void setVoiceFamily(String voiceFamily) + throws DOMException; + + /** + * See the volume property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getVolume(); + public void setVolume(String volume) + throws DOMException; + + /** + * See the white-space property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getWhiteSpace(); + public void setWhiteSpace(String whiteSpace) + throws DOMException; + + /** + * See the widows property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getWidows(); + public void setWidows(String widows) + throws DOMException; + + /** + * See the width property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getWidth(); + public void setWidth(String width) + throws DOMException; + + /** + * See the word-spacing property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getWordSpacing(); + public void setWordSpacing(String wordSpacing) + throws DOMException; + + /** + * See the z-index property definition in CSS2. + * @exception DOMException + * SYNTAX_ERR: Raised if the new value has a syntax error and is + * unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public String getZIndex(); + public void setZIndex(String zIndex) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2TextShadow.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2TextShadow.java new file mode 100644 index 000000000..fd17ef9cd --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSS2TextShadow.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The CSS2TextShadow interface represents a simple value for + * the text-shadow CSS Level 2 property. + *

      For this extension of the CSSValue interface, the + * valueType attribute of the underlying CSSValue + * interface shall be CSS_CUSTOM . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSS2TextShadow extends CSSValue { + /** + * Specifies the color of the text shadow. The CSS Value can contain an + * empty string if no color has been specified. + */ + public CSSValue getColor(); + + /** + * The horizontal position of the text shadow. 0 if no + * length has been specified. + */ + public CSSValue getHorizontal(); + + /** + * The vertical position of the text shadow. 0 if no length + * has been specified. + */ + public CSSValue getVertical(); + + /** + * The blur radius of the text shadow. 0 if no length has + * been specified. + */ + public CSSValue getBlur(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSCharsetRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSCharsetRule.java new file mode 100644 index 000000000..5012a9a73 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSCharsetRule.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSSCharsetRule interface represents a @charset rule in a + * CSS style sheet. The value of the encoding attribute does not + * affect the encoding of text data in the DOM objects; this encoding is + * always UTF-16. After a stylesheet is loaded, the value of the + * encoding attribute is the value found in the + * @charset rule. If there was no @charset in the + * original document, then no CSSCharsetRule is created. The + * value of the encoding attribute may also be used as a hint + * for the encoding used on serialization of the style sheet. + *

      The value of the @charset rule (and therefore of the + * CSSCharsetRule ) may not correspond to the encoding the + * document actually came in; character encoding information e.g. in an HTTP + * header, has priority (see CSS document representation ) but this is not + * reflected in the CSSCharsetRule . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSCharsetRule extends CSSRule { + /** + * The encoding information used in this @charset rule. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified encoding value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this encoding rule is + * readonly. + */ + public String getEncoding(); + public void setEncoding(String encoding) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSFontFaceRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSFontFaceRule.java new file mode 100644 index 000000000..13e0a3dc8 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSFontFaceRule.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The CSSFontFaceRule interface represents a @font-face rule + * in a CSS style sheet. The @font-face rule is used to hold a + * set of font descriptions. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSFontFaceRule extends CSSRule { + /** + * The declaration-block of this rule. + */ + public CSSStyleDeclaration getStyle(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSImportRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSImportRule.java new file mode 100644 index 000000000..6471f7757 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSImportRule.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.stylesheets.MediaList; + +/** + * The CSSImportRule interface represents a @import rule within + * a CSS style sheet. The @import rule is used to import style + * rules from other style sheets. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSImportRule extends CSSRule { + /** + * The location of the style sheet to be imported. The attribute will not + * contain the "url(...)" specifier around the URI. + */ + public String getHref(); + + /** + * A list of media types for which this style sheet may be used. + */ + public MediaList getMedia(); + + /** + * The style sheet referred to by this rule, if it has been loaded. The + * value of this attribute is null if the style sheet has not + * yet been loaded or if it will not be loaded (e.g. if the style sheet + * is for a media type not supported by the user agent). + */ + public CSSStyleSheet getStyleSheet(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSMediaRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSMediaRule.java new file mode 100644 index 000000000..7591243be --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSMediaRule.java @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; +import org.w3c.dom.stylesheets.MediaList; + +/** + * The CSSMediaRule interface represents a @media rule in a CSS + * style sheet. A @media rule can be used to delimit style rules + * for specific media types. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSMediaRule extends CSSRule { + /** + * A list of media types for this rule. + */ + public MediaList getMedia(); + + /** + * A list of all CSS rules contained within the media block. + */ + public CSSRuleList getCssRules(); + + /** + * Used to insert a new rule into the media block. + * @param rule The parsable text representing the rule. For rule sets + * this contains both the selector and the style declaration. For + * at-rules, this specifies both the at-identifier and the rule content. + * + * @param index The index within the media block's rule collection of the + * rule before which to insert the specified rule. If the specified + * index is equal to the length of the media blocks's rule collection, + * the rule will be added to the end of the media block. + * @return The index within the media block's rule collection of the newly + * inserted rule. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the + * specified index, e.g., if an @import rule is inserted + * after a standard rule set or other at-rule. + *
      INDEX_SIZE_ERR: Raised if the specified index is not a valid + * insertion point. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this media rule is + * readonly. + *
      SYNTAX_ERR: Raised if the specified rule has a syntax error + * and is unparsable. + */ + public int insertRule(String rule, + int index) + throws DOMException; + + /** + * Used to delete a rule from the media block. + * @param index The index within the media block's rule collection of the + * rule to remove. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index does not correspond + * to a rule in the media rule list. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this media rule is + * readonly. + */ + public void deleteRule(int index) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSPageRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSPageRule.java new file mode 100644 index 000000000..a43da3bdb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSPageRule.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSSPageRule interface represents a @page rule within a + * CSS style sheet. The @page rule is used to specify the + * dimensions, orientation, margins, etc. of a page box for paged media. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSPageRule extends CSSRule { + /** + * The parsable textual representation of the page selector for the rule. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this rule is readonly. + */ + public String getSelectorText(); + public void setSelectorText(String selectorText) + throws DOMException; + + /** + * The declaration-block of this rule. + */ + public CSSStyleDeclaration getStyle(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSPrimitiveValue.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSPrimitiveValue.java new file mode 100644 index 000000000..7b14261d6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSPrimitiveValue.java @@ -0,0 +1,195 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSSPrimitiveValue interface represents a single CSS value + * . This interface may be used to determine the value of a specific style + * property currently set in a block or to set a specific style property + * explicitly within the block. An instance of this interface might be + * obtained from the getPropertyCSSValue method of the + * CSSStyleDeclaration interface. A + * CSSPrimitiveValue object only occurs in a context of a CSS + * property. + *

      Conversions are allowed between absolute values (from millimeters to + * centimeters, from degrees to radians, and so on) but not between relative + * values. (For example, a pixel value cannot be converted to a centimeter + * value.) Percentage values can't be converted since they are relative to + * the parent value (or another property value). There is one exception for + * color percentage values: since a color percentage value is relative to the + * range 0-255, a color percentage value can be converted to a number; (see + * also the RGBColor interface). + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSPrimitiveValue extends CSSValue { + // UnitTypes + public static final short CSS_UNKNOWN = 0; + public static final short CSS_NUMBER = 1; + public static final short CSS_PERCENTAGE = 2; + public static final short CSS_EMS = 3; + public static final short CSS_EXS = 4; + public static final short CSS_PX = 5; + public static final short CSS_CM = 6; + public static final short CSS_MM = 7; + public static final short CSS_IN = 8; + public static final short CSS_PT = 9; + public static final short CSS_PC = 10; + public static final short CSS_DEG = 11; + public static final short CSS_RAD = 12; + public static final short CSS_GRAD = 13; + public static final short CSS_MS = 14; + public static final short CSS_S = 15; + public static final short CSS_HZ = 16; + public static final short CSS_KHZ = 17; + public static final short CSS_DIMENSION = 18; + public static final short CSS_STRING = 19; + public static final short CSS_URI = 20; + public static final short CSS_IDENT = 21; + public static final short CSS_ATTR = 22; + public static final short CSS_COUNTER = 23; + public static final short CSS_RECT = 24; + public static final short CSS_RGBCOLOR = 25; + + /** + * The type of the value as defined by the constants specified above. + */ + public short getPrimitiveType(); + + /** + * A method to set the float value with a specified unit. If the property + * attached with this value can not accept the specified unit or the float + * value, the value will be unchanged and a DOMException + * will be raised. + * @param unitType A unit code as defined above. The unit code can only + * be a float unit type (i.e. CSS_NUMBER , + * CSS_PERCENTAGE , CSS_EMS , + * CSS_EXS , CSS_PX , CSS_CM , + * CSS_MM , CSS_IN , CSS_PT , + * CSS_PC , CSS_DEG , CSS_RAD , + * CSS_GRAD , CSS_MS , CSS_S , + * CSS_HZ , CSS_KHZ , + * CSS_DIMENSION ). + * @param floatValue The new float value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the attached property doesn't support + * the float value or the unit type. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setFloatValue(short unitType, + float floatValue) + throws DOMException; + + /** + * This method is used to get a float value in a specified unit. If this + * CSS value doesn't contain a float value or can't be converted into the + * specified unit, a DOMException is raised. + * @param unitType A unit code to get the float value. The unit code can + * only be a float unit type (i.e. CSS_NUMBER , + * CSS_PERCENTAGE , CSS_EMS , + * CSS_EXS , CSS_PX , CSS_CM , + * CSS_MM , CSS_IN , CSS_PT , + * CSS_PC , CSS_DEG , CSS_RAD , + * CSS_GRAD , CSS_MS , CSS_S , + * CSS_HZ , CSS_KHZ , + * CSS_DIMENSION ). + * @return The float value in the specified unit. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a float + * value or if the float value can't be converted into the specified + * unit. + */ + public float getFloatValue(short unitType) + throws DOMException; + + /** + * A method to set the string value with the specified unit. If the + * property attached to this value can't accept the specified unit or the + * string value, the value will be unchanged and a + * DOMException will be raised. + * @param stringType A string code as defined above. The string code can + * only be a string unit type (i.e. CSS_STRING , + * CSS_URI , CSS_IDENT , and + * CSS_ATTR ). + * @param stringValue The new string value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a string + * value or if the string value can't be converted into the specified + * unit. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this property is + * readonly. + */ + public void setStringValue(short stringType, + String stringValue) + throws DOMException; + + /** + * This method is used to get the string value. If the CSS value doesn't + * contain a string value, a DOMException is raised. Some + * properties (like 'font-family' or 'voice-family' ) convert a + * whitespace separated list of idents to a string. + * @return The string value in the current unit. The current + * primitiveType can only be a string unit type (i.e. + * CSS_STRING , CSS_URI , + * CSS_IDENT and CSS_ATTR ). + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a string + * value. + */ + public String getStringValue() + throws DOMException; + + /** + * This method is used to get the Counter value. If this CSS value doesn't + * contain a counter value, a DOMException is raised. + * Modification to the corresponding style property can be achieved using + * the Counter interface. + * @return The Counter value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a + * Counter value (e.g. this is not CSS_COUNTER ). + */ + public Counter getCounterValue() + throws DOMException; + + /** + * This method is used to get the Rect value. If this CSS value doesn't + * contain a rect value, a DOMException is raised. + * Modification to the corresponding style property can be achieved using + * the Rect interface. + * @return The Rect value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the CSS value doesn't contain a Rect + * value. (e.g. this is not CSS_RECT ). + */ + public Rect getRectValue() + throws DOMException; + + /** + * This method is used to get the RGB color. If this CSS value doesn't + * contain a RGB color value, a DOMException is raised. + * Modification to the corresponding style property can be achieved using + * the RGBColor interface. + * @return the RGB color value. + * @exception DOMException + * INVALID_ACCESS_ERR: Raised if the attached property can't return a + * RGB color value (e.g. this is not CSS_RGBCOLOR ). + */ + public RGBColor getRGBColorValue() + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSRule.java new file mode 100644 index 000000000..89ed6b6d1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSRule.java @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSSRule interface is the abstract base interface for any + * type of CSS statement . This includes both rule sets and at-rules . An + * implementation is expected to preserve all rules specified in a CSS style + * sheet, even if the rule is not recognized by the parser. Unrecognized + * rules are represented using the CSSUnknownRule interface. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSRule { + // RuleType + public static final short UNKNOWN_RULE = 0; + public static final short STYLE_RULE = 1; + public static final short CHARSET_RULE = 2; + public static final short IMPORT_RULE = 3; + public static final short MEDIA_RULE = 4; + public static final short FONT_FACE_RULE = 5; + public static final short PAGE_RULE = 6; + + /** + * The type of the rule, as defined above. The expectation is that + * binding-specific casting methods can be used to cast down from an + * instance of the CSSRule interface to the specific derived + * interface implied by the type . + */ + public short getType(); + + /** + * The parsable textual representation of the rule. This reflects the + * current state of the rule and not its initial value. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      INVALID_MODIFICATION_ERR: Raised if the specified CSS string + * value represents a different type of rule than the current one. + *
      HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at + * this point in the style sheet. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if the rule is readonly. + */ + public String getCssText(); + public void setCssText(String cssText) + throws DOMException; + + /** + * The style sheet that contains this rule. + */ + public CSSStyleSheet getParentStyleSheet(); + + /** + * If this rule is contained inside another rule (e.g. a style rule inside + * an @media block), this is the containing rule. If this rule is not + * nested inside any other rules, this returns null . + */ + public CSSRule getParentRule(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSRuleList.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSRuleList.java new file mode 100644 index 000000000..b6ce8e032 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSRuleList.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The CSSRuleList interface provides the abstraction of an + * ordered collection of CSS rules. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSRuleList { + /** + * The number of CSSRules in the list. The range of valid + * child rule indices is 0 to length-1 + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve a CSS rule by ordinal index. The order in this + * collection represents the order of the rules in the CSS style sheet. + * @param index Index into the collection + * @return The style rule at the index position in the + * CSSRuleList , or null if that is not a + * valid index. + */ + public CSSRule item(int index); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleDeclaration.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleDeclaration.java new file mode 100644 index 000000000..2a6e537da --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleDeclaration.java @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSSStyleDeclaration interface represents a single CSS + * declaration block . This interface may be used to determine the style + * properties currently set in a block or to set style properties explicitly + * within the block. + *

      While an implementation may not recognize all CSS properties within a + * CSS declaration block, it is expected to provide access to all specified + * properties in the style sheet through the CSSStyleDeclaration + * interface. Furthermore, implementations that support a specific level of + * CSS should correctly handle CSS shorthand properties for that level. For + * a further discussion of shorthand properties, see the + * CSS2Properties interface. + *

      This interface is also used to provide a read-only access to the + * computed values of an element. See also the ViewCSS interface. + * The CSS Object Model doesn't provide an access to the specified or + * actual values of the CSS cascade. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSStyleDeclaration { + /** + * The parsable textual representation of the declaration block (excluding + * the surrounding curly braces). Setting this attribute will result in + * the parsing of the new value and resetting of the properties in the + * declaration block. It also allows the insertion of additional + * properties and their values into the block. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly or a property is readonly. + */ + public String getCssText(); + public void setCssText(String cssText) + throws DOMException; + + /** + * Used to retrieve the value of a CSS property if it has been explicitly + * set within this declaration block. + * @param propertyName The name of the CSS property. See the CSS + * property index . + * @return Returns the value of the property if it has been explicitly set + * for this declaration block. Returns the empty string if the property + * has not been set. + */ + public String getPropertyValue(String propertyName); + + /** + * Used to retrieve the object representation of the value of a CSS + * property if it has been explicitly set within this declaration block. + * This method returns null if the property is a shorthand + * property. Shorthand property values can only be accessed and modified + * as strings, using the getPropertyValue and + * setProperty methods. + * @param propertyName The name of the CSS property. See the CSS + * property index . + * @return Returns the value of the property if it has been explicitly + * set for this declaration block. Returns null if the + * property has not been set. + */ + public CSSValue getPropertyCSSValue(String propertyName); + + /** + * Used to remove a CSS property if it has been explicitly set within + * this declaration block. + * @param propertyName The name of the CSS property. See the CSS + * property index . + * @return Returns the value of the property if it has been explicitly set + * for this declaration block. Returns the empty string if the property + * has not been set or the property name does not correspond to a + * known CSS property. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is readonly + * or the property is readonly. + */ + public String removeProperty(String propertyName) + throws DOMException; + + /** + * Used to retrieve the priority of a CSS property (e.g. the + * "important" qualifier) if the property has been + * explicitly set in this declaration block. + * @param propertyName The name of the CSS property. See the CSS property + * index . + * @return A string representing the priority (e.g. + * "important" ) if one exists. The empty string if none + * exists. + */ + public String getPropertyPriority(String propertyName); + + /** + * Used to set a property value and priority within this declaration + * block. + * @param propertyName The name of the CSS property. See the CSS + * property index . + * @param value The new value of the property. + * @param priority The new priority of the property (e.g. + * "important" ). + * @exception DOMException + * SYNTAX_ERR: Raised if the specified value has a syntax error and + * is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this declaration is + * readonly or the property is readonly. + */ + public void setProperty(String propertyName, + String value, + String priority) + throws DOMException; + + /** + * The number of properties that have been explicitly set in this + * declaration block. The range of valid indices is 0 to length-1 + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve the properties that have been explicitly set in this + * declaration block. The order of the properties retrieved using this + * method does not have to be the order in which they were set. This + * method can be used to iterate over all properties in this declaration + * block. + * @param index Index of the property name to retrieve. + * @return The name of the property at this ordinal position. The empty + * string if no property exists at this position. + */ + public String item(int index); + + /** + * The CSS rule that contains this declaration block or null + * if this CSSStyleDeclaration is not attached to a + * CSSRule . + */ + public CSSRule getParentRule(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleRule.java new file mode 100644 index 000000000..c6c6d7288 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleRule.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSSStyleRule interface represents a single rule set in a + * CSS style sheet. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSStyleRule extends CSSRule { + /** + * The textual representation of the selector for the rule set. The + * implementation may have stripped out insignificant whitespace while + * parsing the selector. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this rule is readonly. + */ + public String getSelectorText(); + public void setSelectorText(String selectorText) + throws DOMException; + + /** + * The declaration-block of this rule set. + */ + public CSSStyleDeclaration getStyle(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleSheet.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleSheet.java new file mode 100644 index 000000000..3626a96c5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSStyleSheet.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; +import org.w3c.dom.stylesheets.StyleSheet; + +/** + * The CSSStyleSheet interface is a concrete interface used to + * represent a CSS style sheet i.e., a style sheet whose content type is + * "text/css". + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSStyleSheet extends StyleSheet { + /** + * If this style sheet comes from an @import rule, the + * ownerRule attribute will contain the + * CSSImportRule . In that case, the ownerNode + * attribute in the StyleSheet interface will be + * null . If the style sheet comes from an element or a + * processing instruction, the ownerRule attribute will be + * null and the ownerNode attribute will + * contain the Node . + */ + public CSSRule getOwnerRule(); + + /** + * The list of all CSS rules contained within the style sheet. This + * includes both rule sets and at-rules . + */ + public CSSRuleList getCssRules(); + + /** + * Used to insert a new rule into the style sheet. The new rule now + * becomes part of the cascade. + * @param rule The parsable text representing the rule. For rule sets + * this contains both the selector and the style declaration. For + * at-rules, this specifies both the at-identifier and the rule content. + * + * @param index The index within the style sheet's rule list of the rule + * before which to insert the specified rule. If the specified index + * is equal to the length of the style sheet's rule collection, the + * rule will be added to the end of the style sheet. + * @return The index within the style sheet's rule collection of the newly + * inserted rule. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if the rule cannot be inserted at the + * specified index e.g. if an @import rule is inserted + * after a standard rule set or other at-rule. + *
      INDEX_SIZE_ERR: Raised if the specified index is not a valid + * insertion point. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this style sheet is + * readonly. + *
      SYNTAX_ERR: Raised if the specified rule has a syntax error + * and is unparsable. + */ + public int insertRule(String rule, + int index) + throws DOMException; + + /** + * Used to delete a rule from the style sheet. + * @param index The index within the style sheet's rule list of the rule + * to remove. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index does not correspond + * to a rule in the style sheet's rule list. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this style sheet is + * readonly. + */ + public void deleteRule(int index) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSUnknownRule.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSUnknownRule.java new file mode 100644 index 000000000..7a460883e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSUnknownRule.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The CSSUnknownRule interface represents an at-rule not + * supported by this user agent. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSUnknownRule extends CSSRule { +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSValue.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSValue.java new file mode 100644 index 000000000..e429f3309 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSValue.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMException; + +/** + * The CSSValue interface represents a simple or a complex + * value. A CSSValue object only occurs in a context of a CSS + * property. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSValue { + // UnitTypes + public static final short CSS_INHERIT = 0; + public static final short CSS_PRIMITIVE_VALUE = 1; + public static final short CSS_VALUE_LIST = 2; + public static final short CSS_CUSTOM = 3; + + /** + * A string representation of the current value. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified CSS string value has a syntax + * error (according to the attached property) or is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this value is readonly. + */ + public String getCssText(); + public void setCssText(String cssText) + throws DOMException; + + /** + * A code defining the type of the value as defined above. + */ + public short getValueType(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSValueList.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSValueList.java new file mode 100644 index 000000000..287e7a87d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/CSSValueList.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The CSSValueList interface provides the abstraction of an + * ordered collection of CSS values. + *

      Some properties allow an empty list into their syntax. In that case, + * these properties take the none identifier. So, an empty list + * means that the property has the value none . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface CSSValueList extends CSSValue { + /** + * The number of CSSValues in the list. The range of valid + * values of the indices is 0 to length-1 + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve a CSS rule by ordinal index. The order in this + * collection represents the order of the values in the CSS style + * property. + * @param index Index into the collection. + * @return The style rule at the index position in the + * CSSValueList , or null if that is not a + * valid index. + */ + public CSSValue item(int index); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/Counter.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/Counter.java new file mode 100644 index 000000000..c5cde0157 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/Counter.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The Counter interface is used to represent any counter or + * counters function value. This interface reflects the values in the + * underlying style property. Hence, modifications made to the + * DOMString objects modify the style property. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface Counter { + /** + * This attribute is used for the identifier of the counter. + */ + public String getIdentifier(); + + /** + * This attribute is used for the style of the list. + */ + public String getListStyle(); + + /** + * This attribute is used for the separator of the nested counters. + */ + public String getSeparator(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/DOMImplementationCSS.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/DOMImplementationCSS.java new file mode 100644 index 000000000..779d7ab8d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/DOMImplementationCSS.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.DOMImplementation; + +/** + * This interface allows the DOM user to create a CSSStyleSheet + * outside the context of a document. There is no way to associate the new + * CSSStyleSheet with a document in DOM Level 2. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface DOMImplementationCSS extends DOMImplementation { + /** + * Creates a new CSSStyleSheet . + * @param title The advisory title. See also the section. + * @param media The comma-separated list of media associated with the new + * style sheet. See also the section. + * @return A new CSS style sheet. + */ + public CSSStyleSheet createCSSStyleSheet(String title, + String media); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/DocumentCSS.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/DocumentCSS.java new file mode 100644 index 000000000..4b956e14e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/DocumentCSS.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.Element; +import org.w3c.dom.stylesheets.DocumentStyle; + +/** + * This interface represents a document with a CSS view. + *

      The getOverrideStyle method provides a mechanism through + * which a DOM author could effect immediate change to the style of an + * element without modifying the explicitly linked style sheets of a document + * or the inline style of elements in the style sheets. This style sheet + * comes after the author style sheet in the cascade algorithm and is called + * override style sheet . The override style sheet takes precedence over + * author style sheets. An "!important" declaration still takes precedence + * over a normal declaration. Override, author, and user style sheets all may + * contain "!important" declarations. User "!important" rules take precedence + * over both override and author "!important" rules, and override + * "!important" rules take precedence over author "!important" rules. + *

      The expectation is that an instance of the DocumentCSS + * interface can be obtained by using binding-specific casting methods on an + * instance of the Document interface. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface DocumentCSS extends DocumentStyle { + /** + * This method is used to retrieve the override style declaration for a + * specified element and a specified pseudo-element. + * @param elt The element whose style is to be modified. This parameter + * cannot be null. + * @param pseudoElt The pseudo-element or null if none. + * @return The override style declaration. + */ + public CSSStyleDeclaration getOverrideStyle(Element elt, + String pseudoElt); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/ElementCSSInlineStyle.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/ElementCSSInlineStyle.java new file mode 100644 index 000000000..e0c8990bc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/ElementCSSInlineStyle.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * Inline style information attached to elements is exposed through the + * style attribute. This represents the contents of the STYLE + * attribute for HTML elements (or elements in other schemas or DTDs which + * use the STYLE attribute in the same way). The expectation is that an + * instance of the ElementCSSInlineStyle interface can be obtained by using + * binding-specific casting methods on an instance of the Element interface + * when the element supports inline CSS style informations. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface ElementCSSInlineStyle { + /** + * The style attribute. + */ + public CSSStyleDeclaration getStyle(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/RGBColor.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/RGBColor.java new file mode 100644 index 000000000..5dbfe2b3b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/RGBColor.java @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The RGBColor interface is used to represent any RGB color + * value. This interface reflects the values in the underlying style + * property. Hence, modifications made to the CSSPrimitiveValue + * objects modify the style property. + *

      A specified RGB color is not clipped (even if the number is outside the + * range 0-255 or 0%-100%). A computed RGB color is clipped depending on the + * device. + *

      Even if a style sheet can only contain an integer for a color value, the + * internal storage of this integer is a float, and this can be used as a + * float in the specified or the computed style. + *

      A color percentage value can always be converted to a number and vice + * versa. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface RGBColor { + /** + * This attribute is used for the red value of the RGB color. + */ + public CSSPrimitiveValue getRed(); + + /** + * This attribute is used for the green value of the RGB color. + */ + public CSSPrimitiveValue getGreen(); + + /** + * This attribute is used for the blue value of the RGB color. + */ + public CSSPrimitiveValue getBlue(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/Rect.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/Rect.java new file mode 100644 index 000000000..f79570dd9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/Rect.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +/** + * The Rect interface is used to represent any rect value. This + * interface reflects the values in the underlying style property. Hence, + * modifications made to the CSSPrimitiveValue objects modify + * the style property. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface Rect { + /** + * This attribute is used for the top of the rect. + */ + public CSSPrimitiveValue getTop(); + + /** + * This attribute is used for the right of the rect. + */ + public CSSPrimitiveValue getRight(); + + /** + * This attribute is used for the bottom of the rect. + */ + public CSSPrimitiveValue getBottom(); + + /** + * This attribute is used for the left of the rect. + */ + public CSSPrimitiveValue getLeft(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/ViewCSS.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/ViewCSS.java new file mode 100644 index 000000000..3e7d8556c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/css/ViewCSS.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.css; + +import org.w3c.dom.Element; +import org.w3c.dom.views.AbstractView; + +/** + * This interface represents a CSS view. The getComputedStyle + * method provides a read only access to the computed values of an element. + *

      The expectation is that an instance of the ViewCSS + * interface can be obtained by using binding-specific casting methods on an + * instance of the View interface. + *

      Since a computed style is related to an Element node, if + * this element is removed from the document, the associated + * CSSStyleDeclaration and CSSValue related to this + * declaration are no longer valid. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface ViewCSS extends AbstractView { + /** + * This method is used to get the computed style as it is defined in . + * @param elt The element whose style is to be computed. This parameter + * cannot be null. + * @param pseudoElt The pseudo-element or null if none. + * @return The computed style. The CSSStyleDeclaration is + * read-only and contains only absolute values. + */ + public CSSStyleDeclaration getComputedStyle(Element elt, + String pseudoElt); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/DocumentEvent.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/DocumentEvent.java new file mode 100644 index 000000000..bdb1f2553 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/DocumentEvent.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.DOMException; + +/** + * The DocumentEvent interface provides a mechanism by which the + * user can create an Event of a type supported by the implementation. It is + * expected that the DocumentEvent interface will be implemented + * on the same object which implements the Document interface in + * an implementation which supports the Event model. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface DocumentEvent { + /** + * + * @param eventType The eventType parameter specifies the + * type of Event interface to be created. If the + * Event interface specified is supported by the + * implementation this method will return a new Event of + * the interface type requested. If the Event is to be + * dispatched via the dispatchEvent method the + * appropriate event init method must be called after creation in order + * to initialize the Event 's values. As an example, a + * user wishing to synthesize some kind of UIEvent would + * call createEvent with the parameter "UIEvents". The + * initUIEvent method could then be called on the newly + * created UIEvent to set the specific type of UIEvent to + * be dispatched and set its context information. The + * createEvent method is used in creating + * Event s when it is either inconvenient or unnecessary + * for the user to create an Event themselves. In cases + * where the implementation provided Event is + * insufficient, users may supply their own Event + * implementations for use with the dispatchEvent method. + * @return The newly created Event + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the implementation does not support + * the type of Event interface requested + */ + public Event createEvent(String eventType) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/Event.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/Event.java new file mode 100644 index 000000000..60520dcbd --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/Event.java @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +/** + * The Event interface is used to provide contextual information + * about an event to the handler processing the event. An object which + * implements the Event interface is generally passed as the + * first parameter to an event handler. More specific context information + * is passed to event handlers by deriving additional interfaces from + * Event which contain information directly relating to the type + * of event they accompany. These derived interfaces are also implemented by + * the object passed to the event listener. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface Event { + // PhaseType + public static final short CAPTURING_PHASE = 1; + public static final short AT_TARGET = 2; + public static final short BUBBLING_PHASE = 3; + + /** + * The name of the event (case-insensitive). The name must be an XML name + * . + */ + public String getType(); + + /** + * Used to indicate the EventTarget to which the event was + * originally dispatched. + */ + public EventTarget getTarget(); + + /** + * Used to indicate the EventTarget whose + * EventListeners are currently being processed. This is + * particularly useful during capturing and bubbling. + */ + public EventTarget getCurrentTarget(); + + /** + * Used to indicate which phase of event flow is currently being + * evaluated. + */ + public short getEventPhase(); + + /** + * Used to indicate whether or not an event is a bubbling event. If the + * event can bubble the value is true, else the value is false. + */ + public boolean getBubbles(); + + /** + * Used to indicate whether or not an event can have its default action + * prevented. If the default action can be prevented the value is true, + * else the value is false. + */ + public boolean getCancelable(); + + /** + * Used to specify the time (in milliseconds relative to the epoch) at + * which the event was created. Due to the fact that some systems may not + * provide this information the value of timeStamp may be + * not available for all events. When not available, a value of 0 will be + * returned. Examples of epoch time are the time of the system start or + * 0:0:0 UTC 1st January 1970. + */ + public long getTimeStamp(); + + /** + * The stopPropagation method is used prevent further + * propagation of an event during event flow. If this method is called by + * any EventListener the event will cease propagating + * through the tree. The event will complete dispatch to all listeners + * on the current EventTarget before event flow stops. This + * method may be used during any stage of event flow. + */ + public void stopPropagation(); + + /** + * If an event is cancelable, the preventDefault method is + * used to signify that the event is to be canceled, meaning any default + * action normally taken by the implementation as a result of the event + * will not occur. If, during any stage of event flow, the + * preventDefault method is called the event is canceled. + * Any default action associated with the event will not occur. Calling + * this method for a non-cancelable event has no effect. Once + * preventDefault has been called it will remain in effect + * throughout the remainder of the event's propagation. This method may + * be used during any stage of event flow. + */ + public void preventDefault(); + + /** + * The initEvent method is used to initialize the value of + * an Event created through the DocumentEvent + * interface. This method may only be called before the + * Event has been dispatched via the + * dispatchEvent method, though it may be called multiple + * times during that phase if necessary. If called multiple times the + * final invocation takes precedence. If called from a subclass of + * Event interface only the values specified in the + * initEvent method are modified, all other attributes are + * left unchanged. + * @param eventTypeArg Specifies the event type. This type may be any + * event type currently defined in this specification or a new event + * type.. The string must be an XML name . Any new event type must + * not begin with any upper, lower, or mixed case version of the + * string "DOM". This prefix is reserved for future DOM event sets. + * It is also strongly recommended that third parties adding their own + * events use their own prefix to avoid confusion and lessen the + * probability of conflicts with other new events. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + */ + public void initEvent(String eventTypeArg, + boolean canBubbleArg, + boolean cancelableArg); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventException.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventException.java new file mode 100644 index 000000000..d570df875 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventException.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +/** + * Event operations may throw an EventException as specified in + * their method descriptions. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public class EventException extends RuntimeException { + public EventException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // EventExceptionCode + public static final short UNSPECIFIED_EVENT_TYPE_ERR = 0; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventListener.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventListener.java new file mode 100644 index 000000000..d79854c3c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventListener.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +/** + * The EventListener interface is the primary method for + * handling events. Users implement the EventListener interface + * and register their listener on an EventTarget using the + * AddEventListener method. The users should also remove their + * EventListener from its EventTarget after they + * have completed using the listener. + *

      When a Node is copied using the cloneNode + * method the EventListener s attached to the source + * Node are not attached to the copied Node . If + * the user wishes the same EventListener s to be added to the + * newly created copy the user must add them manually. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface EventListener { + /** + * This method is called whenever an event occurs of the type for which + * the EventListener interface was registered. + * @param evt The Event contains contextual information + * about the event. It also contains the stopPropagation + * and preventDefault methods which are used in + * determining the event's flow and default action. + */ + public void handleEvent(Event evt); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventTarget.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventTarget.java new file mode 100644 index 000000000..d8b4047d5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/EventTarget.java @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +/** + * The EventTarget interface is implemented by all + * Nodes in an implementation which supports the DOM Event + * Model. The interface allows registration and removal of + * EventListeners on an EventTarget and dispatch of + * events to that EventTarget . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface EventTarget { + /** + * This method allows the registration of event listeners on the event + * target. If an EventListener is added to an + * EventTarget while it is processing an event, it will not + * be triggered by the current actions but may be triggered during a + * later stage of event flow, such as the bubbling phase. + *
      If multiple identical EventListener s are registered + * on the same EventTarget with the same parameters the + * duplicate instances are discarded. They do not cause the + * EventListener to be called twice and since they are + * discarded they do not need to be removed with the + * removeEventListener method. + * @param type The event type for which the user is registering + * @param listener The listener parameter takes an interface + * implemented by the user which contains the methods to be called when + * the event occurs. + * @param useCapture If true, useCapture indicates that the + * user wishes to initiate capture. After initiating capture, all + * events of the specified type will be dispatched to the registered + * EventListener before being dispatched to any + * EventTargets beneath them in the tree. Events which + * are bubbling upward through the tree will not trigger an + * EventListener designated to use capture. + */ + public void addEventListener(String type, + EventListener listener, + boolean useCapture); + + /** + * This method allows the removal of event listeners from the event + * target. If an EventListener is removed from an + * EventTarget while it is processing an event, it will not + * be triggered by the current actions. EventListener s can + * never be invoked after being removed. + *
      Calling removeEventListener with arguments which do + * not identify any currently registered EventListener on + * the EventTarget has no effect. + * @param type Specifies the event type of the EventListener + * being removed. + * @param listener The EventListener parameter indicates the + * EventListener to be removed. + * @param useCapture Specifies whether the EventListener + * being removed was registered as a capturing listener or not. If a + * listener was registered twice, one with capture and one without, + * each must be removed separately. Removal of a capturing listener + * does not affect a non-capturing version of the same listener, and + * vice versa. + */ + public void removeEventListener(String type, + EventListener listener, + boolean useCapture); + + /** + * This method allows the dispatch of events into the implementations + * event model. Events dispatched in this manner will have the same + * capturing and bubbling behavior as events dispatched directly by the + * implementation. The target of the event is the + * EventTarget on which dispatchEvent is called. + * + * @param evt Specifies the event type, behavior, and contextual + * information to be used in processing the event. + * @return The return value of dispatchEvent indicates + * whether any of the listeners which handled the event called + * preventDefault . If preventDefault was + * called the value is false, else the value is true. + * @exception EventException + * UNSPECIFIED_EVENT_TYPE_ERR: Raised if the Event 's + * type was not specified by initializing the event before + * dispatchEvent was called. Specification of the + * Event 's type as null or an empty string + * will also trigger this exception. + */ + public boolean dispatchEvent(Event evt) + throws EventException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/MouseEvent.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/MouseEvent.java new file mode 100644 index 000000000..ff90603fa --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/MouseEvent.java @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.views.AbstractView; + +/** + * The MouseEvent interface provides specific contextual + * information associated with Mouse events. + *

      The detail attribute inherited from UIEvent + * indicates the number of times a mouse button has been pressed and released + * over the same screen location during a user action. The attribute value + * is 1 when the user begins this action and increments by 1 for each full + * sequence of pressing and releasing. If the user moves the mouse between + * the mousedown and mouseup the value will be set to 0, indicating that no + * click is occurring. + *

      In the case of nested elements mouse events are always targeted at the + * most deeply nested element. Ancestors of the targeted element may use + * bubbling to obtain notification of mouse events which occur within its + * descendent elements. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface MouseEvent extends UIEvent { + /** + * The horizontal coordinate at which the event occurred relative to the + * origin of the screen coordinate system. + */ + public int getScreenX(); + + /** + * The vertical coordinate at which the event occurred relative to the + * origin of the screen coordinate system. + */ + public int getScreenY(); + + /** + * The horizontal coordinate at which the event occurred relative to the + * DOM implementation's client area. + */ + public int getClientX(); + + /** + * The vertical coordinate at which the event occurred relative to the + * DOM implementation's client area. + */ + public int getClientY(); + + /** + * Used to indicate whether the 'ctrl' key was depressed during the + * firing of the event. + */ + public boolean getCtrlKey(); + + /** + * Used to indicate whether the 'shift' key was depressed during the + * firing of the event. + */ + public boolean getShiftKey(); + + /** + * Used to indicate whether the 'alt' key was depressed during the firing + * of the event. On some platforms this key may map to an alternative key + * name. + */ + public boolean getAltKey(); + + /** + * Used to indicate whether the 'meta' key was depressed during the + * firing of the event. On some platforms this key may map to an + * alternative key name. + */ + public boolean getMetaKey(); + + /** + * During mouse events caused by the depression or release of a mouse + * button, button is used to indicate which mouse button + * changed state. The values for button range from zero to + * indicate the left button of the mouse, one to indicate the middle + * button if present, and two to indicate the right button. For mice + * configured for left handed use in which the button actions are + * reversed the values are instead read from right to left. + */ + public short getButton(); + + /** + * Used to identify a secondary EventTarget related to a UI + * event. Currently this attribute is used with the mouseover event to + * indicate the EventTarget which the pointing device exited + * and with the mouseout event to indicate the EventTarget + * which the pointing device entered. + */ + public EventTarget getRelatedTarget(); + + /** + * The initMouseEvent method is used to initialize the value + * of a MouseEvent created through the + * DocumentEvent interface. This method may only be called + * before the MouseEvent has been dispatched via the + * dispatchEvent method, though it may be called multiple + * times during that phase if necessary. If called multiple times, the + * final invocation takes precedence. + * @param typeArg Specifies the event type. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + * @param viewArg Specifies the Event 's + * AbstractView . + * @param detailArg Specifies the Event 's mouse click count. + * @param screenXArg Specifies the Event 's screen x + * coordinate + * @param screenYArg Specifies the Event 's screen y + * coordinate + * @param clientXArg Specifies the Event 's client x + * coordinate + * @param clientYArg Specifies the Event 's client y + * coordinate + * @param ctrlKeyArg Specifies whether or not control key was depressed + * during the Event . + * @param altKeyArg Specifies whether or not alt key was depressed during + * the Event . + * @param shiftKeyArg Specifies whether or not shift key was depressed + * during the Event . + * @param metaKeyArg Specifies whether or not meta key was depressed + * during the Event . + * @param buttonArg Specifies the Event 's mouse button. + * @param relatedTargetArg Specifies the Event 's related + * EventTarget . + */ + public void initMouseEvent(String typeArg, + boolean canBubbleArg, + boolean cancelableArg, + AbstractView viewArg, + int detailArg, + int screenXArg, + int screenYArg, + int clientXArg, + int clientYArg, + boolean ctrlKeyArg, + boolean altKeyArg, + boolean shiftKeyArg, + boolean metaKeyArg, + short buttonArg, + EventTarget relatedTargetArg); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/MutationEvent.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/MutationEvent.java new file mode 100644 index 000000000..c15f7413c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/MutationEvent.java @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.Node; + +/** + * The MutationEvent interface provides specific contextual + * information associated with Mutation events. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface MutationEvent extends Event { + + public static final short ADDITION = 2; + public static final short MODIFICATION = 1; + public static final short REMOVAL = 3; + + /** + * relatedNode is used to identify a secondary node related + * to a mutation event. For example, if a mutation event is dispatched to + * a node indicating that its parent has changed, the + * relatedNode is the changed parent. If an event is instead + * dispatch to a subtree indicating a node was changed within it, the + * relatedNode is the changed node. + */ + public Node getRelatedNode(); + + /** + * prevValue indicates the previous value of the + * Attr node in DOMAttrModified events, and of the + * CharacterData node in DOMCharDataModified events. + */ + public String getPrevValue(); + + /** + * newValue indicates the new value of the Attr + * node in DOMAttrModified events, and of the CharacterData + * node in DOMCharDataModified events. + */ + public String getNewValue(); + + /** + * attrName indicates the name of the changed + * Attr node in a DOMAttrModified event. + */ + public String getAttrName(); + + /** + * The initMutationEvent method is used to initialize the + * value of a MutationEvent created through the + * DocumentEvent interface. This method may only be called + * before the MutationEvent has been dispatched via the + * dispatchEvent method, though it may be called multiple + * times during that phase if necessary. If called multiple times, the + * final invocation takes precedence. + * @param typeArg Specifies the event type. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + * @param relatedNodeArg Specifies the Event 's related Node + * @param prevValueArg Specifies the Event 's + * prevValue attribute + * @param newValueArg Specifies the Event 's + * newValue attribute + * @param attrNameArg Specifies the Event 's + * attrName attribute + */ + public void initMutationEvent(String typeArg, + boolean canBubbleArg, + boolean cancelableArg, + Node relatedNodeArg, + String prevValueArg, + String newValueArg, + String attrNameArg); + + public void initMutationEvent(String typeArg, + boolean canBubbleArg, + boolean cancelableArg, + Node relatedNodeArg, + String prevValueArg, + String newValueArg, + String attrNameArg, + short unkonwnParam); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/UIEvent.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/UIEvent.java new file mode 100644 index 000000000..6b0f3aa73 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/events/UIEvent.java @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.events; + +import org.w3c.dom.views.AbstractView; + +/** + * The UIEvent interface provides specific contextual + * information associated with User Interface events. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface UIEvent extends Event { + /** + * The view attribute identifies the + * AbstractView from which the event was generated. + */ + public AbstractView getView(); + + /** + * Specifies some detail information about the Event , + * depending on the type of event. + */ + public int getDetail(); + + /** + * The initUIEvent method is used to initialize the value of + * a UIEvent created through the DocumentEvent + * interface. This method may only be called before the + * UIEvent has been dispatched via the + * dispatchEvent method, though it may be called multiple + * times during that phase if necessary. If called multiple times, the + * final invocation takes precedence. + * @param typeArg Specifies the event type. + * @param canBubbleArg Specifies whether or not the event can bubble. + * @param cancelableArg Specifies whether or not the event's default + * action can be prevented. + * @param viewArg Specifies the Event 's + * AbstractView . + * @param detailArg Specifies the Event 's detail. + */ + public void initUIEvent(String typeArg, + boolean canBubbleArg, + boolean cancelableArg, + AbstractView viewArg, + int detailArg); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAnchorElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAnchorElement.java new file mode 100644 index 000000000..b086cb7f1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAnchorElement.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * The anchor element. See the A element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLAnchorElement extends HTMLElement { + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.0. + */ + public String getAccessKey(); + public void setAccessKey(String accessKey); + + /** + * The character encoding of the linked resource. See the charset + * attribute definition in HTML 4.0. + */ + public String getCharset(); + public void setCharset(String charset); + + /** + * Comma-separated list of lengths, defining an active region geometry. + * See also shape for the shape of the region. See the + * coords attribute definition in HTML 4.0. + */ + public String getCoords(); + public void setCoords(String coords); + + /** + * The URI of the linked resource. See the href attribute definition in + * HTML 4.0. + */ + public String getHref(); + public void setHref(String href); + + /** + * Language code of the linked resource. See the hreflang attribute + * definition in HTML 4.0. + */ + public String getHreflang(); + public void setHreflang(String hreflang); + + /** + * Anchor name. See the name attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Forward link type. See the rel attribute definition in HTML 4.0. + */ + public String getRel(); + public void setRel(String rel); + + /** + * Reverse link type. See the rev attribute definition in HTML 4.0. + */ + public String getRev(); + public void setRev(String rev); + + /** + * The shape of the active area. The coordinates are given by + * coords . See the shape attribute definition in HTML 4.0. + */ + public String getShape(); + public void setShape(String shape); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.0. + */ + public int getTabIndex(); + public void setTabIndex(int tabIndex); + + /** + * Frame to render the resource in. See the target attribute definition + * in HTML 4.0. + */ + public String getTarget(); + public void setTarget(String target); + + /** + * Advisory content type. See the type attribute definition in HTML 4.0. + */ + public String getType(); + public void setType(String type); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAppletElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAppletElement.java new file mode 100644 index 000000000..2e32bd6b9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAppletElement.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * An embedded Java applet. See the APPLET element definition in HTML 4.0. + * This element is deprecated in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLAppletElement extends HTMLElement { + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Alternate text for user agents not rendering the normal content of + * this element. See the alt attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getAlt(); + public void setAlt(String alt); + + /** + * Comma-separated archive list. See the archive attribute definition in + * HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getArchive(); + public void setArchive(String archive); + + /** + * Applet class file. See the code attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getCode(); + public void setCode(String code); + + /** + * Optional base URI for applet. See the codebase attribute definition + * in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getCodeBase(); + public void setCodeBase(String codeBase); + + /** + * Override height. See the height attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getHeight(); + public void setHeight(String height); + + /** + * Horizontal space to the left and right of this image, applet, or + * object. See the hspace attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getHspace(); + public void setHspace(String hspace); + + /** + * The name of the applet. See the name attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Serialized applet file. See the object attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getObject(); + public void setObject(String object); + + /** + * Vertical space above and below this image, applet, or object. See the + * vspace attribute definition in HTML 4.0. This attribute is deprecated + * in HTML 4.0. + */ + public String getVspace(); + public void setVspace(String vspace); + + /** + * Override width. See the width attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAreaElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAreaElement.java new file mode 100644 index 000000000..bbb244825 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLAreaElement.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Client-side image map area definition. See the AREA element definition in + * HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLAreaElement extends HTMLElement { + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.0. + */ + public String getAccessKey(); + public void setAccessKey(String accessKey); + + /** + * Alternate text for user agents not rendering the normal content of + * this element. See the alt attribute definition in HTML 4.0. + */ + public String getAlt(); + public void setAlt(String alt); + + /** + * Comma-separated list of lengths, defining an active region geometry. + * See also shape for the shape of the region. See the + * coords attribute definition in HTML 4.0. + */ + public String getCoords(); + public void setCoords(String coords); + + /** + * The URI of the linked resource. See the href attribute definition in + * HTML 4.0. + */ + public String getHref(); + public void setHref(String href); + + /** + * Specifies that this area is inactive, i.e., has no associated action. + * See the nohref attribute definition in HTML 4.0. + */ + public boolean getNoHref(); + public void setNoHref(boolean noHref); + + /** + * The shape of the active area. The coordinates are given by + * coords . See the shape attribute definition in HTML 4.0. + */ + public String getShape(); + public void setShape(String shape); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.0. + */ + public int getTabIndex(); + public void setTabIndex(int tabIndex); + + /** + * Frame to render the resource in. See the target attribute definition + * in HTML 4.0. + */ + public String getTarget(); + public void setTarget(String target); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBRElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBRElement.java new file mode 100644 index 000000000..12eba4e69 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBRElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Force a line break. See the BR element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLBRElement extends HTMLElement { + /** + * Control flow of text around floats. See the clear attribute definition + * in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getClear(); + public void setClear(String clear); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBaseElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBaseElement.java new file mode 100644 index 000000000..c976632e1 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBaseElement.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Document base URI. See the BASE element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLBaseElement extends HTMLElement { + /** + * The base URI. See the href attribute definition in HTML 4.0. + */ + public String getHref(); + public void setHref(String href); + + /** + * The default target frame. See the target attribute definition in HTML + * 4.0. + */ + public String getTarget(); + public void setTarget(String target); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBaseFontElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBaseFontElement.java new file mode 100644 index 000000000..ba6a9f989 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBaseFontElement.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Base font. See the BASEFONT element definition in HTML 4.0. This element + * is deprecated in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLBaseFontElement extends HTMLElement { + /** + * Font color. See the color attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getColor(); + public void setColor(String color); + + /** + * Font face identifier. See the face attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getFace(); + public void setFace(String face); + + /** + * Font size. See the size attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getSize(); + public void setSize(String size); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBlockquoteElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBlockquoteElement.java new file mode 100644 index 000000000..083b0ea2c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBlockquoteElement.java @@ -0,0 +1,16 @@ +package org.w3c.dom.html; + +import org.w3c.dom.*; + +/** + * ??? See the BLOCKQUOTE element definition in HTML 4.0. + */ +public interface HTMLBlockquoteElement extends HTMLElement { + /** + * A URI designating a document that describes the reason forthe change. See + * the cite attribute definition in HTML 4.0. + */ + public String getCite(); + public void setCite(String cite); +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBodyElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBodyElement.java new file mode 100644 index 000000000..fd780b5b2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLBodyElement.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * The HTML document body. This element is always present in the DOM API, + * even if the tags are not present in the source document. See the BODY + * element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLBodyElement extends HTMLElement { + /** + * Color of active links (after mouse-button down, but before + * mouse-button up). See the alink attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getALink(); + public void setALink(String aLink); + + /** + * URI of the background texture tile image. See the background + * attribute definition in HTML 4.0. This attribute is deprecated in HTML + * 4.0. + */ + public String getBackground(); + public void setBackground(String background); + + /** + * Document background color. See the bgcolor attribute definition in + * HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getBgColor(); + public void setBgColor(String bgColor); + + /** + * Color of links that are not active and unvisited. See the link + * attribute definition in HTML 4.0. This attribute is deprecated in HTML + * 4.0. + */ + public String getLink(); + public void setLink(String link); + + /** + * Document text color. See the text attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getText(); + public void setText(String text); + + /** + * Color of links that have been visited by the user. See the vlink + * attribute definition in HTML 4.0. This attribute is deprecated in HTML + * 4.0. + */ + public String getVLink(); + public void setVLink(String vLink); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLButtonElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLButtonElement.java new file mode 100644 index 000000000..4696cfaa9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLButtonElement.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Push button. See the BUTTON element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLButtonElement extends HTMLElement { + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.0. + */ + public String getAccessKey(); + public void setAccessKey(String accessKey); + + /** + * The control is unavailable in this context. See the disabled + * attribute definition in HTML 4.0. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.0. + */ + public int getTabIndex(); + public void setTabIndex(int tabIndex); + + /** + * The type of button. See the type attribute definition in HTML 4.0. + */ + public String getType(); + + /** + * The current form control value. See the value attribute definition in + * HTML 4.0. + */ + public String getValue(); + public void setValue(String value); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLCollection.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLCollection.java new file mode 100644 index 000000000..8fd54f68c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLCollection.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.Node; + +/** + * An HTMLCollection is a list of nodes. An individual node may + * be accessed by either ordinal index or the node'sname or + * id attributes. Note: Collections in the HTML DOM are assumed + * to be live meaning that they are automatically updated when the + * underlying document is changed. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLCollection { + /** + * This attribute specifies the length or size of the list. + */ + public int getLength(); + + /** + * This method retrieves a node specified by ordinal index. Nodes are + * numbered in tree order (depth-first traversal order). + * @param index The index of the node to be fetched. The index origin is + * 0. + * @return The Node at the corresponding position upon + * success. A value of null is returned if the index is + * out of range. + */ + public Node item(int index); + + /** + * This method retrieves a Node using a name. It first + * searches for a Node with a matching id + * attribute. If it doesn't find one, it then searches for a + * Node with a matching name attribute, but + * only on those elements that are allowed a name attribute. + * @param name The name of the Node to be fetched. + * @return The Node with a name or + * id attribute whose value corresponds to the specified + * string. Upon failure (e.g., no node with this name exists), returns + * null . + */ + public Node namedItem(String name); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDListElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDListElement.java new file mode 100644 index 000000000..0d4bbeb29 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDListElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Definition list. See the DL element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLDListElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute + * definition in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public boolean getCompact(); + public void setCompact(boolean compact); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDOMImplementation.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDOMImplementation.java new file mode 100644 index 000000000..98284078e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDOMImplementation.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.DOMImplementation; + +/** + * The HTMLDOMImplementation interface extends the + * DOMImplementation interface with a method for creating an + * HTML document instance. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface HTMLDOMImplementation extends DOMImplementation { + /** + * Creates an HTMLDocument object with the minimal tree made + * of the following elements: HTML , HEAD , + * TITLE , and BODY . + * @param title The title of the document to be set as the content of the + * TITLE element, through a child Text node. + * @return A new HTMLDocument object. + */ + public HTMLDocument createHTMLDocument(String title); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDirectoryElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDirectoryElement.java new file mode 100644 index 000000000..7c9de1019 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDirectoryElement.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Directory list. See the DIR element definition in HTML 4.0. This element + * is deprecated in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLDirectoryElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute + * definition in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public boolean getCompact(); + public void setCompact(boolean compact); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDivElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDivElement.java new file mode 100644 index 000000000..239a3ad85 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDivElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Generic block container. See the DIV element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLDivElement extends HTMLElement { + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDocument.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDocument.java new file mode 100644 index 000000000..23c3099d6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLDocument.java @@ -0,0 +1,155 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.Document; +import org.w3c.dom.NodeList; + +/** + * An HTMLDocument is the root of the HTML hierarchy and holds + * the entire content. Besides providing access to the hierarchy, it also + * provides some convenience methods for accessing certain sets of + * information from the document. + *

      The following properties have been deprecated in favor of the + * corresponding ones for the BODY element: alinkColor background + * bgColor fgColor linkColor vlinkColor In DOM Level 2, the method + * getElementById is inherited from the Document + * interface where it was moved. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLDocument extends Document { + /** + * The title of a document as specified by the TITLE element + * in the head of the document. + */ + public String getTitle(); + public void setTitle(String title); + + /** + * Returns the URI of the page that linked to this page. The value is an + * empty string if the user navigated to the page directly (not through a + * link, but, for example, via a bookmark). + */ + public String getReferrer(); + + /** + * The domain name of the server that served the document, or + * null if the server cannot be identified by a domain name. + */ + public String getDomain(); + + /** + * The complete URI of the document. + */ + public String getURL(); + + /** + * The element that contains the content for the document. In documents + * with BODY contents, returns the BODY + * element. In frameset documents, this returns the outermost + * FRAMESET element. + */ + public HTMLElement getBody(); + public void setBody(HTMLElement body); + + /** + * A collection of all the IMG elements in a document. The + * behavior is limited to IMG elements for backwards + * compatibility. + */ + public HTMLCollection getImages(); + + /** + * A collection of all the OBJECT elements that include + * applets and APPLET ( deprecated ) elements in a document. + */ + public HTMLCollection getApplets(); + + /** + * A collection of all AREA elements and anchor ( + * A ) elements in a document with a value for the + * href attribute. + */ + public HTMLCollection getLinks(); + + /** + * A collection of all the forms of a document. + */ + public HTMLCollection getForms(); + + /** + * A collection of all the anchor (A ) elements in a document + * with a value for the name attribute. Note. For reasons + * of backwards compatibility, the returned set of anchors only contains + * those anchors created with the name attribute, not those + * created with the id attribute. + */ + public HTMLCollection getAnchors(); + + /** + * The cookies associated with this document. If there are none, the + * value is an empty string. Otherwise, the value is a string: a + * semicolon-delimited list of "name, value" pairs for all the cookies + * associated with the page. For example, + * name=value;expires=date . + */ + public String getCookie(); + public void setCookie(String cookie); + + /** + * Note. This method and the ones following allow a user to add to or + * replace the structure model of a document using strings of unparsed + * HTML. At the time of writing alternate methods for providing similar + * functionality for both HTML and XML documents were being considered. + * The following methods may be deprecated at some point in the future in + * favor of a more general-purpose mechanism. + *
      Open a document stream for writing. If a document exists in the + * target, this method clears it. + */ + public void open(); + + /** + * Closes a document stream opened by open() and forces + * rendering. + */ + public void close(); + + /** + * Write a string of text to a document stream opened by + * open() . The text is parsed into the document's structure + * model. + * @param text The string to be parsed into some structure in the + * document structure model. + */ + public void write(String text); + + /** + * Write a string of text followed by a newline character to a document + * stream opened by open() . The text is parsed into the + * document's structure model. + * @param text The string to be parsed into some structure in the + * document structure model. + */ + public void writeln(String text); + + /** + * Returns the (possibly empty) collection of elements whose + * name value is given by elementName . + * @param elementName The name attribute value for an + * element. + * @return The matching elements. + */ + public NodeList getElementsByName(String elementName); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLElement.java new file mode 100644 index 000000000..73ac6d4cb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLElement.java @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.Element; + +/** + * All HTML element interfaces derive from this class. Elements that only + * expose the HTML core attributes are represented by the base + * HTMLElement interface. These elements are as follows: HEAD + * special: SUB, SUP, SPAN, BDO font: TT, I, B, U, S, STRIKE, BIG, SMALL + * phrase: EM, STRONG, DFN, CODE, SAMP, KBD, VAR, CITE, ACRONYM, ABBR list: + * DD, DT NOFRAMES, NOSCRIPT ADDRESS, CENTER The style attribute + * of an HTML element is accessible through the + * ElementCSSInlineStyle interface which is defined in the . + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLElement extends Element { + /** + * The element's identifier. See the id attribute definition in HTML 4.0. + */ + public String getId(); + public void setId(String id); + + /** + * The element's advisory title. See the title attribute definition in + * HTML 4.0. + */ + public String getTitle(); + public void setTitle(String title); + + /** + * Language code defined in RFC 1766. See the lang attribute definition + * in HTML 4.0. + */ + public String getLang(); + public void setLang(String lang); + + /** + * Specifies the base direction of directionally neutral text and the + * directionality of tables. See the dir attribute definition in HTML + * 4.0. + */ + public String getDir(); + public void setDir(String dir); + + /** + * The class attribute of the element. This attribute has been renamed + * due to conflicts with the "class" keyword exposed by many languages. + * See the class attribute definition in HTML 4.0. + */ + public String getClassName(); + public void setClassName(String className); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFieldSetElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFieldSetElement.java new file mode 100644 index 000000000..0abea21db --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFieldSetElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Organizes form controls into logical groups. See the FIELDSET element + * definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLFieldSetElement extends HTMLElement { + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFontElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFontElement.java new file mode 100644 index 000000000..052020baf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFontElement.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Local change to font. See the FONT element definition in HTML 4.0. This + * element is deprecated in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLFontElement extends HTMLElement { + /** + * Font color. See the color attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getColor(); + public void setColor(String color); + + /** + * Font face identifier. See the face attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getFace(); + public void setFace(String face); + + /** + * Font size. See the size attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getSize(); + public void setSize(String size); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFormElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFormElement.java new file mode 100644 index 000000000..2a74fb328 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFormElement.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * The FORM element encompasses behavior similar to a collection + * and an element. It provides direct access to the contained input elements + * as well as the attributes of the form element. See the FORM element + * definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLFormElement extends HTMLElement { + /** + * Returns a collection of all control elements in the form. + */ + public HTMLCollection getElements(); + + /** + * The number of form controls in the form. + */ + public int getLength(); + + /** + * Names the form. + */ + public String getName(); + public void setName(String name); + + /** + * List of character sets supported by the server. See the + * accept-charset attribute definition in HTML 4.0. + */ + public String getAcceptCharset(); + public void setAcceptCharset(String acceptCharset); + + /** + * Server-side form handler. See the action attribute definition in HTML + * 4.0. + */ + public String getAction(); + public void setAction(String action); + + /** + * The content type of the submitted form, generally + * "application/x-www-form-urlencoded". See the enctype attribute + * definition in HTML 4.0. + */ + public String getEnctype(); + public void setEnctype(String enctype); + + /** + * HTTP method used to submit form. See the method attribute definition + * in HTML 4.0. + */ + public String getMethod(); + public void setMethod(String method); + + /** + * Frame to render the resource in. See the target attribute definition + * in HTML 4.0. + */ + public String getTarget(); + public void setTarget(String target); + + /** + * Submits the form. It performs the same action as a submit button. + */ + public void submit(); + + /** + * Restores a form element's default values. It performs the same action + * as a reset button. + */ + public void reset(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFrameElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFrameElement.java new file mode 100644 index 000000000..6efd70257 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFrameElement.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.Document; + +/** + * Create a frame. See the FRAME element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLFrameElement extends HTMLElement { + /** + * Request frame borders. See the frameborder attribute definition in + * HTML 4.0. + */ + public String getFrameBorder(); + public void setFrameBorder(String frameBorder); + + /** + * URI designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.0. + */ + public String getLongDesc(); + public void setLongDesc(String longDesc); + + /** + * Frame margin height, in pixels. See the marginheight attribute + * definition in HTML 4.0. + */ + public String getMarginHeight(); + public void setMarginHeight(String marginHeight); + + /** + * Frame margin width, in pixels. See the marginwidth attribute + * definition in HTML 4.0. + */ + public String getMarginWidth(); + public void setMarginWidth(String marginWidth); + + /** + * The frame name (object of the target attribute). See the + * name attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * When true, forbid user from resizing frame. See the noresize + * attribute definition in HTML 4.0. + */ + public boolean getNoResize(); + public void setNoResize(boolean noResize); + + /** + * Specify whether or not the frame should have scrollbars. See the + * scrolling attribute definition in HTML 4.0. + */ + public String getScrolling(); + public void setScrolling(String scrolling); + + /** + * A URI designating the initial frame contents. See the src attribute + * definition in HTML 4.0. + */ + public String getSrc(); + public void setSrc(String src); + + /** + * The document this frame contains, if there is any and it is available, + * or null otherwise. + * @since DOM Level 2 + */ + public Document getContentDocument(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFrameSetElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFrameSetElement.java new file mode 100644 index 000000000..c13453b64 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLFrameSetElement.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Create a grid of frames. See the FRAMESET element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLFrameSetElement extends HTMLElement { + /** + * The number of columns of frames in the frameset. See the cols + * attribute definition in HTML 4.0. + */ + public String getCols(); + public void setCols(String cols); + + /** + * The number of rows of frames in the frameset. See the rows attribute + * definition in HTML 4.0. + */ + public String getRows(); + public void setRows(String rows); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHRElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHRElement.java new file mode 100644 index 000000000..8a10aa660 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHRElement.java @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Create a horizontal rule. See the HR element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLHRElement extends HTMLElement { + /** + * Align the rule on the page. See the align attribute definition in + * HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Indicates to the user agent that there should be no shading in the + * rendering of this element. See the noshade attribute definition in + * HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public boolean getNoShade(); + public void setNoShade(boolean noShade); + + /** + * The height of the rule. See the size attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getSize(); + public void setSize(String size); + + /** + * The width of the rule. See the width attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHeadElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHeadElement.java new file mode 100644 index 000000000..93abb7502 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHeadElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Document head information. See the HEAD element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLHeadElement extends HTMLElement { + /** + * URI designating a metadata profile. See the profile attribute + * definition in HTML 4.0. + */ + public String getProfile(); + public void setProfile(String profile); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHeadingElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHeadingElement.java new file mode 100644 index 000000000..8121d2c45 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHeadingElement.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * For the H1 to H6 elements. See the H1 element + * definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLHeadingElement extends HTMLElement { + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHtmlElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHtmlElement.java new file mode 100644 index 000000000..ee8f16eab --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLHtmlElement.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Root of an HTML document. See the HTML element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLHtmlElement extends HTMLElement { + /** + * Version information about the document's DTD. See the version + * attribute definition in HTML 4.0. This attribute is deprecated in HTML + * 4.0. + */ + public String getVersion(); + public void setVersion(String version); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLIFrameElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLIFrameElement.java new file mode 100644 index 000000000..d78f4a99c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLIFrameElement.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.Document; + +/** + * Inline subwindows. See the IFRAME element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLIFrameElement extends HTMLElement { + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Request frame borders. See the frameborder attribute definition in + * HTML 4.0. + */ + public String getFrameBorder(); + public void setFrameBorder(String frameBorder); + + /** + * Frame height. See the height attribute definition in HTML 4.0. + */ + public String getHeight(); + public void setHeight(String height); + + /** + * URI designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.0. + */ + public String getLongDesc(); + public void setLongDesc(String longDesc); + + /** + * Frame margin height, in pixels. See the marginheight attribute + * definition in HTML 4.0. + */ + public String getMarginHeight(); + public void setMarginHeight(String marginHeight); + + /** + * Frame margin width, in pixels. See the marginwidth attribute + * definition in HTML 4.0. + */ + public String getMarginWidth(); + public void setMarginWidth(String marginWidth); + + /** + * The frame name (object of the target attribute). See the + * name attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Specify whether or not the frame should have scrollbars. See the + * scrolling attribute definition in HTML 4.0. + */ + public String getScrolling(); + public void setScrolling(String scrolling); + + /** + * A URI designating the initial frame contents. See the src attribute + * definition in HTML 4.0. + */ + public String getSrc(); + public void setSrc(String src); + + /** + * Frame width. See the width attribute definition in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + + /** + * The document this frame contains, if there is any and it is available, + * or null otherwise. + * @since DOM Level 2 + */ + public Document getContentDocument(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLImageElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLImageElement.java new file mode 100644 index 000000000..6b59c032d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLImageElement.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Embedded image. See the IMG element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLImageElement extends HTMLElement { + /** + * URI designating the source of this image, for low-resolution output. + */ + public String getLowSrc(); + public void setLowSrc(String lowSrc); + + /** + * The name of the element (for backwards compatibility). + */ + public String getName(); + public void setName(String name); + + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Alternate text for user agents not rendering the normal content of + * this element. See the alt attribute definition in HTML 4.0. + */ + public String getAlt(); + public void setAlt(String alt); + + /** + * Width of border around image. See the border attribute definition in + * HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getBorder(); + public void setBorder(String border); + + /** + * Override height. See the height attribute definition in HTML 4.0. + */ + public String getHeight(); + public void setHeight(String height); + + /** + * Horizontal space to the left and right of this image. See the hspace + * attribute definition in HTML 4.0. This attribute is deprecated in HTML + * 4.0. + */ + public String getHspace(); + public void setHspace(String hspace); + + /** + * Use server-side image map. See the ismap attribute definition in HTML + * 4.0. + */ + public boolean getIsMap(); + public void setIsMap(boolean isMap); + + /** + * URI designating a long description of this image or frame. See the + * longdesc attribute definition in HTML 4.0. + */ + public String getLongDesc(); + public void setLongDesc(String longDesc); + + /** + * URI designating the source of this image. See the src attribute + * definition in HTML 4.0. + */ + public String getSrc(); + public void setSrc(String src); + + /** + * Use client-side image map. See the usemap attribute definition in + * HTML 4.0. + */ + public String getUseMap(); + public void setUseMap(String useMap); + + /** + * Vertical space above and below this image. See the vspace attribute + * definition in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getVspace(); + public void setVspace(String vspace); + + /** + * Override width. See the width attribute definition in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLInputElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLInputElement.java new file mode 100644 index 000000000..372eb8a91 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLInputElement.java @@ -0,0 +1,197 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Form control. Note. Depending upon the environment in which the page is + * being viewed, the value property may be read-only for the file upload + * input type. For the "password" input type, the actual value returned may + * be masked to prevent unauthorized use. See the INPUT element definition + * in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLInputElement extends HTMLElement { + /** + * When the type attribute of the element has the value + * "Text", "File" or "Password", this represents the HTML value attribute + * of the element. The value of this attribute does not change if the + * contents of the corresponding form control, in an interactive user + * agent, changes. Changing this attribute, however, resets the contents + * of the form control. See the value attribute definition in HTML 4.0. + */ + public String getDefaultValue(); + public void setDefaultValue(String defaultValue); + + /** + * When type has the value "Radio" or "Checkbox", this + * represents the HTML checked attribute of the element. The value of + * this attribute does not change if the state of the corresponding form + * control, in an interactive user agent, changes. Changes to this + * attribute, however, resets the state of the form control. See the + * checked attribute definition in HTML 4.0. + */ + public boolean getDefaultChecked(); + public void setDefaultChecked(boolean defaultChecked); + + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * A comma-separated list of content types that a server processing this + * form will handle correctly. See the accept attribute definition in + * HTML 4.0. + */ + public String getAccept(); + public void setAccept(String accept); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.0. + */ + public String getAccessKey(); + public void setAccessKey(String accessKey); + + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Alternate text for user agents not rendering the normal content of + * this element. See the alt attribute definition in HTML 4.0. + */ + public String getAlt(); + public void setAlt(String alt); + + /** + * When the type attribute of the element has the value + * "Radio" or "Checkbox", this represents the current state of the form + * control, in an interactive user agent. Changes to this attribute + * change the state of the form control, but do not change the value of + * the HTML value attribute of the element. + */ + public boolean getChecked(); + public void setChecked(boolean checked); + + /** + * The control is unavailable in this context. See the disabled + * attribute definition in HTML 4.0. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * Maximum number of characters for text fields, when type + * has the value "Text" or "Password". See the maxlength attribute + * definition in HTML 4.0. + */ + public int getMaxLength(); + public void setMaxLength(int maxLength); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * This control is read-only. Relevant only when type has + * the value "Text" or "Password". See the readonly attribute definition + * in HTML 4.0. + */ + public boolean getReadOnly(); + public void setReadOnly(boolean readOnly); + + /** + * Size information. The precise meaning is specific to each type of + * field. See the size attribute definition in HTML 4.0. + */ + public String getSize(); + public void setSize(String size); + + /** + * When the type attribute has the value "Image", this + * attribute specifies the location of the image to be used to decorate + * the graphical submit button. See the src attribute definition in HTML + * 4.0. + */ + public String getSrc(); + public void setSrc(String src); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.0. + */ + public int getTabIndex(); + public void setTabIndex(int tabIndex); + + /** + * The type of control created. See the type attribute definition in + * HTML 4.0. + */ + public String getType(); + + /** + * Use client-side image map. See the usemap attribute definition in + * HTML 4.0. + */ + public String getUseMap(); + public void setUseMap(String useMap); + + /** + * When the type attribute of the element has the value + * "Text", "File" or "Password", this represents the current contents of + * the corresponding form control, in an interactive user agent. Changing + * this attribute changes the contents of the form control, but does not + * change the value of the HTML value attribute of the element. When the + * type attribute of the element has the value "Button", + * "Hidden", "Submit", "Reset", "Image", "Checkbox" or "Radio", this + * represents the HTML value attribute of the element. See the value + * attribute definition in HTML 4.0. + */ + public String getValue(); + public void setValue(String value); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + + /** + * Select the contents of the text area. For INPUT elements + * whose type attribute has one of the following values: + * "Text", "File", or "Password". + */ + public void select(); + + /** + * Simulate a mouse-click. For INPUT elements whose + * type attribute has one of the following values: "Button", + * "Checkbox", "Radio", "Reset", or "Submit". + */ + public void click(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLIsIndexElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLIsIndexElement.java new file mode 100644 index 000000000..6eb459627 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLIsIndexElement.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * This element is used for single-line text input. See the ISINDEX element + * definition in HTML 4.0. This element is deprecated in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLIsIndexElement extends HTMLElement { + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * The prompt message. See the prompt attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getPrompt(); + public void setPrompt(String prompt); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLIElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLIElement.java new file mode 100644 index 000000000..c7dba9ca5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLIElement.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * List item. See the LI element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLLIElement extends HTMLElement { + /** + * List item bullet style. See the type attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getType(); + public void setType(String type); + + /** + * Reset sequence number when used in OL . See the value + * attribute definition in HTML 4.0. This attribute is deprecated in HTML + * 4.0. + */ + public int getValue(); + public void setValue(int value); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLabelElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLabelElement.java new file mode 100644 index 000000000..17334155e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLabelElement.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Form field label text. See the LABEL element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLLabelElement extends HTMLElement { + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.0. + */ + public String getAccessKey(); + public void setAccessKey(String accessKey); + + /** + * This attribute links this label with another form control by + * id attribute. See the for attribute definition in HTML + * 4.0. + */ + public String getHtmlFor(); + public void setHtmlFor(String htmlFor); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLegendElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLegendElement.java new file mode 100644 index 000000000..9bf48d43c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLegendElement.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Provides a caption for a FIELDSET grouping. See the LEGEND + * element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLLegendElement extends HTMLElement { + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.0. + */ + public String getAccessKey(); + public void setAccessKey(String accessKey); + + /** + * Text alignment relative to FIELDSET . See the align + * attribute definition in HTML 4.0. This attribute is deprecated in HTML + * 4.0. + */ + public String getAlign(); + public void setAlign(String align); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLinkElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLinkElement.java new file mode 100644 index 000000000..089b90cc5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLLinkElement.java @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * The LINK element specifies a link to an external resource, + * and defines this document's relationship to that resource (or vice versa). + * See the LINK element definition in HTML 4.0 (see also the + * LinkStyle interface in the module). + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLLinkElement extends HTMLElement { + /** + * Enables/disables the link. This is currently only used for style sheet + * links, and may be used to activate or deactivate style sheets. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * The character encoding of the resource being linked to. See the + * charset attribute definition in HTML 4.0. + */ + public String getCharset(); + public void setCharset(String charset); + + /** + * The URI of the linked resource. See the href attribute definition in + * HTML 4.0. + */ + public String getHref(); + public void setHref(String href); + + /** + * Language code of the linked resource. See the hreflang attribute + * definition in HTML 4.0. + */ + public String getHreflang(); + public void setHreflang(String hreflang); + + /** + * Designed for use with one or more target media. See the media + * attribute definition in HTML 4.0. + */ + public String getMedia(); + public void setMedia(String media); + + /** + * Forward link type. See the rel attribute definition in HTML 4.0. + */ + public String getRel(); + public void setRel(String rel); + + /** + * Reverse link type. See the rev attribute definition in HTML 4.0. + */ + public String getRev(); + public void setRev(String rev); + + /** + * Frame to render the resource in. See the target attribute definition + * in HTML 4.0. + */ + public String getTarget(); + public void setTarget(String target); + + /** + * Advisory content type. See the type attribute definition in HTML 4.0. + */ + public String getType(); + public void setType(String type); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMapElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMapElement.java new file mode 100644 index 000000000..bd464b1a7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMapElement.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Client-side image map. See the MAP element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLMapElement extends HTMLElement { + /** + * The list of areas defined for the image map. + */ + public HTMLCollection getAreas(); + + /** + * Names the map (for use with usemap ). See the name + * attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMenuElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMenuElement.java new file mode 100644 index 000000000..cf1fd1247 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMenuElement.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Menu list. See the MENU element definition in HTML 4.0. This element is + * deprecated in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLMenuElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute + * definition in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public boolean getCompact(); + public void setCompact(boolean compact); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMetaElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMetaElement.java new file mode 100644 index 000000000..8cb608a27 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLMetaElement.java @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * This contains generic meta-information about the document. See the META + * element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLMetaElement extends HTMLElement { + /** + * Associated information. See the content attribute definition in HTML + * 4.0. + */ + public String getContent(); + public void setContent(String content); + + /** + * HTTP response header name. See the http-equiv attribute definition in + * HTML 4.0. + */ + public String getHttpEquiv(); + public void setHttpEquiv(String httpEquiv); + + /** + * Meta information name. See the name attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Select form of content. See the scheme attribute definition in HTML + * 4.0. + */ + public String getScheme(); + public void setScheme(String scheme); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLModElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLModElement.java new file mode 100644 index 000000000..419825d8b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLModElement.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Notice of modification to part of a document. See the INS and DEL + * element definitions in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLModElement extends HTMLElement { + /** + * A URI designating a document that describes the reason for the change. + * See the cite attribute definition in HTML 4.0. + */ + public String getCite(); + public void setCite(String cite); + + /** + * The date and time of the change. See the datetime attribute definition + * in HTML 4.0. + */ + public String getDateTime(); + public void setDateTime(String dateTime); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOListElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOListElement.java new file mode 100644 index 000000000..1357ff138 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOListElement.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Ordered list. See the OL element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLOListElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute + * definition in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public boolean getCompact(); + public void setCompact(boolean compact); + + /** + * Starting sequence number. See the start attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public int getStart(); + public void setStart(int start); + + /** + * Numbering style. See the type attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getType(); + public void setType(String type); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLObjectElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLObjectElement.java new file mode 100644 index 000000000..c682e67fc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLObjectElement.java @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.Document; + +/** + * Generic embedded object. Note. In principle, all properties on the object + * element are read-write but in some environments some properties may be + * read-only once the underlying object is instantiated. See the OBJECT + * element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLObjectElement extends HTMLElement { + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * Applet class file. See the code attribute for + * HTMLAppletElement. + */ + public String getCode(); + public void setCode(String code); + + /** + * Aligns this object (vertically or horizontally) with respect to its + * surrounding text. See the align attribute definition in HTML 4.0. + * This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Space-separated list of archives. See the archive attribute definition + * in HTML 4.0. + */ + public String getArchive(); + public void setArchive(String archive); + + /** + * Width of border around the object. See the border attribute definition + * in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getBorder(); + public void setBorder(String border); + + /** + * Base URI for classid , data , and + * archive attributes. See the codebase attribute definition + * in HTML 4.0. + */ + public String getCodeBase(); + public void setCodeBase(String codeBase); + + /** + * Content type for data downloaded via classid attribute. + * See the codetype attribute definition in HTML 4.0. + */ + public String getCodeType(); + public void setCodeType(String codeType); + + /** + * A URI specifying the location of the object's data. See the data + * attribute definition in HTML 4.0. + */ + public String getData(); + public void setData(String data); + + /** + * Declare (for future reference), but do not instantiate, this object. + * See the declare attribute definition in HTML 4.0. + */ + public boolean getDeclare(); + public void setDeclare(boolean declare); + + /** + * Override height. See the height attribute definition in HTML 4.0. + */ + public String getHeight(); + public void setHeight(String height); + + /** + * Horizontal space to the left and right of this image, applet, or + * object. See the hspace attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getHspace(); + public void setHspace(String hspace); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Message to render while loading the object. See the standby attribute + * definition in HTML 4.0. + */ + public String getStandby(); + public void setStandby(String standby); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.0. + */ + public int getTabIndex(); + public void setTabIndex(int tabIndex); + + /** + * Content type for data downloaded via data attribute. See + * the type attribute definition in HTML 4.0. + */ + public String getType(); + public void setType(String type); + + /** + * Use client-side image map. See the usemap attribute definition in + * HTML 4.0. + */ + public String getUseMap(); + public void setUseMap(String useMap); + + /** + * Vertical space above and below this image, applet, or object. See the + * vspace attribute definition in HTML 4.0. This attribute is deprecated + * in HTML 4.0. + */ + public String getVspace(); + public void setVspace(String vspace); + + /** + * Override width. See the width attribute definition in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + + /** + * The document this object contains, if there is any and it is + * available, or null otherwise. + * @since DOM Level 2 + */ + public Document getContentDocument(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOptGroupElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOptGroupElement.java new file mode 100644 index 000000000..ca38157b6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOptGroupElement.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Group options together in logical subdivisions. See the OPTGROUP element + * definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLOptGroupElement extends HTMLElement { + /** + * The control is unavailable in this context. See the disabled + * attribute definition in HTML 4.0. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * Assigns a label to this option group. See the label attribute + * definition in HTML 4.0. + */ + public String getLabel(); + public void setLabel(String label); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOptionElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOptionElement.java new file mode 100644 index 000000000..8af033c37 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLOptionElement.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * A selectable choice. See the OPTION element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLOptionElement extends HTMLElement { + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * Represents the value of the HTML selected attribute. The value of this + * attribute does not change if the state of the corresponding form + * control, in an interactive user agent, changes. Changing + * defaultSelected , however, resets the state of the form + * control. See the selected attribute definition in HTML 4.0. + */ + public boolean getDefaultSelected(); + public void setDefaultSelected(boolean defaultSelected); + + /** + * The text contained within the option element. + */ + public String getText(); + + /** + * The index of this OPTION in its parent SELECT + * , starting from 0. + */ + public int getIndex(); + + /** + * The control is unavailable in this context. See the disabled + * attribute definition in HTML 4.0. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * Option label for use in hierarchical menus. See the label attribute + * definition in HTML 4.0. + */ + public String getLabel(); + public void setLabel(String label); + + /** + * Represents the current state of the corresponding form control, in an + * interactive user agent. Changing this attribute changes the state of + * the form control, but does not change the value of the HTML selected + * attribute of the element. + */ + public boolean getSelected(); + public void setSelected(boolean selected); + + /** + * The current form control value. See the value attribute definition in + * HTML 4.0. + */ + public String getValue(); + public void setValue(String value); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLParagraphElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLParagraphElement.java new file mode 100644 index 000000000..179241a9f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLParagraphElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Paragraphs. See the P element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLParagraphElement extends HTMLElement { + /** + * Horizontal text alignment. See the align attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLParamElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLParamElement.java new file mode 100644 index 000000000..e30fd5329 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLParamElement.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Parameters fed to the OBJECT element. See the PARAM element + * definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLParamElement extends HTMLElement { + /** + * The name of a run-time parameter. See the name attribute definition + * in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Content type for the value attribute when + * valuetype has the value "ref". See the type attribute + * definition in HTML 4.0. + */ + public String getType(); + public void setType(String type); + + /** + * The value of a run-time parameter. See the value attribute definition + * in HTML 4.0. + */ + public String getValue(); + public void setValue(String value); + + /** + * Information about the meaning of the value attribute + * value. See the valuetype attribute definition in HTML 4.0. + */ + public String getValueType(); + public void setValueType(String valueType); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLPreElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLPreElement.java new file mode 100644 index 000000000..23fc398eb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLPreElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Preformatted text. See the PRE element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLPreElement extends HTMLElement { + /** + * Fixed width for content. See the width attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public int getWidth(); + public void setWidth(int width); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLQuoteElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLQuoteElement.java new file mode 100644 index 000000000..26873f48f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLQuoteElement.java @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * For the Q and BLOCKQUOTE elements. See the Q + * element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLQuoteElement extends HTMLElement { + /** + * A URI designating a source document or message. See the cite + * attribute definition in HTML 4.0. + */ + public String getCite(); + public void setCite(String cite); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLScriptElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLScriptElement.java new file mode 100644 index 000000000..3294a504f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLScriptElement.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Script statements. See the SCRIPT element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLScriptElement extends HTMLElement { + /** + * The script content of the element. + */ + public String getText(); + public void setText(String text); + + /** + * Reserved for future use. + */ + public String getHtmlFor(); + public void setHtmlFor(String htmlFor); + + /** + * Reserved for future use. + */ + public String getEvent(); + public void setEvent(String event); + + /** + * The character encoding of the linked resource. See the charset + * attribute definition in HTML 4.0. + */ + public String getCharset(); + public void setCharset(String charset); + + /** + * Indicates that the user agent can defer processing of the script. See + * the defer attribute definition in HTML 4.0. + */ + public boolean getDefer(); + public void setDefer(boolean defer); + + /** + * URI designating an external script. See the src attribute definition + * in HTML 4.0. + */ + public String getSrc(); + public void setSrc(String src); + + /** + * The content type of the script language. See the type attribute + * definition in HTML 4.0. + */ + public String getType(); + public void setType(String type); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLSelectElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLSelectElement.java new file mode 100644 index 000000000..c66995f3c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLSelectElement.java @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.DOMException; + +/** + * The select element allows the selection of an option. The contained + * options can be directly accessed through the select element as a + * collection. See the SELECT element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLSelectElement extends HTMLElement { + /** + * The type of this form control. This is the string "select-multiple" + * when the multiple attribute is true and the string + * "select-one" when false . + */ + public String getType(); + + /** + * The ordinal index of the selected option, starting from 0. The value + * -1 is returned if no element is selected. If multiple options are + * selected, the index of the first selected option is returned. + */ + public int getSelectedIndex(); + public void setSelectedIndex(int selectedIndex); + + /** + * The current form control value. + */ + public String getValue(); + public void setValue(String value); + + /** + * The number of options in this SELECT . + */ + public int getLength(); + + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * The collection of OPTION elements contained by this + * element. + */ + public HTMLCollection getOptions(); + + /** + * The control is unavailable in this context. See the disabled + * attribute definition in HTML 4.0. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * If true, multiple OPTION elements may be selected in + * this SELECT . See the multiple attribute definition in + * HTML 4.0. + */ + public boolean getMultiple(); + public void setMultiple(boolean multiple); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * Number of visible rows. See the size attribute definition in HTML 4.0. + */ + public int getSize(); + public void setSize(int size); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.0. + */ + public int getTabIndex(); + public void setTabIndex(int tabIndex); + + /** + * Add a new element to the collection of OPTION elements + * for this SELECT . This method is the equivalent of the + * appendChild method of the Node interface if + * the before parameter is null . It is + * equivalent to the insertBefore method on the parent of + * before in all other cases. + * @param element The element to add. + * @param before The element to insert before, or null for + * the tail of the list. + * @exception DOMException + * NOT_FOUND_ERR: Raised if before is not a descendant of + * the SELECT element. + */ + public void add(HTMLElement element, + HTMLElement before) + throws DOMException; + + /** + * Remove an element from the collection of OPTION elements + * for this SELECT . Does nothing if no element has the given + * index. + * @param index The index of the item to remove, starting from 0. + */ + public void remove(int index); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLStyleElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLStyleElement.java new file mode 100644 index 000000000..e3d04bd44 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLStyleElement.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Style information. See the STYLE element definition in HTML 4.0, the + * module and the LinkStyle interface in the module. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLStyleElement extends HTMLElement { + /** + * Enables/disables the style sheet. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * Designed for use with one or more target media. See the media + * attribute definition in HTML 4.0. + */ + public String getMedia(); + public void setMedia(String media); + + /** + * The content type pf the style sheet language. See the type attribute + * definition in HTML 4.0. + */ + public String getType(); + public void setType(String type); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableCaptionElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableCaptionElement.java new file mode 100644 index 000000000..58a8bed5e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableCaptionElement.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Table caption See the CAPTION element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTableCaptionElement extends HTMLElement { + /** + * Caption alignment with respect to the table. See the align attribute + * definition in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableCellElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableCellElement.java new file mode 100644 index 000000000..b818ce137 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableCellElement.java @@ -0,0 +1,126 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * The object used to represent the TH and TD + * elements. See the TD element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTableCellElement extends HTMLElement { + /** + * The index of this cell in the row, starting from 0. This index is in + * document tree order and not display order. + */ + public int getCellIndex(); + + /** + * Abbreviation for header cells. See the abbr attribute definition in + * HTML 4.0. + */ + public String getAbbr(); + public void setAbbr(String abbr); + + /** + * Horizontal alignment of data in cell. See the align attribute + * definition in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Names group of related headers. See the axis attribute definition in + * HTML 4.0. + */ + public String getAxis(); + public void setAxis(String axis); + + /** + * Cell background color. See the bgcolor attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getBgColor(); + public void setBgColor(String bgColor); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.0. + */ + public String getCh(); + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition + * in HTML 4.0. + */ + public String getChOff(); + public void setChOff(String chOff); + + /** + * Number of columns spanned by cell. See the colspan attribute + * definition in HTML 4.0. + */ + public int getColSpan(); + public void setColSpan(int colSpan); + + /** + * List of id attribute values for header cells. See the + * headers attribute definition in HTML 4.0. + */ + public String getHeaders(); + public void setHeaders(String headers); + + /** + * Cell height. See the height attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getHeight(); + public void setHeight(String height); + + /** + * Suppress word wrapping. See the nowrap attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public boolean getNoWrap(); + public void setNoWrap(boolean noWrap); + + /** + * Number of rows spanned by cell. See the rowspan attribute definition + * in HTML 4.0. + */ + public int getRowSpan(); + public void setRowSpan(int rowSpan); + + /** + * Scope covered by header cells. See the scope attribute definition in + * HTML 4.0. + */ + public String getScope(); + public void setScope(String scope); + + /** + * Vertical alignment of data in cell. See the valign attribute + * definition in HTML 4.0. + */ + public String getVAlign(); + public void setVAlign(String vAlign); + + /** + * Cell width. See the width attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableColElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableColElement.java new file mode 100644 index 000000000..895ee041e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableColElement.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Regroups the COL and COLGROUP elements. See the + * COL element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTableColElement extends HTMLElement { + /** + * Horizontal alignment of cell data in column. See the align attribute + * definition in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.0. + */ + public String getCh(); + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition + * in HTML 4.0. + */ + public String getChOff(); + public void setChOff(String chOff); + + /** + * Indicates the number of columns in a group or affected by a grouping. + * See the span attribute definition in HTML 4.0. + */ + public int getSpan(); + public void setSpan(int span); + + /** + * Vertical alignment of cell data in column. See the valign attribute + * definition in HTML 4.0. + */ + public String getVAlign(); + public void setVAlign(String vAlign); + + /** + * Default column width. See the width attribute definition in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableElement.java new file mode 100644 index 000000000..42aa2482e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableElement.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.DOMException; + +/** + * The create* and delete* methods on the table allow authors to construct + * and modify tables. HTML 4.0 specifies that only one of each of the + * CAPTION , THEAD , and TFOOT + * elements may exist in a table. Therefore, if one exists, and the + * createTHead() or createTFoot() method is called, the method returns the + * existing THead or TFoot element. See the TABLE element definition in HTML + * 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTableElement extends HTMLElement { + /** + * Returns the table's CAPTION , or void if none exists. + */ + public HTMLTableCaptionElement getCaption(); + public void setCaption(HTMLTableCaptionElement caption); + + /** + * Returns the table's THEAD , or null if none + * exists. + */ + public HTMLTableSectionElement getTHead(); + public void setTHead(HTMLTableSectionElement tHead); + + /** + * Returns the table's TFOOT , or null if none + * exists. + */ + public HTMLTableSectionElement getTFoot(); + public void setTFoot(HTMLTableSectionElement tFoot); + + /** + * Returns a collection of all the rows in the table, including all in + * THEAD , TFOOT , all TBODY + * elements. + */ + public HTMLCollection getRows(); + + /** + * Returns a collection of the defined table bodies. + */ + public HTMLCollection getTBodies(); + + /** + * Specifies the table's position with respect to the rest of the + * document. See the align attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Cell background color. See the bgcolor attribute definition in HTML + * 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getBgColor(); + public void setBgColor(String bgColor); + + /** + * The width of the border around the table. See the border attribute + * definition in HTML 4.0. + */ + public String getBorder(); + public void setBorder(String border); + + /** + * Specifies the horizontal and vertical space between cell content and + * cell borders. See the cellpadding attribute definition in HTML 4.0. + */ + public String getCellPadding(); + public void setCellPadding(String cellPadding); + + /** + * Specifies the horizontal and vertical separation between cells. See + * the cellspacing attribute definition in HTML 4.0. + */ + public String getCellSpacing(); + public void setCellSpacing(String cellSpacing); + + /** + * Specifies which external table borders to render. See the frame + * attribute definition in HTML 4.0. + */ + public String getFrame(); + public void setFrame(String frame); + + /** + * Specifies which internal table borders to render. See the rules + * attribute definition in HTML 4.0. + */ + public String getRules(); + public void setRules(String rules); + + /** + * Description about the purpose or structure of a table. See the + * summary attribute definition in HTML 4.0. + */ + public String getSummary(); + public void setSummary(String summary); + + /** + * Specifies the desired table width. See the width attribute definition + * in HTML 4.0. + */ + public String getWidth(); + public void setWidth(String width); + + /** + * Create a table header row or return an existing one. + * @return A new table header element (THEAD ). + */ + public HTMLElement createTHead(); + + /** + * Delete the header from the table, if one exists. + */ + public void deleteTHead(); + + /** + * Create a table footer row or return an existing one. + * @return A footer element (TFOOT ). + */ + public HTMLElement createTFoot(); + + /** + * Delete the footer from the table, if one exists. + */ + public void deleteTFoot(); + + /** + * Create a new table caption object or return an existing one. + * @return A CAPTION element. + */ + public HTMLElement createCaption(); + + /** + * Delete the table caption, if one exists. + */ + public void deleteCaption(); + + /** + * Insert a new empty row in the table. The new row is inserted + * immediately before and in the same section as the current + * index th row in the table. If index is equal + * to the number of rows, the new row is appended. In addition, when the + * table is empty the row is inserted into a TBODY which is + * created and inserted into the table. Note. A table row cannot be empty + * according to HTML 4.0 Recommendation. + * @param index The row number where to insert a new row. This index + * starts from 0 and is relative to all the rows contained inside the + * table, regardless of section parentage. + * @return The newly created row. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than the + * number of rows or if the index is negative. + */ + public HTMLElement insertRow(int index) + throws DOMException; + + /** + * Delete a table row. + * @param index The index of the row to be deleted. This index starts + * from 0 and is relative to all the rows contained inside the table, + * regardless of section parentage. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than or + * equal to the number of rows or if the index is negative. + */ + public void deleteRow(int index) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableRowElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableRowElement.java new file mode 100644 index 000000000..a15f06f0a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableRowElement.java @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.DOMException; + +/** + * A row in a table. See the TR element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTableRowElement extends HTMLElement { + /** + * The index of this row, relative to the entire table, starting from 0. + * This is in document tree order and not display order. The + * rowIndex does not take into account sections ( + * THEAD , TFOOT , or TBODY ) + * within the table. + */ + public int getRowIndex(); + + /** + * The index of this row, relative to the current section ( + * THEAD , TFOOT , or TBODY ), + * starting from 0. + */ + public int getSectionRowIndex(); + + /** + * The collection of cells in this row. + */ + public HTMLCollection getCells(); + + /** + * Horizontal alignment of data within cells of this row. See the align + * attribute definition in HTML 4.0. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Background color for rows. See the bgcolor attribute definition in + * HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public String getBgColor(); + public void setBgColor(String bgColor); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.0. + */ + public String getCh(); + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition + * in HTML 4.0. + */ + public String getChOff(); + public void setChOff(String chOff); + + /** + * Vertical alignment of data within cells of this row. See the valign + * attribute definition in HTML 4.0. + */ + public String getVAlign(); + public void setVAlign(String vAlign); + + /** + * Insert an empty TD cell into this row. If + * index is equal to the number of cells, the new cell is + * appended + * @param index The place to insert the cell, starting from 0. + * @return The newly created cell. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is + * greater than the number of cells or if the index is negative. + */ + public HTMLElement insertCell(int index) + throws DOMException; + + /** + * Delete a cell from the current row. + * @param index The index of the cell to delete, starting from 0. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is + * greater than or equal to the number of cells or if the index is + * negative. + */ + public void deleteCell(int index) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableSectionElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableSectionElement.java new file mode 100644 index 000000000..99bff3591 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTableSectionElement.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +import org.w3c.dom.DOMException; + +/** + * The THEAD , TFOOT , and TBODY + * elements. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTableSectionElement extends HTMLElement { + /** + * Horizontal alignment of data in cells. See the align + * attribute for HTMLTheadElement for details. + */ + public String getAlign(); + public void setAlign(String align); + + /** + * Alignment character for cells in a column. See the char attribute + * definition in HTML 4.0. + */ + public String getCh(); + public void setCh(String ch); + + /** + * Offset of alignment character. See the charoff attribute definition + * in HTML 4.0. + */ + public String getChOff(); + public void setChOff(String chOff); + + /** + * Vertical alignment of data in cells. See the valign + * attribute for HTMLTheadElement for details. + */ + public String getVAlign(); + public void setVAlign(String vAlign); + + /** + * The collection of rows in this table section. + */ + public HTMLCollection getRows(); + + /** + * Insert a row into this section. The new row is inserted immediately + * before the current index th row in this section. If + * index is equal to the number of rows in this section, the + * new row is appended. + * @param index The row number where to insert a new row. This index + * starts from 0 and is relative only to the rows contained inside this + * section, not all the rows in the table. + * @return The newly created row. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than the + * number of rows of if the index is neagative. + */ + public HTMLElement insertRow(int index) + throws DOMException; + + /** + * Delete a row from this section. + * @param index The index of the row to be deleted. This index starts + * from 0 and is relative only to the rows contained inside this + * section, not all the rows in the table. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if the specified index is greater than or + * equal to the number of rows or if the index is negative. + */ + public void deleteRow(int index) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTextAreaElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTextAreaElement.java new file mode 100644 index 000000000..b189a968d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTextAreaElement.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Multi-line text field. See the TEXTAREA element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTextAreaElement extends HTMLElement { + /** + * Represents the contents of the element. The value of this attribute + * does not change if the contents of the corresponding form control, in + * an interactive user agent, changes. Changing this attribute, however, + * resets the contents of the form control. + */ + public String getDefaultValue(); + public void setDefaultValue(String defaultValue); + + /** + * Returns the FORM element containing this control. Returns + * null if this control is not within the context of a form. + */ + public HTMLFormElement getForm(); + + /** + * A single character access key to give access to the form control. See + * the accesskey attribute definition in HTML 4.0. + */ + public String getAccessKey(); + public void setAccessKey(String accessKey); + + /** + * Width of control (in characters). See the cols attribute definition + * in HTML 4.0. + */ + public int getCols(); + public void setCols(int cols); + + /** + * The control is unavailable in this context. See the disabled + * attribute definition in HTML 4.0. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * Form control or object name when submitted with a form. See the name + * attribute definition in HTML 4.0. + */ + public String getName(); + public void setName(String name); + + /** + * This control is read-only. See the readonly attribute definition in + * HTML 4.0. + */ + public boolean getReadOnly(); + public void setReadOnly(boolean readOnly); + + /** + * Number of text rows. See the rows attribute definition in HTML 4.0. + */ + public int getRows(); + public void setRows(int rows); + + /** + * Index that represents the element's position in the tabbing order. See + * the tabindex attribute definition in HTML 4.0. + */ + public int getTabIndex(); + public void setTabIndex(int tabIndex); + + /** + * The type of this form control. This the string "textarea". + */ + public String getType(); + + /** + * Represents the current contents of the corresponding form control, in + * an interactive user agent. Changing this attribute changes the + * contents of the form control, but does not change the contents of the + * element. If the entirety of the data can not fit into a single + * DOMString , the implementation may truncate the data. + */ + public String getValue(); + public void setValue(String value); + + /** + * Removes keyboard focus from this element. + */ + public void blur(); + + /** + * Gives keyboard focus to this element. + */ + public void focus(); + + /** + * Select the contents of the TEXTAREA . + */ + public void select(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTitleElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTitleElement.java new file mode 100644 index 000000000..9a2b1ff1d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLTitleElement.java @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * The document title. See the TITLE element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLTitleElement extends HTMLElement { + /** + * The specified title as a string. + */ + public String getText(); + public void setText(String text); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLUListElement.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLUListElement.java new file mode 100644 index 000000000..dac1789d9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/HTMLUListElement.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.html; + +/** + * Unordered list. See the UL element definition in HTML 4.0. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public interface HTMLUListElement extends HTMLElement { + /** + * Reduce spacing between list items. See the compact attribute + * definition in HTML 4.0. This attribute is deprecated in HTML 4.0. + */ + public boolean getCompact(); + public void setCompact(boolean compact); + + /** + * Bullet style. See the type attribute definition in HTML 4.0. This + * attribute is deprecated in HTML 4.0. + */ + public String getType(); + public void setType(String type); + +} + diff --git a/sources/net.sf.j2s.java.core/unused/SwingJS-site0.zip b/sources/net.sf.j2s.java.core/src/org/w3c/dom/html/validate-output.txt similarity index 100% rename from sources/net.sf.j2s.java.core/unused/SwingJS-site0.zip rename to sources/net.sf.j2s.java.core/src/org/w3c/dom/html/validate-output.txt diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/DocumentRange.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/DocumentRange.java new file mode 100644 index 000000000..82f3a32d2 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/DocumentRange.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.ranges; + +/** + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface DocumentRange { + /** + * This interface can be obtained from the object implementing the + * Document interface using binding-specific casting methods. + * @return The initial state of the Range returned from this method is + * such that both of its boundary-points are positioned at the + * beginning of the corresponding Document, before any content. The + * Range returned can only be used to select content associated with + * this Document, or with DocumentFragments and Attrs for which this + * Document is the ownerDocument . + */ + public Range createRange(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/Range.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/Range.java new file mode 100644 index 000000000..f3ca789cc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/Range.java @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.ranges; + +import org.w3c.dom.DOMException; +import org.w3c.dom.DocumentFragment; +import org.w3c.dom.Node; + +/** + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface Range { + /** + * Node within which the Range begins + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public Node getStartContainer() + throws DOMException; + + /** + * Offset within the starting node of the Range. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public int getStartOffset() + throws DOMException; + + /** + * Node within which the Range ends + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public Node getEndContainer() + throws DOMException; + + /** + * Offset within the ending node of the Range. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public int getEndOffset() + throws DOMException; + + /** + * TRUE if the Range is collapsed + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public boolean getCollapsed() + throws DOMException; + + /** + * The deepest common ancestor container of the Range's two + * boundary-points. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public Node getCommonAncestorContainer() + throws DOMException; + + /** + * Sets the attributes describing the start of the Range. + * @param refNode The refNode value. This parameter must be + * different fromnull . + * @param offset The startOffset value. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if refNode or an + * ancestor ofrefNode is an Entity, Notation, or + * DocumentType node. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if offset is negative or + * greater than the number of child units in refNode . + * Child units are 16-bit units if refNode is a + * CharacterData, Comment or ProcessingInstruction node. Child units + * are Nodes in all other cases. + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + */ + public void setStart(Node refNode, + int offset) + throws RangeException, DOMException; + + /** + * Sets the attributes describing the end of a Range. + * @param refNode The refNode value. This parameter must be + * different fromnull . + * @param offset The endOffset value. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if refNode or an + * ancestor ofrefNode is an Entity, Notation, or + * DocumentType node. + * @exception DOMException + * INDEX_SIZE_ERR: Raised if offset is negative or + * greater than the number of child units in refNode . + * Child units are 16-bit units if refNode is a + * CharacterData, Comment or ProcessingInstruction node. Child units + * are Nodes in all other cases. + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + */ + public void setEnd(Node refNode, + int offset) + throws RangeException, DOMException; + + /** + * Sets the start position to be before a node + * @param refNode Range starts before refNode + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * refNode is not an Attr, Document, or DocumentFragment + * node or ifrefNode is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void setStartBefore(Node refNode) + throws RangeException, DOMException; + + /** + * Sets the start position to be after a node + * @param refNode Range starts after refNode + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * refNode is not an Attr, Document, or DocumentFragment + * node or if refNode is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void setStartAfter(Node refNode) + throws RangeException, DOMException; + + /** + * Sets the end position to be before a node. + * @param refNode Range ends before refNode + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * refNode is not an Attr, Document, or DocumentFragment + * node or if refNode is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void setEndBefore(Node refNode) + throws RangeException, DOMException; + + /** + * Sets the end of a Range to be after a node + * @param refNode Range ends after refNode . + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if the root container of + * refNode is not an Attr, Document or DocumentFragment + * node or ifrefNode is a Document, DocumentFragment, + * Attr, Entity, or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void setEndAfter(Node refNode) + throws RangeException, DOMException; + + /** + * Collapse a Range onto one of its boundary-points + * @param toStart If TRUE, collapses the Range onto its start; if FALSE, + * collapses it onto its end. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void collapse(boolean toStart) + throws DOMException; + + /** + * Select a node and its contents + * @param refNode The node to select. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if an ancestor of refNode + * is an Entity, Notation or DocumentType node or if + * refNode is a Document, DocumentFragment, Attr, Entity, + * or Notation node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void selectNode(Node refNode) + throws RangeException, DOMException; + + /** + * Select the contents within a node + * @param refNode Node to select from + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if refNode or an + * ancestor ofrefNode is an Entity, Notation or + * DocumentType node. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void selectNodeContents(Node refNode) + throws RangeException, DOMException; + + // CompareHow + public static final short START_TO_START = 0; + public static final short START_TO_END = 1; + public static final short END_TO_END = 2; + public static final short END_TO_START = 3; + + /** + * Compare the boundary-points of two Ranges in a document. + * @param how + * @param sourceRange + * @return -1, 0 or 1 depending on whether the corresponding + * boundary-point of the Range is before, equal to, or after the + * corresponding boundary-point of sourceRange . + * @exception DOMException + * WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the same + * Document or DocumentFragment. + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + */ + public short compareBoundaryPoints(short how, + Range sourceRange) + throws DOMException; + + /** + * Removes the contents of a Range from the containing document or + * document fragment without returning a reference to the removed + * content. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content + * of the Range is read-only or any of the nodes that contain any of + * the content of the Range are read-only. + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + */ + public void deleteContents() + throws DOMException; + + /** + * Moves the contents of a Range from the containing document or document + * fragment to a new DocumentFragment. + * @return A DocumentFragment containing the extracted contents. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content + * of the Range is read-only or any of the nodes which contain any of + * the content of the Range are read-only. + *
      HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be + * extracted into the new DocumentFragment. + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + */ + public DocumentFragment extractContents() + throws DOMException; + + /** + * Duplicates the contents of a Range + * @return A DocumentFragment that contains content equivalent to this + * Range. + * @exception DOMException + * HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be + * extracted into the new DocumentFragment. + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + */ + public DocumentFragment cloneContents() + throws DOMException; + + /** + * Inserts a node into the Document or DocumentFragment at the start of + * the Range. If the container is a Text node, this will be split at the + * start of the Range. Adjacent Text nodes will not be automatically + * merged. + * @param newNode The node to insert at the start of the Range + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of + * the start of the Range is read-only. + *
      WRONG_DOCUMENT_ERR: Raised if newNode and the + * container of the start of the Range were not created from the same + * document. + *
      HIERARCHY_REQUEST_ERR: Raised if the container of the start of + * the Range is of a type that does not allow children of the type of + * newNode or if newNode is an ancestor of + * the container . + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + * @exception RangeException + * INVALID_NODE_TYPE_ERR: Raised if node is an Attr, + * Entity, Notation, DocumentFragment, or Document node. + */ + public void insertNode(Node newNode) + throws DOMException, RangeException; + + /** + * Reparents the contents of the Range to the given node and inserts the + * node at the position of the start of the Range. + * @param newParent The node to surround the contents with. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if an ancestor container of + * either boundary-point of the Range is read-only. + *
      WRONG_DOCUMENT_ERR: Raised if newParent and the + * container of the start of the Range were not created from the same + * document. + *
      HIERARCHY_REQUEST_ERR: Raised if the container of the start of + * the Range is of a type that does not allow children of the type of + * newParent or if newParent is an ancestor + * of the container or if node would end up with a child + * node of a type not allowed by the type of node . + *
      INVALID_STATE_ERR: Raised if detach() has already + * been invoked on this object. + * @exception RangeException + * BAD_BOUNDARYPOINTS_ERR: Raised if the Range partially selects a + * non-text node. + *
      INVALID_NODE_TYPE_ERR: Raised if node is an Attr, + * Entity, DocumentType, Notation, Document, or DocumentFragment node. + */ + public void surroundContents(Node newParent) + throws DOMException, RangeException; + + /** + * Produces a new Range whose boundary-points are equal to the + * boundary-points of the Range. + * @return The duplicated Range. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public Range cloneRange() + throws DOMException; + + /** + * Returns the contents of a Range as a string. This string contains only + * the data characters, not any markup. + * @return The contents of the Range. Only the data characters. + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public String toString() + throws DOMException; + + /** + * Called to indicate that the Range is no longer in use and that the + * implementation may relinquish any resources associated with this Range. + * Subsequent calls to any methods or attribute getters on this Range + * will result in a DOMException being thrown with an error + * code ofINVALID_STATE_ERR . + * @exception DOMException + * INVALID_STATE_ERR: Raised if detach() has already been + * invoked on this object. + */ + public void detach() + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/RangeException.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/RangeException.java new file mode 100644 index 000000000..4e65ffeac --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/ranges/RangeException.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.ranges; + +/** + * Range operations may throw a RangeException as specified in + * their method descriptions. + *

      See also the Document Object Model (DOM) Level 2 Specification. + */ +public class RangeException extends RuntimeException { + public RangeException(short code, String message) { + super(message); + this.code = code; + } + public short code; + // RangeExceptionCode + public static final short BAD_BOUNDARYPOINTS_ERR = 1; + public static final short INVALID_NODE_TYPE_ERR = 2; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/DocumentStyle.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/DocumentStyle.java new file mode 100644 index 000000000..f3bc844d5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/DocumentStyle.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.stylesheets; + +/** + * The DocumentStyle interface provides a mechanism by which the + * style sheets embedded in a document can be retrieved. The expectation is + * that an instance of the DocumentStyle interface can be + * obtained by using binding-specific casting methods on an instance of the + * Document interface. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface DocumentStyle { + /** + * A list containing all the style sheets explicitly linked into or + * embedded in a document. For HTML documents, this includes external + * style sheets, included via the HTML LINK element, and inline STYLE + * elements. In XML, this includes external style sheets, included via + * style sheet processing instructions (see ). + */ + public StyleSheetList getStyleSheets(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/LinkStyle.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/LinkStyle.java new file mode 100644 index 000000000..305406f5c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/LinkStyle.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.stylesheets; + +/** + * The LinkStyle interface provides a mechanism by which a style + * sheet can be retrieved from the node responsible for linking it into a + * document. An instance of the LinkStyle interface can be + * obtained using binding-specific casting methods on an instance of a + * linking node (HTMLLinkElement , HTMLStyleElement + * or ProcessingInstruction in DOM Level 2). + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface LinkStyle { + /** + * The style sheet. + */ + public StyleSheet getSheet(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/MediaList.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/MediaList.java new file mode 100644 index 000000000..0b0eb234e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/MediaList.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.stylesheets; + +import org.w3c.dom.DOMException; + +/** + * The MediaList interface provides the abstraction of an + * ordered collection of media , without defining or constraining how this + * collection is implemented. An empty list is the same as a list that + * contains the medium "all" . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface MediaList { + /** + * The parsable textual representation of the media list. This is a + * comma-separated list of media. + * @exception DOMException + * SYNTAX_ERR: Raised if the specified string value has a syntax error + * and is unparsable. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this media list is + * readonly. + */ + public String getMediaText(); + public void setMediaText(String mediaText) + throws DOMException; + + /** + * The number of media in the list. The range of valid media is + * 0 to length-1 inclusive. + */ + public int getLength(); + + /** + * Returns the index th in the list. If index is + * greater than or equal to the number of media in the list, this returns + * null . + * @param index Index into the collection. + * @return The medium at the index th position in the + * MediaList , or null if that is not a valid + * index. + */ + public String item(int index); + + /** + * Deletes the medium indicated by oldMedium from the list. + * @param oldMedium The medium to delete in the media list. + * @exception DOMException + * NO_MODIFICATION_ALLOWED_ERR: Raised if this list is readonly. + *
      NOT_FOUND_ERR: Raised if oldMedium is not in the + * list. + */ + public void deleteMedium(String oldMedium) + throws DOMException; + + /** + * Adds the medium newMedium to the end of the list. If the + * newMedium is already used, it is first removed. + * @param newMedium The new medium to add. + * @exception DOMException + * INVALID_CHARACTER_ERR: If the medium contains characters that are + * invalid in the underlying style language. + *
      NO_MODIFICATION_ALLOWED_ERR: Raised if this list is readonly. + */ + public void appendMedium(String newMedium) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/StyleSheet.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/StyleSheet.java new file mode 100644 index 000000000..ed3377470 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/StyleSheet.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.stylesheets; + +import org.w3c.dom.Node; + +/** + * The StyleSheet interface is the abstract base interface for + * any type of style sheet. It represents a single style sheet associated + * with a structured document. In HTML, the StyleSheet interface represents + * either an external style sheet, included via the HTML LINK element, or an + * inline STYLE element. In XML, this interface represents an external style + * sheet, included via a style sheet processing instruction . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface StyleSheet { + /** + * This specifies the style sheet language for this style sheet. The style + * sheet language is specified as a content type (e.g. "text/css"). The + * content type is often specified in the ownerNode . Also + * see the type attribute definition for the LINK element in + * HTML 4.0, and the type pseudo-attribute for the XML style sheet + * processing instruction . + */ + public String getType(); + + /** + * false if the style sheet is applied to the document. + * true if it is not. Modifying this attribute may cause a + * new resolution of style for the document. A stylesheet only applies if + * both an appropriate medium definition is present and the disabled + * attribute is false. So, if the media doesn't apply to the current user + * agent, the disabled attribute is ignored. + */ + public boolean getDisabled(); + public void setDisabled(boolean disabled); + + /** + * The node that associates this style sheet with the document. For HTML, + * this may be the corresponding LINK or STYLE + * element. For XML, it may be the linking processing instruction. For + * style sheets that are included by other style sheets, the value of this + * attribute is null . + */ + public Node getOwnerNode(); + + /** + * For style sheet languages that support the concept of style sheet + * inclusion, this attribute represents the including style sheet, if one + * exists. If the style sheet is a top-level style sheet, or the style + * sheet language does not support inclusion, the value of this attribute + * is null . + */ + public StyleSheet getParentStyleSheet(); + + /** + * If the style sheet is a linked style sheet, the value of its attribute + * is its location. For inline style sheets, the value of this attribute + * is null . See the href attribute definition for the + * LINK element in HTML 4.0, and the href pseudo-attribute + * for the XML style sheet processing instruction . + */ + public String getHref(); + + /** + * The advisory title. The title is often specified in the + * ownerNode . See the title attribute definition for the + * LINK element in HTML 4.0, and the title pseudo-attribute + * for the XML style sheet processing instruction . + */ + public String getTitle(); + + /** + * The intended destination media for style information. The media is + * often specified in the ownerNode . If no media has been + * specified, the MediaList will be empty. See the media + * attribute definition for the LINK element in HTML 4.0, + * and the media pseudo-attribute for the XML style sheet processing + * instruction . Modifying the media list may cause a change to the + * attribute disabled . + */ + public MediaList getMedia(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/StyleSheetList.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/StyleSheetList.java new file mode 100644 index 000000000..3657ffa94 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/stylesheets/StyleSheetList.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.stylesheets; + +/** + * The StyleSheetList interface provides the abstraction of an + * ordered collection of style sheets. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface StyleSheetList { + /** + * The number of StyleSheets in the list. The range of valid + * child stylesheet indices is 0 to length-1 + * inclusive. + */ + public int getLength(); + + /** + * Used to retrieve a style sheet by ordinal index. + * @param index Index into the collection + * @return The style sheet at the index position in the + * StyleSheetList , or null if that is not a + * valid index. + */ + public StyleSheet item(int index); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/DocumentTraversal.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/DocumentTraversal.java new file mode 100644 index 000000000..d25a0bc2b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/DocumentTraversal.java @@ -0,0 +1,91 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.DOMException; +import org.w3c.dom.Node; + +/** + * DocumentTraversal contains methods that create iterators and + * tree-walkers to traverse a node and its children in document order (depth + * first, pre-order traversal, which is equivalent to the order in which the + * start tags occur in the text representation of the document). In DOMs + * which support the Traversal feature, DocumentTraversal will + * be implemented by the same objects that implement the Document interface. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface DocumentTraversal { + /** + * Create a new NodeIterator over the subtree rooted at the + * specified node. + * @param root The node which will be iterated together with its + * children. The iterator is initially positioned just before this + * node. The whatToShow flags and the filter, if any, are + * not considered when setting this position. The root must not be + * null . + * @param whatToShow This flag specifies which node types may appear in + * the logical view of the tree presented by the iterator. See the + * description of NodeFilter for the set of possible + * SHOW_ values. These flags can be combined using + * OR . + * @param filter The NodeFilter to be used with this + * TreeWalker , ornull to indicate no filter. + * @param entityReferenceExpansion The value of this flag determines + * whether entity reference nodes are expanded. + * @return The newly created NodeIterator . + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the specified root is + * null . + */ + public NodeIterator createNodeIterator(Node root, + int whatToShow, + NodeFilter filter, + boolean entityReferenceExpansion) + throws DOMException; + + /** + * Create a new TreeWalker over the subtree rooted at the + * specified node. + * @param root The node which will serve as the root for the + * TreeWalker . The whatToShow flags and the + * NodeFilter are not considered when setting this value; + * any node type will be accepted as the root . The + * currentNode of the TreeWalker is + * initialized to this node, whether or not it is visible. The + * root functions as a stopping point for traversal + * methods that look upward in the document structure, such as + * parentNode and nextNode. The root must not + * benull . + * @param whatToShow This flag specifies which node types may appear in + * the logical view of the tree presented by the tree-walker. See the + * description ofNodeFilter for the set of possible SHOW_ + * values. These flags can be combined using OR . + * @param filter The NodeFilter to be used with this + * TreeWalker , ornull to indicate no filter. + * @param entityReferenceExpansion If this flag is false, the contents of + * EntityReference nodes are not presented in the logical + * view. + * @return The newly created TreeWalker . + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if the specified root is + * null . + */ + public TreeWalker createTreeWalker(Node root, + int whatToShow, + NodeFilter filter, + boolean entityReferenceExpansion) + throws DOMException; + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/NodeFilter.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/NodeFilter.java new file mode 100644 index 000000000..05d593929 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/NodeFilter.java @@ -0,0 +1,70 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.Node; + +/** + * Filters are objects that know how to "filter out" nodes. If a + * NodeIterator or TreeWalker is given a + * NodeFilter , it applies the filter before it returns the next + * node. If the filter says to accept the node, the traversal logic returns + * it; otherwise, traversal looks for the next node and pretends that the + * node that was rejected was not there. + *

      The DOM does not provide any filters. NodeFilter is just an + * interface that users can implement to provide their own filters. + *

      NodeFilters do not need to know how to traverse from node to + * node, nor do they need to know anything about the data structure that is + * being traversed. This makes it very easy to write filters, since the only + * thing they have to know how to do is evaluate a single node. One filter + * may be used with a number of different kinds of traversals, encouraging + * code reuse. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface NodeFilter { + // Constants returned by acceptNode + public static final short FILTER_ACCEPT = 1; + public static final short FILTER_REJECT = 2; + public static final short FILTER_SKIP = 3; + + // Constants for whatToShow + public static final int SHOW_ALL = 0xFFFFFFFF; + public static final int SHOW_ELEMENT = 0x00000001; + public static final int SHOW_ATTRIBUTE = 0x00000002; + public static final int SHOW_TEXT = 0x00000004; + public static final int SHOW_CDATA_SECTION = 0x00000008; + public static final int SHOW_ENTITY_REFERENCE = 0x00000010; + public static final int SHOW_ENTITY = 0x00000020; + public static final int SHOW_PROCESSING_INSTRUCTION = 0x00000040; + public static final int SHOW_COMMENT = 0x00000080; + public static final int SHOW_DOCUMENT = 0x00000100; + public static final int SHOW_DOCUMENT_TYPE = 0x00000200; + public static final int SHOW_DOCUMENT_FRAGMENT = 0x00000400; + public static final int SHOW_NOTATION = 0x00000800; + + /** + * Test whether a specified node is visible in the logical view of a + * TreeWalker or NodeIterator . This function + * will be called by the implementation of TreeWalker and + * NodeIterator ; it is not normally called directly from + * user code. (Though you could do so if you wanted to use the same + * filter to guide your own application logic.) + * @param n The node to check to see if it passes the filter or not. + * @return a constant to determine whether the node is accepted, + * rejected, or skipped, as defined above . + */ + public short acceptNode(Node n); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/NodeIterator.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/NodeIterator.java new file mode 100644 index 000000000..af6efd8e5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/NodeIterator.java @@ -0,0 +1,106 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.DOMException; +import org.w3c.dom.Node; + +/** + * Iterators are used to step through a set of nodes, e.g. the set + * of nodes in a NodeList , the document subtree governed by a + * particular Node , the results of a query, or any other set of + * nodes. The set of nodes to be iterated is determined by the implementation + * of the NodeIterator . DOM Level 2 specifies a single + * NodeIterator implementation for document-order traversal of a + * document subtree. Instances of these iterators are created by calling + * DocumentTraversal.createNodeIterator() . + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface NodeIterator { + /** + * The root node of the NodeIterator , as specified when it + * was created. + */ + public Node getRoot(); + + /** + * This attribute determines which node types are presented via the + * iterator. The available set of constants is defined in the + * NodeFilter interface. Nodes not accepted by + * whatToShow will be skipped, but their children may still + * be considered. Note that this skip takes precedence over the filter, + * if any. + */ + public int getWhatToShow(); + + /** + * The NodeFilter used to screen nodes. + */ + public NodeFilter getFilter(); + + /** + * The value of this flag determines whether the children of entity + * reference nodes are visible to the iterator. If false, they and their + * descendents will be rejected. Note that this rejection takes + * precedence over whatToShow and the filter. Also note that + * this is currently the only situation where NodeIterators + * may reject a complete subtree rather than skipping individual nodes. + *
      + *
      To produce a view of the document that has entity references + * expanded and does not expose the entity reference node itself, use the + * whatToShow flags to hide the entity reference node and set + * expandEntityReferences to true when creating the + * iterator. To produce a view of the document that has entity reference + * nodes but no entity expansion, use the whatToShow flags + * to show the entity reference node and set + * expandEntityReferences to false. + */ + public boolean getExpandEntityReferences(); + + /** + * Returns the next node in the set and advances the position of the + * iterator in the set. After a NodeIterator is created, the + * first call tonextNode() returns the first node in the set. + * @return The next Node in the set being iterated over, or + * null if there are no more members in that set. + * @exception DOMException + * INVALID_STATE_ERR: Raised if this method is called after the + * detach method was invoked. + */ + public Node nextNode() + throws DOMException; + + /** + * Returns the previous node in the set and moves the position of the + * NodeIterator backwards in the set. + * @return The previous Node in the set being iterated over, + * ornull if there are no more members in that set. + * @exception DOMException + * INVALID_STATE_ERR: Raised if this method is called after the + * detach method was invoked. + */ + public Node previousNode() + throws DOMException; + + /** + * Detaches the NodeIterator from the set which it iterated + * over, releasing any computational resources and placing the iterator + * in the INVALID state. After detach has been invoked, + * calls tonextNode or previousNode will raise + * the exception INVALID_STATE_ERR. + */ + public void detach(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/TreeWalker.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/TreeWalker.java new file mode 100644 index 000000000..6938fb40c --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/traversal/TreeWalker.java @@ -0,0 +1,167 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.traversal; + +import org.w3c.dom.DOMException; +import org.w3c.dom.Node; + +/** + * TreeWalker objects are used to navigate a document tree or + * subtree using the view of the document defined by their + * whatToShow flags and filter (if any). Any function which + * performs navigation using aTreeWalker will automatically + * support any view defined by aTreeWalker . + *

      Omitting nodes from the logical view of a subtree can result in a + * structure that is substantially different from the same subtree in the + * complete, unfiltered document. Nodes that are siblings in the + * TreeWalker view may be children of different, widely + * separated nodes in the original view. For instance, consider a + * NodeFilter that skips all nodes except for Text nodes and the + * root node of a document. In the logical view that results, all text nodes + * will be siblings and appear as direct children of the root node, no matter + * how deeply nested the structure of the original document. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface TreeWalker { + /** + * The root node of the TreeWalker , as + * specified when it was created. + */ + public Node getRoot(); + + /** + * This attribute determines which node types are presented via the + * TreeWalker . The available set of constants is defined in + * theNodeFilter interface. Nodes not accepted by + * whatToShow will be skipped, but their children may still + * be considered. Note that this skip takes precedence over the filter, + * if any. + */ + public int getWhatToShow(); + + /** + * The filter used to screen nodes. + */ + public NodeFilter getFilter(); + + /** + * The value of this flag determines whether the children of entity + * reference nodes are visible to the TreeWalker . If false, + * they and their descendents will be rejected. Note that this rejection + * takes precedence over whatToShow and the filter, if any. + *
      To produce a view of the document that has entity references + * expanded and does not expose the entity reference node itself, use the + * whatToShow flags to hide the entity reference node and set + * expandEntityReferences to true when creating the + * TreeWalker . To produce a view of the document that has + * entity reference nodes but no entity expansion, use the + * whatToShow flags to show the entity reference node and + * set expandEntityReferences to false. + */ + public boolean getExpandEntityReferences(); + + /** + * The node at which the TreeWalker is currently positioned. + *
      Alterations to the DOM tree may cause the current node to no + * longer be accepted by the TreeWalker 's associated filter. + * currentNode may also be explicitly set to any node, + * whether or not it is within the subtree specified by the + * root node or would be accepted by the filter and + * whatToShow flags. Further traversal occurs relative to + * currentNode even if it is not part of the current view, + * by applying the filters in the requested direction; if no traversal is + * possible, currentNode is not changed. + * @exception DOMException + * NOT_SUPPORTED_ERR: Raised if an attempt is made to set + * currentNode to null . + */ + public Node getCurrentNode(); + public void setCurrentNode(Node currentNode) + throws DOMException; + + /** + * Moves to and returns the closest visible ancestor node of the current + * node. If the search for parentNode attempts to step + * upward from theTreeWalker 's root node, or + * if it fails to find a visible ancestor node, this method retains the + * current position and returnsnull . + * @return The new parent node, or null if the current node + * has no parent in the TreeWalker 's logical view. + */ + public Node parentNode(); + + /** + * Moves the TreeWalker to the first visible child of the + * current node, and returns the new node. If the current node has no + * visible children, returns null , and retains the current + * node. + * @return The new node, or null if the current node has no + * visible children in the TreeWalker 's logical view. + */ + public Node firstChild(); + + /** + * Moves the TreeWalker to the last visible child of the + * current node, and returns the new node. If the current node has no + * visible children, returns null , and retains the current + * node. + * @return The new node, or null if the current node has no + * children in the TreeWalker 's logical view. + */ + public Node lastChild(); + + /** + * Moves the TreeWalker to the previous sibling of the + * current node, and returns the new node. If the current node has no + * visible previous sibling, returns null , and retains the + * current node. + * @return The new node, or null if the current node has no + * previous sibling in the TreeWalker 's logical view. + */ + public Node previousSibling(); + + /** + * Moves the TreeWalker to the next sibling of the current + * node, and returns the new node. If the current node has no visible + * next sibling, returns null , and retains the current node. + * @return The new node, or null if the current node has no + * next sibling in the TreeWalker 's logical view. + */ + public Node nextSibling(); + + /** + * Moves the TreeWalker to the previous visible node in + * document order relative to the current node, and returns the new node. + * If the current node has no previous node, or if the search for + * previousNode attempts to step upward from the + * TreeWalker 's root node, returns + * null , and retains the current node. + * @return The new node, or null if the current node has no + * previous node in the TreeWalker 's logical view. + */ + public Node previousNode(); + + /** + * Moves the TreeWalker to the next visible node in document + * order relative to the current node, and returns the new node. If the + * current node has no next node, or if the search for nextNode attempts + * to step upward from theTreeWalker 's root + * node, returns null , and retains the current node. + * @return The new node, or null if the current node has no + * next node in the TreeWalker 's logical view. + */ + public Node nextNode(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/views/AbstractView.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/views/AbstractView.java new file mode 100644 index 000000000..f25b02c04 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/views/AbstractView.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.views; + +/** + * A base interface that all views shall derive from. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface AbstractView { + /** + * The source DocumentView of which this is an + * AbstractView . + */ + public DocumentView getDocument(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/w3c/dom/views/DocumentView.java b/sources/net.sf.j2s.java.core/src/org/w3c/dom/views/DocumentView.java new file mode 100644 index 000000000..e6f72c81f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/org/w3c/dom/views/DocumentView.java @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2000 World Wide Web Consortium, + * (Massachusetts Institute of Technology, Institut National de + * Recherche en Informatique et en Automatique, Keio University). All + * Rights Reserved. This program is distributed under the W3C's Software + * Intellectual Property License. This program 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 W3C License http://www.w3.org/Consortium/Legal/ for more + * details. + */ + +package org.w3c.dom.views; + +/** + * The DocumentView interface is implemented by + * Document objects in DOM implementations supporting DOM Views. + * It provides an attribute to retrieve the default view of a document. + *

      See also the Document Object Model (DOM) Level 2 Specification. + * @since DOM Level 2 + */ +public interface DocumentView { + /** + * The default AbstractView for this Document , + * or null if none available. + */ + public AbstractView getDefaultView(); + +} + diff --git a/sources/net.sf.j2s.java.core/src/org/xml/sax/helpers/package.html b/sources/net.sf.j2s.java.core/src/org/xml/sax/helpers/package.html deleted file mode 100644 index 8f323c05e..000000000 --- a/sources/net.sf.j2s.java.core/src/org/xml/sax/helpers/package.html +++ /dev/null @@ -1,11 +0,0 @@ - - - - -

      This package contains "helper" classes, including -support for bootstrapping SAX-based applications. - -

      See http://www.saxproject.org -for more information about SAX.

      - - diff --git a/sources/net.sf.j2s.java.core/src/sun/awt/image/ImageWatched.java b/sources/net.sf.j2s.java.core/src/sun/awt/image/ImageWatched.java index 586a7fb78..9971cda0d 100644 --- a/sources/net.sf.j2s.java.core/src/sun/awt/image/ImageWatched.java +++ b/sources/net.sf.j2s.java.core/src/sun/awt/image/ImageWatched.java @@ -28,7 +28,6 @@ package sun.awt.image; -import java.lang.ref.WeakReference; import java.awt.Image; import java.awt.image.ImageObserver; diff --git a/sources/net.sf.j2s.java.core/src/sun/java2d/loops/Blit.java b/sources/net.sf.j2s.java.core/src/sun/java2d/loops/Blit.java index 8b5dd9896..cc7550f02 100644 --- a/sources/net.sf.j2s.java.core/src/sun/java2d/loops/Blit.java +++ b/sources/net.sf.j2s.java.core/src/sun/java2d/loops/Blit.java @@ -24,19 +24,19 @@ */ package sun.java2d.loops; - -import java.awt.Composite; -import java.awt.CompositeContext; -import java.awt.RenderingHints; -import java.awt.image.ColorModel; -import java.awt.image.Raster; -import java.awt.image.WritableRaster; -import java.lang.ref.WeakReference; -import sun.java2d.loops.GraphicsPrimitive; -import sun.java2d.SurfaceData; -import sun.java2d.pipe.Region; -import sun.java2d.pipe.SpanIterator; - +// +//import java.awt.Composite; +//import java.awt.CompositeContext; +//import java.awt.RenderingHints; +//import java.awt.image.ColorModel; +//import java.awt.image.Raster; +//import java.awt.image.WritableRaster; +//import java.lang.ref.WeakReference; +//import sun.java2d.loops.GraphicsPrimitive; +//import sun.java2d.SurfaceData; +//import sun.java2d.pipe.Region; +//import sun.java2d.pipe.SpanIterator; +// /** * Blit * 1) copies rectangle of pixels from one surface to another diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ASCIICaseInsensitiveComparator.java b/sources/net.sf.j2s.java.core/src/sun/misc/ASCIICaseInsensitiveComparator.java new file mode 100644 index 000000000..9fdc6b53b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ASCIICaseInsensitiveComparator.java @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2002, 2004, 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.misc; + +import java.util.Comparator; + +/** Implements a locale and case insensitive comparator suitable for + strings that are known to only contain ASCII characters. Some + tables internal to the JDK contain only ASCII data and are using + the "generalized" java.lang.String case-insensitive comparator + which converts each character to both upper and lower case. */ + +public class ASCIICaseInsensitiveComparator implements Comparator { + public static final Comparator CASE_INSENSITIVE_ORDER = + new ASCIICaseInsensitiveComparator(); + + public int compare(String s1, String s2) { + int n1=s1.length(), n2=s2.length(); + int minLen = n1 < n2 ? n1 : n2; + for (int i=0; i < minLen; i++) { + char c1 = s1.charAt(i); + char c2 = s2.charAt(i); + assert c1 <= '\u007F' && c2 <= '\u007F'; + if (c1 != c2) { + c1 = (char)toLower(c1); + c2 = (char)toLower(c2); + if (c1 != c2) { + return c1 - c2; + } + } + } + return n1 - n2; + } + + /** + * A case insensitive hash code method to go with the case insensitive + * compare() method. + * + * Returns a hash code for this ASCII string as if it were lower case. + * + * returns same answer as:

      + * s.toLowerCase(Locale.US).hashCode();

      + * but does not allocate memory (it does NOT have the special + * case Turkish rules). + * + * @param s a String to compute the hashcode on. + * @return a hash code value for this object. + */ + public static int lowerCaseHashCode(String s) { + int h = 0; + int len = s.length(); + + for (int i = 0; i < len; i++) { + h = 31*h + toLower(s.charAt(i)); + } + + return h; + } + + /* If java.util.regex.ASCII ever becomes public or sun.*, use its code instead:*/ + static boolean isLower(int ch) { + return ((ch-'a')|('z'-ch)) >= 0; + } + + static boolean isUpper(int ch) { + return ((ch-'A')|('Z'-ch)) >= 0; + } + + static int toLower(int ch) { + return isUpper(ch) ? (ch + 0x20) : ch; + } + + static int toUpper(int ch) { + return isLower(ch) ? (ch - 0x20) : ch; + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/BASE64Decoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/BASE64Decoder.java new file mode 100644 index 000000000..e65a1d2bf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/BASE64Decoder.java @@ -0,0 +1,163 @@ +/* + * Copyright (c) 1995, 2011, 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.misc; + +import java.io.OutputStream; +import java.io.PushbackInputStream; +import java.io.PrintStream; + +/** + * This class implements a BASE64 Character decoder as specified in RFC1521. + * + * This RFC is part of the MIME specification which is published by the + * Internet Engineering Task Force (IETF). Unlike some other encoding + * schemes there is nothing in this encoding that tells the decoder + * where a buffer starts or stops, so to use it you will need to isolate + * your encoded data into a single chunk and then feed them this decoder. + * The simplest way to do that is to read all of the encoded data into a + * string and then use: + *

      + *      byte    mydata[];
      + *      BASE64Decoder base64 = new BASE64Decoder();
      + *
      + *      mydata = base64.decodeBuffer(bufferString);
      + * 
      + * This will decode the String in bufferString and give you an array + * of bytes in the array myData. + * + * On errors, this class throws a CEFormatException with the following detail + * strings: + *
      + *    "BASE64Decoder: Not enough bytes for an atom."
      + * 
      + * + * @author Chuck McManis + * @see CharacterEncoder + * @see BASE64Decoder + */ + +public class BASE64Decoder extends CharacterDecoder { + + /** This class has 4 bytes per atom */ + protected int bytesPerAtom() { + return (4); + } + + /** Any multiple of 4 will do, 72 might be common */ + protected int bytesPerLine() { + return (72); + } + + /** + * This character array provides the character to value map + * based on RFC1521. + */ + private final static char pem_array[] = { + // 0 1 2 3 4 5 6 7 + 'A','B','C','D','E','F','G','H', // 0 + 'I','J','K','L','M','N','O','P', // 1 + 'Q','R','S','T','U','V','W','X', // 2 + 'Y','Z','a','b','c','d','e','f', // 3 + 'g','h','i','j','k','l','m','n', // 4 + 'o','p','q','r','s','t','u','v', // 5 + 'w','x','y','z','0','1','2','3', // 6 + '4','5','6','7','8','9','+','/' // 7 + }; + + private final static byte pem_convert_array[] = new byte[256]; + + static { + for (int i = 0; i < 255; i++) { + pem_convert_array[i] = -1; + } + for (int i = 0; i < pem_array.length; i++) { + pem_convert_array[pem_array[i]] = (byte) i; + } + } + + byte decode_buffer[] = new byte[4]; + + /** + * Decode one BASE64 atom into 1, 2, or 3 bytes of data. + */ + @SuppressWarnings("fallthrough") + protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int rem) + throws java.io.IOException + { + int i; + byte a = -1, b = -1, c = -1, d = -1; + + if (rem < 2) { + throw new CEFormatException("BASE64Decoder: Not enough bytes for an atom."); + } + do { + i = inStream.read(); + if (i == -1) { + throw new CEStreamExhausted(); + } + } while (i == '\n' || i == '\r'); + decode_buffer[0] = (byte) i; + + i = readFully(inStream, decode_buffer, 1, rem-1); + if (i == -1) { + throw new CEStreamExhausted(); + } + + if (rem > 3 && decode_buffer[3] == '=') { + rem = 3; + } + if (rem > 2 && decode_buffer[2] == '=') { + rem = 2; + } + switch (rem) { + case 4: + d = pem_convert_array[decode_buffer[3] & 0xff]; + // NOBREAK + case 3: + c = pem_convert_array[decode_buffer[2] & 0xff]; + // NOBREAK + case 2: + b = pem_convert_array[decode_buffer[1] & 0xff]; + a = pem_convert_array[decode_buffer[0] & 0xff]; + break; + } + + switch (rem) { + case 2: + outStream.write( (byte)(((a << 2) & 0xfc) | ((b >>> 4) & 3)) ); + break; + case 3: + outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) ); + outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) ); + break; + case 4: + outStream.write( (byte) (((a << 2) & 0xfc) | ((b >>> 4) & 3)) ); + outStream.write( (byte) (((b << 4) & 0xf0) | ((c >>> 2) & 0xf)) ); + outStream.write( (byte) (((c << 6) & 0xc0) | (d & 0x3f)) ); + break; + } + return; + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/BASE64Encoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/BASE64Encoder.java new file mode 100644 index 000000000..6d3e40043 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/BASE64Encoder.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 1995, 1997, 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.misc; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.IOException; + +/** + * This class implements a BASE64 Character encoder as specified in RFC1521. + * This RFC is part of the MIME specification as published by the Internet + * Engineering Task Force (IETF). Unlike some other encoding schemes there + * is nothing in this encoding that indicates + * where a buffer starts or ends. + * + * This means that the encoded text will simply start with the first line + * of encoded text and end with the last line of encoded text. + * + * @author Chuck McManis + * @see CharacterEncoder + * @see BASE64Decoder + */ + +public class BASE64Encoder extends CharacterEncoder { + + /** this class encodes three bytes per atom. */ + protected int bytesPerAtom() { + return (3); + } + + /** + * this class encodes 57 bytes per line. This results in a maximum + * of 57/3 * 4 or 76 characters per output line. Not counting the + * line termination. + */ + protected int bytesPerLine() { + return (57); + } + + /** This array maps the characters to their 6 bit values */ + private final static char pem_array[] = { + // 0 1 2 3 4 5 6 7 + 'A','B','C','D','E','F','G','H', // 0 + 'I','J','K','L','M','N','O','P', // 1 + 'Q','R','S','T','U','V','W','X', // 2 + 'Y','Z','a','b','c','d','e','f', // 3 + 'g','h','i','j','k','l','m','n', // 4 + 'o','p','q','r','s','t','u','v', // 5 + 'w','x','y','z','0','1','2','3', // 6 + '4','5','6','7','8','9','+','/' // 7 + }; + + /** + * encodeAtom - Take three bytes of input and encode it as 4 + * printable characters. Note that if the length in len is less + * than three is encodes either one or two '=' signs to indicate + * padding characters. + */ + protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len) + throws IOException { + byte a, b, c; + + if (len == 1) { + a = data[offset]; + b = 0; + c = 0; + outStream.write(pem_array[(a >>> 2) & 0x3F]); + outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); + outStream.write('='); + outStream.write('='); + } else if (len == 2) { + a = data[offset]; + b = data[offset+1]; + c = 0; + outStream.write(pem_array[(a >>> 2) & 0x3F]); + outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); + outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); + outStream.write('='); + } else { + a = data[offset]; + b = data[offset+1]; + c = data[offset+2]; + outStream.write(pem_array[(a >>> 2) & 0x3F]); + outStream.write(pem_array[((a << 4) & 0x30) + ((b >>> 4) & 0xf)]); + outStream.write(pem_array[((b << 2) & 0x3c) + ((c >>> 6) & 0x3)]); + outStream.write(pem_array[c & 0x3F]); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/CEFormatException.java b/sources/net.sf.j2s.java.core/src/sun/misc/CEFormatException.java new file mode 100644 index 000000000..6d53fa23d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/CEFormatException.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 1995, 2011, 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.misc; + +import java.io.IOException; + +public class CEFormatException extends IOException { + static final long serialVersionUID = -7139121221067081482L; + public CEFormatException(String s) { + super(s); + } +} + diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/CEStreamExhausted.java b/sources/net.sf.j2s.java.core/src/sun/misc/CEStreamExhausted.java new file mode 100644 index 000000000..fb2054eaf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/CEStreamExhausted.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 1995, 2011, 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.misc; + +import java.io.IOException; + +/** This exception is thrown when EOF is reached */ +public class CEStreamExhausted extends IOException { + static final long serialVersionUID = -5889118049525891904L; +} + diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/CRC16.java b/sources/net.sf.j2s.java.core/src/sun/misc/CRC16.java new file mode 100644 index 000000000..3ec66a0fb --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/CRC16.java @@ -0,0 +1,65 @@ +/* + * Copyright (c) 1994, 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.misc; + +/** + * The CRC-16 class calculates a 16 bit cyclic redundancy check of a set + * of bytes. This error detecting code is used to determine if bit rot + * has occurred in a byte stream. + */ + +public class CRC16 { + + /** value contains the currently computed CRC, set it to 0 initally */ + public int value; + + public CRC16() { + value = 0; + } + + /** update CRC with byte b */ + public void update(byte aByte) { + int a, b; + + a = (int) aByte; + for (int count = 7; count >=0; count--) { + a = a << 1; + b = (a >>> 8) & 1; + if ((value & 0x8000) != 0) { + value = ((value << 1) + b) ^ 0x1021; + } else { + value = (value << 1) + b; + } + } + value = value & 0xffff; + return; + } + + /** reset CRC value to 0 */ + public void reset() { + value = 0; + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Cache.java b/sources/net.sf.j2s.java.core/src/sun/misc/Cache.java new file mode 100644 index 000000000..9a3f134c4 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Cache.java @@ -0,0 +1,346 @@ +/* + * Copyright (c) 1995, 1996, 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.misc; + +import java.util.Dictionary; +import java.util.Enumeration; +import java.util.NoSuchElementException; + +/** + * Caches the collision list. + */ +class CacheEntry extends Ref { + int hash; + Object key; + CacheEntry next; + public Object reconstitute() { + return null; + } +} + +/** + * The Cache class. Maps keys to values. Any object can be used as + * a key and/or value. This is very similar to the Hashtable + * class, except that after putting an object into the Cache, + * it is not guaranteed that a subsequent get will return it. + * The Cache will automatically remove entries if memory is + * getting tight and if the entry is not referenced from outside + * the Cache.

      + * + * To sucessfully store and retrieve objects from a hash table the + * object used as the key must implement the hashCode() and equals() + * methods.

      + * + * This example creates a Cache of numbers. It uses the names of + * the numbers as keys: + *

      + *      Cache numbers = new Cache();
      + *      numbers.put("one", new Integer(1));
      + *      numbers.put("two", new Integer(1));
      + *      numbers.put("three", new Integer(1));
      + * 
      + * To retrieve a number use: + *
      + *      Integer n = (Integer)numbers.get("two");
      + *      if (n != null) {
      + *          System.out.println("two = " + n);
      + *      }
      + * 
      + * + * @see java.lang.Object#hashCode + * @see java.lang.Object#equals + * @see sun.misc.Ref + */ +public +class Cache extends Dictionary { + /** + * The hash table data. + */ + private CacheEntry table[]; + + /** + * The total number of entries in the hash table. + */ + private int count; + + /** + * Rehashes the table when count exceeds this threshold. + */ + private int threshold; + + /** + * The load factor for the hashtable. + */ + private float loadFactor; + + private void init(int initialCapacity, float loadFactor) { + if ((initialCapacity <= 0) || (loadFactor <= 0.0)) { + throw new IllegalArgumentException(); + } + this.loadFactor = loadFactor; + table = new CacheEntry[initialCapacity]; + threshold = (int) (initialCapacity * loadFactor); + } + + /** + * Constructs a new, empty Cache with the specified initial + * capacity and the specified load factor. + * @param initialCapacity the initial number of buckets + * @param loadFactor a number between 0.0 and 1.0, it defines + * the threshold for rehashing the Cache into + * a bigger one. + * @exception IllegalArgumentException If the initial capacity + * is less than or equal to zero. + * @exception IllegalArgumentException If the load factor is + * less than or equal to zero. + */ + public Cache (int initialCapacity, float loadFactor) { + init(initialCapacity, loadFactor); + } + + /** + * Constructs a new, empty Cache with the specified initial + * capacity. + * @param initialCapacity the initial number of buckets + */ + public Cache (int initialCapacity) { + init(initialCapacity, 0.75f); + } + + /** + * Constructs a new, empty Cache. A default capacity and load factor + * is used. Note that the Cache will automatically grow when it gets + * full. + */ + public Cache () { + try { + init(101, 0.75f); + } catch (IllegalArgumentException ex) { + // This should never happen + throw new Error("panic"); + } + } + + /** + * Returns the number of elements contained within the Cache. + */ + public int size() { + return count; + } + + /** + * Returns true if the Cache contains no elements. + */ + public boolean isEmpty() { + return count == 0; + } + + /** + * Returns an enumeration of the Cache's keys. + * @see Cache#elements + * @see Enumeration + */ + public synchronized Enumeration keys() { + return new CacheEnumerator(table, true); + } + + /** + * Returns an enumeration of the elements. Use the Enumeration methods + * on the returned object to fetch the elements sequentially. + * @see Cache#keys + * @see Enumeration + */ + public synchronized Enumeration elements() { + return new CacheEnumerator(table, false); + } + + /** + * Gets the object associated with the specified key in the Cache. + * @param key the key in the hash table + * @returns the element for the key or null if the key + * is not defined in the hash table. + * @see Cache#put + */ + public synchronized Object get(Object key) { + CacheEntry tab[] = table; + int hash = key.hashCode(); + int index = (hash & 0x7FFFFFFF) % tab.length; + for (CacheEntry e = tab[index]; e != null; e = e.next) { + if ((e.hash == hash) && e.key.equals(key)) { + return e.check(); + } + } + return null; + } + + /** + * Rehashes the contents of the table into a bigger table. + * This is method is called automatically when the Cache's + * size exceeds the threshold. + */ + protected void rehash() { + int oldCapacity = table.length; + CacheEntry oldTable[] = table; + + int newCapacity = oldCapacity * 2 + 1; + CacheEntry newTable[] = new CacheEntry[newCapacity]; + + threshold = (int) (newCapacity * loadFactor); + table = newTable; + + // System.out.println("rehash old=" + oldCapacity + ", new=" + + // newCapacity + ", thresh=" + threshold + ", count=" + count); + + for (int i = oldCapacity; i-- > 0;) { + for (CacheEntry old = oldTable[i]; old != null;) { + CacheEntry e = old; + old = old.next; + if (e.check() != null) { + int index = (e.hash & 0x7FFFFFFF) % newCapacity; + e.next = newTable[index]; + newTable[index] = e; + } else + count--; /* remove entries that have disappeared */ + } + } + } + + /** + * Puts the specified element into the Cache, using the specified + * key. The element may be retrieved by doing a get() with the same + * key. The key and the element cannot be null. + * @param key the specified hashtable key + * @param value the specified element + * @return the old value of the key, or null if it did not have one. + * @exception NullPointerException If the value of the specified + * element is null. + * @see Cache#get + */ + public synchronized Object put(Object key, Object value) { + // Make sure the value is not null + if (value == null) { + throw new NullPointerException(); + } + // Makes sure the key is not already in the cache. + CacheEntry tab[] = table; + int hash = key.hashCode(); + int index = (hash & 0x7FFFFFFF) % tab.length; + CacheEntry ne = null; + for (CacheEntry e = tab[index]; e != null; e = e.next) { + if ((e.hash == hash) && e.key.equals(key)) { + Object old = e.check(); + e.setThing(value); + return old; + } else if (e.check() == null) + ne = e; /* reuse old flushed value */ + } + + if (count >= threshold) { + // Rehash the table if the threshold is exceeded + rehash(); + return put(key, value); + } + // Creates the new entry. + if (ne == null) { + ne = new CacheEntry (); + ne.next = tab[index]; + tab[index] = ne; + count++; + } + ne.hash = hash; + ne.key = key; + ne.setThing(value); + return null; + } + + /** + * Removes the element corresponding to the key. Does nothing if the + * key is not present. + * @param key the key that needs to be removed + * @return the value of key, or null if the key was not found. + */ + public synchronized Object remove(Object key) { + CacheEntry tab[] = table; + int hash = key.hashCode(); + int index = (hash & 0x7FFFFFFF) % tab.length; + for (CacheEntry e = tab[index], prev = null; e != null; prev = e, e = e.next) { + if ((e.hash == hash) && e.key.equals(key)) { + if (prev != null) { + prev.next = e.next; + } else { + tab[index] = e.next; + } + count--; + return e.check(); + } + } + return null; + } +} + +/** + * A Cache enumerator class. This class should remain opaque + * to the client. It will use the Enumeration interface. + */ +class CacheEnumerator implements Enumeration { + boolean keys; + int index; + CacheEntry table[]; + CacheEntry entry; + + CacheEnumerator (CacheEntry table[], boolean keys) { + this.table = table; + this.keys = keys; + this.index = table.length; + } + + public boolean hasMoreElements() { + while (index >= 0) { + while (entry != null) + if (entry.check() != null) + return true; + else + entry = entry.next; + while (--index >= 0 && (entry = table[index]) == null) ; + } + return false; + } + + public Object nextElement() { + while (index >= 0) { + if (entry == null) + while (--index >= 0 && (entry = table[index]) == null) ; + if (entry != null) { + CacheEntry e = entry; + entry = e.next; + if (e.check() != null) + return keys ? e.key : e.check(); + } + } + throw new NoSuchElementException("CacheEnumerator"); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/CharacterDecoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/CharacterDecoder.java new file mode 100644 index 000000000..728e76026 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/CharacterDecoder.java @@ -0,0 +1,222 @@ +/* + * Copyright (c) 1995, 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.misc; + +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.io.PushbackInputStream; +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.nio.ByteBuffer; + +/** + * This class defines the decoding half of character encoders. + * A character decoder is an algorithim for transforming 8 bit + * binary data that has been encoded into text by a character + * encoder, back into original binary form. + * + * The character encoders, in general, have been structured + * around a central theme that binary data can be encoded into + * text that has the form: + * + *
      + *      [Buffer Prefix]
      + *      [Line Prefix][encoded data atoms][Line Suffix]
      + *      [Buffer Suffix]
      + * 
      + * + * Of course in the simplest encoding schemes, the buffer has no + * distinct prefix of suffix, however all have some fixed relationship + * between the text in an 'atom' and the binary data itself. + * + * In the CharacterEncoder and CharacterDecoder classes, one complete + * chunk of data is referred to as a buffer. Encoded buffers + * are all text, and decoded buffers (sometimes just referred to as + * buffers) are binary octets. + * + * To create a custom decoder, you must, at a minimum, overide three + * abstract methods in this class. + *
      + *
      bytesPerAtom which tells the decoder how many bytes to + * expect from decodeAtom + *
      decodeAtom which decodes the bytes sent to it as text. + *
      bytesPerLine which tells the encoder the maximum number of + * bytes per line. + *
      + * + * In general, the character decoders return error in the form of a + * CEFormatException. The syntax of the detail string is + *
      + *      DecoderClassName: Error message.
      + * 
      + * + * Several useful decoders have already been written and are + * referenced in the See Also list below. + * + * @author Chuck McManis + * @see CEFormatException + * @see CharacterEncoder + * @see UCDecoder + * @see UUDecoder + * @see BASE64Decoder + */ + +public abstract class CharacterDecoder { + + /** Return the number of bytes per atom of decoding */ + abstract protected int bytesPerAtom(); + + /** Return the maximum number of bytes that can be encoded per line */ + abstract protected int bytesPerLine(); + + /** decode the beginning of the buffer, by default this is a NOP. */ + protected void decodeBufferPrefix(PushbackInputStream aStream, OutputStream bStream) throws IOException { } + + /** decode the buffer suffix, again by default it is a NOP. */ + protected void decodeBufferSuffix(PushbackInputStream aStream, OutputStream bStream) throws IOException { } + + /** + * This method should return, if it knows, the number of bytes + * that will be decoded. Many formats such as uuencoding provide + * this information. By default we return the maximum bytes that + * could have been encoded on the line. + */ + protected int decodeLinePrefix(PushbackInputStream aStream, OutputStream bStream) throws IOException { + return (bytesPerLine()); + } + + /** + * This method post processes the line, if there are error detection + * or correction codes in a line, they are generally processed by + * this method. The simplest version of this method looks for the + * (newline) character. + */ + protected void decodeLineSuffix(PushbackInputStream aStream, OutputStream bStream) throws IOException { } + + /** + * This method does an actual decode. It takes the decoded bytes and + * writes them to the OutputStream. The integer l tells the + * method how many bytes are required. This is always <= bytesPerAtom(). + */ + protected void decodeAtom(PushbackInputStream aStream, OutputStream bStream, int l) throws IOException { + throw new CEStreamExhausted(); + } + + /** + * This method works around the bizarre semantics of BufferedInputStream's + * read method. + */ + protected int readFully(InputStream in, byte buffer[], int offset, int len) + throws java.io.IOException { + for (int i = 0; i < len; i++) { + int q = in.read(); + if (q == -1) + return ((i == 0) ? -1 : i); + buffer[i+offset] = (byte)q; + } + return len; + } + + /** + * Decode the text from the InputStream and write the decoded + * octets to the OutputStream. This method runs until the stream + * is exhausted. + * @exception CEFormatException An error has occurred while decoding + * @exception CEStreamExhausted The input stream is unexpectedly out of data + */ + public void decodeBuffer(InputStream aStream, OutputStream bStream) throws IOException { + int i; + int totalBytes = 0; + + PushbackInputStream ps = new PushbackInputStream (aStream); + decodeBufferPrefix(ps, bStream); + while (true) { + int length; + + try { + length = decodeLinePrefix(ps, bStream); + for (i = 0; (i+bytesPerAtom()) < length; i += bytesPerAtom()) { + decodeAtom(ps, bStream, bytesPerAtom()); + totalBytes += bytesPerAtom(); + } + if ((i + bytesPerAtom()) == length) { + decodeAtom(ps, bStream, bytesPerAtom()); + totalBytes += bytesPerAtom(); + } else { + decodeAtom(ps, bStream, length - i); + totalBytes += (length - i); + } + decodeLineSuffix(ps, bStream); + } catch (CEStreamExhausted e) { + break; + } + } + decodeBufferSuffix(ps, bStream); + } + + /** + * Alternate decode interface that takes a String containing the encoded + * buffer and returns a byte array containing the data. + * @exception CEFormatException An error has occurred while decoding + */ + public byte decodeBuffer(String inputString)[] throws IOException { + byte inputBuffer[] = new byte[inputString.length()]; + ByteArrayInputStream inStream; + ByteArrayOutputStream outStream; + + inputString.getBytes(0, inputString.length(), inputBuffer, 0); + inStream = new ByteArrayInputStream(inputBuffer); + outStream = new ByteArrayOutputStream(); + decodeBuffer(inStream, outStream); + return (outStream.toByteArray()); + } + + /** + * Decode the contents of the inputstream into a buffer. + */ + public byte decodeBuffer(InputStream in)[] throws IOException { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + decodeBuffer(in, outStream); + return (outStream.toByteArray()); + } + + /** + * Decode the contents of the String into a ByteBuffer. + */ + public ByteBuffer decodeBufferToByteBuffer(String inputString) + throws IOException { + return ByteBuffer.wrap(decodeBuffer(inputString)); + } + + /** + * Decode the contents of the inputStream into a ByteBuffer. + */ + public ByteBuffer decodeBufferToByteBuffer(InputStream in) + throws IOException { + return ByteBuffer.wrap(decodeBuffer(in)); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/CharacterEncoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/CharacterEncoder.java new file mode 100644 index 000000000..70c5ff90a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/CharacterEncoder.java @@ -0,0 +1,354 @@ +/* + * Copyright (c) 1995, 2005, 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.misc; + +import java.io.InputStream; +import java.io.ByteArrayInputStream; +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.io.IOException; +import java.nio.ByteBuffer; + + +/** + * This class defines the encoding half of character encoders. + * A character encoder is an algorithim for transforming 8 bit binary + * data into text (generally 7 bit ASCII or 8 bit ISO-Latin-1 text) + * for transmition over text channels such as e-mail and network news. + * + * The character encoders have been structured around a central theme + * that, in general, the encoded text has the form: + * + *
      + *      [Buffer Prefix]
      + *      [Line Prefix][encoded data atoms][Line Suffix]
      + *      [Buffer Suffix]
      + * 
      + * + * In the CharacterEncoder and CharacterDecoder classes, one complete + * chunk of data is referred to as a buffer. Encoded buffers + * are all text, and decoded buffers (sometimes just referred to as + * buffers) are binary octets. + * + * To create a custom encoder, you must, at a minimum, overide three + * abstract methods in this class. + *
      + *
      bytesPerAtom which tells the encoder how many bytes to + * send to encodeAtom + *
      encodeAtom which encodes the bytes sent to it as text. + *
      bytesPerLine which tells the encoder the maximum number of + * bytes per line. + *
      + * + * Several useful encoders have already been written and are + * referenced in the See Also list below. + * + * @author Chuck McManis + * @see CharacterDecoder; + * @see UCEncoder + * @see UUEncoder + * @see BASE64Encoder + */ +public abstract class CharacterEncoder { + + /** Stream that understands "printing" */ + protected PrintStream pStream; + + /** Return the number of bytes per atom of encoding */ + abstract protected int bytesPerAtom(); + + /** Return the number of bytes that can be encoded per line */ + abstract protected int bytesPerLine(); + + /** + * Encode the prefix for the entire buffer. By default is simply + * opens the PrintStream for use by the other functions. + */ + protected void encodeBufferPrefix(OutputStream aStream) throws IOException { + pStream = new PrintStream(aStream); + } + + /** + * Encode the suffix for the entire buffer. + */ + protected void encodeBufferSuffix(OutputStream aStream) throws IOException { + } + + /** + * Encode the prefix that starts every output line. + */ + protected void encodeLinePrefix(OutputStream aStream, int aLength) + throws IOException { + } + + /** + * Encode the suffix that ends every output line. By default + * this method just prints a into the output stream. + */ + protected void encodeLineSuffix(OutputStream aStream) throws IOException { + pStream.println(); + } + + /** Encode one "atom" of information into characters. */ + abstract protected void encodeAtom(OutputStream aStream, byte someBytes[], + int anOffset, int aLength) throws IOException; + + /** + * This method works around the bizarre semantics of BufferedInputStream's + * read method. + */ + protected int readFully(InputStream in, byte buffer[]) + throws java.io.IOException { + for (int i = 0; i < buffer.length; i++) { + int q = in.read(); + if (q == -1) + return i; + buffer[i] = (byte)q; + } + return buffer.length; + } + + /** + * Encode bytes from the input stream, and write them as text characters + * to the output stream. This method will run until it exhausts the + * input stream, but does not print the line suffix for a final + * line that is shorter than bytesPerLine(). + */ + public void encode(InputStream inStream, OutputStream outStream) + throws IOException { + int j; + int numBytes; + byte tmpbuffer[] = new byte[bytesPerLine()]; + + encodeBufferPrefix(outStream); + + while (true) { + numBytes = readFully(inStream, tmpbuffer); + if (numBytes == 0) { + break; + } + encodeLinePrefix(outStream, numBytes); + for (j = 0; j < numBytes; j += bytesPerAtom()) { + + if ((j + bytesPerAtom()) <= numBytes) { + encodeAtom(outStream, tmpbuffer, j, bytesPerAtom()); + } else { + encodeAtom(outStream, tmpbuffer, j, (numBytes)- j); + } + } + if (numBytes < bytesPerLine()) { + break; + } else { + encodeLineSuffix(outStream); + } + } + encodeBufferSuffix(outStream); + } + + /** + * Encode the buffer in aBuffer and write the encoded + * result to the OutputStream aStream. + */ + public void encode(byte aBuffer[], OutputStream aStream) + throws IOException { + ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); + encode(inStream, aStream); + } + + /** + * A 'streamless' version of encode that simply takes a buffer of + * bytes and returns a string containing the encoded buffer. + */ + public String encode(byte aBuffer[]) { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); + String retVal = null; + try { + encode(inStream, outStream); + // explicit ascii->unicode conversion + retVal = outStream.toString("8859_1"); + } catch (Exception IOException) { + // This should never happen. + throw new Error("CharacterEncoder.encode internal error"); + } + return (retVal); + } + + /** + * Return a byte array from the remaining bytes in this ByteBuffer. + *

      + * The ByteBuffer's position will be advanced to ByteBuffer's limit. + *

      + * To avoid an extra copy, the implementation will attempt to return the + * byte array backing the ByteBuffer. If this is not possible, a + * new byte array will be created. + */ + private byte [] getBytes(ByteBuffer bb) { + /* + * This should never return a BufferOverflowException, as we're + * careful to allocate just the right amount. + */ + byte [] buf = null; + + /* + * If it has a usable backing byte buffer, use it. Use only + * if the array exactly represents the current ByteBuffer. + */ + if (bb.hasArray()) { + byte [] tmp = bb.array(); + if ((tmp.length == bb.capacity()) && + (tmp.length == bb.remaining())) { + buf = tmp; + bb.position(bb.limit()); + } + } + + if (buf == null) { + /* + * This class doesn't have a concept of encode(buf, len, off), + * so if we have a partial buffer, we must reallocate + * space. + */ + buf = new byte[bb.remaining()]; + + /* + * position() automatically updated + */ + bb.get(buf); + } + + return buf; + } + + /** + * Encode the aBuffer ByteBuffer and write the encoded + * result to the OutputStream aStream. + *

      + * The ByteBuffer's position will be advanced to ByteBuffer's limit. + */ + public void encode(ByteBuffer aBuffer, OutputStream aStream) + throws IOException { + byte [] buf = getBytes(aBuffer); + encode(buf, aStream); + } + + /** + * A 'streamless' version of encode that simply takes a ByteBuffer + * and returns a string containing the encoded buffer. + *

      + * The ByteBuffer's position will be advanced to ByteBuffer's limit. + */ + public String encode(ByteBuffer aBuffer) { + byte [] buf = getBytes(aBuffer); + return encode(buf); + } + + /** + * Encode bytes from the input stream, and write them as text characters + * to the output stream. This method will run until it exhausts the + * input stream. It differs from encode in that it will add the + * line at the end of a final line that is shorter than bytesPerLine(). + */ + public void encodeBuffer(InputStream inStream, OutputStream outStream) + throws IOException { + int j; + int numBytes; + byte tmpbuffer[] = new byte[bytesPerLine()]; + + encodeBufferPrefix(outStream); + + while (true) { + numBytes = readFully(inStream, tmpbuffer); + if (numBytes == 0) { + break; + } + encodeLinePrefix(outStream, numBytes); + for (j = 0; j < numBytes; j += bytesPerAtom()) { + if ((j + bytesPerAtom()) <= numBytes) { + encodeAtom(outStream, tmpbuffer, j, bytesPerAtom()); + } else { + encodeAtom(outStream, tmpbuffer, j, (numBytes)- j); + } + } + encodeLineSuffix(outStream); + if (numBytes < bytesPerLine()) { + break; + } + } + encodeBufferSuffix(outStream); + } + + /** + * Encode the buffer in aBuffer and write the encoded + * result to the OutputStream aStream. + */ + public void encodeBuffer(byte aBuffer[], OutputStream aStream) + throws IOException { + ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); + encodeBuffer(inStream, aStream); + } + + /** + * A 'streamless' version of encode that simply takes a buffer of + * bytes and returns a string containing the encoded buffer. + */ + public String encodeBuffer(byte aBuffer[]) { + ByteArrayOutputStream outStream = new ByteArrayOutputStream(); + ByteArrayInputStream inStream = new ByteArrayInputStream(aBuffer); + try { + encodeBuffer(inStream, outStream); + } catch (Exception IOException) { + // This should never happen. + throw new Error("CharacterEncoder.encodeBuffer internal error"); + } + return (outStream.toString()); + } + + /** + * Encode the aBuffer ByteBuffer and write the encoded + * result to the OutputStream aStream. + *

      + * The ByteBuffer's position will be advanced to ByteBuffer's limit. + */ + public void encodeBuffer(ByteBuffer aBuffer, OutputStream aStream) + throws IOException { + byte [] buf = getBytes(aBuffer); + encodeBuffer(buf, aStream); + } + + /** + * A 'streamless' version of encode that simply takes a ByteBuffer + * and returns a string containing the encoded buffer. + *

      + * The ByteBuffer's position will be advanced to ByteBuffer's limit. + */ + public String encodeBuffer(ByteBuffer aBuffer) { + byte [] buf = getBytes(aBuffer); + return encodeBuffer(buf); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ClassFileTransformer.java b/sources/net.sf.j2s.java.core/src/sun/misc/ClassFileTransformer.java new file mode 100644 index 000000000..06a195987 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ClassFileTransformer.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2001, 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.misc; + +import java.util.ArrayList; +import java.util.List; + +/** + * This is an abstract base class originally intended to be called by + * {@code java.lang.ClassLoader} when {@code ClassFormatError} is + * thrown inside {@code defineClass()}. It is no longer hooked into + * {@code ClassLoader} and will be removed in a future release. + * + * @author Stanley Man-Kit Ho + */ + +@Deprecated +public abstract class ClassFileTransformer { + + private static final List transformers + = new ArrayList(); + + /** + * Add the class file transformer object. + * + * @param t Class file transformer instance + */ + public static void add(ClassFileTransformer t) { + synchronized (transformers) { + transformers.add(t); + } + } + + /** + * Get the array of ClassFileTransformer object. + * + * @return ClassFileTransformer object array + */ + public static ClassFileTransformer[] getTransformers() { + synchronized (transformers) { + ClassFileTransformer[] result = new ClassFileTransformer[transformers.size()]; + return transformers.toArray(result); + } + } + + + /** + * Transform a byte array from one to the other. + * + * @param b Byte array + * @param off Offset + * @param len Length of byte array + * @return Transformed byte array + */ + public abstract byte[] transform(byte[] b, int off, int len) + throws ClassFormatError; +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ClassLoaderUtil.java b/sources/net.sf.j2s.java.core/src/sun/misc/ClassLoaderUtil.java new file mode 100644 index 000000000..06cc7ff0d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ClassLoaderUtil.java @@ -0,0 +1,172 @@ +/* + * Copyright (c) 2006, 2011, 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.misc; + +/** + * Provides utility functions related to URLClassLoaders or subclasses of it. + * + * W A R N I N G + * + * This class uses undocumented, unpublished, private data structures inside + * java.net.URLClassLoader and sun.misc.URLClassPath. Use with extreme caution. + * + * @author tjquinn + */ + + +import java.io.IOException; +import java.net.URLClassLoader; +import java.util.*; +import java.util.jar.JarFile; + +public class ClassLoaderUtil { + + /** + * Releases resources held by a URLClassLoader. A new classloader must + * be created before the underlying resources can be accessed again. + * @param classLoader the instance of URLClassLoader (or a subclass) + */ + public static void releaseLoader(URLClassLoader classLoader) { + releaseLoader(classLoader, null); + } + + /** + * Releases resources held by a URLClassLoader. Notably, close the jars + * opened by the loader. Initializes and updates the List of + * jars that have been successfully closed. + *

      + * @param classLoader the instance of URLClassLoader (or a subclass) + * @param jarsClosed a List of Strings that will contain the names of jars + * successfully closed; can be null if the caller does not need the information returned + * @return a List of IOExceptions reporting jars that failed to close; null + * indicates that an error other than an IOException occurred attempting to + * release the loader; empty indicates a successful release; non-empty + * indicates at least one error attempting to close an open jar. + */ + public static List releaseLoader(URLClassLoader classLoader, List jarsClosed) { + + List ioExceptions = new LinkedList(); + + try { + /* Records all IOExceptions thrown while closing jar files. */ + + if (jarsClosed != null) { + jarsClosed.clear(); + } + + URLClassPath ucp = SharedSecrets.getJavaNetAccess() + .getURLClassPath(classLoader); + ArrayList loaders = ucp.loaders; + Stack urls = ucp.urls; + HashMap lmap = ucp.lmap; + + /* + *The urls variable in the URLClassPath object holds URLs that have not yet + *been used to resolve a resource or load a class and, therefore, do + *not yet have a loader associated with them. Clear the stack so any + *future requests that might incorrectly reach the loader cannot be + *resolved and cannot open a jar file after we think we've closed + *them all. + */ + synchronized(urls) { + urls.clear(); + } + + /* + *Also clear the map of URLs to loaders so the class loader cannot use + *previously-opened jar files - they are about to be closed. + */ + synchronized(lmap) { + lmap.clear(); + } + + /* + *The URLClassPath object's path variable records the list of all URLs that are on + *the URLClassPath's class path. Leave that unchanged. This might + *help someone trying to debug why a released class loader is still used. + *Because the stack and lmap are now clear, code that incorrectly uses a + *the released class loader will trigger an exception if the + *class or resource would have been resolved by the class + *loader (and no other) if it had not been released. + * + *The list of URLs might provide some hints to the person as to where + *in the code the class loader was set up, which might in turn suggest + *where in the code the class loader needs to stop being used. + *The URLClassPath does not use the path variable to open new jar + *files - it uses the urls Stack for that - so leaving the path variable + *will not by itself allow the class loader to continue handling requests. + */ + + /* + *For each loader, close the jar file associated with that loader. + * + *The URLClassPath's use of loaders is sync-ed on the entire URLClassPath + *object. + */ + synchronized (ucp) { + for (Object o : loaders) { + if (o != null) { + /* + *If the loader is a JarLoader inner class and its jarFile + *field is non-null then try to close that jar file. Add + *it to the list of closed files if successful. + */ + if (o instanceof URLClassPath.JarLoader) { + URLClassPath.JarLoader jl = (URLClassPath.JarLoader)o; + JarFile jarFile = jl.getJarFile(); + try { + if (jarFile != null) { + jarFile.close(); + if (jarsClosed != null) { + jarsClosed.add(jarFile.getName()); + } + } + } catch (IOException ioe) { + /* + *Wrap the IOException to identify which jar + *could not be closed and add it to the list + *of IOExceptions to be returned to the caller. + */ + String jarFileName = (jarFile == null) ? "filename not available":jarFile.getName(); + String msg = "Error closing JAR file: " + jarFileName; + IOException newIOE = new IOException(msg); + newIOE.initCause(ioe); + ioExceptions.add(newIOE); + } + } + } + } + /* + *Now clear the loaders ArrayList. + */ + loaders.clear(); + } + } catch (Throwable t) { + throw new RuntimeException (t); + } + return ioExceptions; + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Cleaner.java b/sources/net.sf.j2s.java.core/src/sun/misc/Cleaner.java new file mode 100644 index 000000000..4baece6c6 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Cleaner.java @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2003, 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.misc; + +//import java.lang.ref.*; +import java.security.AccessController; +import java.security.PrivilegedAction; + + +/** + * General-purpose phantom-reference-based cleaners. + * + *

      Cleaners are a lightweight and more robust alternative to finalization. + * They are lightweight because they are not created by the VM and thus do not + * require a JNI upcall to be created, and because their cleanup code is + * invoked directly by the reference-handler thread rather than by the + * finalizer thread. They are more robust because they use phantom references, + * the weakest type of reference object, thereby avoiding the nasty ordering + * problems inherent to finalization. + * + *

      A cleaner tracks a referent object and encapsulates a thunk of arbitrary + * cleanup code. Some time after the GC detects that a cleaner's referent has + * become phantom-reachable, the reference-handler thread will run the cleaner. + * Cleaners may also be invoked directly; they are thread safe and ensure that + * they run their thunks at most once. + * + *

      Cleaners are not a replacement for finalization. They should be used + * only when the cleanup code is extremely simple and straightforward. + * Nontrivial cleaners are inadvisable since they risk blocking the + * reference-handler thread and delaying further cleanup and finalization. + * + * + * @author Mark Reinhold + */ + +public class Cleaner + // extends PhantomReference +{ +// +// // Dummy reference queue, needed because the PhantomReference constructor +// // insists that we pass a queue. Nothing will ever be placed on this queue +// // since the reference handler invokes cleaners explicitly. +// // +// private static final ReferenceQueue dummyQueue = new ReferenceQueue<>(); +// +// // Doubly-linked list of live cleaners, which prevents the cleaners +// // themselves from being GC'd before their referents +// // +// static private Cleaner first = null; +// +// private Cleaner +// next = null, +// prev = null; +// +// private static synchronized Cleaner add(Cleaner cl) { +// if (first != null) { +// cl.next = first; +// first.prev = cl; +// } +// first = cl; +// return cl; +// } +// +// private static synchronized boolean remove(Cleaner cl) { +// +// // If already removed, do nothing +// if (cl.next == cl) +// return false; +// +// // Update list +// if (first == cl) { +// if (cl.next != null) +// first = cl.next; +// else +// first = cl.prev; +// } +// if (cl.next != null) +// cl.next.prev = cl.prev; +// if (cl.prev != null) +// cl.prev.next = cl.next; +// +// // Indicate removal by pointing the cleaner to itself +// cl.next = cl; +// cl.prev = cl; +// return true; +// +// } +// +// private final Runnable thunk; +// +// private Cleaner(Object referent, Runnable thunk) { +// super(referent, dummyQueue); +// this.thunk = thunk; +// } +// +// /** +// * Creates a new cleaner. +// * +// * @param ob the referent object to be cleaned +// * @param thunk +// * The cleanup code to be run when the cleaner is invoked. The +// * cleanup code is run directly from the reference-handler thread, +// * so it should be as simple and straightforward as possible. +// * +// * @return The new cleaner +// */ +// public static Cleaner create(Object ob, Runnable thunk) { +// if (thunk == null) +// return null; +// return add(new Cleaner(ob, thunk)); +// } +// +// /** +// * Runs this cleaner, if it has not been run before. +// */ +// public void clean() { +// if (!remove(this)) +// return; +// try { +// thunk.run(); +// } catch (final Throwable x) { +// AccessController.doPrivileged(new PrivilegedAction() { +// public Void run() { +// if (System.err != null) +// new Error("Cleaner terminated abnormally", x) +// .printStackTrace(); +// System.exit(1); +// return null; +// }}); +// } +// } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/CompoundEnumeration.java b/sources/net.sf.j2s.java.core/src/sun/misc/CompoundEnumeration.java new file mode 100644 index 000000000..a89ec5f59 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/CompoundEnumeration.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 1998, 2011, 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.misc; + +import java.util.Enumeration; +import java.util.NoSuchElementException; + +/* + * A useful utility class that will enumerate over an array of + * enumerations. + */ +public class CompoundEnumeration implements Enumeration { + private Enumeration[] enums; + private int index = 0; + + public CompoundEnumeration(Enumeration[] enums) { + this.enums = enums; + } + + private boolean next() { + while (index < enums.length) { + if (enums[index] != null && enums[index].hasMoreElements()) { + return true; + } + index++; + } + return false; + } + + public boolean hasMoreElements() { + return next(); + } + + public E nextElement() { + if (!next()) { + throw new NoSuchElementException(); + } + return enums[index].nextElement(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ConditionLock.java b/sources/net.sf.j2s.java.core/src/sun/misc/ConditionLock.java new file mode 100644 index 000000000..e1af52521 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ConditionLock.java @@ -0,0 +1,82 @@ +/* + * Copyright (c) 1994, 2005, 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.misc; + +/** + * ConditionLock is a Lock with a built in state variable. This class + * provides the ability to wait for the state variable to be set to a + * desired value and then acquire the lock.

      + * + * The lockWhen() and unlockWith() methods can be safely intermixed + * with the lock() and unlock() methods. However if there is a thread + * waiting for the state variable to become a particular value and you + * simply call Unlock(), that thread will not be able to acquire the + * lock until the state variable equals its desired value.

      + * + * @author Peter King + */ +public final +class ConditionLock extends Lock { + private int state = 0; + + /** + * Creates a ConditionLock. + */ + public ConditionLock () { + } + + /** + * Creates a ConditionLock in an initialState. + */ + public ConditionLock (int initialState) { + state = initialState; + } + + /** + * Acquires the lock when the state variable equals the desired state. + * + * @param desiredState the desired state + * @exception java.lang.InterruptedException if any thread has + * interrupted this thread. + */ + public synchronized void lockWhen(int desiredState) + throws InterruptedException + { + while (state != desiredState) { + wait(); + } + lock(); + } + + /** + * Releases the lock, and sets the state to a new value. + * @param newState the new state + */ + public synchronized void unlockWith(int newState) { + state = newState; + unlock(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Contended.java b/sources/net.sf.j2s.java.core/src/sun/misc/Contended.java new file mode 100644 index 000000000..2269687a9 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Contended.java @@ -0,0 +1,83 @@ +/* + * 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.misc; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + *

      An annotation expressing that objects and/or their fields are + * expected to encounter memory contention, generally in the form of + * "false sharing". This annotation serves as a hint that such objects + * and fields should reside in locations isolated from those of other + * objects or fields. Susceptibility to memory contention is a + * property of the intended usages of objects and fields, not their + * types or qualifiers. The effects of this annotation will nearly + * always add significant space overhead to objects. The use of + * {@code @Contended} is warranted only when the performance impact of + * this time/space tradeoff is intrinsically worthwhile; for example, + * in concurrent contexts in which each instance of the annotated + * class is often accessed by a different thread. + * + *

      A {@code @Contended} field annotation may optionally include a + * contention group tag. A contention group defines a set of one + * or more fields that collectively must be isolated from all other + * contention groups. The fields in the same contention group may not be + * pairwise isolated. With no contention group tag (or with the default + * empty tag: "") each {@code @Contended} field resides in its own + * distinct and anonymous contention group. + * + *

      When the annotation is used at the class level, the effect is + * equivalent to grouping all the declared fields not already having the + * {@code @Contended} annotation into the same anonymous group. + * With the class level annotation, implementations may choose different + * isolation techniques, such as isolating the entire object, rather than + * isolating distinct fields. A contention group tag has no meaning + * in a class level {@code @Contended} annotation, and is ignored. + * + *

      The class level {@code @Contended} annotation is not inherited and has + * no effect on the fields declared in any sub-classes. The effects of all + * {@code @Contended} annotations, however, remain in force for all + * subclass instances, providing isolation of all the defined contention + * groups. Contention group tags are not inherited, and the same tag used + * in a superclass and subclass, represent distinct contention groups. + * + * @since 1.8 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target({ElementType.FIELD, ElementType.TYPE}) +public @interface Contended { + + /** + * The (optional) contention group tag. + * This tag is only meaningful for field level annotations. + * + * @return contention group tag. + */ + String value() default ""; +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/DoubleConsts.java b/sources/net.sf.j2s.java.core/src/sun/misc/DoubleConsts.java new file mode 100644 index 000000000..2c5964b78 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/DoubleConsts.java @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2003, 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.misc; + +/** + * This class contains additional constants documenting limits of the + * double type. + * + * @author Joseph D. Darcy + */ + +public class DoubleConsts { + /** + * Don't let anyone instantiate this class. + */ + private DoubleConsts() {} + + public static final double POSITIVE_INFINITY = java.lang.Double.POSITIVE_INFINITY; + public static final double NEGATIVE_INFINITY = java.lang.Double.NEGATIVE_INFINITY; + public static final double NaN = java.lang.Double.NaN; + public static final double MAX_VALUE = java.lang.Double.MAX_VALUE; + public static final double MIN_VALUE = java.lang.Double.MIN_VALUE; + + /** + * A constant holding the smallest positive normal value of type + * double, 2-1022. It is equal to the + * value returned by + * Double.longBitsToDouble(0x0010000000000000L). + * + * @since 1.5 + */ + public static final double MIN_NORMAL = 2.2250738585072014E-308; + + + /** + * The number of logical bits in the significand of a + * double number, including the implicit bit. + */ + public static final int SIGNIFICAND_WIDTH = 53; + + /** + * Maximum exponent a finite double number may have. + * It is equal to the value returned by + * Math.ilogb(Double.MAX_VALUE). + */ + public static final int MAX_EXPONENT = 1023; + + /** + * Minimum exponent a normalized double number may + * have. It is equal to the value returned by + * Math.ilogb(Double.MIN_NORMAL). + */ + public static final int MIN_EXPONENT = -1022; + + /** + * The exponent the smallest positive double + * subnormal value would have if it could be normalized. It is + * equal to the value returned by + * FpUtils.ilogb(Double.MIN_VALUE). + */ + public static final int MIN_SUB_EXPONENT = MIN_EXPONENT - + (SIGNIFICAND_WIDTH - 1); + + /** + * Bias used in representing a double exponent. + */ + public static final int EXP_BIAS = 1023; + + /** + * Bit mask to isolate the sign bit of a double. + */ + public static final long SIGN_BIT_MASK = 0x8000000000000000L; + + /** + * Bit mask to isolate the exponent field of a + * double. + */ + public static final long EXP_BIT_MASK = 0x7FF0000000000000L; + + /** + * Bit mask to isolate the significand field of a + * double. + */ + public static final long SIGNIF_BIT_MASK = 0x000FFFFFFFFFFFFFL; + + static { + // verify bit masks cover all bit positions and that the bit + // masks are non-overlapping + assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0L) && + (((SIGN_BIT_MASK & EXP_BIT_MASK) == 0L) && + ((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0L) && + ((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0L))); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionDependency.java b/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionDependency.java new file mode 100644 index 000000000..9f0d0841e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionDependency.java @@ -0,0 +1,570 @@ +/* + * Copyright (c) 1999, 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.misc; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.FileNotFoundException; +import java.util.StringTokenizer; +import java.util.Vector; +import java.util.Enumeration; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.jar.Attributes; +import java.util.jar.Attributes.Name; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.security.PrivilegedActionException; +import java.net.URL; +import java.net.MalformedURLException; +import sun.net.www.ParseUtil; + +/** + *

      + * This class checks dependent extensions a particular jar file may have + * declared through its manifest attributes. + *

      + * Jar file declared dependent extensions through the extension-list + * attribute. The extension-list contains a list of keys used to + * fetch the other attributes describing the required extension. + * If key is the extension key declared in the extension-list + * attribute, the following describing attribute can be found in + * the manifest : + * key-Extension-Name: (Specification package name) + * key-Specification-Version: (Specification-Version) + * key-Implementation-Version: (Implementation-Version) + * key-Implementation-Vendor-Id: (Imlementation-Vendor-Id) + * key-Implementation-Version: (Implementation version) + * key-Implementation-URL: (URL to download the requested extension) + *

      + * This class also maintain versioning consistency of installed + * extensions dependencies declared in jar file manifest. + *

      + * @author Jerome Dochez + */ +public class ExtensionDependency { + + /* Callbak interfaces to delegate installation of missing extensions */ + private static Vector providers; + + /** + *

      + * Register an ExtensionInstallationProvider. The provider is responsible + * for handling the installation (upgrade) of any missing extensions. + *

      + * @param eip ExtensionInstallationProvider implementation + */ + public synchronized static void addExtensionInstallationProvider + (ExtensionInstallationProvider eip) + { + if (providers == null) { + providers = new Vector<>(); + } + providers.add(eip); + } + + /** + *

      + * Unregister a previously installed installation provider + *

      + */ + public synchronized static void removeExtensionInstallationProvider + (ExtensionInstallationProvider eip) + { + providers.remove(eip); + } + + /** + *

      + * Checks the dependencies of the jar file on installed extension. + *

      + * @param jarFile containing the attriutes declaring the dependencies + */ + public static boolean checkExtensionsDependencies(JarFile jar) + { + if (providers == null) { + // no need to bother, nobody is registered to install missing + // extensions + return true; + } + + try { + ExtensionDependency extDep = new ExtensionDependency(); + return extDep.checkExtensions(jar); + } catch (ExtensionInstallationException e) { + debug(e.getMessage()); + } + return false; + } + + /* + * Check for all declared required extensions in the jar file + * manifest. + */ + protected boolean checkExtensions(JarFile jar) + throws ExtensionInstallationException + { + Manifest man; + try { + man = jar.getManifest(); + } catch (IOException e) { + return false; + } + + if (man == null) { + // The applet does not define a manifest file, so + // we just assume all dependencies are satisfied. + return true; + } + + boolean result = true; + Attributes attr = man.getMainAttributes(); + if (attr != null) { + // Let's get the list of declared dependencies + String value = attr.getValue(Name.EXTENSION_LIST); + if (value != null) { + StringTokenizer st = new StringTokenizer(value); + // Iterate over all declared dependencies + while (st.hasMoreTokens()) { + String extensionName = st.nextToken(); + debug("The file " + jar.getName() + + " appears to depend on " + extensionName); + // Sanity Check + String extName = extensionName + "-" + + Name.EXTENSION_NAME.toString(); + if (attr.getValue(extName) == null) { + debug("The jar file " + jar.getName() + + " appers to depend on " + + extensionName + " but does not define the " + + extName + " attribute in its manifest "); + + } else { + if (!checkExtension(extensionName, attr)) { + debug("Failed installing " + extensionName); + result = false; + } + } + } + } else { + debug("No dependencies for " + jar.getName()); + } + } + return result; + } + + + /* + *

      + * Check that a particular dependency on an extension is satisfied. + *

      + * @param extensionName is the key used for the attributes in the manifest + * @param attr is the attributes of the manifest file + * + * @return true if the dependency is satisfied by the installed extensions + */ + protected synchronized boolean checkExtension(final String extensionName, + final Attributes attr) + throws ExtensionInstallationException + { + debug("Checking extension " + extensionName); + if (checkExtensionAgainstInstalled(extensionName, attr)) + return true; + + debug("Extension not currently installed "); + ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr); + return installExtension(reqInfo, null); + } + + /* + *

      + * Check if a particular extension is part of the currently installed + * extensions. + *

      + * @param extensionName is the key for the attributes in the manifest + * @param attr is the attributes of the manifest + * + * @return true if the requested extension is already installed + */ + boolean checkExtensionAgainstInstalled(String extensionName, + Attributes attr) + throws ExtensionInstallationException + { + File fExtension = checkExtensionExists(extensionName); + + if (fExtension != null) { + // Extension already installed, just check against this one + try { + if (checkExtensionAgainst(extensionName, attr, fExtension)) + return true; + } catch (FileNotFoundException e) { + debugException(e); + } catch (IOException e) { + debugException(e); + } + return false; + + } else { + // Not sure if extension is already installed, so check all the + // installed extension jar files to see if we get a match + + File[] installedExts; + + try { + // Get the list of installed extension jar files so we can + // compare the installed versus the requested extension + installedExts = getInstalledExtensions(); + } catch(IOException e) { + debugException(e); + return false; + } + + for (int i=0;i + * Check if the requested extension described by the attributes + * in the manifest under the key extensionName is compatible with + * the jar file. + *

      + * + * @param extensionName key in the attribute list + * @param attr manifest file attributes + * @param file installed extension jar file to compare the requested + * extension against. + */ + protected boolean checkExtensionAgainst(String extensionName, + Attributes attr, + final File file) + throws IOException, + FileNotFoundException, + ExtensionInstallationException + { + + debug("Checking extension " + extensionName + + " against " + file.getName()); + + // Load the jar file ... + Manifest man; + try { + man = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public Manifest run() + throws IOException, FileNotFoundException { + if (!file.exists()) + throw new FileNotFoundException(file.getName()); + JarFile jarFile = new JarFile(file); + return jarFile.getManifest(); + } + }); + } catch(PrivilegedActionException e) { + if (e.getException() instanceof FileNotFoundException) + throw (FileNotFoundException) e.getException(); + throw (IOException) e.getException(); + } + + // Construct the extension information object + ExtensionInfo reqInfo = new ExtensionInfo(extensionName, attr); + debug("Requested Extension : " + reqInfo); + + int isCompatible = ExtensionInfo.INCOMPATIBLE; + ExtensionInfo instInfo = null; + + if (man != null) { + Attributes instAttr = man.getMainAttributes(); + if (instAttr != null) { + instInfo = new ExtensionInfo(null, instAttr); + debug("Extension Installed " + instInfo); + isCompatible = instInfo.isCompatibleWith(reqInfo); + switch(isCompatible) { + case ExtensionInfo.COMPATIBLE: + debug("Extensions are compatible"); + return true; + + case ExtensionInfo.INCOMPATIBLE: + debug("Extensions are incompatible"); + return false; + + default: + // everything else + debug("Extensions require an upgrade or vendor switch"); + return installExtension(reqInfo, instInfo); + + } + } + } + return false; + } + + /* + *

      + * An required extension is missing, if an ExtensionInstallationProvider is + * registered, delegate the installation of that particular extension to it. + *

      + * + * @param reqInfo Missing extension information + * @param instInfo Older installed version information + * + * @return true if the installation is successful + */ + protected boolean installExtension(ExtensionInfo reqInfo, + ExtensionInfo instInfo) + throws ExtensionInstallationException + { + Vector currentProviders; + synchronized(providers) { + @SuppressWarnings("unchecked") + Vector tmp = + (Vector) providers.clone(); + currentProviders = tmp; + } + for (Enumeration e = currentProviders.elements(); + e.hasMoreElements();) { + ExtensionInstallationProvider eip = e.nextElement(); + + if (eip!=null) { + // delegate the installation to the provider + if (eip.installExtension(reqInfo, instInfo)) { + debug(reqInfo.name + " installation successful"); + Launcher.ExtClassLoader cl = (Launcher.ExtClassLoader) + Launcher.getLauncher().getClassLoader().getParent(); + addNewExtensionsToClassLoader(cl); + return true; + } + } + } + // We have tried all of our providers, noone could install this + // extension, we just return failure at this point + debug(reqInfo.name + " installation failed"); + return false; + } + + /** + *

      + * Checks if the extension, that is specified in the extension-list in + * the applet jar manifest, is already installed (i.e. exists in the + * extension directory). + *

      + * + * @param extensionName extension name in the extension-list + * + * @return the extension if it exists in the extension directory + */ + private File checkExtensionExists(String extensionName) { + // Function added to fix bug 4504166 + final String extName = extensionName; + final String[] fileExt = {".jar", ".zip"}; + + return AccessController.doPrivileged( + new PrivilegedAction() { + public File run() { + try { + File fExtension; + File[] dirs = getExtDirs(); + + // Search the extension directories for the extension that is specified + // in the attribute extension-list in the applet jar manifest + for (int i=0;i + * @return the java.ext.dirs property as a list of directory + *

      + */ + private static File[] getExtDirs() { + String s = java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("java.ext.dirs")); + + File[] dirs; + if (s != null) { + StringTokenizer st = + new StringTokenizer(s, File.pathSeparator); + int count = st.countTokens(); + debug("getExtDirs count " + count); + dirs = new File[count]; + for (int i = 0; i < count; i++) { + dirs[i] = new File(st.nextToken()); + debug("getExtDirs dirs["+i+"] "+ dirs[i]); + } + } else { + dirs = new File[0]; + debug("getExtDirs dirs " + dirs); + } + debug("getExtDirs dirs.length " + dirs.length); + return dirs; + } + + /* + *

      + * Scan the directories and return all files installed in those + *

      + * @param dirs list of directories to scan + * + * @return the list of files installed in all the directories + */ + private static File[] getExtFiles(File[] dirs) throws IOException { + Vector urls = new Vector(); + for (int i = 0; i < dirs.length; i++) { + String[] files = dirs[i].list(new JarFilter()); + if (files != null) { + debug("getExtFiles files.length " + files.length); + for (int j = 0; j < files.length; j++) { + File f = new File(dirs[i], files[j]); + urls.add(f); + debug("getExtFiles f["+j+"] "+ f); + } + } + } + File[] ua = new File[urls.size()]; + urls.copyInto(ua); + debug("getExtFiles ua.length " + ua.length); + return ua; + } + + /* + *

      + * @return the list of installed extensions jar files + *

      + */ + private File[] getInstalledExtensions() throws IOException { + return AccessController.doPrivileged( + new PrivilegedAction() { + public File[] run() { + try { + return getExtFiles(getExtDirs()); + } catch(IOException e) { + debug("Cannot get list of installed extensions"); + debugException(e); + return new File[0]; + } + } + }); + } + + /* + *

      + * Add the newly installed jar file to the extension class loader. + *

      + * + * @param cl the current installed extension class loader + * + * @return true if successful + */ + private Boolean addNewExtensionsToClassLoader(Launcher.ExtClassLoader cl) { + try { + File[] installedExts = getInstalledExtensions(); + for (int i=0;i() { + public URL run() { + try { + return ParseUtil.fileToEncodedURL(instFile); + } catch (MalformedURLException e) { + debugException(e); + return null; + } + } + }); + if (instURL != null) { + URL[] urls = cl.getURLs(); + boolean found=false; + for (int j = 0; j + * public static values returned by the isCompatible method + *

      + */ + public static final int COMPATIBLE = 0; + public static final int REQUIRE_SPECIFICATION_UPGRADE = 1; + public static final int REQUIRE_IMPLEMENTATION_UPGRADE = 2; + public static final int REQUIRE_VENDOR_SWITCH = 3; + public static final int INCOMPATIBLE = 4; + + /** + *

      + * attributes fully describer an extension. The underlying described + * extension may be installed and requested. + *

      + */ + public String title; + public String name; + public String specVersion; + public String specVendor; + public String implementationVersion; + public String vendor; + public String vendorId; + public String url; + + // For I18N support + private static final ResourceBundle rb = + ResourceBundle.getBundle("sun.misc.resources.Messages"); + + + /** + *

      + * Create a new uninitialized extension information object + *

      + */ + public ExtensionInfo() { + } + + /** + *

      + * Create and initialize an extension information object. + * The initialization uses the attributes passed as being + * the content of a manifest file to load the extension + * information from. + * Since manifest file may contain information on several + * extension they may depend on, the extension key parameter + * is prepanded to the attribute name to make the key used + * to retrieve the attribute from the manifest file + *

      + * @param extensionKey unique extension key in the manifest + * @param attr Attributes of a manifest file + */ + public ExtensionInfo(String extensionKey, Attributes attr) + throws NullPointerException + { + String s; + if (extensionKey!=null) { + s = extensionKey + "-"; + } else { + s =""; + } + + String attrKey = s + Name.EXTENSION_NAME.toString(); + name = attr.getValue(attrKey); + if (name != null) + name = name.trim(); + + attrKey = s + Name.SPECIFICATION_TITLE.toString(); + title = attr.getValue(attrKey); + if (title != null) + title = title.trim(); + + attrKey = s + Name.SPECIFICATION_VERSION.toString(); + specVersion = attr.getValue(attrKey); + if (specVersion != null) + specVersion = specVersion.trim(); + + attrKey = s + Name.SPECIFICATION_VENDOR.toString(); + specVendor = attr.getValue(attrKey); + if (specVendor != null) + specVendor = specVendor.trim(); + + attrKey = s + Name.IMPLEMENTATION_VERSION.toString(); + implementationVersion = attr.getValue(attrKey); + if (implementationVersion != null) + implementationVersion = implementationVersion.trim(); + + attrKey = s + Name.IMPLEMENTATION_VENDOR.toString(); + vendor = attr.getValue(attrKey); + if (vendor != null) + vendor = vendor.trim(); + + attrKey = s + Name.IMPLEMENTATION_VENDOR_ID.toString(); + vendorId = attr.getValue(attrKey); + if (vendorId != null) + vendorId = vendorId.trim(); + + attrKey =s + Name.IMPLEMENTATION_URL.toString(); + url = attr.getValue(attrKey); + if (url != null) + url = url.trim(); + } + + /** + *

      + * @return true if the extension described by this extension information + * is compatible with the extension described by the extension + * information passed as a parameter + *

      + * + * @param the requested extension information to compare to + */ + public int isCompatibleWith(ExtensionInfo ei) { + + if (name == null || ei.name == null) + return INCOMPATIBLE; + if (name.compareTo(ei.name)==0) { + // is this true, if not spec version is specified, we consider + // the value as being "any". + if (specVersion == null || ei.specVersion == null) + return COMPATIBLE; + + int version = compareExtensionVersion(specVersion, ei.specVersion); + if (version<0) { + // this extension specification is "older" + if (vendorId != null && ei.vendorId !=null) { + if (vendorId.compareTo(ei.vendorId)!=0) { + return REQUIRE_VENDOR_SWITCH; + } + } + return REQUIRE_SPECIFICATION_UPGRADE; + } else { + // the extension spec is compatible, let's look at the + // implementation attributes + if (vendorId != null && ei.vendorId != null) { + // They care who provides the extension + if (vendorId.compareTo(ei.vendorId)!=0) { + // They want to use another vendor implementation + return REQUIRE_VENDOR_SWITCH; + } else { + // Vendor matches, let's see the implementation version + if (implementationVersion != null && ei.implementationVersion != null) { + // they care about the implementation version + version = compareExtensionVersion(implementationVersion, ei.implementationVersion); + if (version<0) { + // This extension is an older implementation + return REQUIRE_IMPLEMENTATION_UPGRADE; + } + } + } + } + // All othe cases, we consider the extensions to be compatible + return COMPATIBLE; + } + } + return INCOMPATIBLE; + } + + /** + *

      + * helper method to print sensible information on the undelying described + * extension + *

      + */ + public String toString() { + return "Extension : title(" + title + "), name(" + name + "), spec vendor(" + + specVendor + "), spec version(" + specVersion + "), impl vendor(" + + vendor + "), impl vendor id(" + vendorId + "), impl version(" + + implementationVersion + "), impl url(" + url + ")"; + } + + /* + *

      + * helper method to compare two versions. + * version are in the x.y.z.t pattern. + *

      + * @param source version to compare to + * @param target version used to compare against + * @return < 0 if source < version + * > 0 if source > version + * = 0 if source = version + */ + private int compareExtensionVersion(String source, String target) + throws NumberFormatException + { + source = source.toLowerCase(); + target = target.toLowerCase(); + + return strictCompareExtensionVersion(source, target); + } + + + /* + *

      + * helper method to compare two versions. + * version are in the x.y.z.t pattern. + *

      + * @param source version to compare to + * @param target version used to compare against + * @return < 0 if source < version + * > 0 if source > version + * = 0 if source = version + */ + private int strictCompareExtensionVersion(String source, String target) + throws NumberFormatException + { + if (source.equals(target)) + return 0; + + StringTokenizer stk = new StringTokenizer(source, ".,"); + StringTokenizer ttk = new StringTokenizer(target, ".,"); + + // Compare number + int n = 0, m = 0, result = 0; + + // Convert token into meaning number for comparision + if (stk.hasMoreTokens()) + n = convertToken(stk.nextToken().toString()); + + // Convert token into meaning number for comparision + if (ttk.hasMoreTokens()) + m = convertToken(ttk.nextToken().toString()); + + if (n > m) + return 1; + else if (m > n) + return -1; + else + { + // Look for index of "." in the string + int sIdx = source.indexOf("."); + int tIdx = target.indexOf("."); + + if (sIdx == -1) + sIdx = source.length() - 1; + + if (tIdx == -1) + tIdx = target.length() - 1; + + return strictCompareExtensionVersion(source.substring(sIdx + 1), + target.substring(tIdx + 1)); + } + } + + private int convertToken(String token) + { + if (token == null || token.equals("")) + return 0; + + int charValue = 0; + int charVersion = 0; + int patchVersion = 0; + int strLength = token.length(); + int endIndex = strLength; + char lastChar; + + Object[] args = {name}; + MessageFormat mf = new MessageFormat(rb.getString("optpkg.versionerror")); + String versionError = mf.format(args); + + // Look for "-" for pre-release + int prIndex = token.indexOf("-"); + + // Look for "_" for patch release + int patchIndex = token.indexOf("_"); + + if (prIndex == -1 && patchIndex == -1) + { + // This is a FCS release + try { + return Integer.parseInt(token) * 100; + } catch (NumberFormatException e) { + System.out.println(versionError); + return 0; + } + } + else if (patchIndex != -1) + { + // This is a patch (update) release + int prversion; + try { + // Obtain the version + prversion = Integer.parseInt(token.substring(0, patchIndex)); + + // Check to see if the patch version is in the n.n.n_nnl format (special release) + lastChar = token.charAt(strLength-1); + if (Character.isLetter(lastChar)) { + // letters a-z have values from 10-35 + charValue = Character.getNumericValue(lastChar); + endIndex = strLength-1; + + // Obtain the patch version id + patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex)); + + if (charValue >= Character.getNumericValue('a') && charValue <= Character.getNumericValue('z')) { + // This is a special release + charVersion = (patchVersion * 100) + charValue; + } else { + // character is not a a-z letter, ignore + charVersion = 0; + System.out.println(versionError); + } + } else { + // This is a regular update release. Obtain the patch version id + patchVersion = Integer.parseInt(token.substring(patchIndex+1, endIndex)); + } + } catch (NumberFormatException e) { + System.out.println(versionError); + return 0; + } + return prversion * 100 + (patchVersion + charVersion); + } + else + { + //This is a milestone release, either a early access, alpha, beta, or RC + + // Obtain the version + int mrversion; + try { + mrversion = Integer.parseInt(token.substring(0, prIndex)); + } catch (NumberFormatException e) { + System.out.println(versionError); + return 0; + } + + // Obtain the patch version string, including the milestone + version + String prString = token.substring(prIndex + 1); + + // Milestone version + String msVersion = ""; + int delta = 0; + + if (prString.indexOf("ea") != -1) + { + msVersion = prString.substring(2); + delta = 50; + } + else if (prString.indexOf("alpha") != -1) + { + msVersion = prString.substring(5); + delta = 40; + } + else if (prString.indexOf("beta") != -1) + { + msVersion = prString.substring(4); + delta = 30; + } + else if (prString.indexOf("rc") != -1) + { + msVersion = prString.substring(2); + delta = 20; + } + + if (msVersion == null || msVersion.equals("")) + { + // No version after the milestone, assume 0 + return mrversion * 100 - delta ; + } + else + { + // Convert the milestone version + try { + return mrversion * 100 - delta + Integer.parseInt(msVersion); + } catch (NumberFormatException e) { + System.out.println(versionError); + return 0; + } + } + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionInstallationException.java b/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionInstallationException.java new file mode 100644 index 000000000..1bf6ff97d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionInstallationException.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1999, 2011, 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.misc; + +/* + * Exception when installation of an extension has failed for + * any reason + * + * @author Jerome Dochez + */ + +public class ExtensionInstallationException extends Exception { + + static final long serialVersionUID = 3139688306909345924L; + + /* + *

      + * Construct a new exception with an exception reason + *

      + */ + public ExtensionInstallationException(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionInstallationProvider.java b/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionInstallationProvider.java new file mode 100644 index 000000000..0b24a1357 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ExtensionInstallationProvider.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1999, 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.misc; + +/** + * This interface defines the contract a extension installation capable + * provided to the extension installation dependency mechanism to + * install new extensions on the user's disk + * + * @author Jerome Dochez + */ +public interface ExtensionInstallationProvider { + + /* + *

      + * Request the installation of an extension in the extension directory + *

      + * + * @param requestExtInfo information on the extension that need to be + * installed + * @param installedExtInfo information on the current compatible installed + * extension. Can be null if no current installation has been found. + * @return true if the installation is successful, false if the + * installation could not be attempted. + * @exception ExtensionInstallationException if an installation was + * attempted but did not succeed. + */ + boolean installExtension(ExtensionInfo requestExtInfo, + ExtensionInfo installedExtInfo) + throws ExtensionInstallationException; +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/FDBigInteger.java b/sources/net.sf.j2s.java.core/src/sun/misc/FDBigInteger.java new file mode 100644 index 000000000..77d6fbc08 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/FDBigInteger.java @@ -0,0 +1,1508 @@ +/* + * 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.misc; + +import java.math.BigInteger; +import java.util.Arrays; +//@ model import org.jmlspecs.models.JMLMath; + +/** + * A simple big integer package specifically for floating point base conversion. + */ +public /*@ spec_bigint_math @*/ class FDBigInteger { + + // + // This class contains many comments that start with "/*@" mark. + // They are behavourial specification in + // the Java Modelling Language (JML): + // http://www.eecs.ucf.edu/~leavens/JML//index.shtml + // + + /*@ + @ public pure model static \bigint UNSIGNED(int v) { + @ return v >= 0 ? v : v + (((\bigint)1) << 32); + @ } + @ + @ public pure model static \bigint UNSIGNED(long v) { + @ return v >= 0 ? v : v + (((\bigint)1) << 64); + @ } + @ + @ public pure model static \bigint AP(int[] data, int len) { + @ return (\sum int i; 0 <= 0 && i < len; UNSIGNED(data[i]) << (i*32)); + @ } + @ + @ public pure model static \bigint pow52(int p5, int p2) { + @ ghost \bigint v = 1; + @ for (int i = 0; i < p5; i++) v *= 5; + @ return v << p2; + @ } + @ + @ public pure model static \bigint pow10(int p10) { + @ return pow52(p10, p10); + @ } + @*/ + + static final int[] SMALL_5_POW = { + 1, + 5, + 5 * 5, + 5 * 5 * 5, + 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 + }; + + static final long[] LONG_5_POW = { + 1L, + 5L, + 5L * 5, + 5L * 5 * 5, + 5L * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + 5L * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5 * 5, + }; + + // Maximum size of cache of powers of 5 as FDBigIntegers. + private static final int MAX_FIVE_POW = 340; + + // Cache of big powers of 5 as FDBigIntegers. + private static final FDBigInteger POW_5_CACHE[]; + + // Initialize FDBigInteger cache of powers of 5. + static { + POW_5_CACHE = new FDBigInteger[MAX_FIVE_POW]; + int i = 0; + while (i < SMALL_5_POW.length) { + FDBigInteger pow5 = new FDBigInteger(new int[]{SMALL_5_POW[i]}, 0); + pow5.makeImmutable(); + POW_5_CACHE[i] = pow5; + i++; + } + FDBigInteger prev = POW_5_CACHE[i - 1]; + while (i < MAX_FIVE_POW) { + POW_5_CACHE[i] = prev = prev.mult(5); + prev.makeImmutable(); + i++; + } + } + + // Zero as an FDBigInteger. + public static final FDBigInteger ZERO = new FDBigInteger(new int[0], 0); + + // Ensure ZERO is immutable. + static { + ZERO.makeImmutable(); + } + + // Constant for casting an int to a long via bitwise AND. + private final static long LONG_MASK = 0xffffffffL; + + //@ spec_public non_null; + private int data[]; // value: data[0] is least significant + //@ spec_public; + private int offset; // number of least significant zero padding ints + //@ spec_public; + private int nWords; // data[nWords-1]!=0, all values above are zero + // if nWords==0 -> this FDBigInteger is zero + //@ spec_public; + private boolean isImmutable = false; + + /*@ + @ public invariant 0 <= nWords && nWords <= data.length && offset >= 0; + @ public invariant nWords == 0 ==> offset == 0; + @ public invariant nWords > 0 ==> data[nWords - 1] != 0; + @ public invariant (\forall int i; nWords <= i && i < data.length; data[i] == 0); + @ public pure model \bigint value() { + @ return AP(data, nWords) << (offset*32); + @ } + @*/ + + /** + * Constructs an FDBigInteger from data and padding. The + * data parameter has the least significant int at + * the zeroth index. The offset parameter gives the number of + * zero ints to be inferred below the least significant element + * of data. + * + * @param data An array containing all non-zero ints of the value. + * @param offset An offset indicating the number of zero ints to pad + * below the least significant element of data. + */ + /*@ + @ requires data != null && offset >= 0; + @ ensures this.value() == \old(AP(data, data.length) << (offset*32)); + @ ensures this.data == \old(data); + @*/ + private FDBigInteger(int[] data, int offset) { + this.data = data; + this.offset = offset; + this.nWords = data.length; + trimLeadingZeros(); + } + + /** + * Constructs an FDBigInteger from a starting value and some + * decimal digits. + * + * @param lValue The starting value. + * @param digits The decimal digits. + * @param kDigits The initial index into digits. + * @param nDigits The final index into digits. + */ + /*@ + @ requires digits != null; + @ requires 0 <= kDigits && kDigits <= nDigits && nDigits <= digits.length; + @ requires (\forall int i; 0 <= i && i < nDigits; '0' <= digits[i] && digits[i] <= '9'); + @ ensures this.value() == \old(lValue * pow10(nDigits - kDigits) + (\sum int i; kDigits <= i && i < nDigits; (digits[i] - '0') * pow10(nDigits - i - 1))); + @*/ + public FDBigInteger(long lValue, char[] digits, int kDigits, int nDigits) { + int n = Math.max((nDigits + 8) / 9, 2); // estimate size needed. + data = new int[n]; // allocate enough space + data[0] = (int) lValue; // starting value + data[1] = (int) (lValue >>> 32); + offset = 0; + nWords = 2; + int i = kDigits; + int limit = nDigits - 5; // slurp digits 5 at a time. + int v; + while (i < limit) { + int ilim = i + 5; + v = (int) digits[i++] - (int) '0'; + while (i < ilim) { + v = 10 * v + (int) digits[i++] - (int) '0'; + } + multAddMe(100000, v); // ... where 100000 is 10^5. + } + int factor = 1; + v = 0; + while (i < nDigits) { + v = 10 * v + (int) digits[i++] - (int) '0'; + factor *= 10; + } + if (factor != 1) { + multAddMe(factor, v); + } + trimLeadingZeros(); + } + + /** + * Returns an FDBigInteger with the numerical value + * 5p5 * 2p2. + * + * @param p5 The exponent of the power-of-five factor. + * @param p2 The exponent of the power-of-two factor. + * @return 5p5 * 2p2 + */ + /*@ + @ requires p5 >= 0 && p2 >= 0; + @ assignable \nothing; + @ ensures \result.value() == \old(pow52(p5, p2)); + @*/ + public static FDBigInteger valueOfPow52(int p5, int p2) { + if (p5 != 0) { + if (p2 == 0) { + return big5pow(p5); + } else if (p5 < SMALL_5_POW.length) { + int pow5 = SMALL_5_POW[p5]; + int wordcount = p2 >> 5; + int bitcount = p2 & 0x1f; + if (bitcount == 0) { + return new FDBigInteger(new int[]{pow5}, wordcount); + } else { + return new FDBigInteger(new int[]{ + pow5 << bitcount, + pow5 >>> (32 - bitcount) + }, wordcount); + } + } else { + return big5pow(p5).leftShift(p2); + } + } else { + return valueOfPow2(p2); + } + } + + /** + * Returns an FDBigInteger with the numerical value + * value * 5p5 * 2p2. + * + * @param value The constant factor. + * @param p5 The exponent of the power-of-five factor. + * @param p2 The exponent of the power-of-two factor. + * @return value * 5p5 * 2p2 + */ + /*@ + @ requires p5 >= 0 && p2 >= 0; + @ assignable \nothing; + @ ensures \result.value() == \old(UNSIGNED(value) * pow52(p5, p2)); + @*/ + public static FDBigInteger valueOfMulPow52(long value, int p5, int p2) { + assert p5 >= 0 : p5; + assert p2 >= 0 : p2; + int v0 = (int) value; + int v1 = (int) (value >>> 32); + int wordcount = p2 >> 5; + int bitcount = p2 & 0x1f; + if (p5 != 0) { + if (p5 < SMALL_5_POW.length) { + long pow5 = SMALL_5_POW[p5] & LONG_MASK; + long carry = (v0 & LONG_MASK) * pow5; + v0 = (int) carry; + carry >>>= 32; + carry = (v1 & LONG_MASK) * pow5 + carry; + v1 = (int) carry; + int v2 = (int) (carry >>> 32); + if (bitcount == 0) { + return new FDBigInteger(new int[]{v0, v1, v2}, wordcount); + } else { + return new FDBigInteger(new int[]{ + v0 << bitcount, + (v1 << bitcount) | (v0 >>> (32 - bitcount)), + (v2 << bitcount) | (v1 >>> (32 - bitcount)), + v2 >>> (32 - bitcount) + }, wordcount); + } + } else { + FDBigInteger pow5 = big5pow(p5); + int[] r; + if (v1 == 0) { + r = new int[pow5.nWords + 1 + ((p2 != 0) ? 1 : 0)]; + mult(pow5.data, pow5.nWords, v0, r); + } else { + r = new int[pow5.nWords + 2 + ((p2 != 0) ? 1 : 0)]; + mult(pow5.data, pow5.nWords, v0, v1, r); + } + return (new FDBigInteger(r, pow5.offset)).leftShift(p2); + } + } else if (p2 != 0) { + if (bitcount == 0) { + return new FDBigInteger(new int[]{v0, v1}, wordcount); + } else { + return new FDBigInteger(new int[]{ + v0 << bitcount, + (v1 << bitcount) | (v0 >>> (32 - bitcount)), + v1 >>> (32 - bitcount) + }, wordcount); + } + } + return new FDBigInteger(new int[]{v0, v1}, 0); + } + + /** + * Returns an FDBigInteger with the numerical value + * 2p2. + * + * @param p2 The exponent of 2. + * @return 2p2 + */ + /*@ + @ requires p2 >= 0; + @ assignable \nothing; + @ ensures \result.value() == pow52(0, p2); + @*/ + private static FDBigInteger valueOfPow2(int p2) { + int wordcount = p2 >> 5; + int bitcount = p2 & 0x1f; + return new FDBigInteger(new int[]{1 << bitcount}, wordcount); + } + + /** + * Removes all leading zeros from this FDBigInteger adjusting + * the offset and number of non-zero leading words accordingly. + */ + /*@ + @ requires data != null; + @ requires 0 <= nWords && nWords <= data.length && offset >= 0; + @ requires nWords == 0 ==> offset == 0; + @ ensures nWords == 0 ==> offset == 0; + @ ensures nWords > 0 ==> data[nWords - 1] != 0; + @*/ + private /*@ helper @*/ void trimLeadingZeros() { + int i = nWords; + if (i > 0 && (data[--i] == 0)) { + //for (; i > 0 && data[i - 1] == 0; i--) ; + while(i > 0 && data[i - 1] == 0) { + i--; + } + this.nWords = i; + if (i == 0) { // all words are zero + this.offset = 0; + } + } + } + + /** + * Retrieves the normalization bias of the FDBigIntger. The + * normalization bias is a left shift such that after it the highest word + * of the value will have the 4 highest bits equal to zero: + * (highestWord & 0xf0000000) == 0, but the next bit should be 1 + * (highestWord & 0x08000000) != 0. + * + * @return The normalization bias. + */ + /*@ + @ requires this.value() > 0; + @*/ + public /*@ pure @*/ int getNormalizationBias() { + if (nWords == 0) { + throw new IllegalArgumentException("Zero value cannot be normalized"); + } + int zeros = Integer.numberOfLeadingZeros(data[nWords - 1]); + return (zeros < 4) ? 28 + zeros : zeros - 4; + } + + // TODO: Why is anticount param needed if it is always 32 - bitcount? + /** + * Left shifts the contents of one int array into another. + * + * @param src The source array. + * @param idx The initial index of the source array. + * @param result The destination array. + * @param bitcount The left shift. + * @param anticount The left anti-shift, e.g., 32-bitcount. + * @param prev The prior source value. + */ + /*@ + @ requires 0 < bitcount && bitcount < 32 && anticount == 32 - bitcount; + @ requires src.length >= idx && result.length > idx; + @ assignable result[*]; + @ ensures AP(result, \old(idx + 1)) == \old((AP(src, idx) + UNSIGNED(prev) << (idx*32)) << bitcount); + @*/ + private static void leftShift(int[] src, int idx, int result[], int bitcount, int anticount, int prev){ + for (; idx > 0; idx--) { + int v = (prev << bitcount); + prev = src[idx - 1]; + v |= (prev >>> anticount); + result[idx] = v; + } + int v = prev << bitcount; + result[0] = v; + } + + /** + * Shifts this FDBigInteger to the left. The shift is performed + * in-place unless the FDBigInteger is immutable in which case + * a new instance of FDBigInteger is returned. + * + * @param shift The number of bits to shift left. + * @return The shifted FDBigInteger. + */ + /*@ + @ requires this.value() == 0 || shift == 0; + @ assignable \nothing; + @ ensures \result == this; + @ + @ also + @ + @ requires this.value() > 0 && shift > 0 && this.isImmutable; + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() << shift); + @ + @ also + @ + @ requires this.value() > 0 && shift > 0 && this.isImmutable; + @ assignable \nothing; + @ ensures \result == this; + @ ensures \result.value() == \old(this.value() << shift); + @*/ + public FDBigInteger leftShift(int shift) { + if (shift == 0 || nWords == 0) { + return this; + } + int wordcount = shift >> 5; + int bitcount = shift & 0x1f; + if (this.isImmutable) { + if (bitcount == 0) { + return new FDBigInteger(Arrays.copyOf(data, nWords), offset + wordcount); + } else { + int anticount = 32 - bitcount; + int idx = nWords - 1; + int prev = data[idx]; + int hi = prev >>> anticount; + int[] result; + if (hi != 0) { + result = new int[nWords + 1]; + result[nWords] = hi; + } else { + result = new int[nWords]; + } + leftShift(data,idx,result,bitcount,anticount,prev); + return new FDBigInteger(result, offset + wordcount); + } + } else { + if (bitcount != 0) { + int anticount = 32 - bitcount; + if ((data[0] << bitcount) == 0) { + int idx = 0; + int prev = data[idx]; + for (; idx < nWords - 1; idx++) { + int v = (prev >>> anticount); + prev = data[idx + 1]; + v |= (prev << bitcount); + data[idx] = v; + } + int v = prev >>> anticount; + data[idx] = v; + if(v==0) { + nWords--; + } + offset++; + } else { + int idx = nWords - 1; + int prev = data[idx]; + int hi = prev >>> anticount; + int[] result = data; + int[] src = data; + if (hi != 0) { + if(nWords == data.length) { + data = result = new int[nWords + 1]; + } + result[nWords++] = hi; + } + leftShift(src,idx,result,bitcount,anticount,prev); + } + } + offset += wordcount; + return this; + } + } + + /** + * Returns the number of ints this FDBigInteger represents. + * + * @return Number of ints required to represent this FDBigInteger. + */ + /*@ + @ requires this.value() == 0; + @ ensures \result == 0; + @ + @ also + @ + @ requires this.value() > 0; + @ ensures ((\bigint)1) << (\result - 1) <= this.value() && this.value() <= ((\bigint)1) << \result; + @*/ + private /*@ pure @*/ int size() { + return nWords + offset; + } + + + /** + * Computes + *
      +     * q = (int)( this / S )
      +     * this = 10 * ( this mod S )
      +     * Return q.
      +     * 
      + * This is the iteration step of digit development for output. + * We assume that S has been normalized, as above, and that + * "this" has been left-shifted accordingly. + * Also assumed, of course, is that the result, q, can be expressed + * as an integer, 0 <= q < 10. + * + * @param The divisor of this FDBigInteger. + * @return q = (int)(this / S). + */ + /*@ + @ requires !this.isImmutable; + @ requires this.size() <= S.size(); + @ requires this.data.length + this.offset >= S.size(); + @ requires S.value() >= ((\bigint)1) << (S.size()*32 - 4); + @ assignable this.nWords, this.offset, this.data, this.data[*]; + @ ensures \result == \old(this.value() / S.value()); + @ ensures this.value() == \old(10 * (this.value() % S.value())); + @*/ + public int quoRemIteration(FDBigInteger S) throws IllegalArgumentException { + assert !this.isImmutable : "cannot modify immutable value"; + // ensure that this and S have the same number of + // digits. If S is properly normalized and q < 10 then + // this must be so. + int thSize = this.size(); + int sSize = S.size(); + if (thSize < sSize) { + // this value is significantly less than S, result of division is zero. + // just mult this by 10. + int p = multAndCarryBy10(this.data, this.nWords, this.data); + if(p!=0) { + this.data[nWords++] = p; + } else { + trimLeadingZeros(); + } + return 0; + } else if (thSize > sSize) { + throw new IllegalArgumentException("disparate values"); + } + // estimate q the obvious way. We will usually be + // right. If not, then we're only off by a little and + // will re-add. + long q = (this.data[this.nWords - 1] & LONG_MASK) / (S.data[S.nWords - 1] & LONG_MASK); + long diff = multDiffMe(q, S); + if (diff != 0L) { + //@ assert q != 0; + //@ assert this.offset == \old(Math.min(this.offset, S.offset)); + //@ assert this.offset <= S.offset; + + // q is too big. + // add S back in until this turns +. This should + // not be very many times! + long sum = 0L; + int tStart = S.offset - this.offset; + //@ assert tStart >= 0; + int[] sd = S.data; + int[] td = this.data; + while (sum == 0L) { + for (int sIndex = 0, tIndex = tStart; tIndex < this.nWords; sIndex++, tIndex++) { + sum += (td[tIndex] & LONG_MASK) + (sd[sIndex] & LONG_MASK); + td[tIndex] = (int) sum; + sum >>>= 32; // Signed or unsigned, answer is 0 or 1 + } + // + // Originally the following line read + // "if ( sum !=0 && sum != -1 )" + // but that would be wrong, because of the + // treatment of the two values as entirely unsigned, + // it would be impossible for a carry-out to be interpreted + // as -1 -- it would have to be a single-bit carry-out, or +1. + // + assert sum == 0 || sum == 1 : sum; // carry out of division correction + q -= 1; + } + } + // finally, we can multiply this by 10. + // it cannot overflow, right, as the high-order word has + // at least 4 high-order zeros! + int p = multAndCarryBy10(this.data, this.nWords, this.data); + assert p == 0 : p; // Carry out of *10 + trimLeadingZeros(); + return (int) q; + } + + /** + * Multiplies this FDBigInteger by 10. The operation will be + * performed in place unless the FDBigInteger is immutable in + * which case a new FDBigInteger will be returned. + * + * @return The FDBigInteger multiplied by 10. + */ + /*@ + @ requires this.value() == 0; + @ assignable \nothing; + @ ensures \result == this; + @ + @ also + @ + @ requires this.value() > 0 && this.isImmutable; + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() * 10); + @ + @ also + @ + @ requires this.value() > 0 && !this.isImmutable; + @ assignable this.nWords, this.data, this.data[*]; + @ ensures \result == this; + @ ensures \result.value() == \old(this.value() * 10); + @*/ + public FDBigInteger multBy10() { + if (nWords == 0) { + return this; + } + if (isImmutable) { + int[] res = new int[nWords + 1]; + res[nWords] = multAndCarryBy10(data, nWords, res); + return new FDBigInteger(res, offset); + } else { + int p = multAndCarryBy10(this.data, this.nWords, this.data); + if (p != 0) { + if (nWords == data.length) { + if (data[0] == 0) { + System.arraycopy(data, 1, data, 0, --nWords); + offset++; + } else { + data = Arrays.copyOf(data, data.length + 1); + } + } + data[nWords++] = p; + } else { + trimLeadingZeros(); + } + return this; + } + } + + /** + * Multiplies this FDBigInteger by + * 5p5 * 2p2. The operation will be + * performed in place if possible, otherwise a new FDBigInteger + * will be returned. + * + * @param p5 The exponent of the power-of-five factor. + * @param p2 The exponent of the power-of-two factor. + * @return + */ + /*@ + @ requires this.value() == 0 || p5 == 0 && p2 == 0; + @ assignable \nothing; + @ ensures \result == this; + @ + @ also + @ + @ requires this.value() > 0 && (p5 > 0 && p2 >= 0 || p5 == 0 && p2 > 0 && this.isImmutable); + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() * pow52(p5, p2)); + @ + @ also + @ + @ requires this.value() > 0 && p5 == 0 && p2 > 0 && !this.isImmutable; + @ assignable this.nWords, this.data, this.data[*]; + @ ensures \result == this; + @ ensures \result.value() == \old(this.value() * pow52(p5, p2)); + @*/ + public FDBigInteger multByPow52(int p5, int p2) { + if (this.nWords == 0) { + return this; + } + FDBigInteger res = this; + if (p5 != 0) { + int[] r; + int extraSize = (p2 != 0) ? 1 : 0; + if (p5 < SMALL_5_POW.length) { + r = new int[this.nWords + 1 + extraSize]; + mult(this.data, this.nWords, SMALL_5_POW[p5], r); + res = new FDBigInteger(r, this.offset); + } else { + FDBigInteger pow5 = big5pow(p5); + r = new int[this.nWords + pow5.size() + extraSize]; + mult(this.data, this.nWords, pow5.data, pow5.nWords, r); + res = new FDBigInteger(r, this.offset + pow5.offset); + } + } + return res.leftShift(p2); + } + + /** + * Multiplies two big integers represented as int arrays. + * + * @param s1 The first array factor. + * @param s1Len The number of elements of s1 to use. + * @param s2 The second array factor. + * @param s2Len The number of elements of s2 to use. + * @param dst The product array. + */ + /*@ + @ requires s1 != dst && s2 != dst; + @ requires s1.length >= s1Len && s2.length >= s2Len && dst.length >= s1Len + s2Len; + @ assignable dst[0 .. s1Len + s2Len - 1]; + @ ensures AP(dst, s1Len + s2Len) == \old(AP(s1, s1Len) * AP(s2, s2Len)); + @*/ + private static void mult(int[] s1, int s1Len, int[] s2, int s2Len, int[] dst) { + for (int i = 0; i < s1Len; i++) { + long v = s1[i] & LONG_MASK; + long p = 0L; + for (int j = 0; j < s2Len; j++) { + p += (dst[i + j] & LONG_MASK) + v * (s2[j] & LONG_MASK); + dst[i + j] = (int) p; + p >>>= 32; + } + dst[i + s2Len] = (int) p; + } + } + + /** + * Subtracts the supplied FDBigInteger subtrahend from this + * FDBigInteger. Assert that the result is positive. + * If the subtrahend is immutable, store the result in this(minuend). + * If this(minuend) is immutable a new FDBigInteger is created. + * + * @param subtrahend The FDBigInteger to be subtracted. + * @return This FDBigInteger less the subtrahend. + */ + /*@ + @ requires this.isImmutable; + @ requires this.value() >= subtrahend.value(); + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() - subtrahend.value()); + @ + @ also + @ + @ requires !subtrahend.isImmutable; + @ requires this.value() >= subtrahend.value(); + @ assignable this.nWords, this.offset, this.data, this.data[*]; + @ ensures \result == this; + @ ensures \result.value() == \old(this.value() - subtrahend.value()); + @*/ + public FDBigInteger leftInplaceSub(FDBigInteger subtrahend) { + assert this.size() >= subtrahend.size() : "result should be positive"; + FDBigInteger minuend; + if (this.isImmutable) { + minuend = new FDBigInteger(this.data.clone(), this.offset); + } else { + minuend = this; + } + int offsetDiff = subtrahend.offset - minuend.offset; + int[] sData = subtrahend.data; + int[] mData = minuend.data; + int subLen = subtrahend.nWords; + int minLen = minuend.nWords; + if (offsetDiff < 0) { + // need to expand minuend + int rLen = minLen - offsetDiff; + if (rLen < mData.length) { + System.arraycopy(mData, 0, mData, -offsetDiff, minLen); + Arrays.fill(mData, 0, -offsetDiff, 0); + } else { + int[] r = new int[rLen]; + System.arraycopy(mData, 0, r, -offsetDiff, minLen); + minuend.data = mData = r; + } + minuend.offset = subtrahend.offset; + minuend.nWords = minLen = rLen; + offsetDiff = 0; + } + long borrow = 0L; + int mIndex = offsetDiff; + for (int sIndex = 0; sIndex < subLen && mIndex < minLen; sIndex++, mIndex++) { + long diff = (mData[mIndex] & LONG_MASK) - (sData[sIndex] & LONG_MASK) + borrow; + mData[mIndex] = (int) diff; + borrow = diff >> 32; // signed shift + } + for (; borrow != 0 && mIndex < minLen; mIndex++) { + long diff = (mData[mIndex] & LONG_MASK) + borrow; + mData[mIndex] = (int) diff; + borrow = diff >> 32; // signed shift + } + assert borrow == 0L : borrow; // borrow out of subtract, + // result should be positive + minuend.trimLeadingZeros(); + return minuend; + } + + /** + * Subtracts the supplied FDBigInteger subtrahend from this + * FDBigInteger. Assert that the result is positive. + * If the this(minuend) is immutable, store the result in subtrahend. + * If subtrahend is immutable a new FDBigInteger is created. + * + * @param subtrahend The FDBigInteger to be subtracted. + * @return This FDBigInteger less the subtrahend. + */ + /*@ + @ requires subtrahend.isImmutable; + @ requires this.value() >= subtrahend.value(); + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() - subtrahend.value()); + @ + @ also + @ + @ requires !subtrahend.isImmutable; + @ requires this.value() >= subtrahend.value(); + @ assignable subtrahend.nWords, subtrahend.offset, subtrahend.data, subtrahend.data[*]; + @ ensures \result == subtrahend; + @ ensures \result.value() == \old(this.value() - subtrahend.value()); + @*/ + public FDBigInteger rightInplaceSub(FDBigInteger subtrahend) { + assert this.size() >= subtrahend.size() : "result should be positive"; + FDBigInteger minuend = this; + if (subtrahend.isImmutable) { + subtrahend = new FDBigInteger(subtrahend.data.clone(), subtrahend.offset); + } + int offsetDiff = minuend.offset - subtrahend.offset; + int[] sData = subtrahend.data; + int[] mData = minuend.data; + int subLen = subtrahend.nWords; + int minLen = minuend.nWords; + if (offsetDiff < 0) { + int rLen = minLen; + if (rLen < sData.length) { + System.arraycopy(sData, 0, sData, -offsetDiff, subLen); + Arrays.fill(sData, 0, -offsetDiff, 0); + } else { + int[] r = new int[rLen]; + System.arraycopy(sData, 0, r, -offsetDiff, subLen); + subtrahend.data = sData = r; + } + subtrahend.offset = minuend.offset; + subLen -= offsetDiff; + offsetDiff = 0; + } else { + int rLen = minLen + offsetDiff; + if (rLen >= sData.length) { + subtrahend.data = sData = Arrays.copyOf(sData, rLen); + } + } + //@ assert minuend == this && minuend.value() == \old(this.value()); + //@ assert mData == minuend.data && minLen == minuend.nWords; + //@ assert subtrahend.offset + subtrahend.data.length >= minuend.size(); + //@ assert sData == subtrahend.data; + //@ assert AP(subtrahend.data, subtrahend.data.length) << subtrahend.offset == \old(subtrahend.value()); + //@ assert subtrahend.offset == Math.min(\old(this.offset), minuend.offset); + //@ assert offsetDiff == minuend.offset - subtrahend.offset; + //@ assert 0 <= offsetDiff && offsetDiff + minLen <= sData.length; + int sIndex = 0; + long borrow = 0L; + for (; sIndex < offsetDiff; sIndex++) { + long diff = 0L - (sData[sIndex] & LONG_MASK) + borrow; + sData[sIndex] = (int) diff; + borrow = diff >> 32; // signed shift + } + //@ assert sIndex == offsetDiff; + for (int mIndex = 0; mIndex < minLen; sIndex++, mIndex++) { + //@ assert sIndex == offsetDiff + mIndex; + long diff = (mData[mIndex] & LONG_MASK) - (sData[sIndex] & LONG_MASK) + borrow; + sData[sIndex] = (int) diff; + borrow = diff >> 32; // signed shift + } + assert borrow == 0L : borrow; // borrow out of subtract, + // result should be positive + subtrahend.nWords = sIndex; + subtrahend.trimLeadingZeros(); + return subtrahend; + + } + + /** + * Determines whether all elements of an array are zero for all indices less + * than a given index. + * + * @param a The array to be examined. + * @param from The index strictly below which elements are to be examined. + * @return Zero if all elements in range are zero, 1 otherwise. + */ + /*@ + @ requires 0 <= from && from <= a.length; + @ ensures \result == (AP(a, from) == 0 ? 0 : 1); + @*/ + private /*@ pure @*/ static int checkZeroTail(int[] a, int from) { + while (from > 0) { + if (a[--from] != 0) { + return 1; + } + } + return 0; + } + + /** + * Compares the parameter with this FDBigInteger. Returns an + * integer accordingly as: + *
      +     * >0: this > other
      +     *  0: this == other
      +     * <0: this < other
      +     * 
      + * + * @param other The FDBigInteger to compare. + * @return A negative value, zero, or a positive value according to the + * result of the comparison. + */ + /*@ + @ ensures \result == (this.value() < other.value() ? -1 : this.value() > other.value() ? +1 : 0); + @*/ + public /*@ pure @*/ int cmp(FDBigInteger other) { + int aSize = nWords + offset; + int bSize = other.nWords + other.offset; + if (aSize > bSize) { + return 1; + } else if (aSize < bSize) { + return -1; + } + int aLen = nWords; + int bLen = other.nWords; + while (aLen > 0 && bLen > 0) { + int a = data[--aLen]; + int b = other.data[--bLen]; + if (a != b) { + return ((a & LONG_MASK) < (b & LONG_MASK)) ? -1 : 1; + } + } + if (aLen > 0) { + return checkZeroTail(data, aLen); + } + if (bLen > 0) { + return -checkZeroTail(other.data, bLen); + } + return 0; + } + + /** + * Compares this FDBigInteger with + * 5p5 * 2p2. + * Returns an integer accordingly as: + *
      +     * >0: this > other
      +     *  0: this == other
      +     * <0: this < other
      +     * 
      + * @param p5 The exponent of the power-of-five factor. + * @param p2 The exponent of the power-of-two factor. + * @return A negative value, zero, or a positive value according to the + * result of the comparison. + */ + /*@ + @ requires p5 >= 0 && p2 >= 0; + @ ensures \result == (this.value() < pow52(p5, p2) ? -1 : this.value() > pow52(p5, p2) ? +1 : 0); + @*/ + public /*@ pure @*/ int cmpPow52(int p5, int p2) { + if (p5 == 0) { + int wordcount = p2 >> 5; + int bitcount = p2 & 0x1f; + int size = this.nWords + this.offset; + if (size > wordcount + 1) { + return 1; + } else if (size < wordcount + 1) { + return -1; + } + int a = this.data[this.nWords -1]; + int b = 1 << bitcount; + if (a != b) { + return ( (a & LONG_MASK) < (b & LONG_MASK)) ? -1 : 1; + } + return checkZeroTail(this.data, this.nWords - 1); + } + return this.cmp(big5pow(p5).leftShift(p2)); + } + + /** + * Compares this FDBigInteger with x + y. Returns a + * value according to the comparison as: + *
      +     * -1: this <  x + y
      +     *  0: this == x + y
      +     *  1: this >  x + y
      +     * 
      + * @param x The first addend of the sum to compare. + * @param y The second addend of the sum to compare. + * @return -1, 0, or 1 according to the result of the comparison. + */ + /*@ + @ ensures \result == (this.value() < x.value() + y.value() ? -1 : this.value() > x.value() + y.value() ? +1 : 0); + @*/ + public /*@ pure @*/ int addAndCmp(FDBigInteger x, FDBigInteger y) { + FDBigInteger big; + FDBigInteger small; + int xSize = x.size(); + int ySize = y.size(); + int bSize; + int sSize; + if (xSize >= ySize) { + big = x; + small = y; + bSize = xSize; + sSize = ySize; + } else { + big = y; + small = x; + bSize = ySize; + sSize = xSize; + } + int thSize = this.size(); + if (bSize == 0) { + return thSize == 0 ? 0 : 1; + } + if (sSize == 0) { + return this.cmp(big); + } + if (bSize > thSize) { + return -1; + } + if (bSize + 1 < thSize) { + return 1; + } + long top = (big.data[big.nWords - 1] & LONG_MASK); + if (sSize == bSize) { + top += (small.data[small.nWords - 1] & LONG_MASK); + } + if ((top >>> 32) == 0) { + if (((top + 1) >>> 32) == 0) { + // good case - no carry extension + if (bSize < thSize) { + return 1; + } + // here sum.nWords == this.nWords + long v = (this.data[this.nWords - 1] & LONG_MASK); + if (v < top) { + return -1; + } + if (v > top + 1) { + return 1; + } + } + } else { // (top>>>32)!=0 guaranteed carry extension + if (bSize + 1 > thSize) { + return -1; + } + // here sum.nWords == this.nWords + top >>>= 32; + long v = (this.data[this.nWords - 1] & LONG_MASK); + if (v < top) { + return -1; + } + if (v > top + 1) { + return 1; + } + } + return this.cmp(big.add(small)); + } + + /** + * Makes this FDBigInteger immutable. + */ + /*@ + @ assignable this.isImmutable; + @ ensures this.isImmutable; + @*/ + public void makeImmutable() { + this.isImmutable = true; + } + + /** + * Multiplies this FDBigInteger by an integer. + * + * @param i The factor by which to multiply this FDBigInteger. + * @return This FDBigInteger multiplied by an integer. + */ + /*@ + @ requires this.value() == 0; + @ assignable \nothing; + @ ensures \result == this; + @ + @ also + @ + @ requires this.value() != 0; + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() * UNSIGNED(i)); + @*/ + private FDBigInteger mult(int i) { + if (this.nWords == 0) { + return this; + } + int[] r = new int[nWords + 1]; + mult(data, nWords, i, r); + return new FDBigInteger(r, offset); + } + + /** + * Multiplies this FDBigInteger by another FDBigInteger. + * + * @param other The FDBigInteger factor by which to multiply. + * @return The product of this and the parameter FDBigIntegers. + */ + /*@ + @ requires this.value() == 0; + @ assignable \nothing; + @ ensures \result == this; + @ + @ also + @ + @ requires this.value() != 0 && other.value() == 0; + @ assignable \nothing; + @ ensures \result == other; + @ + @ also + @ + @ requires this.value() != 0 && other.value() != 0; + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() * other.value()); + @*/ + private FDBigInteger mult(FDBigInteger other) { + if (this.nWords == 0) { + return this; + } + if (this.size() == 1) { + return other.mult(data[0]); + } + if (other.nWords == 0) { + return other; + } + if (other.size() == 1) { + return this.mult(other.data[0]); + } + int[] r = new int[nWords + other.nWords]; + mult(this.data, this.nWords, other.data, other.nWords, r); + return new FDBigInteger(r, this.offset + other.offset); + } + + /** + * Adds another FDBigInteger to this FDBigInteger. + * + * @param other The FDBigInteger to add. + * @return The sum of the FDBigIntegers. + */ + /*@ + @ assignable \nothing; + @ ensures \result.value() == \old(this.value() + other.value()); + @*/ + private FDBigInteger add(FDBigInteger other) { + FDBigInteger big, small; + int bigLen, smallLen; + int tSize = this.size(); + int oSize = other.size(); + if (tSize >= oSize) { + big = this; + bigLen = tSize; + small = other; + smallLen = oSize; + } else { + big = other; + bigLen = oSize; + small = this; + smallLen = tSize; + } + int[] r = new int[bigLen + 1]; + int i = 0; + long carry = 0L; + for (; i < smallLen; i++) { + carry += (i < big.offset ? 0L : (big.data[i - big.offset] & LONG_MASK) ) + + ((i < small.offset ? 0L : (small.data[i - small.offset] & LONG_MASK))); + r[i] = (int) carry; + carry >>= 32; // signed shift. + } + for (; i < bigLen; i++) { + carry += (i < big.offset ? 0L : (big.data[i - big.offset] & LONG_MASK) ); + r[i] = (int) carry; + carry >>= 32; // signed shift. + } + r[bigLen] = (int) carry; + return new FDBigInteger(r, 0); + } + + + /** + * Multiplies a FDBigInteger by an int and adds another int. The + * result is computed in place. This method is intended only to be invoked + * from + * + * FDBigInteger(long lValue, char[] digits, int kDigits, int nDigits) + * . + * + * @param iv The factor by which to multiply this FDBigInteger. + * @param addend The value to add to the product of this + * FDBigInteger and iv. + */ + /*@ + @ requires this.value()*UNSIGNED(iv) + UNSIGNED(addend) < ((\bigint)1) << ((this.data.length + this.offset)*32); + @ assignable this.data[*]; + @ ensures this.value() == \old(this.value()*UNSIGNED(iv) + UNSIGNED(addend)); + @*/ + private /*@ helper @*/ void multAddMe(int iv, int addend) { + long v = iv & LONG_MASK; + // unroll 0th iteration, doing addition. + long p = v * (data[0] & LONG_MASK) + (addend & LONG_MASK); + data[0] = (int) p; + p >>>= 32; + for (int i = 1; i < nWords; i++) { + p += v * (data[i] & LONG_MASK); + data[i] = (int) p; + p >>>= 32; + } + if (p != 0L) { + data[nWords++] = (int) p; // will fail noisily if illegal! + } + } + + // + // original doc: + // + // do this -=q*S + // returns borrow + // + /** + * Multiplies the parameters and subtracts them from this + * FDBigInteger. + * + * @param q The integer parameter. + * @param S The FDBigInteger parameter. + * @return this - q*S. + */ + /*@ + @ ensures nWords == 0 ==> offset == 0; + @ ensures nWords > 0 ==> data[nWords - 1] != 0; + @*/ + /*@ + @ requires 0 < q && q <= (1L << 31); + @ requires data != null; + @ requires 0 <= nWords && nWords <= data.length && offset >= 0; + @ requires !this.isImmutable; + @ requires this.size() == S.size(); + @ requires this != S; + @ assignable this.nWords, this.offset, this.data, this.data[*]; + @ ensures -q <= \result && \result <= 0; + @ ensures this.size() == \old(this.size()); + @ ensures this.value() + (\result << (this.size()*32)) == \old(this.value() - q*S.value()); + @ ensures this.offset == \old(Math.min(this.offset, S.offset)); + @ ensures \old(this.offset <= S.offset) ==> this.nWords == \old(this.nWords); + @ ensures \old(this.offset <= S.offset) ==> this.offset == \old(this.offset); + @ ensures \old(this.offset <= S.offset) ==> this.data == \old(this.data); + @ + @ also + @ + @ requires q == 0; + @ assignable \nothing; + @ ensures \result == 0; + @*/ + private /*@ helper @*/ long multDiffMe(long q, FDBigInteger S) { + long diff = 0L; + if (q != 0) { + int deltaSize = S.offset - this.offset; + if (deltaSize >= 0) { + int[] sd = S.data; + int[] td = this.data; + for (int sIndex = 0, tIndex = deltaSize; sIndex < S.nWords; sIndex++, tIndex++) { + diff += (td[tIndex] & LONG_MASK) - q * (sd[sIndex] & LONG_MASK); + td[tIndex] = (int) diff; + diff >>= 32; // N.B. SIGNED shift. + } + } else { + deltaSize = -deltaSize; + int[] rd = new int[nWords + deltaSize]; + int sIndex = 0; + int rIndex = 0; + int[] sd = S.data; + for (; rIndex < deltaSize && sIndex < S.nWords; sIndex++, rIndex++) { + diff -= q * (sd[sIndex] & LONG_MASK); + rd[rIndex] = (int) diff; + diff >>= 32; // N.B. SIGNED shift. + } + int tIndex = 0; + int[] td = this.data; + for (; sIndex < S.nWords; sIndex++, tIndex++, rIndex++) { + diff += (td[tIndex] & LONG_MASK) - q * (sd[sIndex] & LONG_MASK); + rd[rIndex] = (int) diff; + diff >>= 32; // N.B. SIGNED shift. + } + this.nWords += deltaSize; + this.offset -= deltaSize; + this.data = rd; + } + } + return diff; + } + + + /** + * Multiplies by 10 a big integer represented as an array. The final carry + * is returned. + * + * @param src The array representation of the big integer. + * @param srcLen The number of elements of src to use. + * @param dst The product array. + * @return The final carry of the multiplication. + */ + /*@ + @ requires src.length >= srcLen && dst.length >= srcLen; + @ assignable dst[0 .. srcLen - 1]; + @ ensures 0 <= \result && \result < 10; + @ ensures AP(dst, srcLen) + (\result << (srcLen*32)) == \old(AP(src, srcLen) * 10); + @*/ + private static int multAndCarryBy10(int[] src, int srcLen, int[] dst) { + long carry = 0; + for (int i = 0; i < srcLen; i++) { + long product = (src[i] & LONG_MASK) * 10L + carry; + dst[i] = (int) product; + carry = product >>> 32; + } + return (int) carry; + } + + /** + * Multiplies by a constant value a big integer represented as an array. + * The constant factor is an int. + * + * @param src The array representation of the big integer. + * @param srcLen The number of elements of src to use. + * @param value The constant factor by which to multiply. + * @param dst The product array. + */ + /*@ + @ requires src.length >= srcLen && dst.length >= srcLen + 1; + @ assignable dst[0 .. srcLen]; + @ ensures AP(dst, srcLen + 1) == \old(AP(src, srcLen) * UNSIGNED(value)); + @*/ + private static void mult(int[] src, int srcLen, int value, int[] dst) { + long val = value & LONG_MASK; + long carry = 0; + for (int i = 0; i < srcLen; i++) { + long product = (src[i] & LONG_MASK) * val + carry; + dst[i] = (int) product; + carry = product >>> 32; + } + dst[srcLen] = (int) carry; + } + + /** + * Multiplies by a constant value a big integer represented as an array. + * The constant factor is a long represent as two ints. + * + * @param src The array representation of the big integer. + * @param srcLen The number of elements of src to use. + * @param v0 The lower 32 bits of the long factor. + * @param v1 The upper 32 bits of the long factor. + * @param dst The product array. + */ + /*@ + @ requires src != dst; + @ requires src.length >= srcLen && dst.length >= srcLen + 2; + @ assignable dst[0 .. srcLen + 1]; + @ ensures AP(dst, srcLen + 2) == \old(AP(src, srcLen) * (UNSIGNED(v0) + (UNSIGNED(v1) << 32))); + @*/ + private static void mult(int[] src, int srcLen, int v0, int v1, int[] dst) { + long v = v0 & LONG_MASK; + long carry = 0; + for (int j = 0; j < srcLen; j++) { + long product = v * (src[j] & LONG_MASK) + carry; + dst[j] = (int) product; + carry = product >>> 32; + } + dst[srcLen] = (int) carry; + v = v1 & LONG_MASK; + carry = 0; + for (int j = 0; j < srcLen; j++) { + long product = (dst[j + 1] & LONG_MASK) + v * (src[j] & LONG_MASK) + carry; + dst[j + 1] = (int) product; + carry = product >>> 32; + } + dst[srcLen + 1] = (int) carry; + } + + // Fails assertion for negative exponent. + /** + * Computes 5 raised to a given power. + * + * @param p The exponent of 5. + * @return 5p. + */ + private static FDBigInteger big5pow(int p) { + assert p >= 0 : p; // negative power of 5 + if (p < MAX_FIVE_POW) { + return POW_5_CACHE[p]; + } + return big5powRec(p); + } + + // slow path + /** + * Computes 5 raised to a given power. + * + * @param p The exponent of 5. + * @return 5p. + */ + private static FDBigInteger big5powRec(int p) { + if (p < MAX_FIVE_POW) { + return POW_5_CACHE[p]; + } + // construct the value. + // recursively. + int q, r; + // in order to compute 5^p, + // compute its square root, 5^(p/2) and square. + // or, let q = p / 2, r = p -q, then + // 5^p = 5^(q+r) = 5^q * 5^r + q = p >> 1; + r = p - q; + FDBigInteger bigq = big5powRec(q); + if (r < SMALL_5_POW.length) { + return bigq.mult(SMALL_5_POW[r]); + } else { + return bigq.mult(big5powRec(r)); + } + } + + // for debugging ... + /** + * Converts this FDBigInteger to a hexadecimal string. + * + * @return The hexadecimal string representation. + */ + public String toHexString(){ + if(nWords ==0) { + return "0"; + } + StringBuilder sb = new StringBuilder((nWords +offset)*8); + for(int i= nWords -1; i>=0; i--) { + String subStr = Integer.toHexString(data[i]); + for(int j = subStr.length(); j<8; j++) { + sb.append('0'); + } + sb.append(subStr); + } + for(int i=offset; i>0; i--) { + sb.append("00000000"); + } + return sb.toString(); + } + + // for debugging ... + /** + * Converts this FDBigInteger to a BigInteger. + * + * @return The BigInteger representation. + */ + public BigInteger toBigInteger() { + byte[] magnitude = new byte[nWords * 4 + 1]; + for (int i = 0; i < nWords; i++) { + int w = data[i]; + magnitude[magnitude.length - 4 * i - 1] = (byte) w; + magnitude[magnitude.length - 4 * i - 2] = (byte) (w >> 8); + magnitude[magnitude.length - 4 * i - 3] = (byte) (w >> 16); + magnitude[magnitude.length - 4 * i - 4] = (byte) (w >> 24); + } + return new BigInteger(magnitude).shiftLeft(offset * 32); + } + + // for debugging ... + /** + * Converts this FDBigInteger to a string. + * + * @return The string representation. + */ + @Override + public String toString(){ + return toBigInteger().toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/FloatConsts.java b/sources/net.sf.j2s.java.core/src/sun/misc/FloatConsts.java new file mode 100644 index 000000000..4345c19fc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/FloatConsts.java @@ -0,0 +1,112 @@ +/* + * Copyright (c) 2003, 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.misc; + +/** + * This class contains additional constants documenting limits of the + * float type. + * + * @author Joseph D. Darcy + */ + +public class FloatConsts { + /** + * Don't let anyone instantiate this class. + */ + private FloatConsts() {} + + public static final float POSITIVE_INFINITY = java.lang.Float.POSITIVE_INFINITY; + public static final float NEGATIVE_INFINITY = java.lang.Float.NEGATIVE_INFINITY; + public static final float NaN = java.lang.Float.NaN; + public static final float MAX_VALUE = java.lang.Float.MAX_VALUE; + public static final float MIN_VALUE = java.lang.Float.MIN_VALUE; + + /** + * A constant holding the smallest positive normal value of type + * float, 2-126. It is equal to the value + * returned by Float.intBitsToFloat(0x00800000). + */ + public static final float MIN_NORMAL = 1.17549435E-38f; + + /** + * The number of logical bits in the significand of a + * float number, including the implicit bit. + */ + public static final int SIGNIFICAND_WIDTH = 24; + + /** + * Maximum exponent a finite float number may have. + * It is equal to the value returned by + * Math.ilogb(Float.MAX_VALUE). + */ + public static final int MAX_EXPONENT = 127; + + /** + * Minimum exponent a normalized float number may + * have. It is equal to the value returned by + * Math.ilogb(Float.MIN_NORMAL). + */ + public static final int MIN_EXPONENT = -126; + + /** + * The exponent the smallest positive float subnormal + * value would have if it could be normalized. It is equal to the + * value returned by FpUtils.ilogb(Float.MIN_VALUE). + */ + public static final int MIN_SUB_EXPONENT = MIN_EXPONENT - + (SIGNIFICAND_WIDTH - 1); + + /** + * Bias used in representing a float exponent. + */ + public static final int EXP_BIAS = 127; + + /** + * Bit mask to isolate the sign bit of a float. + */ + public static final int SIGN_BIT_MASK = 0x80000000; + + /** + * Bit mask to isolate the exponent field of a + * float. + */ + public static final int EXP_BIT_MASK = 0x7F800000; + + /** + * Bit mask to isolate the significand field of a + * float. + */ + public static final int SIGNIF_BIT_MASK = 0x007FFFFF; + + static { + // verify bit masks cover all bit positions and that the bit + // masks are non-overlapping + assert(((SIGN_BIT_MASK | EXP_BIT_MASK | SIGNIF_BIT_MASK) == ~0) && + (((SIGN_BIT_MASK & EXP_BIT_MASK) == 0) && + ((SIGN_BIT_MASK & SIGNIF_BIT_MASK) == 0) && + ((EXP_BIT_MASK & SIGNIF_BIT_MASK) == 0))); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/FloatingDecimal.java b/sources/net.sf.j2s.java.core/src/sun/misc/FloatingDecimal.java new file mode 100644 index 000000000..ddd8790bc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/FloatingDecimal.java @@ -0,0 +1,2541 @@ +/* + * Copyright (c) 1996, 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.misc; + +import java.util.Arrays; +import java.util.regex.*; + +/** + * A class for converting between ASCII and decimal representations of a single + * or double precision floating point number. Most conversions are provided via + * static convenience methods, although a BinaryToASCIIConverter + * instance may be obtained and reused. + */ +public class FloatingDecimal{ + // + // Constants of the implementation; + // most are IEEE-754 related. + // (There are more really boring constants at the end.) + // + static final int EXP_SHIFT = DoubleConsts.SIGNIFICAND_WIDTH - 1; + static final long FRACT_HOB = ( 1L<String. + * + * @param d The double precision value. + * @return The value converted to a String. + */ + public static String toJavaFormatString(double d) { + return getBinaryToASCIIConverter(d).toJavaFormatString(); + } + + /** + * Converts a single precision floating point value to a String. + * + * @param f The single precision value. + * @return The value converted to a String. + */ + public static String toJavaFormatString(float f) { + return getBinaryToASCIIConverter(f).toJavaFormatString(); + } + + /** + * Appends a double precision floating point value to an Appendable. + * @param d The double precision value. + * @param buf The Appendable with the value appended. + */ + public static void appendTo(double d, Appendable buf) { + getBinaryToASCIIConverter(d).appendTo(buf); + } + + /** + * Appends a single precision floating point value to an Appendable. + * @param f The single precision value. + * @param buf The Appendable with the value appended. + */ + public static void appendTo(float f, Appendable buf) { + getBinaryToASCIIConverter(f).appendTo(buf); + } + + /** + * Converts a String to a double precision floating point value. + * + * @param s The String to convert. + * @return The double precision value. + * @throws NumberFormatException If the String does not + * represent a properly formatted double precision value. + */ + public static double parseDouble(String s) throws NumberFormatException { + return readJavaFormatString(s).doubleValue(); + } + + /** + * Converts a String to a single precision floating point value. + * + * @param s The String to convert. + * @return The single precision value. + * @throws NumberFormatException If the String does not + * represent a properly formatted single precision value. + */ + public static float parseFloat(String s) throws NumberFormatException { + return readJavaFormatString(s).floatValue(); + } + + /** + * A converter which can process single or double precision floating point + * values into an ASCII String representation. + */ + public interface BinaryToASCIIConverter { + /** + * Converts a floating point value into an ASCII String. + * @return The value converted to a String. + */ + public String toJavaFormatString(); + + /** + * Appends a floating point value to an Appendable. + * @param buf The Appendable to receive the value. + */ + public void appendTo(Appendable buf); + + /** + * Retrieves the decimal exponent most closely corresponding to this value. + * @return The decimal exponent. + */ + public int getDecimalExponent(); + + /** + * Retrieves the value as an array of digits. + * @param digits The digit array. + * @return The number of valid digits copied into the array. + */ + public int getDigits(char[] digits); + + /** + * Indicates the sign of the value. + * @return value < 0.0. + */ + public boolean isNegative(); + + /** + * Indicates whether the value is either infinite or not a number. + * + * @return true if and only if the value is NaN + * or infinite. + */ + public boolean isExceptional(); + + /** + * Indicates whether the value was rounded up during the binary to ASCII + * conversion. + * + * @return true if and only if the value was rounded up. + */ + public boolean digitsRoundedUp(); + + /** + * Indicates whether the binary to ASCII conversion was exact. + * + * @return true if any only if the conversion was exact. + */ + public boolean decimalDigitsExact(); + } + + /** + * A BinaryToASCIIConverter which represents NaN + * and infinite values. + */ + private static class ExceptionalBinaryToASCIIBuffer implements BinaryToASCIIConverter { + final private String image; + private boolean isNegative; + + public ExceptionalBinaryToASCIIBuffer(String image, boolean isNegative) { + this.image = image; + this.isNegative = isNegative; + } + + @Override + public String toJavaFormatString() { + return image; + } + + @Override + public void appendTo(Appendable buf) { + if (buf instanceof StringBuilder) { + ((StringBuilder) buf).append(image); + } else if (buf instanceof StringBuffer) { + ((StringBuffer) buf).append(image); + } else { + assert false; + } + } + + @Override + public int getDecimalExponent() { + throw new IllegalArgumentException("Exceptional value does not have an exponent"); + } + + @Override + public int getDigits(char[] digits) { + throw new IllegalArgumentException("Exceptional value does not have digits"); + } + + @Override + public boolean isNegative() { + return isNegative; + } + + @Override + public boolean isExceptional() { + return true; + } + + @Override + public boolean digitsRoundedUp() { + throw new IllegalArgumentException("Exceptional value is not rounded"); + } + + @Override + public boolean decimalDigitsExact() { + throw new IllegalArgumentException("Exceptional value is not exact"); + } + } + + private static final String INFINITY_REP = "Infinity"; + private static final int INFINITY_LENGTH = INFINITY_REP.length(); + private static final String NAN_REP = "NaN"; + private static final int NAN_LENGTH = NAN_REP.length(); + + private static final BinaryToASCIIConverter B2AC_POSITIVE_INFINITY = new ExceptionalBinaryToASCIIBuffer(INFINITY_REP, false); + private static final BinaryToASCIIConverter B2AC_NEGATIVE_INFINITY = new ExceptionalBinaryToASCIIBuffer("-" + INFINITY_REP, true); + private static final BinaryToASCIIConverter B2AC_NOT_A_NUMBER = new ExceptionalBinaryToASCIIBuffer(NAN_REP, false); + private static final BinaryToASCIIConverter B2AC_POSITIVE_ZERO = new BinaryToASCIIBuffer(false, new char[]{'0'}); + private static final BinaryToASCIIConverter B2AC_NEGATIVE_ZERO = new BinaryToASCIIBuffer(true, new char[]{'0'}); + + /** + * A buffered implementation of BinaryToASCIIConverter. + */ + static class BinaryToASCIIBuffer implements BinaryToASCIIConverter { + private boolean isNegative; + private int decExponent; + private int firstDigitIndex; + private int nDigits; + private final char[] digits; + private final char[] buffer = new char[26]; + + // + // The fields below provide additional information about the result of + // the binary to decimal digits conversion done in dtoa() and roundup() + // methods. They are changed if needed by those two methods. + // + + // True if the dtoa() binary to decimal conversion was exact. + private boolean exactDecimalConversion = false; + + // True if the result of the binary to decimal conversion was rounded-up + // at the end of the conversion process, i.e. roundUp() method was called. + private boolean decimalDigitsRoundedUp = false; + + /** + * Default constructor; used for non-zero values, + * BinaryToASCIIBuffer may be thread-local and reused + */ + BinaryToASCIIBuffer(){ + this.digits = new char[20]; + } + + /** + * Creates a specialized value (positive and negative zeros). + */ + BinaryToASCIIBuffer(boolean isNegative, char[] digits){ + this.isNegative = isNegative; + this.decExponent = 0; + this.digits = digits; + this.firstDigitIndex = 0; + this.nDigits = digits.length; + } + + @Override + public String toJavaFormatString() { + int len = getChars(buffer); + return new String(buffer, 0, len); + } + + @Override + public void appendTo(Appendable buf) { + int len = getChars(buffer); + if (buf instanceof StringBuilder) { + ((StringBuilder) buf).append(buffer, 0, len); + } else if (buf instanceof StringBuffer) { + ((StringBuffer) buf).append(buffer, 0, len); + } else { + assert false; + } + } + + @Override + public int getDecimalExponent() { + return decExponent; + } + + @Override + public int getDigits(char[] digits) { + System.arraycopy(this.digits,firstDigitIndex,digits,0,this.nDigits); + return this.nDigits; + } + + @Override + public boolean isNegative() { + return isNegative; + } + + @Override + public boolean isExceptional() { + return false; + } + + @Override + public boolean digitsRoundedUp() { + return decimalDigitsRoundedUp; + } + + @Override + public boolean decimalDigitsExact() { + return exactDecimalConversion; + } + + private void setSign(boolean isNegative) { + this.isNegative = isNegative; + } + + /** + * This is the easy subcase -- + * all the significant bits, after scaling, are held in lvalue. + * negSign and decExponent tell us what processing and scaling + * has already been done. Exceptional cases have already been + * stripped out. + * In particular: + * lvalue is a finite number (not Inf, nor NaN) + * lvalue > 0L (not zero, nor negative). + * + * The only reason that we develop the digits here, rather than + * calling on Long.toString() is that we can do it a little faster, + * and besides want to treat trailing 0s specially. If Long.toString + * changes, we should re-evaluate this strategy! + */ + private void developLongDigits( int decExponent, long lvalue, int insignificantDigits ){ + if ( insignificantDigits != 0 ){ + // Discard non-significant low-order bits, while rounding, + // up to insignificant value. + long pow10 = FDBigInteger.LONG_5_POW[insignificantDigits] << insignificantDigits; // 10^i == 5^i * 2^i; + long residue = lvalue % pow10; + lvalue /= pow10; + decExponent += insignificantDigits; + if ( residue >= (pow10>>1) ){ + // round up based on the low-order bits we're discarding + lvalue++; + } + } + int digitno = digits.length -1; + int c; + if ( lvalue <= Integer.MAX_VALUE ){ + assert lvalue > 0L : lvalue; // lvalue <= 0 + // even easier subcase! + // can do int arithmetic rather than long! + int ivalue = (int)lvalue; + c = ivalue%10; + ivalue /= 10; + while ( c == 0 ){ + decExponent++; + c = ivalue%10; + ivalue /= 10; + } + while ( ivalue != 0){ + digits[digitno--] = (char)(c+'0'); + decExponent++; + c = ivalue%10; + ivalue /= 10; + } + digits[digitno] = (char)(c+'0'); + } else { + // same algorithm as above (same bugs, too ) + // but using long arithmetic. + c = (int)(lvalue%10L); + lvalue /= 10L; + while ( c == 0 ){ + decExponent++; + c = (int)(lvalue%10L); + lvalue /= 10L; + } + while ( lvalue != 0L ){ + digits[digitno--] = (char)(c+'0'); + decExponent++; + c = (int)(lvalue%10L); + lvalue /= 10; + } + digits[digitno] = (char)(c+'0'); + } + this.decExponent = decExponent+1; + this.firstDigitIndex = digitno; + this.nDigits = this.digits.length - digitno; + } + + private void dtoa( int binExp, long fractBits, int nSignificantBits, boolean isCompatibleFormat) + { + assert fractBits > 0 ; // fractBits here can't be zero or negative + assert (fractBits & FRACT_HOB)!=0 ; // Hi-order bit should be set + // Examine number. Determine if it is an easy case, + // which we can do pretty trivially using float/long conversion, + // or whether we must do real work. + final int tailZeros = Long.numberOfTrailingZeros(fractBits); + + // number of significant bits of fractBits; + final int nFractBits = EXP_SHIFT+1-tailZeros; + + // reset flags to default values as dtoa() does not always set these + // flags and a prior call to dtoa() might have set them to incorrect + // values with respect to the current state. + decimalDigitsRoundedUp = false; + exactDecimalConversion = false; + + // number of significant bits to the right of the point. + int nTinyBits = Math.max( 0, nFractBits - binExp - 1 ); + if ( binExp <= MAX_SMALL_BIN_EXP && binExp >= MIN_SMALL_BIN_EXP ){ + // Look more closely at the number to decide if, + // with scaling by 10^nTinyBits, the result will fit in + // a long. + if ( (nTinyBits < FDBigInteger.LONG_5_POW.length) && ((nFractBits + N_5_BITS[nTinyBits]) < 64 ) ){ + // + // We can do this: + // take the fraction bits, which are normalized. + // (a) nTinyBits == 0: Shift left or right appropriately + // to align the binary point at the extreme right, i.e. + // where a long int point is expected to be. The integer + // result is easily converted to a string. + // (b) nTinyBits > 0: Shift right by EXP_SHIFT-nFractBits, + // which effectively converts to long and scales by + // 2^nTinyBits. Then multiply by 5^nTinyBits to + // complete the scaling. We know this won't overflow + // because we just counted the number of bits necessary + // in the result. The integer you get from this can + // then be converted to a string pretty easily. + // + if ( nTinyBits == 0 ) { + int insignificant; + if ( binExp > nSignificantBits ){ + insignificant = insignificantDigitsForPow2(binExp-nSignificantBits-1); + } else { + insignificant = 0; + } + if ( binExp >= EXP_SHIFT ){ + fractBits <<= (binExp-EXP_SHIFT); + } else { + fractBits >>>= (EXP_SHIFT-binExp) ; + } + developLongDigits( 0, fractBits, insignificant ); + return; + } + // + // The following causes excess digits to be printed + // out in the single-float case. Our manipulation of + // halfULP here is apparently not correct. If we + // better understand how this works, perhaps we can + // use this special case again. But for the time being, + // we do not. + // else { + // fractBits >>>= EXP_SHIFT+1-nFractBits; + // fractBits//= long5pow[ nTinyBits ]; + // halfULP = long5pow[ nTinyBits ] >> (1+nSignificantBits-nFractBits); + // developLongDigits( -nTinyBits, fractBits, insignificantDigits(halfULP) ); + // return; + // } + // + } + } + // + // This is the hard case. We are going to compute large positive + // integers B and S and integer decExp, s.t. + // d = ( B / S )// 10^decExp + // 1 <= B / S < 10 + // Obvious choices are: + // decExp = floor( log10(d) ) + // B = d// 2^nTinyBits// 10^max( 0, -decExp ) + // S = 10^max( 0, decExp)// 2^nTinyBits + // (noting that nTinyBits has already been forced to non-negative) + // I am also going to compute a large positive integer + // M = (1/2^nSignificantBits)// 2^nTinyBits// 10^max( 0, -decExp ) + // i.e. M is (1/2) of the ULP of d, scaled like B. + // When we iterate through dividing B/S and picking off the + // quotient bits, we will know when to stop when the remainder + // is <= M. + // + // We keep track of powers of 2 and powers of 5. + // + int decExp = estimateDecExp(fractBits,binExp); + int B2, B5; // powers of 2 and powers of 5, respectively, in B + int S2, S5; // powers of 2 and powers of 5, respectively, in S + int M2, M5; // powers of 2 and powers of 5, respectively, in M + + B5 = Math.max( 0, -decExp ); + B2 = B5 + nTinyBits + binExp; + + S5 = Math.max( 0, decExp ); + S2 = S5 + nTinyBits; + + M5 = B5; + M2 = B2 - nSignificantBits; + + // + // the long integer fractBits contains the (nFractBits) interesting + // bits from the mantissa of d ( hidden 1 added if necessary) followed + // by (EXP_SHIFT+1-nFractBits) zeros. In the interest of compactness, + // I will shift out those zeros before turning fractBits into a + // FDBigInteger. The resulting whole number will be + // d * 2^(nFractBits-1-binExp). + // + fractBits >>>= tailZeros; + B2 -= nFractBits-1; + int common2factor = Math.min( B2, S2 ); + B2 -= common2factor; + S2 -= common2factor; + M2 -= common2factor; + + // + // HACK!! For exact powers of two, the next smallest number + // is only half as far away as we think (because the meaning of + // ULP changes at power-of-two bounds) for this reason, we + // hack M2. Hope this works. + // + if ( nFractBits == 1 ) { + M2 -= 1; + } + + if ( M2 < 0 ){ + // oops. + // since we cannot scale M down far enough, + // we must scale the other values up. + B2 -= M2; + S2 -= M2; + M2 = 0; + } + // + // Construct, Scale, iterate. + // Some day, we'll write a stopping test that takes + // account of the asymmetry of the spacing of floating-point + // numbers below perfect powers of 2 + // 26 Sept 96 is not that day. + // So we use a symmetric test. + // + int ndigit = 0; + boolean low, high; + long lowDigitDifference; + int q; + + // + // Detect the special cases where all the numbers we are about + // to compute will fit in int or long integers. + // In these cases, we will avoid doing FDBigInteger arithmetic. + // We use the same algorithms, except that we "normalize" + // our FDBigIntegers before iterating. This is to make division easier, + // as it makes our fist guess (quotient of high-order words) + // more accurate! + // + // Some day, we'll write a stopping test that takes + // account of the asymmetry of the spacing of floating-point + // numbers below perfect powers of 2 + // 26 Sept 96 is not that day. + // So we use a symmetric test. + // + // binary digits needed to represent B, approx. + int Bbits = nFractBits + B2 + (( B5 < N_5_BITS.length )? N_5_BITS[B5] : ( B5*3 )); + + // binary digits needed to represent 10*S, approx. + int tenSbits = S2+1 + (( (S5+1) < N_5_BITS.length )? N_5_BITS[(S5+1)] : ( (S5+1)*3 )); + if ( Bbits < 64 && tenSbits < 64){ + if ( Bbits < 32 && tenSbits < 32){ + // wa-hoo! They're all ints! + int b = ((int)fractBits * FDBigInteger.SMALL_5_POW[B5] ) << B2; + int s = FDBigInteger.SMALL_5_POW[S5] << S2; + int m = FDBigInteger.SMALL_5_POW[M5] << M2; + int tens = s * 10; + // + // Unroll the first iteration. If our decExp estimate + // was too high, our first quotient will be zero. In this + // case, we discard it and decrement decExp. + // + ndigit = 0; + q = b / s; + b = 10 * ( b % s ); + m *= 10; + low = (b < m ); + high = (b+m > tens ); + assert q < 10 : q; // excessively large digit + if ( (q == 0) && ! high ){ + // oops. Usually ignore leading zero. + decExp--; + } else { + digits[ndigit++] = (char)('0' + q); + } + // + // HACK! Java spec sez that we always have at least + // one digit after the . in either F- or E-form output. + // Thus we will need more than one digit if we're using + // E-form + // + if ( !isCompatibleFormat ||decExp < -3 || decExp >= 8 ){ + high = low = false; + } + while( ! low && ! high ){ + q = b / s; + b = 10 * ( b % s ); + m *= 10; + assert q < 10 : q; // excessively large digit + if ( m > 0L ){ + low = (b < m ); + high = (b+m > tens ); + } else { + // hack -- m might overflow! + // in this case, it is certainly > b, + // which won't + // and b+m > tens, too, since that has overflowed + // either! + low = true; + high = true; + } + digits[ndigit++] = (char)('0' + q); + } + lowDigitDifference = (b<<1) - tens; + exactDecimalConversion = (b == 0); + } else { + // still good! they're all longs! + long b = (fractBits * FDBigInteger.LONG_5_POW[B5] ) << B2; + long s = FDBigInteger.LONG_5_POW[S5] << S2; + long m = FDBigInteger.LONG_5_POW[M5] << M2; + long tens = s * 10L; + // + // Unroll the first iteration. If our decExp estimate + // was too high, our first quotient will be zero. In this + // case, we discard it and decrement decExp. + // + ndigit = 0; + q = (int) ( b / s ); + b = 10L * ( b % s ); + m *= 10L; + low = (b < m ); + high = (b+m > tens ); + assert q < 10 : q; // excessively large digit + if ( (q == 0) && ! high ){ + // oops. Usually ignore leading zero. + decExp--; + } else { + digits[ndigit++] = (char)('0' + q); + } + // + // HACK! Java spec sez that we always have at least + // one digit after the . in either F- or E-form output. + // Thus we will need more than one digit if we're using + // E-form + // + if ( !isCompatibleFormat || decExp < -3 || decExp >= 8 ){ + high = low = false; + } + while( ! low && ! high ){ + q = (int) ( b / s ); + b = 10 * ( b % s ); + m *= 10; + assert q < 10 : q; // excessively large digit + if ( m > 0L ){ + low = (b < m ); + high = (b+m > tens ); + } else { + // hack -- m might overflow! + // in this case, it is certainly > b, + // which won't + // and b+m > tens, too, since that has overflowed + // either! + low = true; + high = true; + } + digits[ndigit++] = (char)('0' + q); + } + lowDigitDifference = (b<<1) - tens; + exactDecimalConversion = (b == 0); + } + } else { + // + // We really must do FDBigInteger arithmetic. + // Fist, construct our FDBigInteger initial values. + // + FDBigInteger Sval = FDBigInteger.valueOfPow52(S5, S2); + int shiftBias = Sval.getNormalizationBias(); + Sval = Sval.leftShift(shiftBias); // normalize so that division works better + + FDBigInteger Bval = FDBigInteger.valueOfMulPow52(fractBits, B5, B2 + shiftBias); + FDBigInteger Mval = FDBigInteger.valueOfPow52(M5 + 1, M2 + shiftBias + 1); + + FDBigInteger tenSval = FDBigInteger.valueOfPow52(S5 + 1, S2 + shiftBias + 1); //Sval.mult( 10 ); + // + // Unroll the first iteration. If our decExp estimate + // was too high, our first quotient will be zero. In this + // case, we discard it and decrement decExp. + // + ndigit = 0; + q = Bval.quoRemIteration( Sval ); + low = (Bval.cmp( Mval ) < 0); + high = tenSval.addAndCmp(Bval,Mval)<=0; + + assert q < 10 : q; // excessively large digit + if ( (q == 0) && ! high ){ + // oops. Usually ignore leading zero. + decExp--; + } else { + digits[ndigit++] = (char)('0' + q); + } + // + // HACK! Java spec sez that we always have at least + // one digit after the . in either F- or E-form output. + // Thus we will need more than one digit if we're using + // E-form + // + if (!isCompatibleFormat || decExp < -3 || decExp >= 8 ){ + high = low = false; + } + while( ! low && ! high ){ + q = Bval.quoRemIteration( Sval ); + assert q < 10 : q; // excessively large digit + Mval = Mval.multBy10(); //Mval = Mval.mult( 10 ); + low = (Bval.cmp( Mval ) < 0); + high = tenSval.addAndCmp(Bval,Mval)<=0; + digits[ndigit++] = (char)('0' + q); + } + if ( high && low ){ + Bval = Bval.leftShift(1); + lowDigitDifference = Bval.cmp(tenSval); + } else { + lowDigitDifference = 0L; // this here only for flow analysis! + } + exactDecimalConversion = (Bval.cmp( FDBigInteger.ZERO ) == 0); + } + this.decExponent = decExp+1; + this.firstDigitIndex = 0; + this.nDigits = ndigit; + // + // Last digit gets rounded based on stopping condition. + // + if ( high ){ + if ( low ){ + if ( lowDigitDifference == 0L ){ + // it's a tie! + // choose based on which digits we like. + if ( (digits[firstDigitIndex+nDigits-1]&1) != 0 ) { + roundup(); + } + } else if ( lowDigitDifference > 0 ){ + roundup(); + } + } else { + roundup(); + } + } + } + + // add one to the least significant digit. + // in the unlikely event there is a carry out, deal with it. + // assert that this will only happen where there + // is only one digit, e.g. (float)1e-44 seems to do it. + // + private void roundup() { + int i = (firstDigitIndex + nDigits - 1); + int q = digits[i]; + if (q == '9') { + while (q == '9' && i > firstDigitIndex) { + digits[i] = '0'; + q = digits[--i]; + } + if (q == '9') { + // carryout! High-order 1, rest 0s, larger exp. + decExponent += 1; + digits[firstDigitIndex] = '1'; + return; + } + // else fall through. + } + digits[i] = (char) (q + 1); + decimalDigitsRoundedUp = true; + } + + /** + * Estimate decimal exponent. (If it is small-ish, + * we could double-check.) + * + * First, scale the mantissa bits such that 1 <= d2 < 2. + * We are then going to estimate + * log10(d2) ~=~ (d2-1.5)/1.5 + log(1.5) + * and so we can estimate + * log10(d) ~=~ log10(d2) + binExp * log10(2) + * take the floor and call it decExp. + */ + static int estimateDecExp(long fractBits, int binExp) { + double d2 = Double.longBitsToDouble( EXP_ONE | ( fractBits & DoubleConsts.SIGNIF_BIT_MASK ) ); + double d = (d2-1.5D)*0.289529654D + 0.176091259 + (double)binExp * 0.301029995663981; + long dBits = Double.doubleToRawLongBits(d); //can't be NaN here so use raw + int exponent = (int)((dBits & DoubleConsts.EXP_BIT_MASK) >> EXP_SHIFT) - DoubleConsts.EXP_BIAS; + boolean isNegative = (dBits & DoubleConsts.SIGN_BIT_MASK) != 0; // discover sign + if(exponent>=0 && exponent<52) { // hot path + long mask = DoubleConsts.SIGNIF_BIT_MASK >> exponent; + int r = (int)(( (dBits&DoubleConsts.SIGNIF_BIT_MASK) | FRACT_HOB )>>(EXP_SHIFT-exponent)); + return isNegative ? (((mask & dBits) == 0L ) ? -r : -r-1 ) : r; + } else if (exponent < 0) { + return (((dBits&~DoubleConsts.SIGN_BIT_MASK) == 0) ? 0 : + ( (isNegative) ? -1 : 0) ); + } else { //if (exponent >= 52) + return (int)d; + } + } + + private static int insignificantDigits(int insignificant) { + int i; + for ( i = 0; insignificant >= 10L; i++ ) { + insignificant /= 10L; + } + return i; + } + + /** + * Calculates + *
      +         * insignificantDigitsForPow2(v) == insignificantDigits(1L<
      +         */
      +        private static int insignificantDigitsForPow2(int p2) {
      +            if(p2>1 && p2 < insignificantDigitsNumber.length) {
      +                return insignificantDigitsNumber[p2];
      +            }
      +            return 0;
      +        }
      +
      +        /**
      +         *  If insignificant==(1L << ixd)
      +         *  i = insignificantDigitsNumber[idx] is the same as:
      +         *  int i;
      +         *  for ( i = 0; insignificant >= 10L; i++ )
      +         *         insignificant /= 10L;
      +         */
      +        private static int[] insignificantDigitsNumber = {
      +            0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3,
      +            4, 4, 4, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7,
      +            8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11,
      +            12, 12, 12, 12, 13, 13, 13, 14, 14, 14,
      +            15, 15, 15, 15, 16, 16, 16, 17, 17, 17,
      +            18, 18, 18, 19
      +        };
      +
      +        // approximately ceil( log2( long5pow[i] ) )
      +        private static final int[] N_5_BITS = {
      +                0,
      +                3,
      +                5,
      +                7,
      +                10,
      +                12,
      +                14,
      +                17,
      +                19,
      +                21,
      +                24,
      +                26,
      +                28,
      +                31,
      +                33,
      +                35,
      +                38,
      +                40,
      +                42,
      +                45,
      +                47,
      +                49,
      +                52,
      +                54,
      +                56,
      +                59,
      +                61,
      +        };
      +
      +        private int getChars(char[] result) {
      +            assert nDigits <= 19 : nDigits; // generous bound on size of nDigits
      +            int i = 0;
      +            if (isNegative) {
      +                result[0] = '-';
      +                i = 1;
      +            }
      +            if (decExponent > 0 && decExponent < 8) {
      +                // print digits.digits.
      +                int charLength = Math.min(nDigits, decExponent);
      +                System.arraycopy(digits, firstDigitIndex, result, i, charLength);
      +                i += charLength;
      +                if (charLength < decExponent) {
      +                    charLength = decExponent - charLength;
      +                    Arrays.fill(result,i,i+charLength,'0');
      +                    i += charLength;
      +                    result[i++] = '.';
      +                    result[i++] = '0';
      +                } else {
      +                    result[i++] = '.';
      +                    if (charLength < nDigits) {
      +                        int t = nDigits - charLength;
      +                        System.arraycopy(digits, firstDigitIndex+charLength, result, i, t);
      +                        i += t;
      +                    } else {
      +                        result[i++] = '0';
      +                    }
      +                }
      +            } else if (decExponent <= 0 && decExponent > -3) {
      +                result[i++] = '0';
      +                result[i++] = '.';
      +                if (decExponent != 0) {
      +                    Arrays.fill(result, i, i-decExponent, '0');
      +                    i -= decExponent;
      +                }
      +                System.arraycopy(digits, firstDigitIndex, result, i, nDigits);
      +                i += nDigits;
      +            } else {
      +                result[i++] = digits[firstDigitIndex];
      +                result[i++] = '.';
      +                if (nDigits > 1) {
      +                    System.arraycopy(digits, firstDigitIndex+1, result, i, nDigits - 1);
      +                    i += nDigits - 1;
      +                } else {
      +                    result[i++] = '0';
      +                }
      +                result[i++] = 'E';
      +                int e;
      +                if (decExponent <= 0) {
      +                    result[i++] = '-';
      +                    e = -decExponent + 1;
      +                } else {
      +                    e = decExponent - 1;
      +                }
      +                // decExponent has 1, 2, or 3, digits
      +                if (e <= 9) {
      +                    result[i++] = (char) (e + '0');
      +                } else if (e <= 99) {
      +                    result[i++] = (char) (e / 10 + '0');
      +                    result[i++] = (char) (e % 10 + '0');
      +                } else {
      +                    result[i++] = (char) (e / 100 + '0');
      +                    e %= 100;
      +                    result[i++] = (char) (e / 10 + '0');
      +                    result[i++] = (char) (e % 10 + '0');
      +                }
      +            }
      +            return i;
      +        }
      +
      +    }
      +
      +    private static final ThreadLocal threadLocalBinaryToASCIIBuffer =
      +            new ThreadLocal() {
      +                @Override
      +                protected BinaryToASCIIBuffer initialValue() {
      +                    return new BinaryToASCIIBuffer();
      +                }
      +            };
      +
      +    private static BinaryToASCIIBuffer getBinaryToASCIIBuffer() {
      +        return threadLocalBinaryToASCIIBuffer.get();
      +    }
      +
      +    /**
      +     * A converter which can process an ASCII String representation
      +     * of a single or double precision floating point value into a
      +     * float or a double.
      +     */
      +    interface ASCIIToBinaryConverter {
      +
      +        double doubleValue();
      +
      +        float floatValue();
      +
      +    }
      +
      +    /**
      +     * A ASCIIToBinaryConverter container for a double.
      +     */
      +    static class PreparedASCIIToBinaryBuffer implements ASCIIToBinaryConverter {
      +        final private double doubleVal;
      +        final private float floatVal;
      +
      +        public PreparedASCIIToBinaryBuffer(double doubleVal, float floatVal) {
      +            this.doubleVal = doubleVal;
      +            this.floatVal = floatVal;
      +        }
      +
      +        @Override
      +        public double doubleValue() {
      +            return doubleVal;
      +        }
      +
      +        @Override
      +        public float floatValue() {
      +            return floatVal;
      +        }
      +    }
      +
      +    static final ASCIIToBinaryConverter A2BC_POSITIVE_INFINITY = new PreparedASCIIToBinaryBuffer(Double.POSITIVE_INFINITY, Float.POSITIVE_INFINITY);
      +    static final ASCIIToBinaryConverter A2BC_NEGATIVE_INFINITY = new PreparedASCIIToBinaryBuffer(Double.NEGATIVE_INFINITY, Float.NEGATIVE_INFINITY);
      +    static final ASCIIToBinaryConverter A2BC_NOT_A_NUMBER  = new PreparedASCIIToBinaryBuffer(Double.NaN, Float.NaN);
      +    static final ASCIIToBinaryConverter A2BC_POSITIVE_ZERO = new PreparedASCIIToBinaryBuffer(0.0d, 0.0f);
      +    static final ASCIIToBinaryConverter A2BC_NEGATIVE_ZERO = new PreparedASCIIToBinaryBuffer(-0.0d, -0.0f);
      +
      +    /**
      +     * A buffered implementation of ASCIIToBinaryConverter.
      +     */
      +    static class ASCIIToBinaryBuffer implements ASCIIToBinaryConverter {
      +        boolean     isNegative;
      +        int         decExponent;
      +        char        digits[];
      +        int         nDigits;
      +
      +        ASCIIToBinaryBuffer( boolean negSign, int decExponent, char[] digits, int n)
      +        {
      +            this.isNegative = negSign;
      +            this.decExponent = decExponent;
      +            this.digits = digits;
      +            this.nDigits = n;
      +        }
      +
      +        /**
      +         * Takes a FloatingDecimal, which we presumably just scanned in,
      +         * and finds out what its value is, as a double.
      +         *
      +         * AS A SIDE EFFECT, SET roundDir TO INDICATE PREFERRED
      +         * ROUNDING DIRECTION in case the result is really destined
      +         * for a single-precision float.
      +         */
      +        @Override
      +        public double doubleValue() {
      +            int kDigits = Math.min(nDigits, MAX_DECIMAL_DIGITS + 1);
      +            //
      +            // convert the lead kDigits to a long integer.
      +            //
      +            // (special performance hack: start to do it using int)
      +            int iValue = (int) digits[0] - (int) '0';
      +            int iDigits = Math.min(kDigits, INT_DECIMAL_DIGITS);
      +            for (int i = 1; i < iDigits; i++) {
      +                iValue = iValue * 10 + (int) digits[i] - (int) '0';
      +            }
      +            long lValue = (long) iValue;
      +            for (int i = iDigits; i < kDigits; i++) {
      +                lValue = lValue * 10L + (long) ((int) digits[i] - (int) '0');
      +            }
      +            double dValue = (double) lValue;
      +            int exp = decExponent - kDigits;
      +            //
      +            // lValue now contains a long integer with the value of
      +            // the first kDigits digits of the number.
      +            // dValue contains the (double) of the same.
      +            //
      +
      +            if (nDigits <= MAX_DECIMAL_DIGITS) {
      +                //
      +                // possibly an easy case.
      +                // We know that the digits can be represented
      +                // exactly. And if the exponent isn't too outrageous,
      +                // the whole thing can be done with one operation,
      +                // thus one rounding error.
      +                // Note that all our constructors trim all leading and
      +                // trailing zeros, so simple values (including zero)
      +                // will always end up here
      +                //
      +                if (exp == 0 || dValue == 0.0) {
      +                    return (isNegative) ? -dValue : dValue; // small floating integer
      +                }
      +                else if (exp >= 0) {
      +                    if (exp <= MAX_SMALL_TEN) {
      +                        //
      +                        // Can get the answer with one operation,
      +                        // thus one roundoff.
      +                        //
      +                        double rValue = dValue * SMALL_10_POW[exp];
      +                        return (isNegative) ? -rValue : rValue;
      +                    }
      +                    int slop = MAX_DECIMAL_DIGITS - kDigits;
      +                    if (exp <= MAX_SMALL_TEN + slop) {
      +                        //
      +                        // We can multiply dValue by 10^(slop)
      +                        // and it is still "small" and exact.
      +                        // Then we can multiply by 10^(exp-slop)
      +                        // with one rounding.
      +                        //
      +                        dValue *= SMALL_10_POW[slop];
      +                        double rValue = dValue * SMALL_10_POW[exp - slop];
      +                        return (isNegative) ? -rValue : rValue;
      +                    }
      +                    //
      +                    // Else we have a hard case with a positive exp.
      +                    //
      +                } else {
      +                    if (exp >= -MAX_SMALL_TEN) {
      +                        //
      +                        // Can get the answer in one division.
      +                        //
      +                        double rValue = dValue / SMALL_10_POW[-exp];
      +                        return (isNegative) ? -rValue : rValue;
      +                    }
      +                    //
      +                    // Else we have a hard case with a negative exp.
      +                    //
      +                }
      +            }
      +
      +            //
      +            // Harder cases:
      +            // The sum of digits plus exponent is greater than
      +            // what we think we can do with one error.
      +            //
      +            // Start by approximating the right answer by,
      +            // naively, scaling by powers of 10.
      +            //
      +            if (exp > 0) {
      +                if (decExponent > MAX_DECIMAL_EXPONENT + 1) {
      +                    //
      +                    // Lets face it. This is going to be
      +                    // Infinity. Cut to the chase.
      +                    //
      +                    return (isNegative) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
      +                }
      +                if ((exp & 15) != 0) {
      +                    dValue *= SMALL_10_POW[exp & 15];
      +                }
      +                if ((exp >>= 4) != 0) {
      +                    int j;
      +                    for (j = 0; exp > 1; j++, exp >>= 1) {
      +                        if ((exp & 1) != 0) {
      +                            dValue *= BIG_10_POW[j];
      +                        }
      +                    }
      +                    //
      +                    // The reason for the weird exp > 1 condition
      +                    // in the above loop was so that the last multiply
      +                    // would get unrolled. We handle it here.
      +                    // It could overflow.
      +                    //
      +                    double t = dValue * BIG_10_POW[j];
      +                    if (Double.isInfinite(t)) {
      +                        //
      +                        // It did overflow.
      +                        // Look more closely at the result.
      +                        // If the exponent is just one too large,
      +                        // then use the maximum finite as our estimate
      +                        // value. Else call the result infinity
      +                        // and punt it.
      +                        // ( I presume this could happen because
      +                        // rounding forces the result here to be
      +                        // an ULP or two larger than
      +                        // Double.MAX_VALUE ).
      +                        //
      +                        t = dValue / 2.0;
      +                        t *= BIG_10_POW[j];
      +                        if (Double.isInfinite(t)) {
      +                            return (isNegative) ? Double.NEGATIVE_INFINITY : Double.POSITIVE_INFINITY;
      +                        }
      +                        t = Double.MAX_VALUE;
      +                    }
      +                    dValue = t;
      +                }
      +            } else if (exp < 0) {
      +                exp = -exp;
      +                if (decExponent < MIN_DECIMAL_EXPONENT - 1) {
      +                    //
      +                    // Lets face it. This is going to be
      +                    // zero. Cut to the chase.
      +                    //
      +                    return (isNegative) ? -0.0 : 0.0;
      +                }
      +                if ((exp & 15) != 0) {
      +                    dValue /= SMALL_10_POW[exp & 15];
      +                }
      +                if ((exp >>= 4) != 0) {
      +                    int j;
      +                    for (j = 0; exp > 1; j++, exp >>= 1) {
      +                        if ((exp & 1) != 0) {
      +                            dValue *= TINY_10_POW[j];
      +                        }
      +                    }
      +                    //
      +                    // The reason for the weird exp > 1 condition
      +                    // in the above loop was so that the last multiply
      +                    // would get unrolled. We handle it here.
      +                    // It could underflow.
      +                    //
      +                    double t = dValue * TINY_10_POW[j];
      +                    if (t == 0.0) {
      +                        //
      +                        // It did underflow.
      +                        // Look more closely at the result.
      +                        // If the exponent is just one too small,
      +                        // then use the minimum finite as our estimate
      +                        // value. Else call the result 0.0
      +                        // and punt it.
      +                        // ( I presume this could happen because
      +                        // rounding forces the result here to be
      +                        // an ULP or two less than
      +                        // Double.MIN_VALUE ).
      +                        //
      +                        t = dValue * 2.0;
      +                        t *= TINY_10_POW[j];
      +                        if (t == 0.0) {
      +                            return (isNegative) ? -0.0 : 0.0;
      +                        }
      +                        t = Double.MIN_VALUE;
      +                    }
      +                    dValue = t;
      +                }
      +            }
      +
      +            //
      +            // dValue is now approximately the result.
      +            // The hard part is adjusting it, by comparison
      +            // with FDBigInteger arithmetic.
      +            // Formulate the EXACT big-number result as
      +            // bigD0 * 10^exp
      +            //
      +            if (nDigits > MAX_NDIGITS) {
      +                nDigits = MAX_NDIGITS + 1;
      +                digits[MAX_NDIGITS] = '1';
      +            }
      +            FDBigInteger bigD0 = new FDBigInteger(lValue, digits, kDigits, nDigits);
      +            exp = decExponent - nDigits;
      +
      +            long ieeeBits = Double.doubleToRawLongBits(dValue); // IEEE-754 bits of double candidate
      +            final int B5 = Math.max(0, -exp); // powers of 5 in bigB, value is not modified inside correctionLoop
      +            final int D5 = Math.max(0, exp); // powers of 5 in bigD, value is not modified inside correctionLoop
      +            bigD0 = bigD0.multByPow52(D5, 0);
      +            bigD0.makeImmutable();   // prevent bigD0 modification inside correctionLoop
      +            FDBigInteger bigD = null;
      +            int prevD2 = 0;
      +
      +            correctionLoop:
      +            while (true) {
      +                // here ieeeBits can't be NaN, Infinity or zero
      +                int binexp = (int) (ieeeBits >>> EXP_SHIFT);
      +                long bigBbits = ieeeBits & DoubleConsts.SIGNIF_BIT_MASK;
      +                if (binexp > 0) {
      +                    bigBbits |= FRACT_HOB;
      +                } else { // Normalize denormalized numbers.
      +                    assert bigBbits != 0L : bigBbits; // doubleToBigInt(0.0)
      +                    int leadingZeros = Long.numberOfLeadingZeros(bigBbits);
      +                    int shift = leadingZeros - (63 - EXP_SHIFT);
      +                    bigBbits <<= shift;
      +                    binexp = 1 - shift;
      +                }
      +                binexp -= DoubleConsts.EXP_BIAS;
      +                int lowOrderZeros = Long.numberOfTrailingZeros(bigBbits);
      +                bigBbits >>>= lowOrderZeros;
      +                final int bigIntExp = binexp - EXP_SHIFT + lowOrderZeros;
      +                final int bigIntNBits = EXP_SHIFT + 1 - lowOrderZeros;
      +
      +                //
      +                // Scale bigD, bigB appropriately for
      +                // big-integer operations.
      +                // Naively, we multiply by powers of ten
      +                // and powers of two. What we actually do
      +                // is keep track of the powers of 5 and
      +                // powers of 2 we would use, then factor out
      +                // common divisors before doing the work.
      +                //
      +                int B2 = B5; // powers of 2 in bigB
      +                int D2 = D5; // powers of 2 in bigD
      +                int Ulp2;   // powers of 2 in halfUlp.
      +                if (bigIntExp >= 0) {
      +                    B2 += bigIntExp;
      +                } else {
      +                    D2 -= bigIntExp;
      +                }
      +                Ulp2 = B2;
      +                // shift bigB and bigD left by a number s. t.
      +                // halfUlp is still an integer.
      +                int hulpbias;
      +                if (binexp <= -DoubleConsts.EXP_BIAS) {
      +                    // This is going to be a denormalized number
      +                    // (if not actually zero).
      +                    // half an ULP is at 2^-(DoubleConsts.EXP_BIAS+EXP_SHIFT+1)
      +                    hulpbias = binexp + lowOrderZeros + DoubleConsts.EXP_BIAS;
      +                } else {
      +                    hulpbias = 1 + lowOrderZeros;
      +                }
      +                B2 += hulpbias;
      +                D2 += hulpbias;
      +                // if there are common factors of 2, we might just as well
      +                // factor them out, as they add nothing useful.
      +                int common2 = Math.min(B2, Math.min(D2, Ulp2));
      +                B2 -= common2;
      +                D2 -= common2;
      +                Ulp2 -= common2;
      +                // do multiplications by powers of 5 and 2
      +                FDBigInteger bigB = FDBigInteger.valueOfMulPow52(bigBbits, B5, B2);
      +                if (bigD == null || prevD2 != D2) {
      +                    bigD = bigD0.leftShift(D2);
      +                    prevD2 = D2;
      +                }
      +                //
      +                // to recap:
      +                // bigB is the scaled-big-int version of our floating-point
      +                // candidate.
      +                // bigD is the scaled-big-int version of the exact value
      +                // as we understand it.
      +                // halfUlp is 1/2 an ulp of bigB, except for special cases
      +                // of exact powers of 2
      +                //
      +                // the plan is to compare bigB with bigD, and if the difference
      +                // is less than halfUlp, then we're satisfied. Otherwise,
      +                // use the ratio of difference to halfUlp to calculate a fudge
      +                // factor to add to the floating value, then go 'round again.
      +                //
      +                FDBigInteger diff;
      +                int cmpResult;
      +                boolean overvalue;
      +                if ((cmpResult = bigB.cmp(bigD)) > 0) {
      +                    overvalue = true; // our candidate is too big.
      +                    diff = bigB.leftInplaceSub(bigD); // bigB is not user further - reuse
      +                    if ((bigIntNBits == 1) && (bigIntExp > -DoubleConsts.EXP_BIAS + 1)) {
      +                        // candidate is a normalized exact power of 2 and
      +                        // is too big (larger than Double.MIN_NORMAL). We will be subtracting.
      +                        // For our purposes, ulp is the ulp of the
      +                        // next smaller range.
      +                        Ulp2 -= 1;
      +                        if (Ulp2 < 0) {
      +                            // rats. Cannot de-scale ulp this far.
      +                            // must scale diff in other direction.
      +                            Ulp2 = 0;
      +                            diff = diff.leftShift(1);
      +                        }
      +                    }
      +                } else if (cmpResult < 0) {
      +                    overvalue = false; // our candidate is too small.
      +                    diff = bigD.rightInplaceSub(bigB); // bigB is not user further - reuse
      +                } else {
      +                    // the candidate is exactly right!
      +                    // this happens with surprising frequency
      +                    break correctionLoop;
      +                }
      +                cmpResult = diff.cmpPow52(B5, Ulp2);
      +                if ((cmpResult) < 0) {
      +                    // difference is small.
      +                    // this is close enough
      +                    break correctionLoop;
      +                } else if (cmpResult == 0) {
      +                    // difference is exactly half an ULP
      +                    // round to some other value maybe, then finish
      +                    if ((ieeeBits & 1) != 0) { // half ties to even
      +                        ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
      +                    }
      +                    break correctionLoop;
      +                } else {
      +                    // difference is non-trivial.
      +                    // could scale addend by ratio of difference to
      +                    // halfUlp here, if we bothered to compute that difference.
      +                    // Most of the time ( I hope ) it is about 1 anyway.
      +                    ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
      +                    if (ieeeBits == 0 || ieeeBits == DoubleConsts.EXP_BIT_MASK) { // 0.0 or Double.POSITIVE_INFINITY
      +                        break correctionLoop; // oops. Fell off end of range.
      +                    }
      +                    continue; // try again.
      +                }
      +
      +            }
      +            if (isNegative) {
      +                ieeeBits |= DoubleConsts.SIGN_BIT_MASK;
      +            }
      +            return Double.longBitsToDouble(ieeeBits);
      +        }
      +
      +        /**
      +         * Takes a FloatingDecimal, which we presumably just scanned in,
      +         * and finds out what its value is, as a float.
      +         * This is distinct from doubleValue() to avoid the extremely
      +         * unlikely case of a double rounding error, wherein the conversion
      +         * to double has one rounding error, and the conversion of that double
      +         * to a float has another rounding error, IN THE WRONG DIRECTION,
      +         * ( because of the preference to a zero low-order bit ).
      +         */
      +        @Override
      +        public float floatValue() {
      +            int kDigits = Math.min(nDigits, SINGLE_MAX_DECIMAL_DIGITS + 1);
      +            //
      +            // convert the lead kDigits to an integer.
      +            //
      +            int iValue = (int) digits[0] - (int) '0';
      +            for (int i = 1; i < kDigits; i++) {
      +                iValue = iValue * 10 + (int) digits[i] - (int) '0';
      +            }
      +            float fValue = (float) iValue;
      +            int exp = decExponent - kDigits;
      +            //
      +            // iValue now contains an integer with the value of
      +            // the first kDigits digits of the number.
      +            // fValue contains the (float) of the same.
      +            //
      +
      +            if (nDigits <= SINGLE_MAX_DECIMAL_DIGITS) {
      +                //
      +                // possibly an easy case.
      +                // We know that the digits can be represented
      +                // exactly. And if the exponent isn't too outrageous,
      +                // the whole thing can be done with one operation,
      +                // thus one rounding error.
      +                // Note that all our constructors trim all leading and
      +                // trailing zeros, so simple values (including zero)
      +                // will always end up here.
      +                //
      +                if (exp == 0 || fValue == 0.0f) {
      +                    return (isNegative) ? -fValue : fValue; // small floating integer
      +                } else if (exp >= 0) {
      +                    if (exp <= SINGLE_MAX_SMALL_TEN) {
      +                        //
      +                        // Can get the answer with one operation,
      +                        // thus one roundoff.
      +                        //
      +                        fValue *= SINGLE_SMALL_10_POW[exp];
      +                        return (isNegative) ? -fValue : fValue;
      +                    }
      +                    int slop = SINGLE_MAX_DECIMAL_DIGITS - kDigits;
      +                    if (exp <= SINGLE_MAX_SMALL_TEN + slop) {
      +                        //
      +                        // We can multiply fValue by 10^(slop)
      +                        // and it is still "small" and exact.
      +                        // Then we can multiply by 10^(exp-slop)
      +                        // with one rounding.
      +                        //
      +                        fValue *= SINGLE_SMALL_10_POW[slop];
      +                        fValue *= SINGLE_SMALL_10_POW[exp - slop];
      +                        return (isNegative) ? -fValue : fValue;
      +                    }
      +                    //
      +                    // Else we have a hard case with a positive exp.
      +                    //
      +                } else {
      +                    if (exp >= -SINGLE_MAX_SMALL_TEN) {
      +                        //
      +                        // Can get the answer in one division.
      +                        //
      +                        fValue /= SINGLE_SMALL_10_POW[-exp];
      +                        return (isNegative) ? -fValue : fValue;
      +                    }
      +                    //
      +                    // Else we have a hard case with a negative exp.
      +                    //
      +                }
      +            } else if ((decExponent >= nDigits) && (nDigits + decExponent <= MAX_DECIMAL_DIGITS)) {
      +                //
      +                // In double-precision, this is an exact floating integer.
      +                // So we can compute to double, then shorten to float
      +                // with one round, and get the right answer.
      +                //
      +                // First, finish accumulating digits.
      +                // Then convert that integer to a double, multiply
      +                // by the appropriate power of ten, and convert to float.
      +                //
      +                long lValue = (long) iValue;
      +                for (int i = kDigits; i < nDigits; i++) {
      +                    lValue = lValue * 10L + (long) ((int) digits[i] - (int) '0');
      +                }
      +                double dValue = (double) lValue;
      +                exp = decExponent - nDigits;
      +                dValue *= SMALL_10_POW[exp];
      +                fValue = (float) dValue;
      +                return (isNegative) ? -fValue : fValue;
      +
      +            }
      +            //
      +            // Harder cases:
      +            // The sum of digits plus exponent is greater than
      +            // what we think we can do with one error.
      +            //
      +            // Start by approximating the right answer by,
      +            // naively, scaling by powers of 10.
      +            // Scaling uses doubles to avoid overflow/underflow.
      +            //
      +            double dValue = fValue;
      +            if (exp > 0) {
      +                if (decExponent > SINGLE_MAX_DECIMAL_EXPONENT + 1) {
      +                    //
      +                    // Lets face it. This is going to be
      +                    // Infinity. Cut to the chase.
      +                    //
      +                    return (isNegative) ? Float.NEGATIVE_INFINITY : Float.POSITIVE_INFINITY;
      +                }
      +                if ((exp & 15) != 0) {
      +                    dValue *= SMALL_10_POW[exp & 15];
      +                }
      +                if ((exp >>= 4) != 0) {
      +                    int j;
      +                    for (j = 0; exp > 0; j++, exp >>= 1) {
      +                        if ((exp & 1) != 0) {
      +                            dValue *= BIG_10_POW[j];
      +                        }
      +                    }
      +                }
      +            } else if (exp < 0) {
      +                exp = -exp;
      +                if (decExponent < SINGLE_MIN_DECIMAL_EXPONENT - 1) {
      +                    //
      +                    // Lets face it. This is going to be
      +                    // zero. Cut to the chase.
      +                    //
      +                    return (isNegative) ? -0.0f : 0.0f;
      +                }
      +                if ((exp & 15) != 0) {
      +                    dValue /= SMALL_10_POW[exp & 15];
      +                }
      +                if ((exp >>= 4) != 0) {
      +                    int j;
      +                    for (j = 0; exp > 0; j++, exp >>= 1) {
      +                        if ((exp & 1) != 0) {
      +                            dValue *= TINY_10_POW[j];
      +                        }
      +                    }
      +                }
      +            }
      +            fValue = Math.max(Float.MIN_VALUE, Math.min(Float.MAX_VALUE, (float) dValue));
      +
      +            //
      +            // fValue is now approximately the result.
      +            // The hard part is adjusting it, by comparison
      +            // with FDBigInteger arithmetic.
      +            // Formulate the EXACT big-number result as
      +            // bigD0 * 10^exp
      +            //
      +            if (nDigits > SINGLE_MAX_NDIGITS) {
      +                nDigits = SINGLE_MAX_NDIGITS + 1;
      +                digits[SINGLE_MAX_NDIGITS] = '1';
      +            }
      +            FDBigInteger bigD0 = new FDBigInteger(iValue, digits, kDigits, nDigits);
      +            exp = decExponent - nDigits;
      +
      +            int ieeeBits = Float.floatToRawIntBits(fValue); // IEEE-754 bits of float candidate
      +            final int B5 = Math.max(0, -exp); // powers of 5 in bigB, value is not modified inside correctionLoop
      +            final int D5 = Math.max(0, exp); // powers of 5 in bigD, value is not modified inside correctionLoop
      +            bigD0 = bigD0.multByPow52(D5, 0);
      +            bigD0.makeImmutable();   // prevent bigD0 modification inside correctionLoop
      +            FDBigInteger bigD = null;
      +            int prevD2 = 0;
      +
      +            correctionLoop:
      +            while (true) {
      +                // here ieeeBits can't be NaN, Infinity or zero
      +                int binexp = ieeeBits >>> SINGLE_EXP_SHIFT;
      +                int bigBbits = ieeeBits & FloatConsts.SIGNIF_BIT_MASK;
      +                if (binexp > 0) {
      +                    bigBbits |= SINGLE_FRACT_HOB;
      +                } else { // Normalize denormalized numbers.
      +                    assert bigBbits != 0 : bigBbits; // floatToBigInt(0.0)
      +                    int leadingZeros = Integer.numberOfLeadingZeros(bigBbits);
      +                    int shift = leadingZeros - (31 - SINGLE_EXP_SHIFT);
      +                    bigBbits <<= shift;
      +                    binexp = 1 - shift;
      +                }
      +                binexp -= FloatConsts.EXP_BIAS;
      +                int lowOrderZeros = Integer.numberOfTrailingZeros(bigBbits);
      +                bigBbits >>>= lowOrderZeros;
      +                final int bigIntExp = binexp - SINGLE_EXP_SHIFT + lowOrderZeros;
      +                final int bigIntNBits = SINGLE_EXP_SHIFT + 1 - lowOrderZeros;
      +
      +                //
      +                // Scale bigD, bigB appropriately for
      +                // big-integer operations.
      +                // Naively, we multiply by powers of ten
      +                // and powers of two. What we actually do
      +                // is keep track of the powers of 5 and
      +                // powers of 2 we would use, then factor out
      +                // common divisors before doing the work.
      +                //
      +                int B2 = B5; // powers of 2 in bigB
      +                int D2 = D5; // powers of 2 in bigD
      +                int Ulp2;   // powers of 2 in halfUlp.
      +                if (bigIntExp >= 0) {
      +                    B2 += bigIntExp;
      +                } else {
      +                    D2 -= bigIntExp;
      +                }
      +                Ulp2 = B2;
      +                // shift bigB and bigD left by a number s. t.
      +                // halfUlp is still an integer.
      +                int hulpbias;
      +                if (binexp <= -FloatConsts.EXP_BIAS) {
      +                    // This is going to be a denormalized number
      +                    // (if not actually zero).
      +                    // half an ULP is at 2^-(FloatConsts.EXP_BIAS+SINGLE_EXP_SHIFT+1)
      +                    hulpbias = binexp + lowOrderZeros + FloatConsts.EXP_BIAS;
      +                } else {
      +                    hulpbias = 1 + lowOrderZeros;
      +                }
      +                B2 += hulpbias;
      +                D2 += hulpbias;
      +                // if there are common factors of 2, we might just as well
      +                // factor them out, as they add nothing useful.
      +                int common2 = Math.min(B2, Math.min(D2, Ulp2));
      +                B2 -= common2;
      +                D2 -= common2;
      +                Ulp2 -= common2;
      +                // do multiplications by powers of 5 and 2
      +                FDBigInteger bigB = FDBigInteger.valueOfMulPow52(bigBbits, B5, B2);
      +                if (bigD == null || prevD2 != D2) {
      +                    bigD = bigD0.leftShift(D2);
      +                    prevD2 = D2;
      +                }
      +                //
      +                // to recap:
      +                // bigB is the scaled-big-int version of our floating-point
      +                // candidate.
      +                // bigD is the scaled-big-int version of the exact value
      +                // as we understand it.
      +                // halfUlp is 1/2 an ulp of bigB, except for special cases
      +                // of exact powers of 2
      +                //
      +                // the plan is to compare bigB with bigD, and if the difference
      +                // is less than halfUlp, then we're satisfied. Otherwise,
      +                // use the ratio of difference to halfUlp to calculate a fudge
      +                // factor to add to the floating value, then go 'round again.
      +                //
      +                FDBigInteger diff;
      +                int cmpResult;
      +                boolean overvalue;
      +                if ((cmpResult = bigB.cmp(bigD)) > 0) {
      +                    overvalue = true; // our candidate is too big.
      +                    diff = bigB.leftInplaceSub(bigD); // bigB is not user further - reuse
      +                    if ((bigIntNBits == 1) && (bigIntExp > -FloatConsts.EXP_BIAS + 1)) {
      +                        // candidate is a normalized exact power of 2 and
      +                        // is too big (larger than Float.MIN_NORMAL). We will be subtracting.
      +                        // For our purposes, ulp is the ulp of the
      +                        // next smaller range.
      +                        Ulp2 -= 1;
      +                        if (Ulp2 < 0) {
      +                            // rats. Cannot de-scale ulp this far.
      +                            // must scale diff in other direction.
      +                            Ulp2 = 0;
      +                            diff = diff.leftShift(1);
      +                        }
      +                    }
      +                } else if (cmpResult < 0) {
      +                    overvalue = false; // our candidate is too small.
      +                    diff = bigD.rightInplaceSub(bigB); // bigB is not user further - reuse
      +                } else {
      +                    // the candidate is exactly right!
      +                    // this happens with surprising frequency
      +                    break correctionLoop;
      +                }
      +                cmpResult = diff.cmpPow52(B5, Ulp2);
      +                if ((cmpResult) < 0) {
      +                    // difference is small.
      +                    // this is close enough
      +                    break correctionLoop;
      +                } else if (cmpResult == 0) {
      +                    // difference is exactly half an ULP
      +                    // round to some other value maybe, then finish
      +                    if ((ieeeBits & 1) != 0) { // half ties to even
      +                        ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
      +                    }
      +                    break correctionLoop;
      +                } else {
      +                    // difference is non-trivial.
      +                    // could scale addend by ratio of difference to
      +                    // halfUlp here, if we bothered to compute that difference.
      +                    // Most of the time ( I hope ) it is about 1 anyway.
      +                    ieeeBits += overvalue ? -1 : 1; // nextDown or nextUp
      +                    if (ieeeBits == 0 || ieeeBits == FloatConsts.EXP_BIT_MASK) { // 0.0 or Float.POSITIVE_INFINITY
      +                        break correctionLoop; // oops. Fell off end of range.
      +                    }
      +                    continue; // try again.
      +                }
      +
      +            }
      +            if (isNegative) {
      +                ieeeBits |= FloatConsts.SIGN_BIT_MASK;
      +            }
      +            return Float.intBitsToFloat(ieeeBits);
      +        }
      +
      +
      +        /**
      +         * All the positive powers of 10 that can be
      +         * represented exactly in double/float.
      +         */
      +        private static final double[] SMALL_10_POW = {
      +            1.0e0,
      +            1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5,
      +            1.0e6, 1.0e7, 1.0e8, 1.0e9, 1.0e10,
      +            1.0e11, 1.0e12, 1.0e13, 1.0e14, 1.0e15,
      +            1.0e16, 1.0e17, 1.0e18, 1.0e19, 1.0e20,
      +            1.0e21, 1.0e22
      +        };
      +
      +        private static final float[] SINGLE_SMALL_10_POW = {
      +            1.0e0f,
      +            1.0e1f, 1.0e2f, 1.0e3f, 1.0e4f, 1.0e5f,
      +            1.0e6f, 1.0e7f, 1.0e8f, 1.0e9f, 1.0e10f
      +        };
      +
      +        private static final double[] BIG_10_POW = {
      +            1e16, 1e32, 1e64, 1e128, 1e256 };
      +        private static final double[] TINY_10_POW = {
      +            1e-16, 1e-32, 1e-64, 1e-128, 1e-256 };
      +
      +        private static final int MAX_SMALL_TEN = SMALL_10_POW.length-1;
      +        private static final int SINGLE_MAX_SMALL_TEN = SINGLE_SMALL_10_POW.length-1;
      +
      +    }
      +
      +    /**
      +     * Returns a BinaryToASCIIConverter for a double.
      +     * The returned object is a ThreadLocal variable of this class.
      +     *
      +     * @param d The double precision value to convert.
      +     * @return The converter.
      +     */
      +    public static BinaryToASCIIConverter getBinaryToASCIIConverter(double d) {
      +        return getBinaryToASCIIConverter(d, true);
      +    }
      +
      +    /**
      +     * Returns a BinaryToASCIIConverter for a double.
      +     * The returned object is a ThreadLocal variable of this class.
      +     *
      +     * @param d The double precision value to convert.
      +     * @param isCompatibleFormat
      +     * @return The converter.
      +     */
      +    static BinaryToASCIIConverter getBinaryToASCIIConverter(double d, boolean isCompatibleFormat) {
      +        long dBits = Double.doubleToRawLongBits(d);
      +        boolean isNegative = (dBits&DoubleConsts.SIGN_BIT_MASK) != 0; // discover sign
      +        long fractBits = dBits & DoubleConsts.SIGNIF_BIT_MASK;
      +        int  binExp = (int)( (dBits&DoubleConsts.EXP_BIT_MASK) >> EXP_SHIFT );
      +        // Discover obvious special cases of NaN and Infinity.
      +        if ( binExp == (int)(DoubleConsts.EXP_BIT_MASK>>EXP_SHIFT) ) {
      +            if ( fractBits == 0L ){
      +                return isNegative ? B2AC_NEGATIVE_INFINITY : B2AC_POSITIVE_INFINITY;
      +            } else {
      +                return B2AC_NOT_A_NUMBER;
      +            }
      +        }
      +        // Finish unpacking
      +        // Normalize denormalized numbers.
      +        // Insert assumed high-order bit for normalized numbers.
      +        // Subtract exponent bias.
      +        int  nSignificantBits;
      +        if ( binExp == 0 ){
      +            if ( fractBits == 0L ){
      +                // not a denorm, just a 0!
      +                return isNegative ? B2AC_NEGATIVE_ZERO : B2AC_POSITIVE_ZERO;
      +            }
      +            int leadingZeros = Long.numberOfLeadingZeros(fractBits);
      +            int shift = leadingZeros-(63-EXP_SHIFT);
      +            fractBits <<= shift;
      +            binExp = 1 - shift;
      +            nSignificantBits =  64-leadingZeros; // recall binExp is  - shift count.
      +        } else {
      +            fractBits |= FRACT_HOB;
      +            nSignificantBits = EXP_SHIFT+1;
      +        }
      +        binExp -= DoubleConsts.EXP_BIAS;
      +        BinaryToASCIIBuffer buf = getBinaryToASCIIBuffer();
      +        buf.setSign(isNegative);
      +        // call the routine that actually does all the hard work.
      +        buf.dtoa(binExp, fractBits, nSignificantBits, isCompatibleFormat);
      +        return buf;
      +    }
      +
      +    private static BinaryToASCIIConverter getBinaryToASCIIConverter(float f) {
      +        int fBits = Float.floatToRawIntBits( f );
      +        boolean isNegative = (fBits&FloatConsts.SIGN_BIT_MASK) != 0;
      +        int fractBits = fBits&FloatConsts.SIGNIF_BIT_MASK;
      +        int binExp = (fBits&FloatConsts.EXP_BIT_MASK) >> SINGLE_EXP_SHIFT;
      +        // Discover obvious special cases of NaN and Infinity.
      +        if ( binExp == (FloatConsts.EXP_BIT_MASK>>SINGLE_EXP_SHIFT) ) {
      +            if ( fractBits == 0L ){
      +                return isNegative ? B2AC_NEGATIVE_INFINITY : B2AC_POSITIVE_INFINITY;
      +            } else {
      +                return B2AC_NOT_A_NUMBER;
      +            }
      +        }
      +        // Finish unpacking
      +        // Normalize denormalized numbers.
      +        // Insert assumed high-order bit for normalized numbers.
      +        // Subtract exponent bias.
      +        int  nSignificantBits;
      +        if ( binExp == 0 ){
      +            if ( fractBits == 0 ){
      +                // not a denorm, just a 0!
      +                return isNegative ? B2AC_NEGATIVE_ZERO : B2AC_POSITIVE_ZERO;
      +            }
      +            int leadingZeros = Integer.numberOfLeadingZeros(fractBits);
      +            int shift = leadingZeros-(31-SINGLE_EXP_SHIFT);
      +            fractBits <<= shift;
      +            binExp = 1 - shift;
      +            nSignificantBits =  32 - leadingZeros; // recall binExp is  - shift count.
      +        } else {
      +            fractBits |= SINGLE_FRACT_HOB;
      +            nSignificantBits = SINGLE_EXP_SHIFT+1;
      +        }
      +        binExp -= FloatConsts.EXP_BIAS;
      +        BinaryToASCIIBuffer buf = getBinaryToASCIIBuffer();
      +        buf.setSign(isNegative);
      +        // call the routine that actually does all the hard work.
      +        buf.dtoa(binExp, ((long)fractBits)<<(EXP_SHIFT-SINGLE_EXP_SHIFT), nSignificantBits, true);
      +        return buf;
      +    }
      +
      +    @SuppressWarnings("fallthrough")
      +    static ASCIIToBinaryConverter readJavaFormatString( String in ) throws NumberFormatException {
      +        boolean isNegative = false;
      +        boolean signSeen   = false;
      +        int     decExp;
      +        char    c;
      +
      +    parseNumber:
      +        try{
      +            in = in.trim(); // don't fool around with white space.
      +                            // throws NullPointerException if null
      +            int len = in.length();
      +            if ( len == 0 ) {
      +                throw new NumberFormatException("empty String");
      +            }
      +            int i = 0;
      +            switch (in.charAt(i)){
      +            case '-':
      +                isNegative = true;
      +                //FALLTHROUGH
      +            case '+':
      +                i++;
      +                signSeen = true;
      +            }
      +            c = in.charAt(i);
      +            if(c == 'N') { // Check for NaN
      +                if((len-i)==NAN_LENGTH && in.indexOf(NAN_REP,i)==i) {
      +                    return A2BC_NOT_A_NUMBER;
      +                }
      +                // something went wrong, throw exception
      +                break parseNumber;
      +            } else if(c == 'I') { // Check for Infinity strings
      +                if((len-i)==INFINITY_LENGTH && in.indexOf(INFINITY_REP,i)==i) {
      +                    return isNegative? A2BC_NEGATIVE_INFINITY : A2BC_POSITIVE_INFINITY;
      +                }
      +                // something went wrong, throw exception
      +                break parseNumber;
      +            } else if (c == '0')  { // check for hexadecimal floating-point number
      +                if (len > i+1 ) {
      +                    char ch = in.charAt(i+1);
      +                    if (ch == 'x' || ch == 'X' ) { // possible hex string
      +                        return parseHexString(in);
      +                    }
      +                }
      +            }  // look for and process decimal floating-point string
      +
      +            char[] digits = new char[ len ];
      +            int    nDigits= 0;
      +            boolean decSeen = false;
      +            int decPt = 0;
      +            int nLeadZero = 0;
      +            int nTrailZero= 0;
      +
      +        skipLeadingZerosLoop:
      +            while (i < len) {
      +                c = in.charAt(i);
      +                if (c == '0') {
      +                    nLeadZero++;
      +                } else if (c == '.') {
      +                    if (decSeen) {
      +                        // already saw one ., this is the 2nd.
      +                        throw new NumberFormatException("multiple points");
      +                    }
      +                    decPt = i;
      +                    if (signSeen) {
      +                        decPt -= 1;
      +                    }
      +                    decSeen = true;
      +                } else {
      +                    break skipLeadingZerosLoop;
      +                }
      +                i++;
      +            }
      +        digitLoop:
      +            while (i < len) {
      +                c = in.charAt(i);
      +                if (c >= '1' && c <= '9') {
      +                    digits[nDigits++] = c;
      +                    nTrailZero = 0;
      +                } else if (c == '0') {
      +                    digits[nDigits++] = c;
      +                    nTrailZero++;
      +                } else if (c == '.') {
      +                    if (decSeen) {
      +                        // already saw one ., this is the 2nd.
      +                        throw new NumberFormatException("multiple points");
      +                    }
      +                    decPt = i;
      +                    if (signSeen) {
      +                        decPt -= 1;
      +                    }
      +                    decSeen = true;
      +                } else {
      +                    break digitLoop;
      +                }
      +                i++;
      +            }
      +            nDigits -=nTrailZero;
      +            //
      +            // At this point, we've scanned all the digits and decimal
      +            // point we're going to see. Trim off leading and trailing
      +            // zeros, which will just confuse us later, and adjust
      +            // our initial decimal exponent accordingly.
      +            // To review:
      +            // we have seen i total characters.
      +            // nLeadZero of them were zeros before any other digits.
      +            // nTrailZero of them were zeros after any other digits.
      +            // if ( decSeen ), then a . was seen after decPt characters
      +            // ( including leading zeros which have been discarded )
      +            // nDigits characters were neither lead nor trailing
      +            // zeros, nor point
      +            //
      +            //
      +            // special hack: if we saw no non-zero digits, then the
      +            // answer is zero!
      +            // Unfortunately, we feel honor-bound to keep parsing!
      +            //
      +            boolean isZero = (nDigits == 0);
      +            if ( isZero &&  nLeadZero == 0 ){
      +                // we saw NO DIGITS AT ALL,
      +                // not even a crummy 0!
      +                // this is not allowed.
      +                break parseNumber; // go throw exception
      +            }
      +            //
      +            // Our initial exponent is decPt, adjusted by the number of
      +            // discarded zeros. Or, if there was no decPt,
      +            // then its just nDigits adjusted by discarded trailing zeros.
      +            //
      +            if ( decSeen ){
      +                decExp = decPt - nLeadZero;
      +            } else {
      +                decExp = nDigits + nTrailZero;
      +            }
      +
      +            //
      +            // Look for 'e' or 'E' and an optionally signed integer.
      +            //
      +            if ( (i < len) &&  (((c = in.charAt(i) )=='e') || (c == 'E') ) ){
      +                int expSign = 1;
      +                int expVal  = 0;
      +                int reallyBig = Integer.MAX_VALUE / 10;
      +                boolean expOverflow = false;
      +                switch( in.charAt(++i) ){
      +                case '-':
      +                    expSign = -1;
      +                    //FALLTHROUGH
      +                case '+':
      +                    i++;
      +                }
      +                int expAt = i;
      +            expLoop:
      +                while ( i < len  ){
      +                    if ( expVal >= reallyBig ){
      +                        // the next character will cause integer
      +                        // overflow.
      +                        expOverflow = true;
      +                    }
      +                    c = in.charAt(i++);
      +                    if(c>='0' && c<='9') {
      +                        expVal = expVal*10 + ( (int)c - (int)'0' );
      +                    } else {
      +                        i--;           // back up.
      +                        break expLoop; // stop parsing exponent.
      +                    }
      +                }
      +                int expLimit = BIG_DECIMAL_EXPONENT+nDigits+nTrailZero;
      +                if ( expOverflow || ( expVal > expLimit ) ){
      +                    //
      +                    // The intent here is to end up with
      +                    // infinity or zero, as appropriate.
      +                    // The reason for yielding such a small decExponent,
      +                    // rather than something intuitive such as
      +                    // expSign*Integer.MAX_VALUE, is that this value
      +                    // is subject to further manipulation in
      +                    // doubleValue() and floatValue(), and I don't want
      +                    // it to be able to cause overflow there!
      +                    // (The only way we can get into trouble here is for
      +                    // really outrageous nDigits+nTrailZero, such as 2 billion. )
      +                    //
      +                    decExp = expSign*expLimit;
      +                } else {
      +                    // this should not overflow, since we tested
      +                    // for expVal > (MAX+N), where N >= abs(decExp)
      +                    decExp = decExp + expSign*expVal;
      +                }
      +
      +                // if we saw something not a digit ( or end of string )
      +                // after the [Ee][+-], without seeing any digits at all
      +                // this is certainly an error. If we saw some digits,
      +                // but then some trailing garbage, that might be ok.
      +                // so we just fall through in that case.
      +                // HUMBUG
      +                if ( i == expAt ) {
      +                    break parseNumber; // certainly bad
      +                }
      +            }
      +            //
      +            // We parsed everything we could.
      +            // If there are leftovers, then this is not good input!
      +            //
      +            if ( i < len &&
      +                ((i != len - 1) ||
      +                (in.charAt(i) != 'f' &&
      +                 in.charAt(i) != 'F' &&
      +                 in.charAt(i) != 'd' &&
      +                 in.charAt(i) != 'D'))) {
      +                break parseNumber; // go throw exception
      +            }
      +            if(isZero) {
      +                return isNegative ? A2BC_NEGATIVE_ZERO : A2BC_POSITIVE_ZERO;
      +            }
      +            return new ASCIIToBinaryBuffer(isNegative, decExp, digits, nDigits);
      +        } catch ( StringIndexOutOfBoundsException e ){ }
      +        throw new NumberFormatException("For input string: \"" + in + "\"");
      +    }
      +
      +    private static class HexFloatPattern {
      +        /**
      +         * Grammar is compatible with hexadecimal floating-point constants
      +         * described in section 6.4.4.2 of the C99 specification.
      +         */
      +        private static final Pattern VALUE = Pattern.compile(
      +                   //1           234                   56                7                   8      9
      +                    "([-+])?0[xX](((\\p{XDigit}+)\\.?)|((\\p{XDigit}*)\\.(\\p{XDigit}+)))[pP]([-+])?(\\p{Digit}+)[fFdD]?"
      +                    );
      +    }
      +
      +    /**
      +     * Converts string s to a suitable floating decimal; uses the
      +     * double constructor and sets the roundDir variable appropriately
      +     * in case the value is later converted to a float.
      +     *
      +     * @param s The String to parse.
      +     */
      +   static ASCIIToBinaryConverter parseHexString(String s) {
      +            // Verify string is a member of the hexadecimal floating-point
      +            // string language.
      +            Matcher m = HexFloatPattern.VALUE.matcher(s);
      +            boolean validInput = m.matches();
      +            if (!validInput) {
      +                // Input does not match pattern
      +                throw new NumberFormatException("For input string: \"" + s + "\"");
      +            } else { // validInput
      +                //
      +                // We must isolate the sign, significand, and exponent
      +                // fields.  The sign value is straightforward.  Since
      +                // floating-point numbers are stored with a normalized
      +                // representation, the significand and exponent are
      +                // interrelated.
      +                //
      +                // After extracting the sign, we normalized the
      +                // significand as a hexadecimal value, calculating an
      +                // exponent adjust for any shifts made during
      +                // normalization.  If the significand is zero, the
      +                // exponent doesn't need to be examined since the output
      +                // will be zero.
      +                //
      +                // Next the exponent in the input string is extracted.
      +                // Afterwards, the significand is normalized as a *binary*
      +                // value and the input value's normalized exponent can be
      +                // computed.  The significand bits are copied into a
      +                // double significand; if the string has more logical bits
      +                // than can fit in a double, the extra bits affect the
      +                // round and sticky bits which are used to round the final
      +                // value.
      +                //
      +                //  Extract significand sign
      +                String group1 = m.group(1);
      +                boolean isNegative = ((group1 != null) && group1.equals("-"));
      +
      +                //  Extract Significand magnitude
      +                //
      +                // Based on the form of the significand, calculate how the
      +                // binary exponent needs to be adjusted to create a
      +                // normalized//hexadecimal* floating-point number; that
      +                // is, a number where there is one nonzero hex digit to
      +                // the left of the (hexa)decimal point.  Since we are
      +                // adjusting a binary, not hexadecimal exponent, the
      +                // exponent is adjusted by a multiple of 4.
      +                //
      +                // There are a number of significand scenarios to consider;
      +                // letters are used in indicate nonzero digits:
      +                //
      +                // 1. 000xxxx       =>      x.xxx   normalized
      +                //    increase exponent by (number of x's - 1)*4
      +                //
      +                // 2. 000xxx.yyyy =>        x.xxyyyy        normalized
      +                //    increase exponent by (number of x's - 1)*4
      +                //
      +                // 3. .000yyy  =>   y.yy    normalized
      +                //    decrease exponent by (number of zeros + 1)*4
      +                //
      +                // 4. 000.00000yyy => y.yy normalized
      +                //    decrease exponent by (number of zeros to right of point + 1)*4
      +                //
      +                // If the significand is exactly zero, return a properly
      +                // signed zero.
      +                //
      +
      +                String significandString = null;
      +                int signifLength = 0;
      +                int exponentAdjust = 0;
      +                {
      +                    int leftDigits = 0; // number of meaningful digits to
      +                    // left of "decimal" point
      +                    // (leading zeros stripped)
      +                    int rightDigits = 0; // number of digits to right of
      +                    // "decimal" point; leading zeros
      +                    // must always be accounted for
      +                    //
      +                    // The significand is made up of either
      +                    //
      +                    // 1. group 4 entirely (integer portion only)
      +                    //
      +                    // OR
      +                    //
      +                    // 2. the fractional portion from group 7 plus any
      +                    // (optional) integer portions from group 6.
      +                    //
      +                    String group4;
      +                    if ((group4 = m.group(4)) != null) {  // Integer-only significand
      +                        // Leading zeros never matter on the integer portion
      +                        significandString = stripLeadingZeros(group4);
      +                        leftDigits = significandString.length();
      +                    } else {
      +                        // Group 6 is the optional integer; leading zeros
      +                        // never matter on the integer portion
      +                        String group6 = stripLeadingZeros(m.group(6));
      +                        leftDigits = group6.length();
      +
      +                        // fraction
      +                        String group7 = m.group(7);
      +                        rightDigits = group7.length();
      +
      +                        // Turn "integer.fraction" into "integer"+"fraction"
      +                        significandString =
      +                                ((group6 == null) ? "" : group6) + // is the null
      +                                        // check necessary?
      +                                        group7;
      +                    }
      +
      +                    significandString = stripLeadingZeros(significandString);
      +                    signifLength = significandString.length();
      +
      +                    //
      +                    // Adjust exponent as described above
      +                    //
      +                    if (leftDigits >= 1) {  // Cases 1 and 2
      +                        exponentAdjust = 4 * (leftDigits - 1);
      +                    } else {                // Cases 3 and 4
      +                        exponentAdjust = -4 * (rightDigits - signifLength + 1);
      +                    }
      +
      +                    // If the significand is zero, the exponent doesn't
      +                    // matter; return a properly signed zero.
      +
      +                    if (signifLength == 0) { // Only zeros in input
      +                        return isNegative ? A2BC_NEGATIVE_ZERO : A2BC_POSITIVE_ZERO;
      +                    }
      +                }
      +
      +                //  Extract Exponent
      +                //
      +                // Use an int to read in the exponent value; this should
      +                // provide more than sufficient range for non-contrived
      +                // inputs.  If reading the exponent in as an int does
      +                // overflow, examine the sign of the exponent and
      +                // significand to determine what to do.
      +                //
      +                String group8 = m.group(8);
      +                boolean positiveExponent = (group8 == null) || group8.equals("+");
      +                long unsignedRawExponent;
      +                try {
      +                    unsignedRawExponent = Integer.parseInt(m.group(9));
      +                }
      +                catch (NumberFormatException e) {
      +                    // At this point, we know the exponent is
      +                    // syntactically well-formed as a sequence of
      +                    // digits.  Therefore, if an NumberFormatException
      +                    // is thrown, it must be due to overflowing int's
      +                    // range.  Also, at this point, we have already
      +                    // checked for a zero significand.  Thus the signs
      +                    // of the exponent and significand determine the
      +                    // final result:
      +                    //
      +                    //                      significand
      +                    //                      +               -
      +                    // exponent     +       +infinity       -infinity
      +                    //              -       +0.0            -0.0
      +                    return isNegative ?
      +                              (positiveExponent ? A2BC_NEGATIVE_INFINITY : A2BC_NEGATIVE_ZERO)
      +                            : (positiveExponent ? A2BC_POSITIVE_INFINITY : A2BC_POSITIVE_ZERO);
      +
      +                }
      +
      +                long rawExponent =
      +                        (positiveExponent ? 1L : -1L) * // exponent sign
      +                                unsignedRawExponent;            // exponent magnitude
      +
      +                // Calculate partially adjusted exponent
      +                long exponent = rawExponent + exponentAdjust;
      +
      +                // Starting copying non-zero bits into proper position in
      +                // a long; copy explicit bit too; this will be masked
      +                // later for normal values.
      +
      +                boolean round = false;
      +                boolean sticky = false;
      +                int nextShift = 0;
      +                long significand = 0L;
      +                // First iteration is different, since we only copy
      +                // from the leading significand bit; one more exponent
      +                // adjust will be needed...
      +
      +                // IMPORTANT: make leadingDigit a long to avoid
      +                // surprising shift semantics!
      +                long leadingDigit = getHexDigit(significandString, 0);
      +
      +                //
      +                // Left shift the leading digit (53 - (bit position of
      +                // leading 1 in digit)); this sets the top bit of the
      +                // significand to 1.  The nextShift value is adjusted
      +                // to take into account the number of bit positions of
      +                // the leadingDigit actually used.  Finally, the
      +                // exponent is adjusted to normalize the significand
      +                // as a binary value, not just a hex value.
      +                //
      +                if (leadingDigit == 1) {
      +                    significand |= leadingDigit << 52;
      +                    nextShift = 52 - 4;
      +                    // exponent += 0
      +                } else if (leadingDigit <= 3) { // [2, 3]
      +                    significand |= leadingDigit << 51;
      +                    nextShift = 52 - 5;
      +                    exponent += 1;
      +                } else if (leadingDigit <= 7) { // [4, 7]
      +                    significand |= leadingDigit << 50;
      +                    nextShift = 52 - 6;
      +                    exponent += 2;
      +                } else if (leadingDigit <= 15) { // [8, f]
      +                    significand |= leadingDigit << 49;
      +                    nextShift = 52 - 7;
      +                    exponent += 3;
      +                } else {
      +                    throw new AssertionError("Result from digit conversion too large!");
      +                }
      +                // The preceding if-else could be replaced by a single
      +                // code block based on the high-order bit set in
      +                // leadingDigit.  Given leadingOnePosition,
      +
      +                // significand |= leadingDigit << (SIGNIFICAND_WIDTH - leadingOnePosition);
      +                // nextShift = 52 - (3 + leadingOnePosition);
      +                // exponent += (leadingOnePosition-1);
      +
      +                //
      +                // Now the exponent variable is equal to the normalized
      +                // binary exponent.  Code below will make representation
      +                // adjustments if the exponent is incremented after
      +                // rounding (includes overflows to infinity) or if the
      +                // result is subnormal.
      +                //
      +
      +                // Copy digit into significand until the significand can't
      +                // hold another full hex digit or there are no more input
      +                // hex digits.
      +                int i = 0;
      +                for (i = 1;
      +                     i < signifLength && nextShift >= 0;
      +                     i++) {
      +                    long currentDigit = getHexDigit(significandString, i);
      +                    significand |= (currentDigit << nextShift);
      +                    nextShift -= 4;
      +                }
      +
      +                // After the above loop, the bulk of the string is copied.
      +                // Now, we must copy any partial hex digits into the
      +                // significand AND compute the round bit and start computing
      +                // sticky bit.
      +
      +                if (i < signifLength) { // at least one hex input digit exists
      +                    long currentDigit = getHexDigit(significandString, i);
      +
      +                    // from nextShift, figure out how many bits need
      +                    // to be copied, if any
      +                    switch (nextShift) { // must be negative
      +                        case -1:
      +                            // three bits need to be copied in; can
      +                            // set round bit
      +                            significand |= ((currentDigit & 0xEL) >> 1);
      +                            round = (currentDigit & 0x1L) != 0L;
      +                            break;
      +
      +                        case -2:
      +                            // two bits need to be copied in; can
      +                            // set round and start sticky
      +                            significand |= ((currentDigit & 0xCL) >> 2);
      +                            round = (currentDigit & 0x2L) != 0L;
      +                            sticky = (currentDigit & 0x1L) != 0;
      +                            break;
      +
      +                        case -3:
      +                            // one bit needs to be copied in
      +                            significand |= ((currentDigit & 0x8L) >> 3);
      +                            // Now set round and start sticky, if possible
      +                            round = (currentDigit & 0x4L) != 0L;
      +                            sticky = (currentDigit & 0x3L) != 0;
      +                            break;
      +
      +                        case -4:
      +                            // all bits copied into significand; set
      +                            // round and start sticky
      +                            round = ((currentDigit & 0x8L) != 0);  // is top bit set?
      +                            // nonzeros in three low order bits?
      +                            sticky = (currentDigit & 0x7L) != 0;
      +                            break;
      +
      +                        default:
      +                            throw new AssertionError("Unexpected shift distance remainder.");
      +                            // break;
      +                    }
      +
      +                    // Round is set; sticky might be set.
      +
      +                    // For the sticky bit, it suffices to check the
      +                    // current digit and test for any nonzero digits in
      +                    // the remaining unprocessed input.
      +                    i++;
      +                    while (i < signifLength && !sticky) {
      +                        currentDigit = getHexDigit(significandString, i);
      +                        sticky = sticky || (currentDigit != 0);
      +                        i++;
      +                    }
      +
      +                }
      +                // else all of string was seen, round and sticky are
      +                // correct as false.
      +
      +                // Float calculations
      +                int floatBits = isNegative ? FloatConsts.SIGN_BIT_MASK : 0;
      +                if (exponent >= FloatConsts.MIN_EXPONENT) {
      +                    if (exponent > FloatConsts.MAX_EXPONENT) {
      +                        // Float.POSITIVE_INFINITY
      +                        floatBits |= FloatConsts.EXP_BIT_MASK;
      +                    } else {
      +                        int threshShift = DoubleConsts.SIGNIFICAND_WIDTH - FloatConsts.SIGNIFICAND_WIDTH - 1;
      +                        boolean floatSticky = (significand & ((1L << threshShift) - 1)) != 0 || round || sticky;
      +                        int iValue = (int) (significand >>> threshShift);
      +                        if ((iValue & 3) != 1 || floatSticky) {
      +                            iValue++;
      +                        }
      +                        floatBits |= (((((int) exponent) + (FloatConsts.EXP_BIAS - 1))) << SINGLE_EXP_SHIFT) + (iValue >> 1);
      +                    }
      +                } else {
      +                    if (exponent < FloatConsts.MIN_SUB_EXPONENT - 1) {
      +                        // 0
      +                    } else {
      +                        // exponent == -127 ==> threshShift = 53 - 2 + (-149) - (-127) = 53 - 24
      +                        int threshShift = (int) ((DoubleConsts.SIGNIFICAND_WIDTH - 2 + FloatConsts.MIN_SUB_EXPONENT) - exponent);
      +                        assert threshShift >= DoubleConsts.SIGNIFICAND_WIDTH - FloatConsts.SIGNIFICAND_WIDTH;
      +                        assert threshShift < DoubleConsts.SIGNIFICAND_WIDTH;
      +                        boolean floatSticky = (significand & ((1L << threshShift) - 1)) != 0 || round || sticky;
      +                        int iValue = (int) (significand >>> threshShift);
      +                        if ((iValue & 3) != 1 || floatSticky) {
      +                            iValue++;
      +                        }
      +                        floatBits |= iValue >> 1;
      +                    }
      +                }
      +                float fValue = Float.intBitsToFloat(floatBits);
      +
      +                // Check for overflow and update exponent accordingly.
      +                if (exponent > DoubleConsts.MAX_EXPONENT) {         // Infinite result
      +                    // overflow to properly signed infinity
      +                    return isNegative ? A2BC_NEGATIVE_INFINITY : A2BC_POSITIVE_INFINITY;
      +                } else {  // Finite return value
      +                    if (exponent <= DoubleConsts.MAX_EXPONENT && // (Usually) normal result
      +                            exponent >= DoubleConsts.MIN_EXPONENT) {
      +
      +                        // The result returned in this block cannot be a
      +                        // zero or subnormal; however after the
      +                        // significand is adjusted from rounding, we could
      +                        // still overflow in infinity.
      +
      +                        // AND exponent bits into significand; if the
      +                        // significand is incremented and overflows from
      +                        // rounding, this combination will update the
      +                        // exponent correctly, even in the case of
      +                        // Double.MAX_VALUE overflowing to infinity.
      +
      +                        significand = ((( exponent +
      +                                (long) DoubleConsts.EXP_BIAS) <<
      +                                (DoubleConsts.SIGNIFICAND_WIDTH - 1))
      +                                & DoubleConsts.EXP_BIT_MASK) |
      +                                (DoubleConsts.SIGNIF_BIT_MASK & significand);
      +
      +                    } else {  // Subnormal or zero
      +                        // (exponent < DoubleConsts.MIN_EXPONENT)
      +
      +                        if (exponent < (DoubleConsts.MIN_SUB_EXPONENT - 1)) {
      +                            // No way to round back to nonzero value
      +                            // regardless of significand if the exponent is
      +                            // less than -1075.
      +                            return isNegative ? A2BC_NEGATIVE_ZERO : A2BC_POSITIVE_ZERO;
      +                        } else { //  -1075 <= exponent <= MIN_EXPONENT -1 = -1023
      +                            //
      +                            // Find bit position to round to; recompute
      +                            // round and sticky bits, and shift
      +                            // significand right appropriately.
      +                            //
      +
      +                            sticky = sticky || round;
      +                            round = false;
      +
      +                            // Number of bits of significand to preserve is
      +                            // exponent - abs_min_exp +1
      +                            // check:
      +                            // -1075 +1074 + 1 = 0
      +                            // -1023 +1074 + 1 = 52
      +
      +                            int bitsDiscarded = 53 -
      +                                    ((int) exponent - DoubleConsts.MIN_SUB_EXPONENT + 1);
      +                            assert bitsDiscarded >= 1 && bitsDiscarded <= 53;
      +
      +                            // What to do here:
      +                            // First, isolate the new round bit
      +                            round = (significand & (1L << (bitsDiscarded - 1))) != 0L;
      +                            if (bitsDiscarded > 1) {
      +                                // create mask to update sticky bits; low
      +                                // order bitsDiscarded bits should be 1
      +                                long mask = ~((~0L) << (bitsDiscarded - 1));
      +                                sticky = sticky || ((significand & mask) != 0L);
      +                            }
      +
      +                            // Now, discard the bits
      +                            significand = significand >> bitsDiscarded;
      +
      +                            significand = ((((long) (DoubleConsts.MIN_EXPONENT - 1) + // subnorm exp.
      +                                    (long) DoubleConsts.EXP_BIAS) <<
      +                                    (DoubleConsts.SIGNIFICAND_WIDTH - 1))
      +                                    & DoubleConsts.EXP_BIT_MASK) |
      +                                    (DoubleConsts.SIGNIF_BIT_MASK & significand);
      +                        }
      +                    }
      +
      +                    // The significand variable now contains the currently
      +                    // appropriate exponent bits too.
      +
      +                    //
      +                    // Determine if significand should be incremented;
      +                    // making this determination depends on the least
      +                    // significant bit and the round and sticky bits.
      +                    //
      +                    // Round to nearest even rounding table, adapted from
      +                    // table 4.7 in "Computer Arithmetic" by IsraelKoren.
      +                    // The digit to the left of the "decimal" point is the
      +                    // least significant bit, the digits to the right of
      +                    // the point are the round and sticky bits
      +                    //
      +                    // Number       Round(x)
      +                    // x0.00        x0.
      +                    // x0.01        x0.
      +                    // x0.10        x0.
      +                    // x0.11        x1. = x0. +1
      +                    // x1.00        x1.
      +                    // x1.01        x1.
      +                    // x1.10        x1. + 1
      +                    // x1.11        x1. + 1
      +                    //
      +                    boolean leastZero = ((significand & 1L) == 0L);
      +                    if ((leastZero && round && sticky) ||
      +                            ((!leastZero) && round)) {
      +                        significand++;
      +                    }
      +
      +                    double value = isNegative ?
      +                            Double.longBitsToDouble(significand | DoubleConsts.SIGN_BIT_MASK) :
      +                            Double.longBitsToDouble(significand );
      +
      +                    return new PreparedASCIIToBinaryBuffer(value, fValue);
      +                }
      +            }
      +    }
      +
      +    /**
      +     * Returns s with any leading zeros removed.
      +     */
      +    static String stripLeadingZeros(String s) {
      +//        return  s.replaceFirst("^0+", "");
      +        if(!s.isEmpty() && s.charAt(0)=='0') {
      +            for(int i=1; iposition
      +     * of string s.
      +     */
      +    static int getHexDigit(String s, int position) {
      +        int value = Character.digit(s.charAt(position), 16);
      +        if (value <= -1 || value >= 16) {
      +            throw new AssertionError("Unexpected failure of digit conversion of " +
      +                                     s.charAt(position));
      +        }
      +        return value;
      +    }
      +}
      diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/FormattedFloatingDecimal.java b/sources/net.sf.j2s.java.core/src/sun/misc/FormattedFloatingDecimal.java
      new file mode 100644
      index 000000000..fc53920e3
      --- /dev/null
      +++ b/sources/net.sf.j2s.java.core/src/sun/misc/FormattedFloatingDecimal.java
      @@ -0,0 +1,349 @@
      +/*
      + * Copyright (c) 2003, 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.misc;
      +
      +import java.util.Arrays;
      +
      +public class FormattedFloatingDecimal{
      +
      +    public enum Form { SCIENTIFIC, COMPATIBLE, DECIMAL_FLOAT, GENERAL };
      +
      +
      +    public static FormattedFloatingDecimal valueOf(double d, int precision, Form form){
      +        FloatingDecimal.BinaryToASCIIConverter fdConverter =
      +                FloatingDecimal.getBinaryToASCIIConverter(d, form == Form.COMPATIBLE);
      +        return new FormattedFloatingDecimal(precision,form, fdConverter);
      +    }
      +
      +    private int decExponentRounded;
      +    private char[] mantissa;
      +    private char[] exponent;
      +
      +    private static final ThreadLocal threadLocalCharBuffer =
      +            new ThreadLocal() {
      +                @Override
      +                protected Object initialValue() {
      +                    return new char[20];
      +                }
      +            };
      +
      +    private static char[] getBuffer(){
      +        return (char[]) threadLocalCharBuffer.get();
      +    }
      +
      +    private FormattedFloatingDecimal(int precision, Form form, FloatingDecimal.BinaryToASCIIConverter fdConverter) {
      +        if (fdConverter.isExceptional()) {
      +            this.mantissa = fdConverter.toJavaFormatString().toCharArray();
      +            this.exponent = null;
      +            return;
      +        }
      +        char[] digits = getBuffer();
      +        int nDigits = fdConverter.getDigits(digits);
      +        int decExp = fdConverter.getDecimalExponent();
      +        int exp;
      +        boolean isNegative = fdConverter.isNegative();
      +        switch (form) {
      +            case COMPATIBLE:
      +                exp = decExp;
      +                this.decExponentRounded = exp;
      +                fillCompatible(precision, digits, nDigits, exp, isNegative);
      +                break;
      +            case DECIMAL_FLOAT:
      +                exp = applyPrecision(decExp, digits, nDigits, decExp + precision);
      +                fillDecimal(precision, digits, nDigits, exp, isNegative);
      +                this.decExponentRounded = exp;
      +                break;
      +            case SCIENTIFIC:
      +                exp = applyPrecision(decExp, digits, nDigits, precision + 1);
      +                fillScientific(precision, digits, nDigits, exp, isNegative);
      +                this.decExponentRounded = exp;
      +                break;
      +            case GENERAL:
      +                exp = applyPrecision(decExp, digits, nDigits, precision);
      +                // adjust precision to be the number of digits to right of decimal
      +                // the real exponent to be output is actually exp - 1, not exp
      +                if (exp - 1 < -4 || exp - 1 >= precision) {
      +                    // form = Form.SCIENTIFIC;
      +                    precision--;
      +                    fillScientific(precision, digits, nDigits, exp, isNegative);
      +                } else {
      +                    // form = Form.DECIMAL_FLOAT;
      +                    precision = precision - exp;
      +                    fillDecimal(precision, digits, nDigits, exp, isNegative);
      +                }
      +                this.decExponentRounded = exp;
      +                break;
      +            default:
      +                assert false;
      +        }
      +    }
      +
      +    // returns the exponent after rounding has been done by applyPrecision
      +    public int getExponentRounded() {
      +        return decExponentRounded - 1;
      +    }
      +
      +    public char[] getMantissa(){
      +        return mantissa;
      +    }
      +
      +    public char[] getExponent(){
      +        return exponent;
      +    }
      +
      +    /**
      +     * Returns new decExp in case of overflow.
      +     */
      +    private static int applyPrecision(int decExp, char[] digits, int nDigits, int prec) {
      +        if (prec >= nDigits || prec < 0) {
      +            // no rounding necessary
      +            return decExp;
      +        }
      +        if (prec == 0) {
      +            // only one digit (0 or 1) is returned because the precision
      +            // excludes all significant digits
      +            if (digits[0] >= '5') {
      +                digits[0] = '1';
      +                Arrays.fill(digits, 1, nDigits, '0');
      +                return decExp + 1;
      +            } else {
      +                Arrays.fill(digits, 0, nDigits, '0');
      +                return decExp;
      +            }
      +        }
      +        int q = digits[prec];
      +        if (q >= '5') {
      +            int i = prec;
      +            q = digits[--i];
      +            if ( q == '9' ) {
      +                while ( q == '9' && i > 0 ){
      +                    q = digits[--i];
      +                }
      +                if ( q == '9' ){
      +                    // carryout! High-order 1, rest 0s, larger exp.
      +                    digits[0] = '1';
      +                    Arrays.fill(digits, 1, nDigits, '0');
      +                    return decExp+1;
      +                }
      +            }
      +            digits[i] = (char)(q + 1);
      +            Arrays.fill(digits, i+1, nDigits, '0');
      +        } else {
      +            Arrays.fill(digits, prec, nDigits, '0');
      +        }
      +        return decExp;
      +    }
      +
      +    /**
      +     * Fills mantissa and exponent char arrays for compatible format.
      +     */
      +    private void fillCompatible(int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
      +        int startIndex = isNegative ? 1 : 0;
      +        if (exp > 0 && exp < 8) {
      +            // print digits.digits.
      +            if (nDigits < exp) {
      +                int extraZeros = exp - nDigits;
      +                mantissa = create(isNegative, nDigits + extraZeros + 2);
      +                System.arraycopy(digits, 0, mantissa, startIndex, nDigits);
      +                Arrays.fill(mantissa, startIndex + nDigits, startIndex + nDigits + extraZeros, '0');
      +                mantissa[startIndex + nDigits + extraZeros] = '.';
      +                mantissa[startIndex + nDigits + extraZeros+1] = '0';
      +            } else if (exp < nDigits) {
      +                int t = Math.min(nDigits - exp, precision);
      +                mantissa = create(isNegative, exp + 1 + t);
      +                System.arraycopy(digits, 0, mantissa, startIndex, exp);
      +                mantissa[startIndex + exp ] = '.';
      +                System.arraycopy(digits, exp, mantissa, startIndex+exp+1, t);
      +            } else { // exp == digits.length
      +                mantissa = create(isNegative, nDigits + 2);
      +                System.arraycopy(digits, 0, mantissa, startIndex, nDigits);
      +                mantissa[startIndex + nDigits ] = '.';
      +                mantissa[startIndex + nDigits +1] = '0';
      +            }
      +        } else if (exp <= 0 && exp > -3) {
      +            int zeros = Math.max(0, Math.min(-exp, precision));
      +            int t = Math.max(0, Math.min(nDigits, precision + exp));
      +            // write '0' s before the significant digits
      +            if (zeros > 0) {
      +                mantissa = create(isNegative, zeros + 2 + t);
      +                mantissa[startIndex] = '0';
      +                mantissa[startIndex+1] = '.';
      +                Arrays.fill(mantissa, startIndex + 2, startIndex + 2 + zeros, '0');
      +                if (t > 0) {
      +                    // copy only when significant digits are within the precision
      +                    System.arraycopy(digits, 0, mantissa, startIndex + 2 + zeros, t);
      +                }
      +            } else if (t > 0) {
      +                mantissa = create(isNegative, zeros + 2 + t);
      +                mantissa[startIndex] = '0';
      +                mantissa[startIndex + 1] = '.';
      +                // copy only when significant digits are within the precision
      +                System.arraycopy(digits, 0, mantissa, startIndex + 2, t);
      +            } else {
      +                this.mantissa = create(isNegative, 1);
      +                this.mantissa[startIndex] = '0';
      +            }
      +        } else {
      +            if (nDigits > 1) {
      +                mantissa = create(isNegative, nDigits + 1);
      +                mantissa[startIndex] = digits[0];
      +                mantissa[startIndex + 1] = '.';
      +                System.arraycopy(digits, 1, mantissa, startIndex + 2, nDigits - 1);
      +            } else {
      +                mantissa = create(isNegative, 3);
      +                mantissa[startIndex] = digits[0];
      +                mantissa[startIndex + 1] = '.';
      +                mantissa[startIndex + 2] = '0';
      +            }
      +            int e, expStartIntex;
      +            boolean isNegExp = (exp <= 0);
      +            if (isNegExp) {
      +                e = -exp + 1;
      +                expStartIntex = 1;
      +            } else {
      +                e = exp - 1;
      +                expStartIntex = 0;
      +            }
      +            // decExponent has 1, 2, or 3, digits
      +            if (e <= 9) {
      +                exponent = create(isNegExp,1);
      +                exponent[expStartIntex] = (char) (e + '0');
      +            } else if (e <= 99) {
      +                exponent = create(isNegExp,2);
      +                exponent[expStartIntex] = (char) (e / 10 + '0');
      +                exponent[expStartIntex+1] = (char) (e % 10 + '0');
      +            } else {
      +                exponent = create(isNegExp,3);
      +                exponent[expStartIntex] = (char) (e / 100 + '0');
      +                e %= 100;
      +                exponent[expStartIntex+1] = (char) (e / 10 + '0');
      +                exponent[expStartIntex+2] = (char) (e % 10 + '0');
      +            }
      +        }
      +    }
      +
      +    private static char[] create(boolean isNegative, int size) {
      +        if(isNegative) {
      +            char[] r = new char[size +1];
      +            r[0] = '-';
      +            return r;
      +        } else {
      +            return new char[size];
      +        }
      +    }
      +
      +    /*
      +     * Fills mantissa char arrays for DECIMAL_FLOAT format.
      +     * Exponent should be equal to null.
      +     */
      +    private void fillDecimal(int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
      +        int startIndex = isNegative ? 1 : 0;
      +        if (exp > 0) {
      +            // print digits.digits.
      +            if (nDigits < exp) {
      +                mantissa = create(isNegative,exp);
      +                System.arraycopy(digits, 0, mantissa, startIndex, nDigits);
      +                Arrays.fill(mantissa, startIndex + nDigits, startIndex + exp, '0');
      +                // Do not append ".0" for formatted floats since the user
      +                // may request that it be omitted. It is added as necessary
      +                // by the Formatter.
      +            } else {
      +                int t = Math.min(nDigits - exp, precision);
      +                mantissa = create(isNegative, exp + (t > 0 ? (t + 1) : 0));
      +                System.arraycopy(digits, 0, mantissa, startIndex, exp);
      +                // Do not append ".0" for formatted floats since the user
      +                // may request that it be omitted. It is added as necessary
      +                // by the Formatter.
      +                if (t > 0) {
      +                    mantissa[startIndex + exp] = '.';
      +                    System.arraycopy(digits, exp, mantissa, startIndex + exp + 1, t);
      +                }
      +            }
      +        } else if (exp <= 0) {
      +            int zeros = Math.max(0, Math.min(-exp, precision));
      +            int t = Math.max(0, Math.min(nDigits, precision + exp));
      +            // write '0' s before the significant digits
      +            if (zeros > 0) {
      +                mantissa = create(isNegative, zeros + 2 + t);
      +                mantissa[startIndex] = '0';
      +                mantissa[startIndex+1] = '.';
      +                Arrays.fill(mantissa, startIndex + 2, startIndex + 2 + zeros, '0');
      +                if (t > 0) {
      +                    // copy only when significant digits are within the precision
      +                    System.arraycopy(digits, 0, mantissa, startIndex + 2 + zeros, t);
      +                }
      +            } else if (t > 0) {
      +                mantissa = create(isNegative, zeros + 2 + t);
      +                mantissa[startIndex] = '0';
      +                mantissa[startIndex + 1] = '.';
      +                // copy only when significant digits are within the precision
      +                System.arraycopy(digits, 0, mantissa, startIndex + 2, t);
      +            } else {
      +                this.mantissa = create(isNegative, 1);
      +                this.mantissa[startIndex] = '0';
      +            }
      +        }
      +    }
      +
      +    /**
      +     * Fills mantissa and exponent char arrays for SCIENTIFIC format.
      +     */
      +    private void fillScientific(int precision, char[] digits, int nDigits, int exp, boolean isNegative) {
      +        int startIndex = isNegative ? 1 : 0;
      +        int t = Math.max(0, Math.min(nDigits - 1, precision));
      +        if (t > 0) {
      +            mantissa = create(isNegative, t + 2);
      +            mantissa[startIndex] = digits[0];
      +            mantissa[startIndex + 1] = '.';
      +            System.arraycopy(digits, 1, mantissa, startIndex + 2, t);
      +        } else {
      +            mantissa = create(isNegative, 1);
      +            mantissa[startIndex] = digits[0];
      +        }
      +        char expSign;
      +        int e;
      +        if (exp <= 0) {
      +            expSign = '-';
      +            e = -exp + 1;
      +        } else {
      +            expSign = '+' ;
      +            e = exp - 1;
      +        }
      +        // decExponent has 1, 2, or 3, digits
      +        if (e <= 9) {
      +            exponent = new char[] { expSign,
      +                    '0', (char) (e + '0') };
      +        } else if (e <= 99) {
      +            exponent = new char[] { expSign,
      +                    (char) (e / 10 + '0'), (char) (e % 10 + '0') };
      +        } else {
      +            char hiExpChar = (char) (e / 100 + '0');
      +            e %= 100;
      +            exponent = new char[] { expSign,
      +                    hiExpChar, (char) (e / 10 + '0'), (char) (e % 10 + '0') };
      +        }
      +    }
      +}
      diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/FpUtils.java b/sources/net.sf.j2s.java.core/src/sun/misc/FpUtils.java
      new file mode 100644
      index 000000000..a874c80f6
      --- /dev/null
      +++ b/sources/net.sf.j2s.java.core/src/sun/misc/FpUtils.java
      @@ -0,0 +1,931 @@
      +/*
      + * Copyright (c) 2003, 2011, 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.misc;
      +
      +import sun.misc.FloatConsts;
      +import sun.misc.DoubleConsts;
      +
      +/**
      + * The class {@code FpUtils} contains static utility methods for
      + * manipulating and inspecting {@code float} and
      + * {@code double} floating-point numbers.  These methods include
      + * functionality recommended or required by the IEEE 754
      + * floating-point standard.
      + *
      + * @author Joseph D. Darcy
      + */
      +
      +public class FpUtils {
      +    /*
      +     * The methods in this class are reasonably implemented using
      +     * direct or indirect bit-level manipulation of floating-point
      +     * values.  However, having access to the IEEE 754 recommended
      +     * functions would obviate the need for most programmers to engage
      +     * in floating-point bit-twiddling.
      +     *
      +     * An IEEE 754 number has three fields, from most significant bit
      +     * to to least significant, sign, exponent, and significand.
      +     *
      +     *  msb                                lsb
      +     * [sign|exponent|  fractional_significand]
      +     *
      +     * Using some encoding cleverness, explained below, the high order
      +     * bit of the logical significand does not need to be explicitly
      +     * stored, thus "fractional_significand" instead of simply
      +     * "significand" in the figure above.
      +     *
      +     * For finite normal numbers, the numerical value encoded is
      +     *
      +     * (-1)^sign * 2^(exponent)*(1.fractional_significand)
      +     *
      +     * Most finite floating-point numbers are normalized; the exponent
      +     * value is reduced until the leading significand bit is 1.
      +     * Therefore, the leading 1 is redundant and is not explicitly
      +     * stored.  If a numerical value is so small it cannot be
      +     * normalized, it has a subnormal representation. Subnormal
      +     * numbers don't have a leading 1 in their significand; subnormals
      +     * are encoding using a special exponent value.  In other words,
      +     * the high-order bit of the logical significand can be elided in
      +     * from the representation in either case since the bit's value is
      +     * implicit from the exponent value.
      +     *
      +     * The exponent field uses a biased representation; if the bits of
      +     * the exponent are interpreted as a unsigned integer E, the
      +     * exponent represented is E - E_bias where E_bias depends on the
      +     * floating-point format.  E can range between E_min and E_max,
      +     * constants which depend on the floating-point format.  E_min and
      +     * E_max are -126 and +127 for float, -1022 and +1023 for double.
      +     *
      +     * The 32-bit float format has 1 sign bit, 8 exponent bits, and 23
      +     * bits for the significand (which is logically 24 bits wide
      +     * because of the implicit bit).  The 64-bit double format has 1
      +     * sign bit, 11 exponent bits, and 52 bits for the significand
      +     * (logically 53 bits).
      +     *
      +     * Subnormal numbers and zero have the special exponent value
      +     * E_min -1; the numerical value represented by a subnormal is:
      +     *
      +     * (-1)^sign * 2^(E_min)*(0.fractional_significand)
      +     *
      +     * Zero is represented by all zero bits in the exponent and all
      +     * zero bits in the significand; zero can have either sign.
      +     *
      +     * Infinity and NaN are encoded using the exponent value E_max +
      +     * 1.  Signed infinities have all significand bits zero; NaNs have
      +     * at least one non-zero significand bit.
      +     *
      +     * The details of IEEE 754 floating-point encoding will be used in
      +     * the methods below without further comment.  For further
      +     * exposition on IEEE 754 numbers, see "IEEE Standard for Binary
      +     * Floating-Point Arithmetic" ANSI/IEEE Std 754-1985 or William
      +     * Kahan's "Lecture Notes on the Status of IEEE Standard 754 for
      +     * Binary Floating-Point Arithmetic",
      +     * http://www.cs.berkeley.edu/~wkahan/ieee754status/ieee754.ps.
      +     *
      +     * Many of this class's methods are members of the set of IEEE 754
      +     * recommended functions or similar functions recommended or
      +     * required by IEEE 754R.  Discussion of various implementation
      +     * techniques for these functions have occurred in:
      +     *
      +     * W.J. Cody and Jerome T. Coonen, "Algorithm 772 Functions to
      +     * Support the IEEE Standard for Binary Floating-Point
      +     * Arithmetic," ACM Transactions on Mathematical Software,
      +     * vol. 19, no. 4, December 1993, pp. 443-451.
      +     *
      +     * Joseph D. Darcy, "Writing robust IEEE recommended functions in
      +     * ``100% Pure Java''(TM)," University of California, Berkeley
      +     * technical report UCB//CSD-98-1009.
      +     */
      +
      +    /**
      +     * Don't let anyone instantiate this class.
      +     */
      +    private FpUtils() {}
      +
      +    // Helper Methods
      +
      +    // The following helper methods are used in the implementation of
      +    // the public recommended functions; they generally omit certain
      +    // tests for exception cases.
      +
      +    /**
      +     * Returns unbiased exponent of a {@code double}.
      +     * @deprecated Use Math.getExponent.
      +     */
      +    @Deprecated
      +    public static int getExponent(double d){
      +        return Math.getExponent(d);
      +    }
      +
      +    /**
      +     * Returns unbiased exponent of a {@code float}.
      +     * @deprecated Use Math.getExponent.
      +     */
      +    @Deprecated
      +    public static int getExponent(float f){
      +        return Math.getExponent(f);
      +    }
      +
      +
      +    /**
      +     * Returns the first floating-point argument with the sign of the
      +     * second floating-point argument.  Note that unlike the {@link
      +     * FpUtils#copySign(double, double) copySign} method, this method
      +     * does not require NaN {@code sign} arguments to be treated
      +     * as positive values; implementations are permitted to treat some
      +     * NaN arguments as positive and other NaN arguments as negative
      +     * to allow greater performance.
      +     *
      +     * @param magnitude  the parameter providing the magnitude of the result
      +     * @param sign   the parameter providing the sign of the result
      +     * @return a value with the magnitude of {@code magnitude}
      +     * and the sign of {@code sign}.
      +     * @author Joseph D. Darcy
      +     * @deprecated Use Math.copySign.
      +     */
      +    @Deprecated
      +    public static double rawCopySign(double magnitude, double sign) {
      +        return Math.copySign(magnitude, sign);
      +    }
      +
      +    /**
      +     * Returns the first floating-point argument with the sign of the
      +     * second floating-point argument.  Note that unlike the {@link
      +     * FpUtils#copySign(float, float) copySign} method, this method
      +     * does not require NaN {@code sign} arguments to be treated
      +     * as positive values; implementations are permitted to treat some
      +     * NaN arguments as positive and other NaN arguments as negative
      +     * to allow greater performance.
      +     *
      +     * @param magnitude  the parameter providing the magnitude of the result
      +     * @param sign   the parameter providing the sign of the result
      +     * @return a value with the magnitude of {@code magnitude}
      +     * and the sign of {@code sign}.
      +     * @author Joseph D. Darcy
      +     * @deprecated Use Math.copySign.
      +     */
      +    @Deprecated
      +    public static float rawCopySign(float magnitude, float sign) {
      +        return Math.copySign(magnitude, sign);
      +    }
      +
      +    /* ***************************************************************** */
      +
      +    /**
      +     * Returns {@code true} if the argument is a finite
      +     * floating-point value; returns {@code false} otherwise (for
      +     * NaN and infinity arguments).
      +     *
      +     * @param d the {@code double} value to be tested
      +     * @return {@code true} if the argument is a finite
      +     * floating-point value, {@code false} otherwise.
      +     * @deprecated Use Double.isFinite.
      +     */
      +    @Deprecated
      +    public static boolean isFinite(double d) {
      +        return Double.isFinite(d);
      +    }
      +
      +    /**
      +     * Returns {@code true} if the argument is a finite
      +     * floating-point value; returns {@code false} otherwise (for
      +     * NaN and infinity arguments).
      +     *
      +     * @param f the {@code float} value to be tested
      +     * @return {@code true} if the argument is a finite
      +     * floating-point value, {@code false} otherwise.
      +     * @deprecated Use Float.isFinite.
      +     */
      +     @Deprecated
      +     public static boolean isFinite(float f) {
      +         return Float.isFinite(f);
      +    }
      +
      +    /**
      +     * Returns {@code true} if the specified number is infinitely
      +     * large in magnitude, {@code false} otherwise.
      +     *
      +     * 

      Note that this method is equivalent to the {@link + * Double#isInfinite(double) Double.isInfinite} method; the + * functionality is included in this class for convenience. + * + * @param d the value to be tested. + * @return {@code true} if the value of the argument is positive + * infinity or negative infinity; {@code false} otherwise. + */ + public static boolean isInfinite(double d) { + return Double.isInfinite(d); + } + + /** + * Returns {@code true} if the specified number is infinitely + * large in magnitude, {@code false} otherwise. + * + *

      Note that this method is equivalent to the {@link + * Float#isInfinite(float) Float.isInfinite} method; the + * functionality is included in this class for convenience. + * + * @param f the value to be tested. + * @return {@code true} if the argument is positive infinity or + * negative infinity; {@code false} otherwise. + */ + public static boolean isInfinite(float f) { + return Float.isInfinite(f); + } + + /** + * Returns {@code true} if the specified number is a + * Not-a-Number (NaN) value, {@code false} otherwise. + * + *

      Note that this method is equivalent to the {@link + * Double#isNaN(double) Double.isNaN} method; the functionality is + * included in this class for convenience. + * + * @param d the value to be tested. + * @return {@code true} if the value of the argument is NaN; + * {@code false} otherwise. + */ + public static boolean isNaN(double d) { + return Double.isNaN(d); + } + + /** + * Returns {@code true} if the specified number is a + * Not-a-Number (NaN) value, {@code false} otherwise. + * + *

      Note that this method is equivalent to the {@link + * Float#isNaN(float) Float.isNaN} method; the functionality is + * included in this class for convenience. + * + * @param f the value to be tested. + * @return {@code true} if the argument is NaN; + * {@code false} otherwise. + */ + public static boolean isNaN(float f) { + return Float.isNaN(f); + } + + /** + * Returns {@code true} if the unordered relation holds + * between the two arguments. When two floating-point values are + * unordered, one value is neither less than, equal to, nor + * greater than the other. For the unordered relation to be true, + * at least one argument must be a {@code NaN}. + * + * @param arg1 the first argument + * @param arg2 the second argument + * @return {@code true} if at least one argument is a NaN, + * {@code false} otherwise. + */ + public static boolean isUnordered(double arg1, double arg2) { + return isNaN(arg1) || isNaN(arg2); + } + + /** + * Returns {@code true} if the unordered relation holds + * between the two arguments. When two floating-point values are + * unordered, one value is neither less than, equal to, nor + * greater than the other. For the unordered relation to be true, + * at least one argument must be a {@code NaN}. + * + * @param arg1 the first argument + * @param arg2 the second argument + * @return {@code true} if at least one argument is a NaN, + * {@code false} otherwise. + */ + public static boolean isUnordered(float arg1, float arg2) { + return isNaN(arg1) || isNaN(arg2); + } + + /** + * Returns unbiased exponent of a {@code double}; for + * subnormal values, the number is treated as if it were + * normalized. That is for all finite, non-zero, positive numbers + * x, scalb(x, -ilogb(x)) is + * always in the range [1, 2). + *

      + * Special cases: + *

        + *
      • If the argument is NaN, then the result is 230. + *
      • If the argument is infinite, then the result is 228. + *
      • If the argument is zero, then the result is -(228). + *
      + * + * @param d floating-point number whose exponent is to be extracted + * @return unbiased exponent of the argument. + * @author Joseph D. Darcy + */ + public static int ilogb(double d) { + int exponent = getExponent(d); + + switch (exponent) { + case DoubleConsts.MAX_EXPONENT+1: // NaN or infinity + if( isNaN(d) ) + return (1<<30); // 2^30 + else // infinite value + return (1<<28); // 2^28 + + case DoubleConsts.MIN_EXPONENT-1: // zero or subnormal + if(d == 0.0) { + return -(1<<28); // -(2^28) + } + else { + long transducer = Double.doubleToRawLongBits(d); + + /* + * To avoid causing slow arithmetic on subnormals, + * the scaling to determine when d's significand + * is normalized is done in integer arithmetic. + * (there must be at least one "1" bit in the + * significand since zero has been screened out. + */ + + // isolate significand bits + transducer &= DoubleConsts.SIGNIF_BIT_MASK; + assert(transducer != 0L); + + // This loop is simple and functional. We might be + // able to do something more clever that was faster; + // e.g. number of leading zero detection on + // (transducer << (# exponent and sign bits). + while (transducer < + (1L << (DoubleConsts.SIGNIFICAND_WIDTH - 1))) { + transducer *= 2; + exponent--; + } + exponent++; + assert( exponent >= + DoubleConsts.MIN_EXPONENT - (DoubleConsts.SIGNIFICAND_WIDTH-1) && + exponent < DoubleConsts.MIN_EXPONENT); + return exponent; + } + + default: + assert( exponent >= DoubleConsts.MIN_EXPONENT && + exponent <= DoubleConsts.MAX_EXPONENT); + return exponent; + } + } + + /** + * Returns unbiased exponent of a {@code float}; for + * subnormal values, the number is treated as if it were + * normalized. That is for all finite, non-zero, positive numbers + * x, scalb(x, -ilogb(x)) is + * always in the range [1, 2). + *

      + * Special cases: + *

        + *
      • If the argument is NaN, then the result is 230. + *
      • If the argument is infinite, then the result is 228. + *
      • If the argument is zero, then the result is -(228). + *
      + * + * @param f floating-point number whose exponent is to be extracted + * @return unbiased exponent of the argument. + * @author Joseph D. Darcy + */ + public static int ilogb(float f) { + int exponent = getExponent(f); + + switch (exponent) { + case FloatConsts.MAX_EXPONENT+1: // NaN or infinity + if( isNaN(f) ) + return (1<<30); // 2^30 + else // infinite value + return (1<<28); // 2^28 + + case FloatConsts.MIN_EXPONENT-1: // zero or subnormal + if(f == 0.0f) { + return -(1<<28); // -(2^28) + } + else { + int transducer = Float.floatToRawIntBits(f); + + /* + * To avoid causing slow arithmetic on subnormals, + * the scaling to determine when f's significand + * is normalized is done in integer arithmetic. + * (there must be at least one "1" bit in the + * significand since zero has been screened out. + */ + + // isolate significand bits + transducer &= FloatConsts.SIGNIF_BIT_MASK; + assert(transducer != 0); + + // This loop is simple and functional. We might be + // able to do something more clever that was faster; + // e.g. number of leading zero detection on + // (transducer << (# exponent and sign bits). + while (transducer < + (1 << (FloatConsts.SIGNIFICAND_WIDTH - 1))) { + transducer *= 2; + exponent--; + } + exponent++; + assert( exponent >= + FloatConsts.MIN_EXPONENT - (FloatConsts.SIGNIFICAND_WIDTH-1) && + exponent < FloatConsts.MIN_EXPONENT); + return exponent; + } + + default: + assert( exponent >= FloatConsts.MIN_EXPONENT && + exponent <= FloatConsts.MAX_EXPONENT); + return exponent; + } + } + + + /* + * The scalb operation should be reasonably fast; however, there + * are tradeoffs in writing a method to minimize the worst case + * performance and writing a method to minimize the time for + * expected common inputs. Some processors operate very slowly on + * subnormal operands, taking hundreds or thousands of cycles for + * one floating-point add or multiply as opposed to, say, four + * cycles for normal operands. For processors with very slow + * subnormal execution, scalb would be fastest if written entirely + * with integer operations; in other words, scalb would need to + * include the logic of performing correct rounding of subnormal + * values. This could be reasonably done in at most a few hundred + * cycles. However, this approach may penalize normal operations + * since at least the exponent of the floating-point argument must + * be examined. + * + * The approach taken in this implementation is a compromise. + * Floating-point multiplication is used to do most of the work; + * but knowingly multiplying by a subnormal scaling factor is + * avoided. However, the floating-point argument is not examined + * to see whether or not it is subnormal since subnormal inputs + * are assumed to be rare. At most three multiplies are needed to + * scale from the largest to smallest exponent ranges (scaling + * down, at most two multiplies are needed if subnormal scaling + * factors are allowed). However, in this implementation an + * expensive integer remainder operation is avoided at the cost of + * requiring five floating-point multiplies in the worst case, + * which should still be a performance win. + * + * If scaling of entire arrays is a concern, it would probably be + * more efficient to provide a double[] scalb(double[], int) + * version of scalb to avoid having to recompute the needed + * scaling factors for each floating-point value. + */ + + /** + * Return {@code d} × + * 2{@code scale_factor} rounded as if performed + * by a single correctly rounded floating-point multiply to a + * member of the double value set. See section 4.2.3 of + * The Java™ Language Specification + * for a discussion of floating-point + * value sets. If the exponent of the result is between the + * {@code double}'s minimum exponent and maximum exponent, + * the answer is calculated exactly. If the exponent of the + * result would be larger than {@code doubles}'s maximum + * exponent, an infinity is returned. Note that if the result is + * subnormal, precision may be lost; that is, when {@code scalb(x, + * n)} is subnormal, {@code scalb(scalb(x, n), -n)} may + * not equal x. When the result is non-NaN, the result has + * the same sign as {@code d}. + * + *

      + * Special cases: + *

        + *
      • If the first argument is NaN, NaN is returned. + *
      • If the first argument is infinite, then an infinity of the + * same sign is returned. + *
      • If the first argument is zero, then a zero of the same + * sign is returned. + *
      + * + * @param d number to be scaled by a power of two. + * @param scale_factor power of 2 used to scale {@code d} + * @return {@code d * }2{@code scale_factor} + * @author Joseph D. Darcy + * @deprecated Use Math.scalb. + */ + @Deprecated + public static double scalb(double d, int scale_factor) { + return Math.scalb(d, scale_factor); + } + + /** + * Return {@code f} × + * 2{@code scale_factor} rounded as if performed + * by a single correctly rounded floating-point multiply to a + * member of the float value set. See section 4.2.3 of + * The Java™ Language Specification + * for a discussion of floating-point + * value sets. If the exponent of the result is between the + * {@code float}'s minimum exponent and maximum exponent, the + * answer is calculated exactly. If the exponent of the result + * would be larger than {@code float}'s maximum exponent, an + * infinity is returned. Note that if the result is subnormal, + * precision may be lost; that is, when {@code scalb(x, n)} + * is subnormal, {@code scalb(scalb(x, n), -n)} may not equal + * x. When the result is non-NaN, the result has the same + * sign as {@code f}. + * + *

      + * Special cases: + *

        + *
      • If the first argument is NaN, NaN is returned. + *
      • If the first argument is infinite, then an infinity of the + * same sign is returned. + *
      • If the first argument is zero, then a zero of the same + * sign is returned. + *
      + * + * @param f number to be scaled by a power of two. + * @param scale_factor power of 2 used to scale {@code f} + * @return {@code f * }2{@code scale_factor} + * @author Joseph D. Darcy + * @deprecated Use Math.scalb. + */ + @Deprecated + public static float scalb(float f, int scale_factor) { + return Math.scalb(f, scale_factor); + } + + /** + * Returns the floating-point number adjacent to the first + * argument in the direction of the second argument. If both + * arguments compare as equal the second argument is returned. + * + *

      + * Special cases: + *

        + *
      • If either argument is a NaN, then NaN is returned. + * + *
      • If both arguments are signed zeros, {@code direction} + * is returned unchanged (as implied by the requirement of + * returning the second argument if the arguments compare as + * equal). + * + *
      • If {@code start} is + * ±{@code Double.MIN_VALUE} and {@code direction} + * has a value such that the result should have a smaller + * magnitude, then a zero with the same sign as {@code start} + * is returned. + * + *
      • If {@code start} is infinite and + * {@code direction} has a value such that the result should + * have a smaller magnitude, {@code Double.MAX_VALUE} with the + * same sign as {@code start} is returned. + * + *
      • If {@code start} is equal to ± + * {@code Double.MAX_VALUE} and {@code direction} has a + * value such that the result should have a larger magnitude, an + * infinity with same sign as {@code start} is returned. + *
      + * + * @param start starting floating-point value + * @param direction value indicating which of + * {@code start}'s neighbors or {@code start} should + * be returned + * @return The floating-point number adjacent to {@code start} in the + * direction of {@code direction}. + * @author Joseph D. Darcy + * @deprecated Use Math.nextAfter + */ + @Deprecated + public static double nextAfter(double start, double direction) { + return Math.nextAfter(start, direction); + } + + /** + * Returns the floating-point number adjacent to the first + * argument in the direction of the second argument. If both + * arguments compare as equal, the second argument is returned. + * + *

      + * Special cases: + *

        + *
      • If either argument is a NaN, then NaN is returned. + * + *
      • If both arguments are signed zeros, a {@code float} + * zero with the same sign as {@code direction} is returned + * (as implied by the requirement of returning the second argument + * if the arguments compare as equal). + * + *
      • If {@code start} is + * ±{@code Float.MIN_VALUE} and {@code direction} + * has a value such that the result should have a smaller + * magnitude, then a zero with the same sign as {@code start} + * is returned. + * + *
      • If {@code start} is infinite and + * {@code direction} has a value such that the result should + * have a smaller magnitude, {@code Float.MAX_VALUE} with the + * same sign as {@code start} is returned. + * + *
      • If {@code start} is equal to ± + * {@code Float.MAX_VALUE} and {@code direction} has a + * value such that the result should have a larger magnitude, an + * infinity with same sign as {@code start} is returned. + *
      + * + * @param start starting floating-point value + * @param direction value indicating which of + * {@code start}'s neighbors or {@code start} should + * be returned + * @return The floating-point number adjacent to {@code start} in the + * direction of {@code direction}. + * @author Joseph D. Darcy + * @deprecated Use Math.nextAfter. + */ + @Deprecated + public static float nextAfter(float start, double direction) { + return Math.nextAfter(start, direction); + } + + /** + * Returns the floating-point value adjacent to {@code d} in + * the direction of positive infinity. This method is + * semantically equivalent to {@code nextAfter(d, + * Double.POSITIVE_INFINITY)}; however, a {@code nextUp} + * implementation may run faster than its equivalent + * {@code nextAfter} call. + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, the result is NaN. + * + *
      • If the argument is positive infinity, the result is + * positive infinity. + * + *
      • If the argument is zero, the result is + * {@code Double.MIN_VALUE} + * + *
      + * + * @param d starting floating-point value + * @return The adjacent floating-point value closer to positive + * infinity. + * @author Joseph D. Darcy + * @deprecated use Math.nextUp. + */ + @Deprecated + public static double nextUp(double d) { + return Math.nextUp(d); + } + + /** + * Returns the floating-point value adjacent to {@code f} in + * the direction of positive infinity. This method is + * semantically equivalent to {@code nextAfter(f, + * Double.POSITIVE_INFINITY)}; however, a {@code nextUp} + * implementation may run faster than its equivalent + * {@code nextAfter} call. + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, the result is NaN. + * + *
      • If the argument is positive infinity, the result is + * positive infinity. + * + *
      • If the argument is zero, the result is + * {@code Float.MIN_VALUE} + * + *
      + * + * @param f starting floating-point value + * @return The adjacent floating-point value closer to positive + * infinity. + * @author Joseph D. Darcy + * @deprecated Use Math.nextUp. + */ + @Deprecated + public static float nextUp(float f) { + return Math.nextUp(f); + } + + /** + * Returns the floating-point value adjacent to {@code d} in + * the direction of negative infinity. This method is + * semantically equivalent to {@code nextAfter(d, + * Double.NEGATIVE_INFINITY)}; however, a + * {@code nextDown} implementation may run faster than its + * equivalent {@code nextAfter} call. + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, the result is NaN. + * + *
      • If the argument is negative infinity, the result is + * negative infinity. + * + *
      • If the argument is zero, the result is + * {@code -Double.MIN_VALUE} + * + *
      + * + * @param d starting floating-point value + * @return The adjacent floating-point value closer to negative + * infinity. + * @author Joseph D. Darcy + * @deprecated Use Math.nextDown. + */ + @Deprecated + public static double nextDown(double d) { + return Math.nextDown(d); + } + + /** + * Returns the floating-point value adjacent to {@code f} in + * the direction of negative infinity. This method is + * semantically equivalent to {@code nextAfter(f, + * Float.NEGATIVE_INFINITY)}; however, a + * {@code nextDown} implementation may run faster than its + * equivalent {@code nextAfter} call. + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, the result is NaN. + * + *
      • If the argument is negative infinity, the result is + * negative infinity. + * + *
      • If the argument is zero, the result is + * {@code -Float.MIN_VALUE} + * + *
      + * + * @param f starting floating-point value + * @return The adjacent floating-point value closer to negative + * infinity. + * @author Joseph D. Darcy + * @deprecated Use Math.nextDown. + */ + @Deprecated + public static double nextDown(float f) { + return Math.nextDown(f); + } + + /** + * Returns the first floating-point argument with the sign of the + * second floating-point argument. For this method, a NaN + * {@code sign} argument is always treated as if it were + * positive. + * + * @param magnitude the parameter providing the magnitude of the result + * @param sign the parameter providing the sign of the result + * @return a value with the magnitude of {@code magnitude} + * and the sign of {@code sign}. + * @author Joseph D. Darcy + * @since 1.5 + * @deprecated Use StrictMath.copySign. + */ + @Deprecated + public static double copySign(double magnitude, double sign) { + return StrictMath.copySign(magnitude, sign); + } + + /** + * Returns the first floating-point argument with the sign of the + * second floating-point argument. For this method, a NaN + * {@code sign} argument is always treated as if it were + * positive. + * + * @param magnitude the parameter providing the magnitude of the result + * @param sign the parameter providing the sign of the result + * @return a value with the magnitude of {@code magnitude} + * and the sign of {@code sign}. + * @author Joseph D. Darcy + * @deprecated Use StrictMath.copySign. + */ + @Deprecated + public static float copySign(float magnitude, float sign) { + return StrictMath.copySign(magnitude, sign); + } + + /** + * Returns the size of an ulp of the argument. An ulp of a + * {@code double} value is the positive distance between this + * floating-point value and the {@code double} value next + * larger in magnitude. Note that for non-NaN x, + * ulp(-x) == ulp(x). + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, then the result is NaN. + *
      • If the argument is positive or negative infinity, then the + * result is positive infinity. + *
      • If the argument is positive or negative zero, then the result is + * {@code Double.MIN_VALUE}. + *
      • If the argument is ±{@code Double.MAX_VALUE}, then + * the result is equal to 2971. + *
      + * + * @param d the floating-point value whose ulp is to be returned + * @return the size of an ulp of the argument + * @author Joseph D. Darcy + * @since 1.5 + * @deprecated Use Math.ulp. + */ + @Deprecated + public static double ulp(double d) { + return Math.ulp(d); + } + + /** + * Returns the size of an ulp of the argument. An ulp of a + * {@code float} value is the positive distance between this + * floating-point value and the {@code float} value next + * larger in magnitude. Note that for non-NaN x, + * ulp(-x) == ulp(x). + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, then the result is NaN. + *
      • If the argument is positive or negative infinity, then the + * result is positive infinity. + *
      • If the argument is positive or negative zero, then the result is + * {@code Float.MIN_VALUE}. + *
      • If the argument is ±{@code Float.MAX_VALUE}, then + * the result is equal to 2104. + *
      + * + * @param f the floating-point value whose ulp is to be returned + * @return the size of an ulp of the argument + * @author Joseph D. Darcy + * @since 1.5 + * @deprecated Use Math.ulp. + */ + @Deprecated + public static float ulp(float f) { + return Math.ulp(f); + } + + /** + * Returns the signum function of the argument; zero if the argument + * is zero, 1.0 if the argument is greater than zero, -1.0 if the + * argument is less than zero. + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, then the result is NaN. + *
      • If the argument is positive zero or negative zero, then the + * result is the same as the argument. + *
      + * + * @param d the floating-point value whose signum is to be returned + * @return the signum function of the argument + * @author Joseph D. Darcy + * @since 1.5 + * @deprecated Use Math.signum. + */ + @Deprecated + public static double signum(double d) { + return Math.signum(d); + } + + /** + * Returns the signum function of the argument; zero if the argument + * is zero, 1.0f if the argument is greater than zero, -1.0f if the + * argument is less than zero. + * + *

      Special Cases: + *

        + *
      • If the argument is NaN, then the result is NaN. + *
      • If the argument is positive zero or negative zero, then the + * result is the same as the argument. + *
      + * + * @param f the floating-point value whose signum is to be returned + * @return the signum function of the argument + * @author Joseph D. Darcy + * @since 1.5 + * @deprecated Use Math.signum. + */ + @Deprecated + public static float signum(float f) { + return Math.signum(f); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/HexDumpEncoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/HexDumpEncoder.java new file mode 100644 index 000000000..4f909060e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/HexDumpEncoder.java @@ -0,0 +1,120 @@ +/* + * Copyright (c) 1995, 1997, 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.misc; +import java.io.PrintStream; +import java.io.OutputStream; +import java.io.IOException; + +/** + * This class encodes a buffer into the classic: "Hexadecimal Dump" format of + * the past. It is useful for analyzing the contents of binary buffers. + * The format produced is as follows: + *
      + * xxxx: 00 11 22 33 44 55 66 77   88 99 aa bb cc dd ee ff ................
      + * 
      + * Where xxxx is the offset into the buffer in 16 byte chunks, followed + * by ascii coded hexadecimal bytes followed by the ASCII representation of + * the bytes or '.' if they are not valid bytes. + * + * @author Chuck McManis + */ + +public class HexDumpEncoder extends CharacterEncoder { + + private int offset; + private int thisLineLength; + private int currentByte; + private byte thisLine[] = new byte[16]; + + static void hexDigit(PrintStream p, byte x) { + char c; + + c = (char) ((x >> 4) & 0xf); + if (c > 9) + c = (char) ((c-10) + 'A'); + else + c = (char)(c + '0'); + p.write(c); + c = (char) (x & 0xf); + if (c > 9) + c = (char)((c-10) + 'A'); + else + c = (char)(c + '0'); + p.write(c); + } + + protected int bytesPerAtom() { + return (1); + } + + protected int bytesPerLine() { + return (16); + } + + protected void encodeBufferPrefix(OutputStream o) throws IOException { + offset = 0; + super.encodeBufferPrefix(o); + } + + protected void encodeLinePrefix(OutputStream o, int len) throws IOException { + hexDigit(pStream, (byte)((offset >>> 8) & 0xff)); + hexDigit(pStream, (byte)(offset & 0xff)); + pStream.print(": "); + currentByte = 0; + thisLineLength = len; + } + + protected void encodeAtom(OutputStream o, byte buf[], int off, int len) throws IOException { + thisLine[currentByte] = buf[off]; + hexDigit(pStream, buf[off]); + pStream.print(" "); + currentByte++; + if (currentByte == 8) + pStream.print(" "); + } + + protected void encodeLineSuffix(OutputStream o) throws IOException { + if (thisLineLength < 16) { + for (int i = thisLineLength; i < 16; i++) { + pStream.print(" "); + if (i == 7) + pStream.print(" "); + } + } + pStream.print(" "); + for (int i = 0; i < thisLineLength; i++) { + if ((thisLine[i] < ' ') || (thisLine[i] > 'z')) { + pStream.print("."); + } else { + pStream.write(thisLine[i]); + } + } + pStream.println(); + offset += thisLineLength; + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/InnocuousThread.java b/sources/net.sf.j2s.java.core/src/sun/misc/InnocuousThread.java new file mode 100644 index 000000000..db4310294 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/InnocuousThread.java @@ -0,0 +1,121 @@ +/* + * 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.misc; + +import java.security.AccessControlContext; +import java.security.ProtectionDomain; + +/** + * A thread that has no permissions, is not a member of any user-defined + * ThreadGroup and supports the ability to erase ThreadLocals. + * + * @implNote Based on the implementation of InnocuousForkJoinWorkerThread. + */ +public final class InnocuousThread extends Thread { + private static final Unsafe UNSAFE; + private static final ThreadGroup THREADGROUP; + private static final AccessControlContext ACC; + private static final long THREADLOCALS; + private static final long INHERITABLETHREADLOCALS; + private static final long INHERITEDACCESSCONTROLCONTEXT; + + public InnocuousThread(Runnable target) { + super(THREADGROUP, target, "anInnocuousThread"); + UNSAFE.putOrderedObject(this, INHERITEDACCESSCONTROLCONTEXT, ACC); + eraseThreadLocals(); + } + + @Override + public ClassLoader getContextClassLoader() { + // always report system class loader + return ClassLoader.getSystemClassLoader(); + } + + @Override + public void setUncaughtExceptionHandler(UncaughtExceptionHandler x) { + // silently fail + } + + @Override + public void setContextClassLoader(ClassLoader cl) { + throw new SecurityException("setContextClassLoader"); + } + + // ensure run method is run only once + private volatile boolean hasRun; + + @Override + public void run() { + if (Thread.currentThread() == this && !hasRun) { + hasRun = true; + super.run(); + } + } + + /** + * Drops all thread locals (and inherited thread locals). + */ + public void eraseThreadLocals() { + UNSAFE.putObject(this, THREADLOCALS, null); + UNSAFE.putObject(this, INHERITABLETHREADLOCALS, null); + } + + // Use Unsafe to access Thread group and ThreadGroup parent fields + static { + try { + ACC = new AccessControlContext(new ProtectionDomain[] { + new ProtectionDomain(null, null) + }); + + // Find and use topmost ThreadGroup as parent of new group + UNSAFE = Unsafe.getUnsafe(); + Class tk = Thread.class; + Class gk = ThreadGroup.class; + + THREADLOCALS = UNSAFE.objectFieldOffset + (tk.getDeclaredField("threadLocals")); + INHERITABLETHREADLOCALS = UNSAFE.objectFieldOffset + (tk.getDeclaredField("inheritableThreadLocals")); + INHERITEDACCESSCONTROLCONTEXT = UNSAFE.objectFieldOffset + (tk.getDeclaredField("inheritedAccessControlContext")); + + long tg = UNSAFE.objectFieldOffset(tk.getDeclaredField("group")); + long gp = UNSAFE.objectFieldOffset(gk.getDeclaredField("parent")); + ThreadGroup group = (ThreadGroup) + UNSAFE.getObject(Thread.currentThread(), tg); + + while (group != null) { + ThreadGroup parent = (ThreadGroup)UNSAFE.getObject(group, gp); + if (parent == null) + break; + group = parent; + } + THREADGROUP = new ThreadGroup(group, "InnocuousThreadGroup"); + } catch (Exception e) { + throw new Error(e); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/InvalidJarIndexException.java b/sources/net.sf.j2s.java.core/src/sun/misc/InvalidJarIndexException.java new file mode 100644 index 000000000..44ca4ff71 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/InvalidJarIndexException.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 1999, 2011, 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.misc; + +import java.lang.LinkageError; + +/** + * Thrown if the URLClassLoader finds the INDEX.LIST file of + * a jar file contains incorrect information. + * + * @author Zhenghua Li + * @since 1.3 + */ + +public +class InvalidJarIndexException extends RuntimeException { + + static final long serialVersionUID = -6159797516569680148L; + + /** + * Constructs an InvalidJarIndexException with no + * detail message. + */ + public InvalidJarIndexException() { + super(); + } + + /** + * Constructs an InvalidJarIndexException with the + * specified detail message. + * + * @param s the detail message. + */ + public InvalidJarIndexException(String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JarFilter.java b/sources/net.sf.j2s.java.core/src/sun/misc/JarFilter.java new file mode 100644 index 000000000..0af055f74 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JarFilter.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2001, 2006, 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.misc; + +import java.io.File; +import java.io.FilenameFilter; + +/** + *

      + * This class checks that only jar and zip files are included in the file list. + * This class is used in extension installation support (ExtensionDependency). + *

      + * + * @author Michael Colburn + */ +public class JarFilter implements FilenameFilter { + + public boolean accept(File dir, String name) { + String lower = name.toLowerCase(); + return lower.endsWith(".jar") || lower.endsWith(".zip"); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JarIndex.java b/sources/net.sf.j2s.java.core/src/sun/misc/JarIndex.java new file mode 100644 index 000000000..e43b9ee7f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JarIndex.java @@ -0,0 +1,353 @@ +/* + * Copyright (c) 1999, 2012, 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.misc; + +import java.io.*; +import java.util.*; +import java.util.jar.*; +import java.util.zip.*; + +/** + * This class is used to maintain mappings from packages, classes + * and resources to their enclosing JAR files. Mappings are kept + * at the package level except for class or resource files that + * are located at the root directory. URLClassLoader uses the mapping + * information to determine where to fetch an extension class or + * resource from. + * + * @author Zhenghua Li + * @since 1.3 + */ + +public class JarIndex { + + /** + * The hash map that maintains mappings from + * package/classe/resource to jar file list(s) + */ + private HashMap> indexMap; + + /** + * The hash map that maintains mappings from + * jar file to package/class/resource lists + */ + private HashMap> jarMap; + + /* + * An ordered list of jar file names. + */ + private String[] jarFiles; + + /** + * The index file name. + */ + public static final String INDEX_NAME = "META-INF/INDEX.LIST"; + + /** + * true if, and only if, sun.misc.JarIndex.metaInfFilenames is set to true. + * If true, the names of the files in META-INF, and its subdirectories, will + * be added to the index. Otherwise, just the directory names are added. + */ + private static final boolean metaInfFilenames = + "true".equals(System.getProperty("sun.misc.JarIndex.metaInfFilenames")); + + /** + * Constructs a new, empty jar index. + */ + public JarIndex() { + indexMap = new HashMap<>(); + jarMap = new HashMap<>(); + } + + /** + * Constructs a new index from the specified input stream. + * + * @param is the input stream containing the index data + */ + public JarIndex(InputStream is) throws IOException { + this(); + read(is); + } + + /** + * Constructs a new index for the specified list of jar files. + * + * @param files the list of jar files to construct the index from. + */ + public JarIndex(String[] files) throws IOException { + this(); + this.jarFiles = files; + parseJars(files); + } + + /** + * Returns the jar index, or null if none. + * + * This single parameter version of the method is retained + * for binary compatibility with earlier releases. + * + * @param jar the JAR file to get the index from. + * @exception IOException if an I/O error has occurred. + */ + public static JarIndex getJarIndex(JarFile jar) throws IOException { + return getJarIndex(jar, null); + } + + /** + * Returns the jar index, or null if none. + * + * @param jar the JAR file to get the index from. + * @exception IOException if an I/O error has occurred. + */ + public static JarIndex getJarIndex(JarFile jar, MetaIndex metaIndex) throws IOException { + JarIndex index = null; + /* If metaIndex is not null, check the meta index to see + if META-INF/INDEX.LIST is contained in jar file or not. + */ + if (metaIndex != null && + !metaIndex.mayContain(INDEX_NAME)) { + return null; + } + JarEntry e = jar.getJarEntry(INDEX_NAME); + // if found, then load the index + if (e != null) { + index = new JarIndex(jar.getInputStream(e)); + } + return index; + } + + /** + * Returns the jar files that are defined in this index. + */ + public String[] getJarFiles() { + return jarFiles; + } + + /* + * Add the key, value pair to the hashmap, the value will + * be put in a linked list which is created if necessary. + */ + private void addToList(String key, String value, + HashMap> t) { + LinkedList list = t.get(key); + if (list == null) { + list = new LinkedList<>(); + list.add(value); + t.put(key, list); + } else if (!list.contains(value)) { + list.add(value); + } + } + + /** + * Returns the list of jar files that are mapped to the file. + * + * @param fileName the key of the mapping + */ + public LinkedList get(String fileName) { + LinkedList jarFiles = null; + if ((jarFiles = indexMap.get(fileName)) == null) { + /* try the package name again */ + int pos; + if((pos = fileName.lastIndexOf("/")) != -1) { + jarFiles = indexMap.get(fileName.substring(0, pos)); + } + } + return jarFiles; + } + + /** + * Add the mapping from the specified file to the specified + * jar file. If there were no mapping for the package of the + * specified file before, a new linked list will be created, + * the jar file is added to the list and a new mapping from + * the package to the jar file list is added to the hashmap. + * Otherwise, the jar file will be added to the end of the + * existing list. + * + * @param fileName the file name + * @param jarName the jar file that the file is mapped to + * + */ + public void add(String fileName, String jarName) { + String packageName; + int pos; + if((pos = fileName.lastIndexOf("/")) != -1) { + packageName = fileName.substring(0, pos); + } else { + packageName = fileName; + } + + addMapping(packageName, jarName); + } + + /** + * Same as add(String,String) except that it doesn't strip off from the + * last index of '/'. It just adds the jarItem (filename or package) + * as it is received. + */ + private void addMapping(String jarItem, String jarName) { + // add the mapping to indexMap + addToList(jarItem, jarName, indexMap); + + // add the mapping to jarMap + addToList(jarName, jarItem, jarMap); + } + + /** + * Go through all the jar files and construct the + * index table. + */ + private void parseJars(String[] files) throws IOException { + if (files == null) { + return; + } + + String currentJar = null; + + for (int i = 0; i < files.length; i++) { + currentJar = files[i]; + ZipFile zrf = new ZipFile(currentJar.replace + ('/', File.separatorChar)); + + Enumeration entries = zrf.entries(); + while(entries.hasMoreElements()) { + ZipEntry entry = entries.nextElement(); + String fileName = entry.getName(); + + // Skip the META-INF directory, the index, and manifest. + // Any files in META-INF/ will be indexed explicitly + if (fileName.equals("META-INF/") || + fileName.equals(INDEX_NAME) || + fileName.equals(JarFile.MANIFEST_NAME)) + continue; + + if (!metaInfFilenames || !fileName.startsWith("META-INF/")) { + add(fileName, currentJar); + } else if (!entry.isDirectory()) { + // Add files under META-INF explicitly so that certain + // services, like ServiceLoader, etc, can be located + // with greater accuracy. Directories can be skipped + // since each file will be added explicitly. + addMapping(fileName, currentJar); + } + } + + zrf.close(); + } + } + + /** + * Writes the index to the specified OutputStream + * + * @param out the output stream + * @exception IOException if an I/O error has occurred + */ + public void write(OutputStream out) throws IOException { + BufferedWriter bw = new BufferedWriter + (new OutputStreamWriter(out, "UTF8")); + bw.write("JarIndex-Version: 1.0\n\n"); + + if (jarFiles != null) { + for (int i = 0; i < jarFiles.length; i++) { + /* print out the jar file name */ + String jar = jarFiles[i]; + bw.write(jar + "\n"); + LinkedList jarlist = jarMap.get(jar); + if (jarlist != null) { + Iterator listitr = jarlist.iterator(); + while(listitr.hasNext()) { + bw.write(listitr.next() + "\n"); + } + } + bw.write("\n"); + } + bw.flush(); + } + } + + + /** + * Reads the index from the specified InputStream. + * + * @param is the input stream + * @exception IOException if an I/O error has occurred + */ + public void read(InputStream is) throws IOException { + BufferedReader br = new BufferedReader + (new InputStreamReader(is, "UTF8")); + String line = null; + String currentJar = null; + + /* an ordered list of jar file names */ + Vector jars = new Vector<>(); + + /* read until we see a .jar line */ + while((line = br.readLine()) != null && !line.endsWith(".jar")); + + for(;line != null; line = br.readLine()) { + if (line.length() == 0) + continue; + + if (line.endsWith(".jar")) { + currentJar = line; + jars.add(currentJar); + } else { + String name = line; + addMapping(name, currentJar); + } + } + + jarFiles = jars.toArray(new String[jars.size()]); + } + + /** + * Merges the current index into another index, taking into account + * the relative path of the current index. + * + * @param toIndex The destination index which the current index will + * merge into. + * @param path The relative path of the this index to the destination + * index. + * + */ + public void merge(JarIndex toIndex, String path) { + Iterator>> itr = indexMap.entrySet().iterator(); + while(itr.hasNext()) { + Map.Entry> e = itr.next(); + String packageName = e.getKey(); + LinkedList from_list = e.getValue(); + Iterator listItr = from_list.iterator(); + while(listItr.hasNext()) { + String jarName = listItr.next(); + if (path != null) { + jarName = path.concat(jarName); + } + toIndex.addMapping(packageName, jarName); + } + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaAWTAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaAWTAccess.java new file mode 100644 index 000000000..7b24dc451 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaAWTAccess.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2011, 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.misc; + +public interface JavaAWTAccess { + + // Returns the AppContext used for applet logging isolation, or null if + // no isolation is required. + // If there's no applet, or if the caller is a stand alone application, + // or running in the main app context, returns null. + // Otherwise, returns the AppContext of the calling applet. + public Object getAppletContext(); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaIOAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaIOAccess.java new file mode 100644 index 000000000..ab2888bfc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaIOAccess.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2005, 2006, 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.misc; +import java.io.Console; +import java.nio.charset.Charset; + +public interface JavaIOAccess { + public Console console(); + public Charset charset(); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaIOFileDescriptorAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaIOFileDescriptorAccess.java new file mode 100644 index 000000000..9e987e6c3 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaIOFileDescriptorAccess.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2007, 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.misc; + +import java.io.FileDescriptor; + +/* + * @author Chris Hegarty + */ + +public interface JavaIOFileDescriptorAccess { + public void set(FileDescriptor obj, int fd); + public int get(FileDescriptor fd); + + // Only valid on Windows + public void setHandle(FileDescriptor obj, long handle); + public long getHandle(FileDescriptor obj); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaLangAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaLangAccess.java new file mode 100644 index 000000000..812f88e20 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaLangAccess.java @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2003, 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.misc; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Executable; +import java.security.AccessControlContext; +import java.util.Map; + +import sun.reflect.ConstantPool; +import sun.reflect.annotation.AnnotationType; +import sun.nio.ch.Interruptible; + +public interface JavaLangAccess { + /** Return the constant pool for a class. */ + ConstantPool getConstantPool(Class klass); + + /** + * Compare-And-Swap the AnnotationType instance corresponding to this class. + * (This method only applies to annotation types.) + */ + boolean casAnnotationType(Class klass, AnnotationType oldType, AnnotationType newType); + + /** + * Get the AnnotationType instance corresponding to this class. + * (This method only applies to annotation types.) + */ + AnnotationType getAnnotationType(Class klass); + + /** + * Get the declared annotations for a given class, indexed by their types. + */ + Map, Annotation> getDeclaredAnnotationMap(Class klass); + + /** + * Get the array of bytes that is the class-file representation + * of this Class' annotations. + */ + byte[] getRawClassAnnotations(Class klass); + + /** + * Get the array of bytes that is the class-file representation + * of this Class' type annotations. + */ + byte[] getRawClassTypeAnnotations(Class klass); + + /** + * Get the array of bytes that is the class-file representation + * of this Executable's type annotations. + */ + byte[] getRawExecutableTypeAnnotations(Executable executable); + + /** + * Returns the elements of an enum class or null if the + * Class object does not represent an enum type; + * the result is uncloned, cached, and shared by all callers. + */ + > E[] getEnumConstantsShared(Class klass); + + /** Set thread's blocker field. */ + void blockedOn(Thread t, Interruptible b); + + /** + * Registers a shutdown hook. + * + * It is expected that this method with registerShutdownInProgress=true + * is only used to register DeleteOnExitHook since the first file + * may be added to the delete on exit list by the application shutdown + * hooks. + * + * @params slot the slot in the shutdown hook array, whose element + * will be invoked in order during shutdown + * @params registerShutdownInProgress true to allow the hook + * to be registered even if the shutdown is in progress. + * @params hook the hook to be registered + * + * @throw IllegalStateException if shutdown is in progress and + * the slot is not valid to register. + */ + void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook); + + /** + * Returns the number of stack frames represented by the given throwable. + */ + int getStackTraceDepth(Throwable t); + + /** + * Returns the ith StackTraceElement for the given throwable. + */ + StackTraceElement getStackTraceElement(Throwable t, int i); + + /** + * Returns a new string backed by the provided character array. The + * character array is not copied and must never be modified after the + * String is created, in order to fulfill String's contract. + * + * @param chars the character array to back the string + * @return a newly created string whose content is the character array + */ + String newStringUnsafe(char[] chars); + + /** + * Returns a new Thread with the given Runnable and an + * inherited AccessControlContext. + */ + Thread newThreadWithAcc(Runnable target, AccessControlContext acc); + + /** + * Invokes the finalize method of the given object. + */ + void invokeFinalize(Object o) throws Throwable; +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaNetAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaNetAccess.java new file mode 100644 index 000000000..cc7bec122 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaNetAccess.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2006, 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.misc; + +import java.net.URLClassLoader; + +public interface JavaNetAccess { + /** + * return the URLClassPath belonging to the given loader + */ + URLClassPath getURLClassPath (URLClassLoader u); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaNetHttpCookieAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaNetHttpCookieAccess.java new file mode 100644 index 000000000..8149a222b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaNetHttpCookieAccess.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2011, 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.misc; + +import java.net.HttpCookie; +import java.util.List; + +public interface JavaNetHttpCookieAccess { + /* + * Constructs cookies from Set-Cookie or Set-Cookie2 header string, + * retaining the original header String in the cookie itself. + */ + public List parse(String header); + + /* + * Returns the original header this cookie was consructed from, if it was + * constructed by parsing a header, otherwise null. + */ + public String header(HttpCookie cookie); +} + diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaNioAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaNioAccess.java new file mode 100644 index 000000000..e4f0a7812 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaNioAccess.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2007, 2011, 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.misc; + +import java.nio.Buffer; +import java.nio.ByteBuffer; + +public interface JavaNioAccess { + /** + * Provides access to information on buffer usage. + */ + interface BufferPool { + String getName(); + long getCount(); + long getTotalCapacity(); + long getMemoryUsed(); + } + BufferPool getDirectBufferPool(); + + /** + * Constructs a direct ByteBuffer referring to the block of memory starting + * at the given memory address and and extending {@code cap} bytes. + * The {@code ob} parameter is an arbitrary object that is attached + * to the resulting buffer. + */ + ByteBuffer newDirectByteBuffer(long addr, int cap, Object ob); + + /** + * Truncates a buffer by changing its capacity to 0. + */ + void truncate(Buffer buf); + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaSecurityAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaSecurityAccess.java new file mode 100644 index 000000000..ac305826e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaSecurityAccess.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2010, 2011, 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.misc; + +import java.security.AccessControlContext; +import java.security.PrivilegedAction; + +public interface JavaSecurityAccess { + + T doIntersectionPrivilege(PrivilegedAction action, + AccessControlContext stack, + AccessControlContext context); + + T doIntersectionPrivilege(PrivilegedAction action, + AccessControlContext context); + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaSecurityProtectionDomainAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaSecurityProtectionDomainAccess.java new file mode 100644 index 000000000..95560ffab --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaSecurityProtectionDomainAccess.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2009, 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.misc; + +import java.security.PermissionCollection; +import java.security.ProtectionDomain; + +public interface JavaSecurityProtectionDomainAccess { + interface ProtectionDomainCache { + void put(ProtectionDomain pd, PermissionCollection pc); + PermissionCollection get(ProtectionDomain pd); + } + /** + * Returns the ProtectionDomainCache. + */ + ProtectionDomainCache getProtectionDomainCache(); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaUtilJarAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaUtilJarAccess.java new file mode 100644 index 000000000..3453855d5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaUtilJarAccess.java @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2002, 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.misc; + +import java.io.IOException; +import java.net.URL; +import java.security.CodeSource; +import java.util.Enumeration; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarFile; + +public interface JavaUtilJarAccess { + public boolean jarFileHasClassPathAttribute(JarFile jar) throws IOException; + public CodeSource[] getCodeSources(JarFile jar, URL url); + public CodeSource getCodeSource(JarFile jar, URL url, String name); + public Enumeration entryNames(JarFile jar, CodeSource[] cs); + public Enumeration entries2(JarFile jar); + public void setEagerValidation(JarFile jar, boolean eager); + public List getManifestDigests(JarFile jar); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/JavaUtilZipFileAccess.java b/sources/net.sf.j2s.java.core/src/sun/misc/JavaUtilZipFileAccess.java new file mode 100644 index 000000000..0534f3400 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/JavaUtilZipFileAccess.java @@ -0,0 +1,33 @@ +/* + * 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.misc; + +import java.util.zip.ZipFile; + +public interface JavaUtilZipFileAccess { + public boolean startsWithLocHeader(ZipFile zip); +} + diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/LRUCache.java b/sources/net.sf.j2s.java.core/src/sun/misc/LRUCache.java new file mode 100644 index 000000000..8c14c174f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/LRUCache.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2003, 2011, 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.misc; + +/** + * Utility class for small LRU caches. + * + * @author Mark Reinhold + */ +public abstract class LRUCache { + + private V[] oa = null; + private final int size; + + public LRUCache(int size) { + this.size = size; + } + + abstract protected V create(N name); + + abstract protected boolean hasName(V ob, N name); + + public static void moveToFront(Object[] oa, int i) { + Object ob = oa[i]; + for (int j = i; j > 0; j--) + oa[j] = oa[j - 1]; + oa[0] = ob; + } + + public V forName(N name) { + if (oa == null) { + @SuppressWarnings("unchecked") + V[] temp = (V[])new Object[size]; + oa = temp; + } else { + for (int i = 0; i < oa.length; i++) { + V ob = oa[i]; + if (ob == null) + continue; + if (hasName(ob, name)) { + if (i > 0) + moveToFront(oa, i); + return ob; + } + } + } + + // Create a new object + V ob = create(name); + oa[oa.length - 1] = ob; + moveToFront(oa, oa.length - 1); + return ob; + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Launcher.java b/sources/net.sf.j2s.java.core/src/sun/misc/Launcher.java new file mode 100644 index 000000000..f72f60e85 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Launcher.java @@ -0,0 +1,606 @@ +/* + * Copyright (c) 1998, 2014, 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.misc; + +import java.io.File; +import java.io.IOException; +import java.io.FilePermission; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.MalformedURLException; +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; +import java.util.HashSet; +import java.util.StringTokenizer; +import java.util.Set; +import java.util.Vector; +import java.security.AccessController; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.security.AccessControlContext; +import java.security.PermissionCollection; +import java.security.Permissions; +import java.security.Permission; +import java.security.ProtectionDomain; +import java.security.CodeSource; +import sun.security.util.SecurityConstants; +import sun.net.www.ParseUtil; + +/** + * This class is used by the system to launch the main application. +Launcher */ +public class Launcher { + private static URLStreamHandlerFactory factory = new Factory(); + private static Launcher launcher = new Launcher(); + private static String bootClassPath = + System.getProperty("sun.boot.class.path"); + + public static Launcher getLauncher() { + return launcher; + } + + private ClassLoader loader; + + public Launcher() { + // Create the extension class loader + ClassLoader extcl; + try { + extcl = ExtClassLoader.getExtClassLoader(); + } catch (IOException e) { + throw new InternalError( + "Could not create extension class loader", e); + } + + // Now create the class loader to use to launch the application + try { + loader = AppClassLoader.getAppClassLoader(extcl); + } catch (IOException e) { + throw new InternalError( + "Could not create application class loader", e); + } + + // Also set the context class loader for the primordial thread. + Thread.currentThread().setContextClassLoader(loader); + + // Finally, install a security manager if requested + String s = System.getProperty("java.security.manager"); + if (s != null) { + SecurityManager sm = null; + if ("".equals(s) || "default".equals(s)) { + sm = new java.lang.SecurityManager(); + } else { + try { + sm = (SecurityManager)loader.loadClass(s).newInstance(); + } catch (IllegalAccessException e) { + } catch (InstantiationException e) { + } catch (ClassNotFoundException e) { + } catch (ClassCastException e) { + } + } + if (sm != null) { + System.setSecurityManager(sm); + } else { + throw new InternalError( + "Could not create SecurityManager: " + s); + } + } + } + + /* + * Returns the class loader used to launch the main application. + */ + public ClassLoader getClassLoader() { + return loader; + } + + /* + * The class loader used for loading installed extensions. + */ + static class ExtClassLoader extends URLClassLoader { + + static { + ClassLoader.registerAsParallelCapable(); + } + + /** + * create an ExtClassLoader. The ExtClassLoader is created + * within a context that limits which files it can read + */ + public static ExtClassLoader getExtClassLoader() throws IOException + { + final File[] dirs = getExtDirs(); + + try { + // Prior implementations of this doPrivileged() block supplied + // aa synthesized ACC via a call to the private method + // ExtClassLoader.getContext(). + + return AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public ExtClassLoader run() throws IOException { + int len = dirs.length; + for (int i = 0; i < len; i++) { + MetaIndex.registerDirectory(dirs[i]); + } + return new ExtClassLoader(dirs); + } + }); + } catch (java.security.PrivilegedActionException e) { + throw (IOException) e.getException(); + } + } + + void addExtURL(URL url) { + super.addURL(url); + } + + /* + * Creates a new ExtClassLoader for the specified directories. + */ + public ExtClassLoader(File[] dirs) throws IOException { + super(getExtURLs(dirs), null, factory); + SharedSecrets.getJavaNetAccess(). + getURLClassPath(this).initLookupCache(this); + } + + private static File[] getExtDirs() { + String s = System.getProperty("java.ext.dirs"); + File[] dirs; + if (s != null) { + StringTokenizer st = + new StringTokenizer(s, File.pathSeparator); + int count = st.countTokens(); + dirs = new File[count]; + for (int i = 0; i < count; i++) { + dirs[i] = new File(st.nextToken()); + } + } else { + dirs = new File[0]; + } + return dirs; + } + + private static URL[] getExtURLs(File[] dirs) throws IOException { + Vector urls = new Vector(); + for (int i = 0; i < dirs.length; i++) { + String[] files = dirs[i].list(); + if (files != null) { + for (int j = 0; j < files.length; j++) { + if (!files[j].equals("meta-index")) { + File f = new File(dirs[i], files[j]); + urls.add(getFileURL(f)); + } + } + } + } + URL[] ua = new URL[urls.size()]; + urls.copyInto(ua); + return ua; + } + + /* + * Searches the installed extension directories for the specified + * library name. For each extension directory, we first look for + * the native library in the subdirectory whose name is the value + * of the system property os.arch. Failing that, we + * look in the extension directory itself. + */ + public String findLibrary(String name) { + name = System.mapLibraryName(name); + URL[] urls = super.getURLs(); + File prevDir = null; + for (int i = 0; i < urls.length; i++) { + // Get the ext directory from the URL + File dir = new File(urls[i].getPath()).getParentFile(); + if (dir != null && !dir.equals(prevDir)) { + // Look in architecture-specific subdirectory first + // Read from the saved system properties to avoid deadlock + String arch = VM.getSavedProperty("os.arch"); + if (arch != null) { + File file = new File(new File(dir, arch), name); + if (file.exists()) { + return file.getAbsolutePath(); + } + } + // Then check the extension directory + File file = new File(dir, name); + if (file.exists()) { + return file.getAbsolutePath(); + } + } + prevDir = dir; + } + return null; + } + + private static AccessControlContext getContext(File[] dirs) + throws IOException + { + PathPermissions perms = + new PathPermissions(dirs); + + ProtectionDomain domain = new ProtectionDomain( + new CodeSource(perms.getCodeBase(), + (java.security.cert.Certificate[]) null), + perms); + + AccessControlContext acc = + new AccessControlContext(new ProtectionDomain[] { domain }); + + return acc; + } + } + + /** + * The class loader used for loading from java.class.path. + * runs in a restricted security context. + */ + static class AppClassLoader extends URLClassLoader { + + static { + ClassLoader.registerAsParallelCapable(); + } + + public static ClassLoader getAppClassLoader(final ClassLoader extcl) + throws IOException + { + final String s = System.getProperty("java.class.path"); + final File[] path = (s == null) ? new File[0] : getClassPath(s); + + // Note: on bugid 4256530 + // Prior implementations of this doPrivileged() block supplied + // a rather restrictive ACC via a call to the private method + // AppClassLoader.getContext(). This proved overly restrictive + // when loading classes. Specifically it prevent + // accessClassInPackage.sun.* grants from being honored. + // + return AccessController.doPrivileged( + new PrivilegedAction() { + public AppClassLoader run() { + URL[] urls = + (s == null) ? new URL[0] : pathToURLs(path); + return new AppClassLoader(urls, extcl); + } + }); + } + + final URLClassPath ucp; + + /* + * Creates a new AppClassLoader + */ + AppClassLoader(URL[] urls, ClassLoader parent) { + super(urls, parent, factory); + ucp = SharedSecrets.getJavaNetAccess().getURLClassPath(this); + ucp.initLookupCache(this); + } + + /** + * Override loadClass so we can checkPackageAccess. + */ + public Class loadClass(String name, boolean resolve) + throws ClassNotFoundException + { + int i = name.lastIndexOf('.'); + if (i != -1) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + sm.checkPackageAccess(name.substring(0, i)); + } + } + + if (ucp.knownToNotExist(name)) { + // The class of the given name is not found in the parent + // class loader as well as its local URLClassPath. + // Check if this class has already been defined dynamically; + // if so, return the loaded class; otherwise, skip the parent + // delegation and findClass. + Class c = findLoadedClass(name); + if (c != null) { + if (resolve) { + resolveClass(c); + } + return c; + } + throw new ClassNotFoundException(name); + } + + return (super.loadClass(name, resolve)); + } + + /** + * allow any classes loaded from classpath to exit the VM. + */ + protected PermissionCollection getPermissions(CodeSource codesource) + { + PermissionCollection perms = super.getPermissions(codesource); + perms.add(new RuntimePermission("exitVM")); + return perms; + } + + /** + * This class loader supports dynamic additions to the class path + * at runtime. + * + * @see java.lang.instrument.Instrumentation#appendToSystemClassPathSearch + */ + private void appendToClassPathForInstrumentation(String path) { + assert(Thread.holdsLock(this)); + + // addURL is a no-op if path already contains the URL + super.addURL( getFileURL(new File(path)) ); + } + + /** + * create a context that can read any directories (recursively) + * mentioned in the class path. In the case of a jar, it has to + * be the directory containing the jar, not just the jar, as jar + * files might refer to other jar files. + */ + + private static AccessControlContext getContext(File[] cp) + throws java.net.MalformedURLException + { + PathPermissions perms = + new PathPermissions(cp); + + ProtectionDomain domain = + new ProtectionDomain(new CodeSource(perms.getCodeBase(), + (java.security.cert.Certificate[]) null), + perms); + + AccessControlContext acc = + new AccessControlContext(new ProtectionDomain[] { domain }); + + return acc; + } + } + + private static class BootClassPathHolder { + static final URLClassPath bcp; + static { + URL[] urls; + if (bootClassPath != null) { + urls = AccessController.doPrivileged( + new PrivilegedAction() { + public URL[] run() { + File[] classPath = getClassPath(bootClassPath); + int len = classPath.length; + Set seenDirs = new HashSet(); + for (int i = 0; i < len; i++) { + File curEntry = classPath[i]; + // Negative test used to properly handle + // nonexistent jars on boot class path + if (!curEntry.isDirectory()) { + curEntry = curEntry.getParentFile(); + } + if (curEntry != null && seenDirs.add(curEntry)) { + MetaIndex.registerDirectory(curEntry); + } + } + return pathToURLs(classPath); + } + } + ); + } else { + urls = new URL[0]; + } + bcp = new URLClassPath(urls, factory); + bcp.initLookupCache(null); + } + } + + public static URLClassPath getBootstrapClassPath() { + return BootClassPathHolder.bcp; + } + + private static URL[] pathToURLs(File[] path) { + URL[] urls = new URL[path.length]; + for (int i = 0; i < path.length; i++) { + urls[i] = getFileURL(path[i]); + } + // DEBUG + //for (int i = 0; i < urls.length; i++) { + // System.out.println("urls[" + i + "] = " + '"' + urls[i] + '"'); + //} + return urls; + } + + private static File[] getClassPath(String cp) { + File[] path; + if (cp != null) { + int count = 0, maxCount = 1; + int pos = 0, lastPos = 0; + // Count the number of separators first + while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) { + maxCount++; + lastPos = pos + 1; + } + path = new File[maxCount]; + lastPos = pos = 0; + // Now scan for each path component + while ((pos = cp.indexOf(File.pathSeparator, lastPos)) != -1) { + if (pos - lastPos > 0) { + path[count++] = new File(cp.substring(lastPos, pos)); + } else { + // empty path component translates to "." + path[count++] = new File("."); + } + lastPos = pos + 1; + } + // Make sure we include the last path component + if (lastPos < cp.length()) { + path[count++] = new File(cp.substring(lastPos)); + } else { + path[count++] = new File("."); + } + // Trim array to correct size + if (count != maxCount) { + File[] tmp = new File[count]; + System.arraycopy(path, 0, tmp, 0, count); + path = tmp; + } + } else { + path = new File[0]; + } + // DEBUG + //for (int i = 0; i < path.length; i++) { + // System.out.println("path[" + i + "] = " + '"' + path[i] + '"'); + //} + return path; + } + + private static URLStreamHandler fileHandler; + + static URL getFileURL(File file) { + try { + file = file.getCanonicalFile(); + } catch (IOException e) {} + + try { + return ParseUtil.fileToEncodedURL(file); + } catch (MalformedURLException e) { + // Should never happen since we specify the protocol... + throw new InternalError(e); + } + } + + /* + * The stream handler factory for loading system protocol handlers. + */ + private static class Factory implements URLStreamHandlerFactory { + private static String PREFIX = "sun.net.www.protocol"; + + public URLStreamHandler createURLStreamHandler(String protocol) { + String name = PREFIX + "." + protocol + ".Handler"; + try { + Class c = Class.forName(name); + return (URLStreamHandler)c.newInstance(); + } catch (ReflectiveOperationException e) { + throw new InternalError("could not load " + protocol + + "system protocol handler", e); + } + } + } +} + +class PathPermissions extends PermissionCollection { + // use serialVersionUID from JDK 1.2.2 for interoperability + private static final long serialVersionUID = 8133287259134945693L; + + private File path[]; + private Permissions perms; + + URL codeBase; + + PathPermissions(File path[]) + { + this.path = path; + this.perms = null; + this.codeBase = null; + } + + URL getCodeBase() + { + return codeBase; + } + + public void add(java.security.Permission permission) { + throw new SecurityException("attempt to add a permission"); + } + + private synchronized void init() + { + if (perms != null) + return; + + perms = new Permissions(); + + // this is needed to be able to create the classloader itself! + perms.add(SecurityConstants.CREATE_CLASSLOADER_PERMISSION); + + // add permission to read any "java.*" property + perms.add(new java.util.PropertyPermission("java.*", + SecurityConstants.PROPERTY_READ_ACTION)); + + AccessController.doPrivileged(new PrivilegedAction() { + public Void run() { + for (int i=0; i < path.length; i++) { + File f = path[i]; + String path; + try { + path = f.getCanonicalPath(); + } catch (IOException ioe) { + path = f.getAbsolutePath(); + } + if (i == 0) { + codeBase = Launcher.getFileURL(new File(path)); + } + if (f.isDirectory()) { + if (path.endsWith(File.separator)) { + perms.add(new FilePermission(path+"-", + SecurityConstants.FILE_READ_ACTION)); + } else { + perms.add(new FilePermission( + path + File.separator+"-", + SecurityConstants.FILE_READ_ACTION)); + } + } else { + int endIndex = path.lastIndexOf(File.separatorChar); + if (endIndex != -1) { + path = path.substring(0, endIndex+1) + "-"; + perms.add(new FilePermission(path, + SecurityConstants.FILE_READ_ACTION)); + } else { + // XXX? + } + } + } + return null; + } + }); + } + + public boolean implies(java.security.Permission permission) { + if (perms == null) + init(); + return perms.implies(permission); + } + + public java.util.Enumeration elements() { + if (perms == null) + init(); + synchronized (perms) { + return perms.elements(); + } + } + + public String toString() { + if (perms == null) + init(); + return perms.toString(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Lock.java b/sources/net.sf.j2s.java.core/src/sun/misc/Lock.java new file mode 100644 index 000000000..7dc7b5b68 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Lock.java @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1994, 2005, 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.misc; + +/** + * The Lock class provides a simple, useful interface to a lock. + * Unlike monitors which synchronize access to an object, locks + * synchronize access to an arbitrary set of resources (objects, + * methods, variables, etc.).

      + * + * The programmer using locks must be responsible for clearly defining + * the semantics of their use and should handle deadlock avoidance in + * the face of exceptions.

      + * + * For example, if you want to protect a set of method invocations with + * a lock, and one of the methods may throw an exception, you must be + * prepared to release the lock similarly to the following example: + *

      + *      class SomeClass {
      + *          Lock myLock = new Lock();
      +
      + *          void someMethod() {
      + *              myLock.lock();
      + *              try {
      + *                  StartOperation();
      + *                  ContinueOperation();
      + *                  EndOperation();
      + *              } finally {
      + *                  myLock.unlock();
      + *              }
      + *          }
      + *      }
      + * 
      + * + * @author Peter King + */ +public +class Lock { + private boolean locked = false; + + /** + * Create a lock, which is initially not locked. + */ + public Lock () { + } + + /** + * Acquire the lock. If someone else has the lock, wait until it + * has been freed, and then try to acquire it again. This method + * will not return until the lock has been acquired. + * + * @exception java.lang.InterruptedException if any thread has + * interrupted this thread. + */ + public final synchronized void lock() throws InterruptedException { + while (locked) { + wait(); + } + locked = true; + } + + /** + * Release the lock. If someone else is waiting for the lock, the + * will be notitified so they can try to acquire the lock again. + */ + public final synchronized void unlock() { + locked = false; + notifyAll(); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/NativeSignalHandler.java b/sources/net.sf.j2s.java.core/src/sun/misc/NativeSignalHandler.java new file mode 100644 index 000000000..39c68c29b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/NativeSignalHandler.java @@ -0,0 +1,47 @@ +/* + * Copyright (c) 1998, 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.misc; + +/* A package-private class implementing a signal handler in native code. */ + +final class NativeSignalHandler implements SignalHandler { + + private final long handler; + + long getHandler() { + return handler; + } + + NativeSignalHandler(long handler) { + this.handler = handler; + } + + public void handle(Signal sig) { + handle0(sig.getNumber(), handler); + } + + private static native void handle0(int number, long handler); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Perf.java b/sources/net.sf.j2s.java.core/src/sun/misc/Perf.java new file mode 100644 index 000000000..09b507212 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Perf.java @@ -0,0 +1,539 @@ +/* + * Copyright (c) 2002, 2006, 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.misc; + +import java.nio.ByteBuffer; +import java.security.Permission; +import java.security.PrivilegedAction; +import java.io.IOException; +import java.io.UnsupportedEncodingException; + +/** + * The Perf class provides the ability to attach to an instrumentation + * buffer maintained by a Java virtual machine. The instrumentation + * buffer may be for the Java virtual machine running the methods of + * this class or it may be for another Java virtual machine on the + * same system. + *

      + * In addition, this class provides methods to create instrumentation + * objects in the instrumentation buffer for the Java virtual machine + * that is running these methods. It also contains methods for acquiring + * the value of a platform specific high resolution clock for time + * stamp and interval measurement purposes. + * + * @author Brian Doherty + * @since 1.4.2 + * @see #getPerf + * @see sun.misc.Perf$GetPerfAction + * @see java.nio.ByteBuffer + */ +public final class Perf { +// +// private static Perf instance; +// +// private static final int PERF_MODE_RO = 0; +// private static final int PERF_MODE_RW = 1; +// +// private Perf() { } // prevent instantiation +// +// /** +// * The GetPerfAction class is a convenience class for acquiring access +// * to the singleton Perf instance using the +// * AccessController.doPrivileged() method. +// *

      +// * An instance of this class can be used as the argument to +// * AccessController.doPrivileged(PrivilegedAction). +// *

      Here is a suggested idiom for use of this class: +// * +// *

      +//     * class MyTrustedClass {
      +//     *   private static final Perf perf =
      +//     *       AccessController.doPrivileged(new Perf.GetPerfAction());
      +//     *   ...
      +//     * }
      +//     * 
      +// *

      +// * In the presence of a security manager, the MyTrustedClass +// * class in the above example will need to be granted the +// * "sun.misc.Perf.getPerf" RuntimePermission +// * permission in order to successfully acquire the singleton Perf instance. +// *

      +// * Please note that the "sun.misc.Perf.getPerf" permission +// * is not a JDK specified permission. +// * +// * @see java.security.AccessController#doPrivileged(PrivilegedAction) +// * @see java.lang.RuntimePermission +// */ +// public static class GetPerfAction implements PrivilegedAction +// { +// /** +// * Run the Perf.getPerf() method in a privileged context. +// * +// * @see #getPerf +// */ +// public Perf run() { +// return getPerf(); +// } +// } +// +// /** +// * Return a reference to the singleton Perf instance. +// *

      +// * The getPerf() method returns the singleton instance of the Perf +// * class. The returned object provides the caller with the capability +// * for accessing the instrumentation buffer for this or another local +// * Java virtual machine. +// *

      +// * If a security manager is installed, its checkPermission +// * method is called with a RuntimePermission with a target +// * of "sun.misc.Perf.getPerf". A security exception will result +// * if the caller has not been granted this permission. +// *

      +// * Access to the returned Perf object should be protected +// * by its caller and not passed on to untrusted code. This object can +// * be used to attach to the instrumentation buffer provided by this Java +// * virtual machine or for those of other Java virtual machines running +// * on the same system. The instrumentation buffer may contain senstitive +// * information. API's built on top of this interface may want to provide +// * finer grained access control to the contents of individual +// * instrumentation objects contained within the buffer. +// *

      +// * Please note that the "sun.misc.Perf.getPerf" permission +// * is not a JDK specified permission. +// * +// * @return A reference to the singleton Perf instance. +// * @throws AccessControlException if a security manager exists and +// * its checkPermission method doesn't allow +// * access to the "sun.misc.Perf.getPerf" target. +// * @see java.lang.RuntimePermission +// * @see #attach +// */ +// public static Perf getPerf() +// { +// SecurityManager security = System.getSecurityManager(); +// if (security != null) { +// Permission perm = new RuntimePermission("sun.misc.Perf.getPerf"); +// security.checkPermission(perm); +// } +// +// return instance; +// } +// +// /** +// * Attach to the instrumentation buffer for the specified Java virtual +// * machine. +// *

      +// * This method will attach to the instrumentation buffer for the +// * specified virtual machine. It returns a ByteBuffer object +// * that is initialized to access the instrumentation buffer for the +// * indicated Java virtual machine. The lvmid parameter is +// * a integer value that uniquely identifies the target local Java virtual +// * machine. It is typically, but not necessarily, the process id of +// * the target Java virtual machine. +// *

      +// * If the lvmid identifies a Java virtual machine different +// * from the one running this method, then the coherency characteristics +// * of the buffer are implementation dependent. Implementations that do +// * not support named, coherent, shared memory may return a +// * ByteBuffer object that contains only a snap shot of the +// * data in the instrumentation buffer. Implementations that support named, +// * coherent, shared memory, may return a ByteBuffer object +// * that will be changing dynamically over time as the target Java virtual +// * machine updates its mapping of this buffer. +// *

      +// * If the lvmid is 0 or equal to the actual lvmid +// * for the Java virtual machine running this method, then the returned +// * ByteBuffer object will always be coherent and dynamically +// * changing. +// *

      +// * The attach mode specifies the access permissions requested for the +// * instrumentation buffer of the target virtual machine. The permitted +// * access permissions are: +// *

      +// * +// *

    • "r" - Read only access. This Java virtual machine has only +// * read access to the instrumentation buffer for the target Java +// * virtual machine. +// *
    • "rw" - Read/Write access. This Java virtual machine has read and +// * write access to the instrumentation buffer for the target Java virtual +// * machine. This mode is currently not supported and is reserved for +// * future enhancements. +// * +// * +// * @param lvmid an integer that uniquely identifies the +// * target local Java virtual machine. +// * @param mode a string indicating the attach mode. +// * @return ByteBuffer a direct allocated byte buffer +// * @throws IllegalArgumentException The lvmid or mode was invalid. +// * @throws IOException An I/O error occurred while trying to acquire +// * the instrumentation buffer. +// * @throws OutOfMemoryError The instrumentation buffer could not be mapped +// * into the virtual machine's address space. +// * @see java.nio.ByteBuffer +// */ +// public ByteBuffer attach(int lvmid, String mode) +// throws IllegalArgumentException, IOException +// { +// if (mode.compareTo("r") == 0) { +// return attachImpl(null, lvmid, PERF_MODE_RO); +// } +// else if (mode.compareTo("rw") == 0) { +// return attachImpl(null, lvmid, PERF_MODE_RW); +// } +// else { +// throw new IllegalArgumentException("unknown mode"); +// } +// } +// +// /** +// * Attach to the instrumentation buffer for the specified Java virtual +// * machine owned by the given user. +// *

      +// * This method behaves just as the attach(int lvmid, String mode) +// * method, except that it only searches for Java virtual machines +// * owned by the specified user. +// * +// * @param user A String object containing the +// * name of the user that owns the target Java +// * virtual machine. +// * @param lvmid an integer that uniquely identifies the +// * target local Java virtual machine. +// * @param mode a string indicating the attach mode. +// * @return ByteBuffer a direct allocated byte buffer +// * @throws IllegalArgumentException The lvmid or mode was invalid. +// * @throws IOException An I/O error occurred while trying to acquire +// * the instrumentation buffer. +// * @throws OutOfMemoryError The instrumentation buffer could not be mapped +// * into the virtual machine's address space. +// * @see java.nio.ByteBuffer +// */ +// public ByteBuffer attach(String user, int lvmid, String mode) +// throws IllegalArgumentException, IOException +// { +// if (mode.compareTo("r") == 0) { +// return attachImpl(user, lvmid, PERF_MODE_RO); +// } +// else if (mode.compareTo("rw") == 0) { +// return attachImpl(user, lvmid, PERF_MODE_RW); +// } +// else { +// throw new IllegalArgumentException("unknown mode"); +// } +// } +// +//// /** +//// * Call the implementation specific attach method. +//// *

      +//// * This method calls into the Java virtual machine to perform the platform +//// * specific attach method. Buffers returned from this method are +//// * internally managed as PhantomRefereces to provide for +//// * guaranteed, secure release of the native resources. +//// * +//// * @param user A String object containing the +//// * name of the user that owns the target Java +//// * virtual machine. +//// * @param lvmid an integer that uniquely identifies the +//// * target local Java virtual machine. +//// * @param mode a string indicating the attach mode. +//// * @return ByteBuffer a direct allocated byte buffer +//// * @throws IllegalArgumentException The lvmid or mode was invalid. +//// * @throws IOException An I/O error occurred while trying to acquire +//// * the instrumentation buffer. +//// * @throws OutOfMemoryError The instrumentation buffer could not be mapped +//// * into the virtual machine's address space. +//// */ +//// private ByteBuffer attachImpl(String user, int lvmid, int mode) +//// throws IllegalArgumentException, IOException +//// { +//// final ByteBuffer b = attach(user, lvmid, mode); +//// +//// if (lvmid == 0) { +//// // The native instrumentation buffer for this Java virtual +//// // machine is never unmapped. +//// return b; +//// } +//// else { +//// // This is an instrumentation buffer for another Java virtual +//// // machine with native resources that need to be managed. We +//// // create a duplicate of the native ByteBuffer and manage it +//// // with a Cleaner object (PhantomReference). When the duplicate +//// // becomes only phantomly reachable, the native resources will +//// // be released. +//// +//// final ByteBuffer dup = b.duplicate(); +//// Cleaner.create(dup, new Runnable() { +//// public void run() { +//// try { +//// instance.detach(b); +//// } +//// catch (Throwable th) { +//// // avoid crashing the reference handler thread, +//// // but provide for some diagnosability +//// assert false : th.toString(); +//// } +//// } +//// }); +//// return dup; +//// } +//// } +//// +// /** +// * Native method to perform the implementation specific attach mechanism. +// *

      +// * The implementation of this method may return distinct or identical +// * ByteBuffer objects for two distinct calls requesting +// * attachment to the same Java virtual machine. +// *

      +// * For the Sun HotSpot JVM, two distinct calls to attach to the same +// * target Java virtual machine will result in two distinct ByteBuffer +// * objects returned by this method. This may change in a future release. +// * +// * @param user A String object containing the +// * name of the user that owns the target Java +// * virtual machine. +// * @param lvmid an integer that uniquely identifies the +// * target local Java virtual machine. +// * @param mode a string indicating the attach mode. +// * @return ByteBuffer a direct allocated byte buffer +// * @throws IllegalArgumentException The lvmid or mode was invalid. +// * @throws IOException An I/O error occurred while trying to acquire +// * the instrumentation buffer. +// * @throws OutOfMemoryError The instrumentation buffer could not be mapped +// * into the virtual machine's address space. +// */ +// private native ByteBuffer attach(String user, int lvmid, int mode) +// throws IllegalArgumentException, IOException; +// +// /** +// * Native method to perform the implementation specific detach mechanism. +// *

      +// * If this method is passed a ByteBuffer object that is +// * not created by the attach method, then the results of +// * this method are undefined, with unpredictable and potentially damaging +// * effects to the Java virtual machine. To prevent accidental or malicious +// * use of this method, all native ByteBuffer created by the +// * attach method are managed internally as PhantomReferences +// * and resources are freed by the system. +// *

      +// * If this method is passed a ByteBuffer object created +// * by the attach method with a lvmid for the Java virtual +// * machine running this method (lvmid=0, for example), then the detach +// * request is silently ignored. +// * +// * @param ByteBuffer A direct allocated byte buffer created by the +// * attach method. +// * @see java.nio.ByteBuffer +// * @see #attach +// */ +// private native void detach(ByteBuffer bb); +// +// /** +// * Create a long scalar entry in the instrumentation buffer +// * with the given variability characteristic, units, and initial value. +// *

      +// * Access to the instrument is provided through the returned +// * ByteBuffer object. Typically, this object should be wrapped +// * with LongBuffer view object. +// * +// * @param variability the variability characteristic for this entry. +// * @param units the units for this entry. +// * @param name the name of this entry. +// * @param value the initial value for this entry. +// * @return ByteBuffer a direct allocated ByteBuffer object that +// * allows write access to a native memory location +// * containing a long value. +// * +// * see sun.misc.perf.Variability +// * see sun.misc.perf.Units +// * @see java.nio.ByteBuffer +// */ +// public native ByteBuffer createLong(String name, int variability, +// int units, long value); +// +// /** +// * Create a String entry in the instrumentation buffer with +// * the given variability characteristic, units, and initial value. +// *

      +// * The maximum length of the String stored in this string +// * instrument is given in by maxLength parameter. Updates +// * to this instrument with String values with lengths greater +// * than maxLength will be truncated to maxLength. +// * The truncated value will be terminated by a null character. +// *

      +// * The underlying implementation may further limit the length of the +// * value, but will continue to preserve the null terminator. +// *

      +// * Access to the instrument is provided through the returned +// * ByteBuffer object. +// * +// * @param variability the variability characteristic for this entry. +// * @param units the units for this entry. +// * @param name the name of this entry. +// * @param value the initial value for this entry. +// * @param maxLength the maximum string length for this string +// * instrument. +// * @return ByteBuffer a direct allocated ByteBuffer that allows +// * write access to a native memory location +// * containing a long value. +// * +// * see sun.misc.perf.Variability +// * see sun.misc.perf.Units +// * @see java.nio.ByteBuffer +// */ +// public ByteBuffer createString(String name, int variability, +// int units, String value, int maxLength) +// { +// byte[] v = getBytes(value); +// byte[] v1 = new byte[v.length+1]; +// System.arraycopy(v, 0, v1, 0, v.length); +// v1[v.length] = '\0'; +// return createByteArray(name, variability, units, v1, Math.max(v1.length, maxLength)); +// } +// +// /** +// * Create a String entry in the instrumentation buffer with +// * the given variability characteristic, units, and initial value. +// *

      +// * The maximum length of the String stored in this string +// * instrument is implied by the length of the value parameter. +// * Subsequent updates to the value of this instrument will be truncated +// * to this implied maximum length. The truncated value will be terminated +// * by a null character. +// *

      +// * The underlying implementation may further limit the length of the +// * initial or subsequent value, but will continue to preserve the null +// * terminator. +// *

      +// * Access to the instrument is provided through the returned +// * ByteBuffer object. +// * +// * @param variability the variability characteristic for this entry. +// * @param units the units for this entry. +// * @param name the name of this entry. +// * @param value the initial value for this entry. +// * @return ByteBuffer a direct allocated ByteBuffer that allows +// * write access to a native memory location +// * containing a long value. +// * +// * see sun.misc.perf.Variability +// * see sun.misc.perf.Units +// * @see java.nio.ByteBuffer +// */ +// public ByteBuffer createString(String name, int variability, +// int units, String value) +// { +// byte[] v = getBytes(value); +// byte[] v1 = new byte[v.length+1]; +// System.arraycopy(v, 0, v1, 0, v.length); +// v1[v.length] = '\0'; +// return createByteArray(name, variability, units, v1, v1.length); +// } +// +// /** +// * Create a byte vector entry in the instrumentation buffer +// * with the given variability characteristic, units, and initial value. +// *

      +// * The maxLength parameter limits the size of the byte +// * array instrument such that the initial or subsequent updates beyond +// * this length are silently ignored. No special handling of truncated +// * updates is provided. +// *

      +// * The underlying implementation may further limit the length of the +// * length of the initial or subsequent value. +// *

      +// * Access to the instrument is provided through the returned +// * ByteBuffer object. +// * +// * @param variability the variability characteristic for this entry. +// * @param units the units for this entry. +// * @param name the name of this entry. +// * @param value the initial value for this entry. +// * @param maxLength the maximum length of this byte array. +// * @return ByteBuffer a direct allocated byte buffer that allows +// * write access to a native memory location +// * containing a long value. +// * +// * see sun.misc.perf.Variability +// * see sun.misc.perf.Units +// * @see java.nio.ByteBuffer +// */ +// public native ByteBuffer createByteArray(String name, int variability, +// int units, byte[] value, +// int maxLength); +// +// +// /** +// * convert string to an array of UTF-8 bytes +// */ +// private static byte[] getBytes(String s) +// { +// byte[] bytes = null; +// +// try { +// bytes = s.getBytes("UTF-8"); +// } +// catch (UnsupportedEncodingException e) { +// // ignore, UTF-8 encoding is always known +// } +// +// return bytes; +// } +// +// /** +// * Return the value of the High Resolution Counter. +// * +// * The High Resolution Counter returns the number of ticks since +// * since the start of the Java virtual machine. The resolution of +// * the counter is machine dependent and can be determined from the +// * value return by the {@link #highResFrequency} method. +// * +// * @return the number of ticks of machine dependent resolution since +// * the start of the Java virtual machine. +// * +// * @see #highResFrequency +// * @see java.lang.System#currentTimeMillis() +// */ +// public native long highResCounter(); +// +// /** +// * Returns the frequency of the High Resolution Counter, in ticks per +// * second. +// * +// * This value can be used to convert the value of the High Resolution +// * Counter, as returned from a call to the {@link #highResCounter} method, +// * into the number of seconds since the start of the Java virtual machine. +// * +// * @return the frequency of the High Resolution Counter. +// * @see #highResCounter +// */ +// public native long highResFrequency(); +// +// private static native void registerNatives(); +// +// static { +// registerNatives(); +// instance = new Perf(); +// } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/PerfCounter.java b/sources/net.sf.j2s.java.core/src/sun/misc/PerfCounter.java new file mode 100644 index 000000000..cf00f459d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/PerfCounter.java @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2009, 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.misc; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.nio.LongBuffer; +import java.security.AccessController; + +/** + * Performance counter support for internal JRE classes. + * This class defines a fixed list of counters for the platform + * to use as an interim solution until RFE# 6209222 is implemented. + * The perf counters will be created in the jvmstat perf buffer + * that the HotSpot VM creates. The default size is 32K and thus + * the number of counters is bounded. You can alter the size + * with -XX:PerfDataMemorySize= option. If there is + * insufficient memory in the jvmstat perf buffer, the C heap memory + * will be used and thus the application will continue to run if + * the counters added exceeds the buffer size but the counters + * will be missing. + * + * See HotSpot jvmstat implementation for certain circumstances + * that the jvmstat perf buffer is not supported. + * + */ +public class PerfCounter { +// private static final Perf perf = +// AccessController.doPrivileged(new Perf.GetPerfAction()); +// +// // Must match values defined in hotspot/src/share/vm/runtime/perfdata.hpp +// private final static int V_Constant = 1; +// private final static int V_Monotonic = 2; +// private final static int V_Variable = 3; +// private final static int U_None = 1; +// +// private final String name; +// private long lb; +// +// private PerfCounter(String name, int type) { +// this.name = name; +// ByteBuffer bb = perf.createLong(name, type, U_None, 0L); +// bb.order(ByteOrder.nativeOrder()); +// this.lb = System.currentTimeMillis();//bb.asLongBuffer(); +// } +// +// static PerfCounter newPerfCounter(String name) { +// return new PerfCounter(name, V_Variable); +// } +// +// static PerfCounter newConstantPerfCounter(String name) { +// PerfCounter c = new PerfCounter(name, V_Constant); +// return c; +// } +// +// /** +// * Returns the current value of the perf counter. +// */ +// public synchronized long get() { +// return lb;//; +// } +// +// /** +// * Sets the value of the perf counter to the given newValue. +// */ +// public synchronized void set(long newValue) { +// lb = newValue;//.put(0, newValue); +// } +// +// /** +// * Adds the given value to the perf counter. +// */ +// public synchronized void add(long value) { +// long res = get() + value; +// lb = res;//.put(0, res); +// } +// +// /** +// * Increments the perf counter with 1. +// */ +// public void increment() { +// add(1); +// } +// +// /** +// * Adds the given interval to the perf counter. +// */ +// public void addTime(long interval) { +// add(interval); +// } +// +// /** +// * Adds the elapsed time from the given start time (ns) to the perf counter. +// */ +// public void addElapsedTimeFrom(long startTime) { +// add(System.nanoTime() - startTime); +// } +// +// @Override +// public String toString() { +// return name + " = " + get(); +// } +// +// static class CoreCounters { +// static final PerfCounter pdt = newPerfCounter("sun.classloader.parentDelegationTime"); +// static final PerfCounter lc = newPerfCounter("sun.classloader.findClasses"); +// static final PerfCounter lct = newPerfCounter("sun.classloader.findClassTime"); +// static final PerfCounter rcbt = newPerfCounter("sun.urlClassLoader.readClassBytesTime"); +// static final PerfCounter zfc = newPerfCounter("sun.zip.zipFiles"); +// static final PerfCounter zfot = newPerfCounter("sun.zip.zipFile.openTime"); +// } +// +// static class WindowsClientCounters { +// static final PerfCounter d3dAvailable = newConstantPerfCounter("sun.java2d.d3d.available"); +// } +// +// /** +// * Number of findClass calls +// */ +// public static PerfCounter getFindClasses() { +// return CoreCounters.lc; +// } +// +// /** +// * Time (ns) spent in finding classes that includes +// * lookup and read class bytes and defineClass +// */ +// public static PerfCounter getFindClassTime() { +// return CoreCounters.lct; +// } +// +// /** +// * Time (ns) spent in finding classes +// */ +// public static PerfCounter getReadClassBytesTime() { +// return CoreCounters.rcbt; +// } +// +// /** +// * Time (ns) spent in the parent delegation to +// * the parent of the defining class loader +// */ +// public static PerfCounter getParentDelegationTime() { +// return CoreCounters.pdt; +// } +// +// /** +// * Number of zip files opened. +// */ +// public static PerfCounter getZipFileCount() { +// return CoreCounters.zfc; +// } +// +// /** +// * Time (ns) spent in opening the zip files that +// * includes building the entries hash table +// */ +// public static PerfCounter getZipFileOpenTime() { +// return CoreCounters.zfot; +// } +// +// /** +// * D3D graphic pipeline available +// */ +// public static PerfCounter getD3DAvailable() { +// return WindowsClientCounters.d3dAvailable; +// } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/PerformanceLogger.java b/sources/net.sf.j2s.java.core/src/sun/misc/PerformanceLogger.java new file mode 100644 index 000000000..9f4a9e490 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/PerformanceLogger.java @@ -0,0 +1,315 @@ +/* + * Copyright (c) 2002, 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.misc; + +import java.util.Vector; +import java.io.FileWriter; +import java.io.File; +import java.io.OutputStreamWriter; +import java.io.Writer; + +/** + * This class is intended to be a central place for the jdk to + * log timing events of interest. There is pre-defined event + * of startTime, as well as a general + * mechanism of setting arbitrary times in an array. + * All unreserved times in the array can be used by callers + * in application-defined situations. The caller is responsible + * for setting and getting all times and for doing whatever + * analysis is interesting; this class is merely a central container + * for those timing values. + * Note that, due to the variables in this class being static, + * use of particular time values by multiple applets will cause + * confusing results. For example, if plugin runs two applets + * simultaneously, the initTime for those applets will collide + * and the results may be undefined. + *

      + * To automatically track startup performance in an app or applet, + * use the command-line parameter sun.perflog as follows:
      + * -Dsun.perflog[=file:] + *
      + * where simply using the parameter with no value will enable output + * to the console and a value of "file:" will cause + * that given filename to be created and used for all output. + *

      + * By default, times are measured using System.currentTimeMillis(). To use + * System.nanoTime() instead, add the command-line parameter:
      + -Dsun.perflog.nano=true + *
      + *

      + * Warning: Use at your own risk! + * This class is intended for internal testing + * purposes only and may be removed at any time. More + * permanent monitoring and profiling APIs are expected to be + * developed for future releases and this class will cease to + * exist once those APIs are in place. + * @author Chet Haase + */ +public class PerformanceLogger { + + // Timing values of global interest + private static final int START_INDEX = 0; // VM start + private static final int LAST_RESERVED = START_INDEX; + + private static boolean perfLoggingOn = false; + private static boolean useNanoTime = false; + private static Vector times; + private static String logFileName = null; + private static Writer logWriter = null; + private static long baseTime; + + static { + String perfLoggingProp = + java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("sun.perflog")); + if (perfLoggingProp != null) { + perfLoggingOn = true; + + // Check if we should use nanoTime + String perfNanoProp = + java.security.AccessController.doPrivileged( + new sun.security.action.GetPropertyAction("sun.perflog.nano")); + if (perfNanoProp != null) { + useNanoTime = true; + } + + // Now, figure out what the user wants to do with the data + if (perfLoggingProp.regionMatches(true, 0, "file:", 0, 5)) { + logFileName = perfLoggingProp.substring(5); + } + if (logFileName != null) { + if (logWriter == null) { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + try { + File logFile = new File(logFileName); + logFile.createNewFile(); + logWriter = new FileWriter(logFile); + } catch (Exception e) { + System.out.println(e + ": Creating logfile " + + logFileName + + ". Log to console"); + } + return null; + } + }); + } + } + if (logWriter == null) { + logWriter = new OutputStreamWriter(System.out); + } + } + times = new Vector(10); + // Reserve predefined slots + for (int i = 0; i <= LAST_RESERVED; ++i) { + times.add(new TimeData("Time " + i + " not set", 0)); + } + } + + /** + * Returns status of whether logging is enabled or not. This is + * provided as a convenience method so that users do not have to + * perform the same GetPropertyAction check as above to determine whether + * to enable performance logging. + */ + public static boolean loggingEnabled() { + return perfLoggingOn; + } + + + /** + * Internal class used to store time/message data together. + */ + static class TimeData { + String message; + long time; + + TimeData(String message, long time) { + this.message = message; + this.time = time; + } + + String getMessage() { + return message; + } + + long getTime() { + return time; + } + } + + /** + * Return the current time, in millis or nanos as appropriate + */ + private static long getCurrentTime() { + if (useNanoTime) { + return System.nanoTime(); + } else { + return System.currentTimeMillis(); + } + } + + /** + * Sets the start time. Ideally, this is the earliest time available + * during the startup of a Java applet or application. This time is + * later used to analyze the difference between the initial startup + * time and other events in the system (such as an applet's init time). + */ + public static void setStartTime(String message) { + if (loggingEnabled()) { + long nowTime = getCurrentTime(); + setStartTime(message, nowTime); + } + } + + /** + * Sets the base time, output can then + * be displayed as offsets from the base time;. + */ + public static void setBaseTime(long time) { + if (loggingEnabled()) { + baseTime = time; + } + } + + /** + * Sets the start time. + * This version of the method is + * given the time to log, instead of expecting this method to + * get the time itself. This is done in case the time was + * recorded much earlier than this method was called. + */ + public static void setStartTime(String message, long time) { + if (loggingEnabled()) { + times.set(START_INDEX, new TimeData(message, time)); + } + } + + /** + * Gets the start time, which should be the time when + * the java process started, prior to the VM actually being + * loaded. + */ + public static long getStartTime() { + if (loggingEnabled()) { + return times.get(START_INDEX).getTime(); + } else { + return 0; + } + } + + /** + * Sets the value of a given time and returns the index of the + * slot that that time was stored in. + */ + public static int setTime(String message) { + if (loggingEnabled()) { + long nowTime = getCurrentTime(); + return setTime(message, nowTime); + } else { + return 0; + } + } + + /** + * Sets the value of a given time and returns the index of the + * slot that that time was stored in. + * This version of the method is + * given the time to log, instead of expecting this method to + * get the time itself. This is done in case the time was + * recorded much earlier than this method was called. + */ + public static int setTime(String message, long time) { + if (loggingEnabled()) { + // times is already synchronized, but we need to ensure that + // the size used in times.set() is the same used when returning + // the index of that operation. + synchronized (times) { + times.add(new TimeData(message, time)); + return (times.size() - 1); + } + } else { + return 0; + } + } + + /** + * Returns time at given index. + */ + public static long getTimeAtIndex(int index) { + if (loggingEnabled()) { + return times.get(index).getTime(); + } else { + return 0; + } + } + + /** + * Returns message at given index. + */ + public static String getMessageAtIndex(int index) { + if (loggingEnabled()) { + return times.get(index).getMessage(); + } else { + return null; + } + } + + /** + * Outputs all data to parameter-specified Writer object + */ + public static void outputLog(Writer writer) { + if (loggingEnabled()) { + try { + synchronized(times) { + for (int i = 0; i < times.size(); ++i) { + TimeData td = times.get(i); + if (td != null) { + writer.write(i + " " + td.getMessage() + ": " + + (td.getTime() - baseTime) + "\n"); + + } + } + } + writer.flush(); + } catch (Exception e) { + System.out.println(e + ": Writing performance log to " + + writer); + } + } + } + + /** + * Outputs all data to whatever location the user specified + * via sun.perflog command-line parameter. + */ + public static void outputLog() { + outputLog(logWriter); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ProxyGenerator.java b/sources/net.sf.j2s.java.core/src/sun/misc/ProxyGenerator.java new file mode 100644 index 000000000..d561df61d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ProxyGenerator.java @@ -0,0 +1,2031 @@ +/* + * Copyright (c) 1999, 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.misc; + +import java.io.ByteArrayOutputStream; +import java.io.DataOutputStream; +import java.io.File; +import java.io.IOException; +import java.io.OutputStream; +import java.lang.reflect.Array; +import java.lang.reflect.Method; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.ListIterator; +import java.util.Map; +import sun.security.action.GetBooleanAction; + +/** + * ProxyGenerator contains the code to generate a dynamic proxy class + * for the java.lang.reflect.Proxy API. + * + * The external interfaces to ProxyGenerator is the static + * "generateProxyClass" method. + * + * @author Peter Jones + * @since 1.3 + */ +public class ProxyGenerator { + /* + * In the comments below, "JVMS" refers to The Java Virtual Machine + * Specification Second Edition and "JLS" refers to the original + * version of The Java Language Specification, unless otherwise + * specified. + */ + + /* generate 1.5-era class file version */ + private static final int CLASSFILE_MAJOR_VERSION = 49; + private static final int CLASSFILE_MINOR_VERSION = 0; + + /* + * beginning of constants copied from + * sun.tools.java.RuntimeConstants (which no longer exists): + */ + + /* constant pool tags */ + private static final int CONSTANT_UTF8 = 1; + private static final int CONSTANT_UNICODE = 2; + private static final int CONSTANT_INTEGER = 3; + private static final int CONSTANT_FLOAT = 4; + private static final int CONSTANT_LONG = 5; + private static final int CONSTANT_DOUBLE = 6; + private static final int CONSTANT_CLASS = 7; + private static final int CONSTANT_STRING = 8; + private static final int CONSTANT_FIELD = 9; + private static final int CONSTANT_METHOD = 10; + private static final int CONSTANT_INTERFACEMETHOD = 11; + private static final int CONSTANT_NAMEANDTYPE = 12; + + /* access and modifier flags */ + private static final int ACC_PUBLIC = 0x00000001; + private static final int ACC_PRIVATE = 0x00000002; +// private static final int ACC_PROTECTED = 0x00000004; + private static final int ACC_STATIC = 0x00000008; + private static final int ACC_FINAL = 0x00000010; +// private static final int ACC_SYNCHRONIZED = 0x00000020; +// private static final int ACC_VOLATILE = 0x00000040; +// private static final int ACC_TRANSIENT = 0x00000080; +// private static final int ACC_NATIVE = 0x00000100; +// private static final int ACC_INTERFACE = 0x00000200; +// private static final int ACC_ABSTRACT = 0x00000400; + private static final int ACC_SUPER = 0x00000020; +// private static final int ACC_STRICT = 0x00000800; + + /* opcodes */ +// private static final int opc_nop = 0; + private static final int opc_aconst_null = 1; +// private static final int opc_iconst_m1 = 2; + private static final int opc_iconst_0 = 3; +// private static final int opc_iconst_1 = 4; +// private static final int opc_iconst_2 = 5; +// private static final int opc_iconst_3 = 6; +// private static final int opc_iconst_4 = 7; +// private static final int opc_iconst_5 = 8; +// private static final int opc_lconst_0 = 9; +// private static final int opc_lconst_1 = 10; +// private static final int opc_fconst_0 = 11; +// private static final int opc_fconst_1 = 12; +// private static final int opc_fconst_2 = 13; +// private static final int opc_dconst_0 = 14; +// private static final int opc_dconst_1 = 15; + private static final int opc_bipush = 16; + private static final int opc_sipush = 17; + private static final int opc_ldc = 18; + private static final int opc_ldc_w = 19; +// private static final int opc_ldc2_w = 20; + private static final int opc_iload = 21; + private static final int opc_lload = 22; + private static final int opc_fload = 23; + private static final int opc_dload = 24; + private static final int opc_aload = 25; + private static final int opc_iload_0 = 26; +// private static final int opc_iload_1 = 27; +// private static final int opc_iload_2 = 28; +// private static final int opc_iload_3 = 29; + private static final int opc_lload_0 = 30; +// private static final int opc_lload_1 = 31; +// private static final int opc_lload_2 = 32; +// private static final int opc_lload_3 = 33; + private static final int opc_fload_0 = 34; +// private static final int opc_fload_1 = 35; +// private static final int opc_fload_2 = 36; +// private static final int opc_fload_3 = 37; + private static final int opc_dload_0 = 38; +// private static final int opc_dload_1 = 39; +// private static final int opc_dload_2 = 40; +// private static final int opc_dload_3 = 41; + private static final int opc_aload_0 = 42; +// private static final int opc_aload_1 = 43; +// private static final int opc_aload_2 = 44; +// private static final int opc_aload_3 = 45; +// private static final int opc_iaload = 46; +// private static final int opc_laload = 47; +// private static final int opc_faload = 48; +// private static final int opc_daload = 49; +// private static final int opc_aaload = 50; +// private static final int opc_baload = 51; +// private static final int opc_caload = 52; +// private static final int opc_saload = 53; +// private static final int opc_istore = 54; +// private static final int opc_lstore = 55; +// private static final int opc_fstore = 56; +// private static final int opc_dstore = 57; + private static final int opc_astore = 58; +// private static final int opc_istore_0 = 59; +// private static final int opc_istore_1 = 60; +// private static final int opc_istore_2 = 61; +// private static final int opc_istore_3 = 62; +// private static final int opc_lstore_0 = 63; +// private static final int opc_lstore_1 = 64; +// private static final int opc_lstore_2 = 65; +// private static final int opc_lstore_3 = 66; +// private static final int opc_fstore_0 = 67; +// private static final int opc_fstore_1 = 68; +// private static final int opc_fstore_2 = 69; +// private static final int opc_fstore_3 = 70; +// private static final int opc_dstore_0 = 71; +// private static final int opc_dstore_1 = 72; +// private static final int opc_dstore_2 = 73; +// private static final int opc_dstore_3 = 74; + private static final int opc_astore_0 = 75; +// private static final int opc_astore_1 = 76; +// private static final int opc_astore_2 = 77; +// private static final int opc_astore_3 = 78; +// private static final int opc_iastore = 79; +// private static final int opc_lastore = 80; +// private static final int opc_fastore = 81; +// private static final int opc_dastore = 82; + private static final int opc_aastore = 83; +// private static final int opc_bastore = 84; +// private static final int opc_castore = 85; +// private static final int opc_sastore = 86; + private static final int opc_pop = 87; +// private static final int opc_pop2 = 88; + private static final int opc_dup = 89; +// private static final int opc_dup_x1 = 90; +// private static final int opc_dup_x2 = 91; +// private static final int opc_dup2 = 92; +// private static final int opc_dup2_x1 = 93; +// private static final int opc_dup2_x2 = 94; +// private static final int opc_swap = 95; +// private static final int opc_iadd = 96; +// private static final int opc_ladd = 97; +// private static final int opc_fadd = 98; +// private static final int opc_dadd = 99; +// private static final int opc_isub = 100; +// private static final int opc_lsub = 101; +// private static final int opc_fsub = 102; +// private static final int opc_dsub = 103; +// private static final int opc_imul = 104; +// private static final int opc_lmul = 105; +// private static final int opc_fmul = 106; +// private static final int opc_dmul = 107; +// private static final int opc_idiv = 108; +// private static final int opc_ldiv = 109; +// private static final int opc_fdiv = 110; +// private static final int opc_ddiv = 111; +// private static final int opc_irem = 112; +// private static final int opc_lrem = 113; +// private static final int opc_frem = 114; +// private static final int opc_drem = 115; +// private static final int opc_ineg = 116; +// private static final int opc_lneg = 117; +// private static final int opc_fneg = 118; +// private static final int opc_dneg = 119; +// private static final int opc_ishl = 120; +// private static final int opc_lshl = 121; +// private static final int opc_ishr = 122; +// private static final int opc_lshr = 123; +// private static final int opc_iushr = 124; +// private static final int opc_lushr = 125; +// private static final int opc_iand = 126; +// private static final int opc_land = 127; +// private static final int opc_ior = 128; +// private static final int opc_lor = 129; +// private static final int opc_ixor = 130; +// private static final int opc_lxor = 131; +// private static final int opc_iinc = 132; +// private static final int opc_i2l = 133; +// private static final int opc_i2f = 134; +// private static final int opc_i2d = 135; +// private static final int opc_l2i = 136; +// private static final int opc_l2f = 137; +// private static final int opc_l2d = 138; +// private static final int opc_f2i = 139; +// private static final int opc_f2l = 140; +// private static final int opc_f2d = 141; +// private static final int opc_d2i = 142; +// private static final int opc_d2l = 143; +// private static final int opc_d2f = 144; +// private static final int opc_i2b = 145; +// private static final int opc_i2c = 146; +// private static final int opc_i2s = 147; +// private static final int opc_lcmp = 148; +// private static final int opc_fcmpl = 149; +// private static final int opc_fcmpg = 150; +// private static final int opc_dcmpl = 151; +// private static final int opc_dcmpg = 152; +// private static final int opc_ifeq = 153; +// private static final int opc_ifne = 154; +// private static final int opc_iflt = 155; +// private static final int opc_ifge = 156; +// private static final int opc_ifgt = 157; +// private static final int opc_ifle = 158; +// private static final int opc_if_icmpeq = 159; +// private static final int opc_if_icmpne = 160; +// private static final int opc_if_icmplt = 161; +// private static final int opc_if_icmpge = 162; +// private static final int opc_if_icmpgt = 163; +// private static final int opc_if_icmple = 164; +// private static final int opc_if_acmpeq = 165; +// private static final int opc_if_acmpne = 166; +// private static final int opc_goto = 167; +// private static final int opc_jsr = 168; +// private static final int opc_ret = 169; +// private static final int opc_tableswitch = 170; +// private static final int opc_lookupswitch = 171; + private static final int opc_ireturn = 172; + private static final int opc_lreturn = 173; + private static final int opc_freturn = 174; + private static final int opc_dreturn = 175; + private static final int opc_areturn = 176; + private static final int opc_return = 177; + private static final int opc_getstatic = 178; + private static final int opc_putstatic = 179; + private static final int opc_getfield = 180; +// private static final int opc_putfield = 181; + private static final int opc_invokevirtual = 182; + private static final int opc_invokespecial = 183; + private static final int opc_invokestatic = 184; + private static final int opc_invokeinterface = 185; + private static final int opc_new = 187; +// private static final int opc_newarray = 188; + private static final int opc_anewarray = 189; +// private static final int opc_arraylength = 190; + private static final int opc_athrow = 191; + private static final int opc_checkcast = 192; +// private static final int opc_instanceof = 193; +// private static final int opc_monitorenter = 194; +// private static final int opc_monitorexit = 195; + private static final int opc_wide = 196; +// private static final int opc_multianewarray = 197; +// private static final int opc_ifnull = 198; +// private static final int opc_ifnonnull = 199; +// private static final int opc_goto_w = 200; +// private static final int opc_jsr_w = 201; + + // end of constants copied from sun.tools.java.RuntimeConstants + + /** name of the superclass of proxy classes */ + private final static String superclassName = "java/lang/reflect/Proxy"; + + /** name of field for storing a proxy instance's invocation handler */ + private final static String handlerFieldName = "h"; + + /** debugging flag for saving generated class files */ + private final static boolean saveGeneratedFiles = + java.security.AccessController.doPrivileged( + new GetBooleanAction( + "sun.misc.ProxyGenerator.saveGeneratedFiles")).booleanValue(); + + /** + * Generate a public proxy class given a name and a list of proxy interfaces. + */ + public static byte[] generateProxyClass(final String name, + Class[] interfaces) { + return generateProxyClass(name, interfaces, (ACC_PUBLIC | ACC_FINAL | ACC_SUPER)); + } + + /** + * Generate a proxy class given a name and a list of proxy interfaces. + * + * @param name the class name of the proxy class + * @param interfaces proxy interfaces + * @param accessFlags access flags of the proxy class + */ + public static byte[] generateProxyClass(final String name, + Class[] interfaces, + int accessFlags) + { + ProxyGenerator gen = new ProxyGenerator(name, interfaces, accessFlags); + final byte[] classFile = gen.generateClassFile(); + + if (saveGeneratedFiles) { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction() { + public Void run() { + try { + int i = name.lastIndexOf('.'); + Path path; + if (i > 0) { + Path dir = Paths.get(name.substring(0, i).replace('.', File.separatorChar)); + Files.createDirectories(dir); + path = dir.resolve(name.substring(i+1, name.length()) + ".class"); + } else { + path = Paths.get(name + ".class"); + } + Files.write(path, classFile); + return null; + } catch (IOException e) { + throw new InternalError( + "I/O exception saving generated file: " + e); + } + } + }); + } + + return classFile; + } + + /* preloaded Method objects for methods in java.lang.Object */ + private static Method hashCodeMethod; + private static Method equalsMethod; + private static Method toStringMethod; + static { + try { + hashCodeMethod = Object.class.getMethod("hashCode"); + equalsMethod = + Object.class.getMethod("equals", new Class[] { Object.class }); + toStringMethod = Object.class.getMethod("toString"); + } catch (NoSuchMethodException e) { + throw new NoSuchMethodError(e.getMessage()); + } + } + + /** name of proxy class */ + private String className; + + /** proxy interfaces */ + private Class[] interfaces; + + /** proxy class access flags */ + private int accessFlags; + + /** constant pool of class being generated */ + private ConstantPool cp = new ConstantPool(); + + /** FieldInfo struct for each field of generated class */ + private List fields = new ArrayList<>(); + + /** MethodInfo struct for each method of generated class */ + private List methods = new ArrayList<>(); + + /** + * maps method signature string to list of ProxyMethod objects for + * proxy methods with that signature + */ + private Map> proxyMethods = new HashMap<>(); + + /** count of ProxyMethod objects added to proxyMethods */ + private int proxyMethodCount = 0; + + /** + * Construct a ProxyGenerator to generate a proxy class with the + * specified name and for the given interfaces. + * + * A ProxyGenerator object contains the state for the ongoing + * generation of a particular proxy class. + */ + private ProxyGenerator(String className, Class[] interfaces, int accessFlags) { + this.className = className; + this.interfaces = interfaces; + this.accessFlags = accessFlags; + } + + /** + * Generate a class file for the proxy class. This method drives the + * class file generation process. + */ + private byte[] generateClassFile() { + + /* ============================================================ + * Step 1: Assemble ProxyMethod objects for all methods to + * generate proxy dispatching code for. + */ + + /* + * Record that proxy methods are needed for the hashCode, equals, + * and toString methods of java.lang.Object. This is done before + * the methods from the proxy interfaces so that the methods from + * java.lang.Object take precedence over duplicate methods in the + * proxy interfaces. + */ + addProxyMethod(hashCodeMethod, Object.class); + addProxyMethod(equalsMethod, Object.class); + addProxyMethod(toStringMethod, Object.class); + + /* + * Now record all of the methods from the proxy interfaces, giving + * earlier interfaces precedence over later ones with duplicate + * methods. + */ + for (Class intf : interfaces) { + for (Method m : intf.getMethods()) { + addProxyMethod(m, intf); + } + } + + /* + * For each set of proxy methods with the same signature, + * verify that the methods' return types are compatible. + */ + for (List sigmethods : proxyMethods.values()) { + checkReturnTypes(sigmethods); + } + + /* ============================================================ + * Step 2: Assemble FieldInfo and MethodInfo structs for all of + * fields and methods in the class we are generating. + */ + try { + methods.add(generateConstructor()); + + for (List sigmethods : proxyMethods.values()) { + for (ProxyMethod pm : sigmethods) { + + // add static field for method's Method object + fields.add(new FieldInfo(pm.methodFieldName, + "Ljava/lang/reflect/Method;", + ACC_PRIVATE | ACC_STATIC)); + + // generate code for proxy method and add it + methods.add(pm.generateMethod()); + } + } + + methods.add(generateStaticInitializer()); + + } catch (IOException e) { + throw new InternalError("unexpected I/O Exception", e); + } + + if (methods.size() > 65535) { + throw new IllegalArgumentException("method limit exceeded"); + } + if (fields.size() > 65535) { + throw new IllegalArgumentException("field limit exceeded"); + } + + /* ============================================================ + * Step 3: Write the final class file. + */ + + /* + * Make sure that constant pool indexes are reserved for the + * following items before starting to write the final class file. + */ + cp.getClass(dotToSlash(className)); + cp.getClass(superclassName); + for (Class intf: interfaces) { + cp.getClass(dotToSlash(intf.getName())); + } + + /* + * Disallow new constant pool additions beyond this point, since + * we are about to write the final constant pool table. + */ + cp.setReadOnly(); + + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + DataOutputStream dout = new DataOutputStream(bout); + + try { + /* + * Write all the items of the "ClassFile" structure. + * See JVMS section 4.1. + */ + // u4 magic; + dout.writeInt(0xCAFEBABE); + // u2 minor_version; + dout.writeShort(CLASSFILE_MINOR_VERSION); + // u2 major_version; + dout.writeShort(CLASSFILE_MAJOR_VERSION); + + cp.write(dout); // (write constant pool) + + // u2 access_flags; + dout.writeShort(accessFlags); + // u2 this_class; + dout.writeShort(cp.getClass(dotToSlash(className))); + // u2 super_class; + dout.writeShort(cp.getClass(superclassName)); + + // u2 interfaces_count; + dout.writeShort(interfaces.length); + // u2 interfaces[interfaces_count]; + for (Class intf : interfaces) { + dout.writeShort(cp.getClass( + dotToSlash(intf.getName()))); + } + + // u2 fields_count; + dout.writeShort(fields.size()); + // field_info fields[fields_count]; + for (FieldInfo f : fields) { + f.write(dout); + } + + // u2 methods_count; + dout.writeShort(methods.size()); + // method_info methods[methods_count]; + for (MethodInfo m : methods) { + m.write(dout); + } + + // u2 attributes_count; + dout.writeShort(0); // (no ClassFile attributes for proxy classes) + + } catch (IOException e) { + throw new InternalError("unexpected I/O Exception", e); + } + + return bout.toByteArray(); + } + + /** + * Add another method to be proxied, either by creating a new + * ProxyMethod object or augmenting an old one for a duplicate + * method. + * + * "fromClass" indicates the proxy interface that the method was + * found through, which may be different from (a subinterface of) + * the method's "declaring class". Note that the first Method + * object passed for a given name and descriptor identifies the + * Method object (and thus the declaring class) that will be + * passed to the invocation handler's "invoke" method for a given + * set of duplicate methods. + */ + private void addProxyMethod(Method m, Class fromClass) { + String name = m.getName(); + Class[] parameterTypes = m.getParameterTypes(); + Class returnType = m.getReturnType(); + Class[] exceptionTypes = m.getExceptionTypes(); + + String sig = name + getParameterDescriptors(parameterTypes); + List sigmethods = proxyMethods.get(sig); + if (sigmethods != null) { + for (ProxyMethod pm : sigmethods) { + if (returnType == pm.returnType) { + /* + * Found a match: reduce exception types to the + * greatest set of exceptions that can thrown + * compatibly with the throws clauses of both + * overridden methods. + */ + List> legalExceptions = new ArrayList<>(); + collectCompatibleTypes( + exceptionTypes, pm.exceptionTypes, legalExceptions); + collectCompatibleTypes( + pm.exceptionTypes, exceptionTypes, legalExceptions); + pm.exceptionTypes = new Class[legalExceptions.size()]; + pm.exceptionTypes = + legalExceptions.toArray(pm.exceptionTypes); + return; + } + } + } else { + sigmethods = new ArrayList<>(3); + proxyMethods.put(sig, sigmethods); + } + sigmethods.add(new ProxyMethod(name, parameterTypes, returnType, + exceptionTypes, fromClass)); + } + + /** + * For a given set of proxy methods with the same signature, check + * that their return types are compatible according to the Proxy + * specification. + * + * Specifically, if there is more than one such method, then all + * of the return types must be reference types, and there must be + * one return type that is assignable to each of the rest of them. + */ + private static void checkReturnTypes(List methods) { + /* + * If there is only one method with a given signature, there + * cannot be a conflict. This is the only case in which a + * primitive (or void) return type is allowed. + */ + if (methods.size() < 2) { + return; + } + + /* + * List of return types that are not yet known to be + * assignable from ("covered" by) any of the others. + */ + LinkedList> uncoveredReturnTypes = new LinkedList<>(); + + nextNewReturnType: + for (ProxyMethod pm : methods) { + Class newReturnType = pm.returnType; + if (newReturnType.isPrimitive()) { + throw new IllegalArgumentException( + "methods with same signature " + + getFriendlyMethodSignature(pm.methodName, + pm.parameterTypes) + + " but incompatible return types: " + + newReturnType.getName() + " and others"); + } + boolean added = false; + + /* + * Compare the new return type to the existing uncovered + * return types. + */ + ListIterator> liter = uncoveredReturnTypes.listIterator(); + while (liter.hasNext()) { + Class uncoveredReturnType = liter.next(); + + /* + * If an existing uncovered return type is assignable + * to this new one, then we can forget the new one. + */ + if (newReturnType.isAssignableFrom(uncoveredReturnType)) { + assert !added; + continue nextNewReturnType; + } + + /* + * If the new return type is assignable to an existing + * uncovered one, then should replace the existing one + * with the new one (or just forget the existing one, + * if the new one has already be put in the list). + */ + if (uncoveredReturnType.isAssignableFrom(newReturnType)) { + // (we can assume that each return type is unique) + if (!added) { + liter.set(newReturnType); + added = true; + } else { + liter.remove(); + } + } + } + + /* + * If we got through the list of existing uncovered return + * types without an assignability relationship, then add + * the new return type to the list of uncovered ones. + */ + if (!added) { + uncoveredReturnTypes.add(newReturnType); + } + } + + /* + * We shouldn't end up with more than one return type that is + * not assignable from any of the others. + */ + if (uncoveredReturnTypes.size() > 1) { + ProxyMethod pm = methods.get(0); + throw new IllegalArgumentException( + "methods with same signature " + + getFriendlyMethodSignature(pm.methodName, pm.parameterTypes) + + " but incompatible return types: " + uncoveredReturnTypes); + } + } + + /** + * A FieldInfo object contains information about a particular field + * in the class being generated. The class mirrors the data items of + * the "field_info" structure of the class file format (see JVMS 4.5). + */ + private class FieldInfo { + public int accessFlags; + public String name; + public String descriptor; + + public FieldInfo(String name, String descriptor, int accessFlags) { + this.name = name; + this.descriptor = descriptor; + this.accessFlags = accessFlags; + + /* + * Make sure that constant pool indexes are reserved for the + * following items before starting to write the final class file. + */ + cp.getUtf8(name); + cp.getUtf8(descriptor); + } + + public void write(DataOutputStream out) throws IOException { + /* + * Write all the items of the "field_info" structure. + * See JVMS section 4.5. + */ + // u2 access_flags; + out.writeShort(accessFlags); + // u2 name_index; + out.writeShort(cp.getUtf8(name)); + // u2 descriptor_index; + out.writeShort(cp.getUtf8(descriptor)); + // u2 attributes_count; + out.writeShort(0); // (no field_info attributes for proxy classes) + } + } + + /** + * An ExceptionTableEntry object holds values for the data items of + * an entry in the "exception_table" item of the "Code" attribute of + * "method_info" structures (see JVMS 4.7.3). + */ + private static class ExceptionTableEntry { + public short startPc; + public short endPc; + public short handlerPc; + public short catchType; + + public ExceptionTableEntry(short startPc, short endPc, + short handlerPc, short catchType) + { + this.startPc = startPc; + this.endPc = endPc; + this.handlerPc = handlerPc; + this.catchType = catchType; + } + }; + + /** + * A MethodInfo object contains information about a particular method + * in the class being generated. This class mirrors the data items of + * the "method_info" structure of the class file format (see JVMS 4.6). + */ + private class MethodInfo { + public int accessFlags; + public String name; + public String descriptor; + public short maxStack; + public short maxLocals; + public ByteArrayOutputStream code = new ByteArrayOutputStream(); + public List exceptionTable = + new ArrayList(); + public short[] declaredExceptions; + + public MethodInfo(String name, String descriptor, int accessFlags) { + this.name = name; + this.descriptor = descriptor; + this.accessFlags = accessFlags; + + /* + * Make sure that constant pool indexes are reserved for the + * following items before starting to write the final class file. + */ + cp.getUtf8(name); + cp.getUtf8(descriptor); + cp.getUtf8("Code"); + cp.getUtf8("Exceptions"); + } + + public void write(DataOutputStream out) throws IOException { + /* + * Write all the items of the "method_info" structure. + * See JVMS section 4.6. + */ + // u2 access_flags; + out.writeShort(accessFlags); + // u2 name_index; + out.writeShort(cp.getUtf8(name)); + // u2 descriptor_index; + out.writeShort(cp.getUtf8(descriptor)); + // u2 attributes_count; + out.writeShort(2); // (two method_info attributes:) + + // Write "Code" attribute. See JVMS section 4.7.3. + + // u2 attribute_name_index; + out.writeShort(cp.getUtf8("Code")); + // u4 attribute_length; + out.writeInt(12 + code.size() + 8 * exceptionTable.size()); + // u2 max_stack; + out.writeShort(maxStack); + // u2 max_locals; + out.writeShort(maxLocals); + // u2 code_length; + out.writeInt(code.size()); + // u1 code[code_length]; + code.writeTo(out); + // u2 exception_table_length; + out.writeShort(exceptionTable.size()); + for (ExceptionTableEntry e : exceptionTable) { + // u2 start_pc; + out.writeShort(e.startPc); + // u2 end_pc; + out.writeShort(e.endPc); + // u2 handler_pc; + out.writeShort(e.handlerPc); + // u2 catch_type; + out.writeShort(e.catchType); + } + // u2 attributes_count; + out.writeShort(0); + + // write "Exceptions" attribute. See JVMS section 4.7.4. + + // u2 attribute_name_index; + out.writeShort(cp.getUtf8("Exceptions")); + // u4 attributes_length; + out.writeInt(2 + 2 * declaredExceptions.length); + // u2 number_of_exceptions; + out.writeShort(declaredExceptions.length); + // u2 exception_index_table[number_of_exceptions]; + for (short value : declaredExceptions) { + out.writeShort(value); + } + } + + } + + /** + * A ProxyMethod object represents a proxy method in the proxy class + * being generated: a method whose implementation will encode and + * dispatch invocations to the proxy instance's invocation handler. + */ + private class ProxyMethod { + + public String methodName; + public Class[] parameterTypes; + public Class returnType; + public Class[] exceptionTypes; + public Class fromClass; + public String methodFieldName; + + private ProxyMethod(String methodName, Class[] parameterTypes, + Class returnType, Class[] exceptionTypes, + Class fromClass) + { + this.methodName = methodName; + this.parameterTypes = parameterTypes; + this.returnType = returnType; + this.exceptionTypes = exceptionTypes; + this.fromClass = fromClass; + this.methodFieldName = "m" + proxyMethodCount++; + } + + /** + * Return a MethodInfo object for this method, including generating + * the code and exception table entry. + */ + private MethodInfo generateMethod() throws IOException { + String desc = getMethodDescriptor(parameterTypes, returnType); + MethodInfo minfo = new MethodInfo(methodName, desc, + ACC_PUBLIC | ACC_FINAL); + + int[] parameterSlot = new int[parameterTypes.length]; + int nextSlot = 1; + for (int i = 0; i < parameterSlot.length; i++) { + parameterSlot[i] = nextSlot; + nextSlot += getWordsPerType(parameterTypes[i]); + } + int localSlot0 = nextSlot; + short pc, tryBegin = 0, tryEnd; + + DataOutputStream out = new DataOutputStream(minfo.code); + + code_aload(0, out); + + out.writeByte(opc_getfield); + out.writeShort(cp.getFieldRef( + superclassName, + handlerFieldName, "Ljava/lang/reflect/InvocationHandler;")); + + code_aload(0, out); + + out.writeByte(opc_getstatic); + out.writeShort(cp.getFieldRef( + dotToSlash(className), + methodFieldName, "Ljava/lang/reflect/Method;")); + + if (parameterTypes.length > 0) { + + code_ipush(parameterTypes.length, out); + + out.writeByte(opc_anewarray); + out.writeShort(cp.getClass("java/lang/Object")); + + for (int i = 0; i < parameterTypes.length; i++) { + + out.writeByte(opc_dup); + + code_ipush(i, out); + + codeWrapArgument(parameterTypes[i], parameterSlot[i], out); + + out.writeByte(opc_aastore); + } + } else { + + out.writeByte(opc_aconst_null); + } + + out.writeByte(opc_invokeinterface); + out.writeShort(cp.getInterfaceMethodRef( + "java/lang/reflect/InvocationHandler", + "invoke", + "(Ljava/lang/Object;Ljava/lang/reflect/Method;" + + "[Ljava/lang/Object;)Ljava/lang/Object;")); + out.writeByte(4); + out.writeByte(0); + + if (returnType == void.class) { + + out.writeByte(opc_pop); + + out.writeByte(opc_return); + + } else { + + codeUnwrapReturnValue(returnType, out); + } + + tryEnd = pc = (short) minfo.code.size(); + + List> catchList = computeUniqueCatchList(exceptionTypes); + if (catchList.size() > 0) { + + for (Class ex : catchList) { + minfo.exceptionTable.add(new ExceptionTableEntry( + tryBegin, tryEnd, pc, + cp.getClass(dotToSlash(ex.getName())))); + } + + out.writeByte(opc_athrow); + + pc = (short) minfo.code.size(); + + minfo.exceptionTable.add(new ExceptionTableEntry( + tryBegin, tryEnd, pc, cp.getClass("java/lang/Throwable"))); + + code_astore(localSlot0, out); + + out.writeByte(opc_new); + out.writeShort(cp.getClass( + "java/lang/reflect/UndeclaredThrowableException")); + + out.writeByte(opc_dup); + + code_aload(localSlot0, out); + + out.writeByte(opc_invokespecial); + + out.writeShort(cp.getMethodRef( + "java/lang/reflect/UndeclaredThrowableException", + "", "(Ljava/lang/Throwable;)V")); + + out.writeByte(opc_athrow); + } + + if (minfo.code.size() > 65535) { + throw new IllegalArgumentException("code size limit exceeded"); + } + + minfo.maxStack = 10; + minfo.maxLocals = (short) (localSlot0 + 1); + minfo.declaredExceptions = new short[exceptionTypes.length]; + for (int i = 0; i < exceptionTypes.length; i++) { + minfo.declaredExceptions[i] = cp.getClass( + dotToSlash(exceptionTypes[i].getName())); + } + + return minfo; + } + + /** + * Generate code for wrapping an argument of the given type + * whose value can be found at the specified local variable + * index, in order for it to be passed (as an Object) to the + * invocation handler's "invoke" method. The code is written + * to the supplied stream. + */ + private void codeWrapArgument(Class type, int slot, + DataOutputStream out) + throws IOException + { + if (type.isPrimitive()) { + PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type); + + if (type == int.class || + type == boolean.class || + type == byte.class || + type == char.class || + type == short.class) + { + code_iload(slot, out); + } else if (type == long.class) { + code_lload(slot, out); + } else if (type == float.class) { + code_fload(slot, out); + } else if (type == double.class) { + code_dload(slot, out); + } else { + throw new AssertionError(); + } + + out.writeByte(opc_invokestatic); + out.writeShort(cp.getMethodRef( + prim.wrapperClassName, + "valueOf", prim.wrapperValueOfDesc)); + + } else { + + code_aload(slot, out); + } + } + + /** + * Generate code for unwrapping a return value of the given + * type from the invocation handler's "invoke" method (as type + * Object) to its correct type. The code is written to the + * supplied stream. + */ + private void codeUnwrapReturnValue(Class type, DataOutputStream out) + throws IOException + { + if (type.isPrimitive()) { + PrimitiveTypeInfo prim = PrimitiveTypeInfo.get(type); + + out.writeByte(opc_checkcast); + out.writeShort(cp.getClass(prim.wrapperClassName)); + + out.writeByte(opc_invokevirtual); + out.writeShort(cp.getMethodRef( + prim.wrapperClassName, + prim.unwrapMethodName, prim.unwrapMethodDesc)); + + if (type == int.class || + type == boolean.class || + type == byte.class || + type == char.class || + type == short.class) + { + out.writeByte(opc_ireturn); + } else if (type == long.class) { + out.writeByte(opc_lreturn); + } else if (type == float.class) { + out.writeByte(opc_freturn); + } else if (type == double.class) { + out.writeByte(opc_dreturn); + } else { + throw new AssertionError(); + } + + } else { + + out.writeByte(opc_checkcast); + out.writeShort(cp.getClass(dotToSlash(type.getName()))); + + out.writeByte(opc_areturn); + } + } + + /** + * Generate code for initializing the static field that stores + * the Method object for this proxy method. The code is written + * to the supplied stream. + */ + private void codeFieldInitialization(DataOutputStream out) + throws IOException + { + codeClassForName(fromClass, out); + + code_ldc(cp.getString(methodName), out); + + code_ipush(parameterTypes.length, out); + + out.writeByte(opc_anewarray); + out.writeShort(cp.getClass("java/lang/Class")); + + for (int i = 0; i < parameterTypes.length; i++) { + + out.writeByte(opc_dup); + + code_ipush(i, out); + + if (parameterTypes[i].isPrimitive()) { + PrimitiveTypeInfo prim = + PrimitiveTypeInfo.get(parameterTypes[i]); + + out.writeByte(opc_getstatic); + out.writeShort(cp.getFieldRef( + prim.wrapperClassName, "TYPE", "Ljava/lang/Class;")); + + } else { + codeClassForName(parameterTypes[i], out); + } + + out.writeByte(opc_aastore); + } + + out.writeByte(opc_invokevirtual); + out.writeShort(cp.getMethodRef( + "java/lang/Class", + "getMethod", + "(Ljava/lang/String;[Ljava/lang/Class;)" + + "Ljava/lang/reflect/Method;")); + + out.writeByte(opc_putstatic); + out.writeShort(cp.getFieldRef( + dotToSlash(className), + methodFieldName, "Ljava/lang/reflect/Method;")); + } + } + + /** + * Generate the constructor method for the proxy class. + */ + private MethodInfo generateConstructor() throws IOException { + MethodInfo minfo = new MethodInfo( + "", "(Ljava/lang/reflect/InvocationHandler;)V", + ACC_PUBLIC); + + DataOutputStream out = new DataOutputStream(minfo.code); + + code_aload(0, out); + + code_aload(1, out); + + out.writeByte(opc_invokespecial); + out.writeShort(cp.getMethodRef( + superclassName, + "", "(Ljava/lang/reflect/InvocationHandler;)V")); + + out.writeByte(opc_return); + + minfo.maxStack = 10; + minfo.maxLocals = 2; + minfo.declaredExceptions = new short[0]; + + return minfo; + } + + /** + * Generate the static initializer method for the proxy class. + */ + private MethodInfo generateStaticInitializer() throws IOException { + MethodInfo minfo = new MethodInfo( + "", "()V", ACC_STATIC); + + int localSlot0 = 1; + short pc, tryBegin = 0, tryEnd; + + DataOutputStream out = new DataOutputStream(minfo.code); + + for (List sigmethods : proxyMethods.values()) { + for (ProxyMethod pm : sigmethods) { + pm.codeFieldInitialization(out); + } + } + + out.writeByte(opc_return); + + tryEnd = pc = (short) minfo.code.size(); + + minfo.exceptionTable.add(new ExceptionTableEntry( + tryBegin, tryEnd, pc, + cp.getClass("java/lang/NoSuchMethodException"))); + + code_astore(localSlot0, out); + + out.writeByte(opc_new); + out.writeShort(cp.getClass("java/lang/NoSuchMethodError")); + + out.writeByte(opc_dup); + + code_aload(localSlot0, out); + + out.writeByte(opc_invokevirtual); + out.writeShort(cp.getMethodRef( + "java/lang/Throwable", "getMessage", "()Ljava/lang/String;")); + + out.writeByte(opc_invokespecial); + out.writeShort(cp.getMethodRef( + "java/lang/NoSuchMethodError", "", "(Ljava/lang/String;)V")); + + out.writeByte(opc_athrow); + + pc = (short) minfo.code.size(); + + minfo.exceptionTable.add(new ExceptionTableEntry( + tryBegin, tryEnd, pc, + cp.getClass("java/lang/ClassNotFoundException"))); + + code_astore(localSlot0, out); + + out.writeByte(opc_new); + out.writeShort(cp.getClass("java/lang/NoClassDefFoundError")); + + out.writeByte(opc_dup); + + code_aload(localSlot0, out); + + out.writeByte(opc_invokevirtual); + out.writeShort(cp.getMethodRef( + "java/lang/Throwable", "getMessage", "()Ljava/lang/String;")); + + out.writeByte(opc_invokespecial); + out.writeShort(cp.getMethodRef( + "java/lang/NoClassDefFoundError", + "", "(Ljava/lang/String;)V")); + + out.writeByte(opc_athrow); + + if (minfo.code.size() > 65535) { + throw new IllegalArgumentException("code size limit exceeded"); + } + + minfo.maxStack = 10; + minfo.maxLocals = (short) (localSlot0 + 1); + minfo.declaredExceptions = new short[0]; + + return minfo; + } + + + /* + * =============== Code Generation Utility Methods =============== + */ + + /* + * The following methods generate code for the load or store operation + * indicated by their name for the given local variable. The code is + * written to the supplied stream. + */ + + private void code_iload(int lvar, DataOutputStream out) + throws IOException + { + codeLocalLoadStore(lvar, opc_iload, opc_iload_0, out); + } + + private void code_lload(int lvar, DataOutputStream out) + throws IOException + { + codeLocalLoadStore(lvar, opc_lload, opc_lload_0, out); + } + + private void code_fload(int lvar, DataOutputStream out) + throws IOException + { + codeLocalLoadStore(lvar, opc_fload, opc_fload_0, out); + } + + private void code_dload(int lvar, DataOutputStream out) + throws IOException + { + codeLocalLoadStore(lvar, opc_dload, opc_dload_0, out); + } + + private void code_aload(int lvar, DataOutputStream out) + throws IOException + { + codeLocalLoadStore(lvar, opc_aload, opc_aload_0, out); + } + +// private void code_istore(int lvar, DataOutputStream out) +// throws IOException +// { +// codeLocalLoadStore(lvar, opc_istore, opc_istore_0, out); +// } + +// private void code_lstore(int lvar, DataOutputStream out) +// throws IOException +// { +// codeLocalLoadStore(lvar, opc_lstore, opc_lstore_0, out); +// } + +// private void code_fstore(int lvar, DataOutputStream out) +// throws IOException +// { +// codeLocalLoadStore(lvar, opc_fstore, opc_fstore_0, out); +// } + +// private void code_dstore(int lvar, DataOutputStream out) +// throws IOException +// { +// codeLocalLoadStore(lvar, opc_dstore, opc_dstore_0, out); +// } + + private void code_astore(int lvar, DataOutputStream out) + throws IOException + { + codeLocalLoadStore(lvar, opc_astore, opc_astore_0, out); + } + + /** + * Generate code for a load or store instruction for the given local + * variable. The code is written to the supplied stream. + * + * "opcode" indicates the opcode form of the desired load or store + * instruction that takes an explicit local variable index, and + * "opcode_0" indicates the corresponding form of the instruction + * with the implicit index 0. + */ + private void codeLocalLoadStore(int lvar, int opcode, int opcode_0, + DataOutputStream out) + throws IOException + { + assert lvar >= 0 && lvar <= 0xFFFF; + if (lvar <= 3) { + out.writeByte(opcode_0 + lvar); + } else if (lvar <= 0xFF) { + out.writeByte(opcode); + out.writeByte(lvar & 0xFF); + } else { + /* + * Use the "wide" instruction modifier for local variable + * indexes that do not fit into an unsigned byte. + */ + out.writeByte(opc_wide); + out.writeByte(opcode); + out.writeShort(lvar & 0xFFFF); + } + } + + /** + * Generate code for an "ldc" instruction for the given constant pool + * index (the "ldc_w" instruction is used if the index does not fit + * into an unsigned byte). The code is written to the supplied stream. + */ + private void code_ldc(int index, DataOutputStream out) + throws IOException + { + assert index >= 0 && index <= 0xFFFF; + if (index <= 0xFF) { + out.writeByte(opc_ldc); + out.writeByte(index & 0xFF); + } else { + out.writeByte(opc_ldc_w); + out.writeShort(index & 0xFFFF); + } + } + + /** + * Generate code to push a constant integer value on to the operand + * stack, using the "iconst_", "bipush", or "sipush" instructions + * depending on the size of the value. The code is written to the + * supplied stream. + */ + private void code_ipush(int value, DataOutputStream out) + throws IOException + { + if (value >= -1 && value <= 5) { + out.writeByte(opc_iconst_0 + value); + } else if (value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) { + out.writeByte(opc_bipush); + out.writeByte(value & 0xFF); + } else if (value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) { + out.writeByte(opc_sipush); + out.writeShort(value & 0xFFFF); + } else { + throw new AssertionError(); + } + } + + /** + * Generate code to invoke the Class.forName with the name of the given + * class to get its Class object at runtime. The code is written to + * the supplied stream. Note that the code generated by this method + * may caused the checked ClassNotFoundException to be thrown. + */ + private void codeClassForName(Class cl, DataOutputStream out) + throws IOException + { + code_ldc(cp.getString(cl.getName()), out); + + out.writeByte(opc_invokestatic); + out.writeShort(cp.getMethodRef( + "java/lang/Class", + "forName", "(Ljava/lang/String;)Ljava/lang/Class;")); + } + + + /* + * ==================== General Utility Methods ==================== + */ + + /** + * Convert a fully qualified class name that uses '.' as the package + * separator, the external representation used by the Java language + * and APIs, to a fully qualified class name that uses '/' as the + * package separator, the representation used in the class file + * format (see JVMS section 4.2). + */ + private static String dotToSlash(String name) { + return name.replace('.', '/'); + } + + /** + * Return the "method descriptor" string for a method with the given + * parameter types and return type. See JVMS section 4.3.3. + */ + private static String getMethodDescriptor(Class[] parameterTypes, + Class returnType) + { + return getParameterDescriptors(parameterTypes) + + ((returnType == void.class) ? "V" : getFieldType(returnType)); + } + + /** + * Return the list of "parameter descriptor" strings enclosed in + * parentheses corresponding to the given parameter types (in other + * words, a method descriptor without a return descriptor). This + * string is useful for constructing string keys for methods without + * regard to their return type. + */ + private static String getParameterDescriptors(Class[] parameterTypes) { + StringBuilder desc = new StringBuilder("("); + for (int i = 0; i < parameterTypes.length; i++) { + desc.append(getFieldType(parameterTypes[i])); + } + desc.append(')'); + return desc.toString(); + } + + /** + * Return the "field type" string for the given type, appropriate for + * a field descriptor, a parameter descriptor, or a return descriptor + * other than "void". See JVMS section 4.3.2. + */ + private static String getFieldType(Class type) { + if (type.isPrimitive()) { + return PrimitiveTypeInfo.get(type).baseTypeString; + } else if (type.isArray()) { + /* + * According to JLS 20.3.2, the getName() method on Class does + * return the VM type descriptor format for array classes (only); + * using that should be quicker than the otherwise obvious code: + * + * return "[" + getTypeDescriptor(type.getComponentType()); + */ + return type.getName().replace('.', '/'); + } else { + return "L" + dotToSlash(type.getName()) + ";"; + } + } + + /** + * Returns a human-readable string representing the signature of a + * method with the given name and parameter types. + */ + private static String getFriendlyMethodSignature(String name, + Class[] parameterTypes) + { + StringBuilder sig = new StringBuilder(name); + sig.append('('); + for (int i = 0; i < parameterTypes.length; i++) { + if (i > 0) { + sig.append(','); + } + Class parameterType = parameterTypes[i]; + int dimensions = 0; + while (parameterType.isArray()) { + parameterType = parameterType.getComponentType(); + dimensions++; + } + sig.append(parameterType.getName()); + while (dimensions-- > 0) { + sig.append("[]"); + } + } + sig.append(')'); + return sig.toString(); + } + + /** + * Return the number of abstract "words", or consecutive local variable + * indexes, required to contain a value of the given type. See JVMS + * section 3.6.1. + * + * Note that the original version of the JVMS contained a definition of + * this abstract notion of a "word" in section 3.4, but that definition + * was removed for the second edition. + */ + private static int getWordsPerType(Class type) { + if (type == long.class || type == double.class) { + return 2; + } else { + return 1; + } + } + + /** + * Add to the given list all of the types in the "from" array that + * are not already contained in the list and are assignable to at + * least one of the types in the "with" array. + * + * This method is useful for computing the greatest common set of + * declared exceptions from duplicate methods inherited from + * different interfaces. + */ + private static void collectCompatibleTypes(Class[] from, + Class[] with, + List> list) + { + for (Class fc: from) { + if (!list.contains(fc)) { + for (Class wc: with) { + if (wc.isAssignableFrom(fc)) { + list.add(fc); + break; + } + } + } + } + } + + /** + * Given the exceptions declared in the throws clause of a proxy method, + * compute the exceptions that need to be caught from the invocation + * handler's invoke method and rethrown intact in the method's + * implementation before catching other Throwables and wrapping them + * in UndeclaredThrowableExceptions. + * + * The exceptions to be caught are returned in a List object. Each + * exception in the returned list is guaranteed to not be a subclass of + * any of the other exceptions in the list, so the catch blocks for + * these exceptions may be generated in any order relative to each other. + * + * Error and RuntimeException are each always contained by the returned + * list (if none of their superclasses are contained), since those + * unchecked exceptions should always be rethrown intact, and thus their + * subclasses will never appear in the returned list. + * + * The returned List will be empty if java.lang.Throwable is in the + * given list of declared exceptions, indicating that no exceptions + * need to be caught. + */ + private static List> computeUniqueCatchList(Class[] exceptions) { + List> uniqueList = new ArrayList<>(); + // unique exceptions to catch + + uniqueList.add(Error.class); // always catch/rethrow these + uniqueList.add(RuntimeException.class); + + nextException: + for (Class ex: exceptions) { + if (ex.isAssignableFrom(Throwable.class)) { + /* + * If Throwable is declared to be thrown by the proxy method, + * then no catch blocks are necessary, because the invoke + * can, at most, throw Throwable anyway. + */ + uniqueList.clear(); + break; + } else if (!Throwable.class.isAssignableFrom(ex)) { + /* + * Ignore types that cannot be thrown by the invoke method. + */ + continue; + } + /* + * Compare this exception against the current list of + * exceptions that need to be caught: + */ + for (int j = 0; j < uniqueList.size();) { + Class ex2 = uniqueList.get(j); + if (ex2.isAssignableFrom(ex)) { + /* + * if a superclass of this exception is already on + * the list to catch, then ignore this one and continue; + */ + continue nextException; + } else if (ex.isAssignableFrom(ex2)) { + /* + * if a subclass of this exception is on the list + * to catch, then remove it; + */ + uniqueList.remove(j); + } else { + j++; // else continue comparing. + } + } + // This exception is unique (so far): add it to the list to catch. + uniqueList.add(ex); + } + return uniqueList; + } + + /** + * A PrimitiveTypeInfo object contains assorted information about + * a primitive type in its public fields. The struct for a particular + * primitive type can be obtained using the static "get" method. + */ + private static class PrimitiveTypeInfo { + + /** "base type" used in various descriptors (see JVMS section 4.3.2) */ + public String baseTypeString; + + /** name of corresponding wrapper class */ + public String wrapperClassName; + + /** method descriptor for wrapper class "valueOf" factory method */ + public String wrapperValueOfDesc; + + /** name of wrapper class method for retrieving primitive value */ + public String unwrapMethodName; + + /** descriptor of same method */ + public String unwrapMethodDesc; + + private static Map,PrimitiveTypeInfo> table = new HashMap<>(); + static { + add(byte.class, Byte.class); + add(char.class, Character.class); + add(double.class, Double.class); + add(float.class, Float.class); + add(int.class, Integer.class); + add(long.class, Long.class); + add(short.class, Short.class); + add(boolean.class, Boolean.class); + } + + private static void add(Class primitiveClass, Class wrapperClass) { + table.put(primitiveClass, + new PrimitiveTypeInfo(primitiveClass, wrapperClass)); + } + + private PrimitiveTypeInfo(Class primitiveClass, Class wrapperClass) { + assert primitiveClass.isPrimitive(); + + baseTypeString = + Array.newInstance(primitiveClass, 0) + .getClass().getName().substring(1); + wrapperClassName = dotToSlash(wrapperClass.getName()); + wrapperValueOfDesc = + "(" + baseTypeString + ")L" + wrapperClassName + ";"; + unwrapMethodName = primitiveClass.getName() + "Value"; + unwrapMethodDesc = "()" + baseTypeString; + } + + public static PrimitiveTypeInfo get(Class cl) { + return table.get(cl); + } + } + + + /** + * A ConstantPool object represents the constant pool of a class file + * being generated. This representation of a constant pool is designed + * specifically for use by ProxyGenerator; in particular, it assumes + * that constant pool entries will not need to be resorted (for example, + * by their type, as the Java compiler does), so that the final index + * value can be assigned and used when an entry is first created. + * + * Note that new entries cannot be created after the constant pool has + * been written to a class file. To prevent such logic errors, a + * ConstantPool instance can be marked "read only", so that further + * attempts to add new entries will fail with a runtime exception. + * + * See JVMS section 4.4 for more information about the constant pool + * of a class file. + */ + private static class ConstantPool { + + /** + * list of constant pool entries, in constant pool index order. + * + * This list is used when writing the constant pool to a stream + * and for assigning the next index value. Note that element 0 + * of this list corresponds to constant pool index 1. + */ + private List pool = new ArrayList<>(32); + + /** + * maps constant pool data of all types to constant pool indexes. + * + * This map is used to look up the index of an existing entry for + * values of all types. + */ + private Map map = new HashMap<>(16); + + /** true if no new constant pool entries may be added */ + private boolean readOnly = false; + + /** + * Get or assign the index for a CONSTANT_Utf8 entry. + */ + public short getUtf8(String s) { + if (s == null) { + throw new NullPointerException(); + } + return getValue(s); + } + + /** + * Get or assign the index for a CONSTANT_Integer entry. + */ + public short getInteger(int i) { + return getValue(new Integer(i)); + } + + /** + * Get or assign the index for a CONSTANT_Float entry. + */ + public short getFloat(float f) { + return getValue(new Float(f)); + } + + /** + * Get or assign the index for a CONSTANT_Class entry. + */ + public short getClass(String name) { + short utf8Index = getUtf8(name); + return getIndirect(new IndirectEntry( + CONSTANT_CLASS, utf8Index)); + } + + /** + * Get or assign the index for a CONSTANT_String entry. + */ + public short getString(String s) { + short utf8Index = getUtf8(s); + return getIndirect(new IndirectEntry( + CONSTANT_STRING, utf8Index)); + } + + /** + * Get or assign the index for a CONSTANT_FieldRef entry. + */ + public short getFieldRef(String className, + String name, String descriptor) + { + short classIndex = getClass(className); + short nameAndTypeIndex = getNameAndType(name, descriptor); + return getIndirect(new IndirectEntry( + CONSTANT_FIELD, classIndex, nameAndTypeIndex)); + } + + /** + * Get or assign the index for a CONSTANT_MethodRef entry. + */ + public short getMethodRef(String className, + String name, String descriptor) + { + short classIndex = getClass(className); + short nameAndTypeIndex = getNameAndType(name, descriptor); + return getIndirect(new IndirectEntry( + CONSTANT_METHOD, classIndex, nameAndTypeIndex)); + } + + /** + * Get or assign the index for a CONSTANT_InterfaceMethodRef entry. + */ + public short getInterfaceMethodRef(String className, String name, + String descriptor) + { + short classIndex = getClass(className); + short nameAndTypeIndex = getNameAndType(name, descriptor); + return getIndirect(new IndirectEntry( + CONSTANT_INTERFACEMETHOD, classIndex, nameAndTypeIndex)); + } + + /** + * Get or assign the index for a CONSTANT_NameAndType entry. + */ + public short getNameAndType(String name, String descriptor) { + short nameIndex = getUtf8(name); + short descriptorIndex = getUtf8(descriptor); + return getIndirect(new IndirectEntry( + CONSTANT_NAMEANDTYPE, nameIndex, descriptorIndex)); + } + + /** + * Set this ConstantPool instance to be "read only". + * + * After this method has been called, further requests to get + * an index for a non-existent entry will cause an InternalError + * to be thrown instead of creating of the entry. + */ + public void setReadOnly() { + readOnly = true; + } + + /** + * Write this constant pool to a stream as part of + * the class file format. + * + * This consists of writing the "constant_pool_count" and + * "constant_pool[]" items of the "ClassFile" structure, as + * described in JVMS section 4.1. + */ + public void write(OutputStream out) throws IOException { + DataOutputStream dataOut = new DataOutputStream(out); + + // constant_pool_count: number of entries plus one + dataOut.writeShort(pool.size() + 1); + + for (Entry e : pool) { + e.write(dataOut); + } + } + + /** + * Add a new constant pool entry and return its index. + */ + private short addEntry(Entry entry) { + pool.add(entry); + /* + * Note that this way of determining the index of the + * added entry is wrong if this pool supports + * CONSTANT_Long or CONSTANT_Double entries. + */ + if (pool.size() >= 65535) { + throw new IllegalArgumentException( + "constant pool size limit exceeded"); + } + return (short) pool.size(); + } + + /** + * Get or assign the index for an entry of a type that contains + * a direct value. The type of the given object determines the + * type of the desired entry as follows: + * + * java.lang.String CONSTANT_Utf8 + * java.lang.Integer CONSTANT_Integer + * java.lang.Float CONSTANT_Float + * java.lang.Long CONSTANT_Long + * java.lang.Double CONSTANT_DOUBLE + */ + private short getValue(Object key) { + Short index = map.get(key); + if (index != null) { + return index.shortValue(); + } else { + if (readOnly) { + throw new InternalError( + "late constant pool addition: " + key); + } + short i = addEntry(new ValueEntry(key)); + map.put(key, new Short(i)); + return i; + } + } + + /** + * Get or assign the index for an entry of a type that contains + * references to other constant pool entries. + */ + private short getIndirect(IndirectEntry e) { + Short index = map.get(e); + if (index != null) { + return index.shortValue(); + } else { + if (readOnly) { + throw new InternalError("late constant pool addition"); + } + short i = addEntry(e); + map.put(e, new Short(i)); + return i; + } + } + + /** + * Entry is the abstact superclass of all constant pool entry types + * that can be stored in the "pool" list; its purpose is to define a + * common method for writing constant pool entries to a class file. + */ + private static abstract class Entry { + public abstract void write(DataOutputStream out) + throws IOException; + } + + /** + * ValueEntry represents a constant pool entry of a type that + * contains a direct value (see the comments for the "getValue" + * method for a list of such types). + * + * ValueEntry objects are not used as keys for their entries in the + * Map "map", so no useful hashCode or equals methods are defined. + */ + private static class ValueEntry extends Entry { + private Object value; + + public ValueEntry(Object value) { + this.value = value; + } + + public void write(DataOutputStream out) throws IOException { + if (value instanceof String) { + out.writeByte(CONSTANT_UTF8); + out.writeUTF((String) value); + } else if (value instanceof Integer) { + out.writeByte(CONSTANT_INTEGER); + out.writeInt(((Integer) value).intValue()); + } else if (value instanceof Float) { + out.writeByte(CONSTANT_FLOAT); + out.writeFloat(((Float) value).floatValue()); + } else if (value instanceof Long) { + out.writeByte(CONSTANT_LONG); + out.writeLong(((Long) value).longValue()); + } else if (value instanceof Double) { + out.writeDouble(CONSTANT_DOUBLE); + out.writeDouble(((Double) value).doubleValue()); + } else { + throw new InternalError("bogus value entry: " + value); + } + } + } + + /** + * IndirectEntry represents a constant pool entry of a type that + * references other constant pool entries, i.e., the following types: + * + * CONSTANT_Class, CONSTANT_String, CONSTANT_Fieldref, + * CONSTANT_Methodref, CONSTANT_InterfaceMethodref, and + * CONSTANT_NameAndType. + * + * Each of these entry types contains either one or two indexes of + * other constant pool entries. + * + * IndirectEntry objects are used as the keys for their entries in + * the Map "map", so the hashCode and equals methods are overridden + * to allow matching. + */ + private static class IndirectEntry extends Entry { + private int tag; + private short index0; + private short index1; + + /** + * Construct an IndirectEntry for a constant pool entry type + * that contains one index of another entry. + */ + public IndirectEntry(int tag, short index) { + this.tag = tag; + this.index0 = index; + this.index1 = 0; + } + + /** + * Construct an IndirectEntry for a constant pool entry type + * that contains two indexes for other entries. + */ + public IndirectEntry(int tag, short index0, short index1) { + this.tag = tag; + this.index0 = index0; + this.index1 = index1; + } + + public void write(DataOutputStream out) throws IOException { + out.writeByte(tag); + out.writeShort(index0); + /* + * If this entry type contains two indexes, write + * out the second, too. + */ + if (tag == CONSTANT_FIELD || + tag == CONSTANT_METHOD || + tag == CONSTANT_INTERFACEMETHOD || + tag == CONSTANT_NAMEANDTYPE) + { + out.writeShort(index1); + } + } + + public int hashCode() { + return tag + index0 + index1; + } + + public boolean equals(Object obj) { + if (obj instanceof IndirectEntry) { + IndirectEntry other = (IndirectEntry) obj; + if (tag == other.tag && + index0 == other.index0 && index1 == other.index1) + { + return true; + } + } + return false; + } + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Queue.java b/sources/net.sf.j2s.java.core/src/sun/misc/Queue.java index 74ed6d8ad..0eed6a087 100644 --- a/sources/net.sf.j2s.java.core/src/sun/misc/Queue.java +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Queue.java @@ -1,8 +1,5 @@ /* - * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017 - * for use in SwingJS via transpilation into JavaScript using Java2Script. - * - * Copyright (c) 1996, 2005, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1996, 2011, 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 @@ -31,8 +28,6 @@ import java.util.Enumeration; import java.util.NoSuchElementException; -import swingjs.JSUtil; - /** * Queue: implements a simple queue mechanism. Allows for enumeration of the * elements. @@ -40,13 +35,12 @@ * @author Herb Jellinek */ -@SuppressWarnings({"rawtypes"}) -public class Queue { +public class Queue { int length = 0; - QueueElement head = null; - QueueElement tail = null; + QueueElement head = null; + QueueElement tail = null; public Queue() { } @@ -54,9 +48,9 @@ public Queue() { /** * Enqueue an object. */ - public synchronized void enqueue(Object obj) { + public synchronized void enqueue(T obj) { - QueueElement newElt = new QueueElement(obj); + QueueElement newElt = new QueueElement<>(obj); if (head == null) { head = newElt; @@ -78,7 +72,7 @@ public synchronized void enqueue(Object obj) { * @exception java.lang.InterruptedException if any thread has * interrupted this thread. */ - public Object dequeue() throws InterruptedException { + public T dequeue() throws InterruptedException { return dequeue(0L); } @@ -91,15 +85,13 @@ public Object dequeue() throws InterruptedException { * @exception java.lang.InterruptedException if any thread has * interrupted this thread. */ - public synchronized Object dequeue(long timeOut) + public synchronized T dequeue(long timeOut) throws InterruptedException { while (tail == null) { - JSUtil.warn("Cannot wait in Queue.java"); - wait(timeOut); } - QueueElement elt = tail; + QueueElement elt = tail; tail = elt.prev; if (tail == null) { head = null; @@ -123,8 +115,8 @@ public synchronized boolean isEmpty() { * order. Use the Enumeration methods on the returned object to * fetch the elements sequentially. */ - public final synchronized Enumeration elements() { - return new LIFOQueueEnumerator(this); + public final synchronized Enumeration elements() { + return new LIFOQueueEnumerator<>(this); } /** @@ -132,8 +124,8 @@ public final synchronized Enumeration elements() { * order. Use the Enumeration methods on the returned object to * fetch the elements sequentially. */ - public final synchronized Enumeration reverseElements() { - return new FIFOQueueEnumerator(this); + public final synchronized Enumeration reverseElements() { + return new FIFOQueueEnumerator<>(this); } public synchronized void dump(String msg) { @@ -141,8 +133,8 @@ public synchronized void dump(String msg) { System.err.println("["+length+" elt(s); head = "+ (head == null ? "null" : (head.obj)+"")+ " tail = "+(tail == null ? "null" : (tail.obj)+"")); - QueueElement cursor = head; - QueueElement last = null; + QueueElement cursor = head; + QueueElement last = null; while (cursor != null) { System.err.println(" "+cursor); last = cursor; @@ -155,26 +147,23 @@ public synchronized void dump(String msg) { } } -@SuppressWarnings("rawtypes") -final class FIFOQueueEnumerator implements Enumeration { - Queue queue; - QueueElement cursor; +final class FIFOQueueEnumerator implements Enumeration { + Queue queue; + QueueElement cursor; - FIFOQueueEnumerator(Queue q) { + FIFOQueueEnumerator(Queue q) { queue = q; cursor = q.tail; } - @Override - public boolean hasMoreElements() { + public boolean hasMoreElements() { return (cursor != null); } - @Override - public Object nextElement() { + public T nextElement() { synchronized (queue) { if (cursor != null) { - QueueElement result = cursor; + QueueElement result = cursor; cursor = cursor.prev; return result.obj; } @@ -183,26 +172,23 @@ public Object nextElement() { } } -@SuppressWarnings("rawtypes") -final class LIFOQueueEnumerator implements Enumeration { - Queue queue; - QueueElement cursor; +final class LIFOQueueEnumerator implements Enumeration { + Queue queue; + QueueElement cursor; - LIFOQueueEnumerator(Queue q) { + LIFOQueueEnumerator(Queue q) { queue = q; cursor = q.head; } - @Override - public boolean hasMoreElements() { + public boolean hasMoreElements() { return (cursor != null); } - @Override - public Object nextElement() { + public T nextElement() { synchronized (queue) { if (cursor != null) { - QueueElement result = cursor; + QueueElement result = cursor; cursor = cursor.next; return result.obj; } @@ -211,18 +197,17 @@ public Object nextElement() { } } -class QueueElement { - QueueElement next = null; - QueueElement prev = null; +class QueueElement { + QueueElement next = null; + QueueElement prev = null; - Object obj = null; + T obj = null; - QueueElement(Object obj) { + QueueElement(T obj) { this.obj = obj; } - @Override - public String toString() { + public String toString() { return "QueueElement[obj="+obj+(prev == null ? " null" : " prev")+ (next == null ? " null" : " next")+"]"; } diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/REException.java b/sources/net.sf.j2s.java.core/src/sun/misc/REException.java new file mode 100644 index 000000000..db68992d5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/REException.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 1995, 2011, 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.misc; + +/** + * A class to signal exception from the RegexpPool class. + * @author James Gosling + */ + +public class REException extends Exception { + + private static final long serialVersionUID = 4656584872733646963L; + + REException (String s) { + super(s); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Regexp.java b/sources/net.sf.j2s.java.core/src/sun/misc/Regexp.java new file mode 100644 index 000000000..4d488363b --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Regexp.java @@ -0,0 +1,141 @@ +/* + * Copyright (c) 1995, 2004, 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.misc; + +/** + * A class to represent a regular expression. Only handles '*'s. + * @author James Gosling + */ + +public class Regexp { + /** if true then the matching process ignores case. */ + public boolean ignoreCase; + + /* + * regular expressions are carved into three regions: a constant string + * prefix, a constant string suffix, and a series of floating strings in + * between. In the input regular expression, they are separated by *s + */ + public String exp; + public String prefix, suffix; + public boolean exact; + public int prefixLen, suffixLen, totalLen; + public String mids[]; + + /** Create a new regular expression object. The regular expression + is a series of constant strings separated by *s. For example: +

      +
      *.gif
      Matches any string that ends in ".gif". +
      /tmp/*
      Matches any string that starts with "/tmp/". +
      /tmp/*.gif
      Matches any string that starts with "/tmp/" and ends + with ".gif". +
      /tmp/*new*.gif
      Matches any string that starts with "/tmp/" + and ends with ".gif" and has "new" somewhere in between. +
      + */ + public Regexp (String s) { + exp = s; + int firstst = s.indexOf('*'); + int lastst = s.lastIndexOf('*'); + if (firstst < 0) { + totalLen = s.length(); + exact = true; // no * s + } else { + prefixLen = firstst; + if (firstst == 0) + prefix = null; + else + prefix = s.substring(0, firstst); + suffixLen = s.length() - lastst - 1; + if (suffixLen == 0) + suffix = null; + else + suffix = s.substring(lastst + 1); + int nmids = 0; + int pos = firstst; + while (pos < lastst && pos >= 0) { + nmids++; + pos = s.indexOf('*', pos + 1); + } + totalLen = prefixLen + suffixLen; + if (nmids > 0) { + mids = new String[nmids]; + pos = firstst; + for (int i = 0; i < nmids; i++) { + pos++; + int npos = s.indexOf('*', pos); + if (pos < npos) { + mids[i] = s.substring(pos, npos); + totalLen += mids[i].length(); + } + pos = npos; + } + } + } + } + + /** Returns true iff the String s matches this regular expression. */ + final boolean matches(String s) { + return matches(s, 0, s.length()); + } + + /** Returns true iff the substring of s from offset for len characters + matches this regular expression. */ + boolean matches(String s, int offset, int len) { + if (exact) + return len == totalLen && + exp.regionMatches(ignoreCase, 0, s, offset, len); + if (len < totalLen) + return false; + if (prefixLen > 0 && + !prefix.regionMatches(ignoreCase, + 0, s, offset, prefixLen) + || + suffixLen > 0 && + !suffix.regionMatches(ignoreCase, + 0, s, offset + len - suffixLen, + suffixLen)) + return false; + if (mids == null) + return true; + int nmids = mids.length; + int spos = offset + prefixLen; + int limit = offset+len-suffixLen; + for (int i = 0; ilimit) + return false; + spos+=ml; + } + return true; + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/RegexpPool.java b/sources/net.sf.j2s.java.core/src/sun/misc/RegexpPool.java new file mode 100644 index 000000000..c82c66fee --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/RegexpPool.java @@ -0,0 +1,319 @@ +/* + * Copyright (c) 1995, 2001, 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.misc; +import java.io.*; + +/** + * A class to represent a pool of regular expressions. A string + * can be matched against the whole pool all at once. It is much + * faster than doing individual regular expression matches one-by-one. + * + * @see java.misc.RegexpTarget + * @author James Gosling + */ + +public class RegexpPool { + private RegexpNode prefixMachine = new RegexpNode(); + private RegexpNode suffixMachine = new RegexpNode(); + private static final int BIG = 0x7FFFFFFF; + private int lastDepth = BIG; + + public RegexpPool () { + } + + /** + * Add a regular expression to the pool of regular expressions. + * @param re The regular expression to add to the pool. + For now, only handles strings that either begin or end with + a '*'. + * @param ret The object to be returned when this regular expression is + matched. If ret is an instance of the RegexpTarget class, ret.found + is called with the string fragment that matched the '*' as its + parameter. + * @exception REException error + */ + public void add(String re, Object ret) throws REException { + add(re, ret, false); + } + + /** + * Replace the target for the regular expression with a different + * target. + * + * @param re The regular expression to be replaced in the pool. + * For now, only handles strings that either begin or end with + * a '*'. + * @param ret The object to be returned when this regular expression is + * matched. If ret is an instance of the RegexpTarget class, ret.found + * is called with the string fragment that matched the '*' as its + * parameter. + */ + public void replace(String re, Object ret) { + try { + add(re, ret, true); + } catch(Exception e) { + // should never occur if replace is true + } + } + + /** + * Delete the regular expression and its target. + * @param re The regular expression to be deleted from the pool. + * must begin or end with a '*' + * @return target - the old target. + */ + public Object delete(String re) { + Object o = null; + RegexpNode p = prefixMachine; + RegexpNode best = p; + int len = re.length() - 1; + int i; + boolean prefix = true; + + if (!re.startsWith("*") || + !re.endsWith("*")) + len++; + + if (len <= 0) + return null; + + /* March forward through the prefix machine */ + for (i = 0; p != null; i++) { + if (p.result != null && p.depth < BIG + && (!p.exact || i == len)) { + best = p; + } + if (i >= len) + break; + p = p.find(re.charAt(i)); + } + + /* march backward through the suffix machine */ + p = suffixMachine; + for (i = len; --i >= 0 && p != null;) { + if (p.result != null && p.depth < BIG) { + prefix = false; + best = p; + } + p = p.find(re.charAt(i)); + } + + // delete only if there is an exact match + if (prefix) { + if (re.equals(best.re)) { + o = best.result; + best.result = null; + + } + } else { + if (re.equals(best.re)) { + o = best.result; + best.result = null; + } + } + return o; + } + + /** Search for a match to a string & return the object associated + with it with the match. When multiple regular expressions + would match the string, the best match is returned first. + The next best match is returned the next time matchNext is + called. + @param s The string to match against the regular expressions + in the pool. + @return null on failure, otherwise the object associated with + the regular expression when it was added to the pool. + If the object is an instance of RegexpTarget, then + the return value is the result from calling + return.found(string_that_matched_wildcard). + */ + public Object match(String s) { + return matchAfter(s, BIG); + } + + /** Identical to match except that it will only find matches to + regular expressions that were added to the pool after + the last regular expression that matched in the last call + to match() or matchNext() */ + public Object matchNext(String s) { + return matchAfter(s, lastDepth); + } + + private void add(String re, Object ret, boolean replace) throws REException { + int len = re.length(); + RegexpNode p; + if (re.charAt(0) == '*') { + p = suffixMachine; + while (len > 1) + p = p.add(re.charAt(--len)); + } else { + boolean exact = false; + if (re.charAt(len - 1) == '*') + len--; + else + exact = true; + p = prefixMachine; + for (int i = 0; i < len; i++) + p = p.add(re.charAt(i)); + p.exact = exact; + } + + if (p.result != null && !replace) + throw new REException(re + " is a duplicate"); + + p.re = re; + p.result = ret; + } + + private Object matchAfter(String s, int lastMatchDepth) { + RegexpNode p = prefixMachine; + RegexpNode best = p; + int bst = 0; + int bend = 0; + int len = s.length(); + int i; + if (len <= 0) + return null; + /* March forward through the prefix machine */ + for (i = 0; p != null; i++) { + if (p.result != null && p.depth < lastMatchDepth + && (!p.exact || i == len)) { + lastDepth = p.depth; + best = p; + bst = i; + bend = len; + } + if (i >= len) + break; + p = p.find(s.charAt(i)); + } + /* march backward through the suffix machine */ + p = suffixMachine; + for (i = len; --i >= 0 && p != null;) { + if (p.result != null && p.depth < lastMatchDepth) { + lastDepth = p.depth; + best = p; + bst = 0; + bend = i+1; + } + p = p.find(s.charAt(i)); + } + Object o = best.result; + if (o != null && o instanceof RegexpTarget) + o = ((RegexpTarget) o).found(s.substring(bst, bend)); + return o; + } + + /** Resets the pool so that the next call to matchNext looks + at all regular expressions in the pool. match(s); is equivalent + to reset(); matchNext(s); +

      Multithreading note: reset/nextMatch leave state in the + regular expression pool. If multiple threads could be using this + pool this way, they should be syncronized to avoid race hazards. + match() was done in such a way that there are no such race + hazards: multiple threads can be matching in the same pool + simultaneously. */ + public void reset() { + lastDepth = BIG; + } + + /** Print this pool to standard output */ + public void print(PrintStream out) { + out.print("Regexp pool:\n"); + if (suffixMachine.firstchild != null) { + out.print(" Suffix machine: "); + suffixMachine.firstchild.print(out); + out.print("\n"); + } + if (prefixMachine.firstchild != null) { + out.print(" Prefix machine: "); + prefixMachine.firstchild.print(out); + out.print("\n"); + } + } + +} + +/* A node in a regular expression finite state machine. */ +class RegexpNode { + char c; + RegexpNode firstchild; + RegexpNode nextsibling; + int depth; + boolean exact; + Object result; + String re = null; + + RegexpNode () { + c = '#'; + depth = 0; + } + RegexpNode (char C, int depth) { + c = C; + this.depth = depth; + } + RegexpNode add(char C) { + RegexpNode p = firstchild; + if (p == null) + p = new RegexpNode (C, depth+1); + else { + while (p != null) + if (p.c == C) + return p; + else + p = p.nextsibling; + p = new RegexpNode (C, depth+1); + p.nextsibling = firstchild; + } + firstchild = p; + return p; + } + RegexpNode find(char C) { + for (RegexpNode p = firstchild; + p != null; + p = p.nextsibling) + if (p.c == C) + return p; + return null; + } + void print(PrintStream out) { + if (nextsibling != null) { + RegexpNode p = this; + out.print("("); + while (p != null) { + out.write(p.c); + if (p.firstchild != null) + p.firstchild.print(out); + p = p.nextsibling; + out.write(p != null ? '|' : ')'); + } + } else { + out.write(c); + if (firstchild != null) + firstchild.print(out); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/RegexpTarget.java b/sources/net.sf.j2s.java.core/src/sun/misc/RegexpTarget.java new file mode 100644 index 000000000..a44028acf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/RegexpTarget.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1995, 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.misc; + +/** + * A class to define actions to be performed when a regular expression match + * occurs. + * @author James Gosling + */ + +public interface RegexpTarget { + /** Gets called when a pattern in a RegexpPool matches. + * This method is called by RegexpPool.match() who passes the return + * value from found() back to its caller. + * @param remainder the string that matched the * in the pattern. + */ + Object found(String remainder); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Request.java b/sources/net.sf.j2s.java.core/src/sun/misc/Request.java new file mode 100644 index 000000000..5301e4cc5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Request.java @@ -0,0 +1,41 @@ +/* + * Copyright (c) 1996, 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.misc; + +/** + * Requests are functor objects; that is, they provide part of the mechanism + * for deferred function application. + * + * @author Steven B. Byrne + */ + +abstract public class Request { + /** + * The main task of the Request object is to be exectuted from a request + * queue. + */ + abstract public void execute(); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/RequestProcessor.java b/sources/net.sf.j2s.java.core/src/sun/misc/RequestProcessor.java new file mode 100644 index 000000000..54a62724d --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/RequestProcessor.java @@ -0,0 +1,96 @@ +/* + * Copyright (c) 1996, 2011, 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.misc; + +/** + * The request processor allows functors (Request instances) to be created + * in arbitrary threads, and to be posted for execution in a non-restricted + * thread. + * + * @author Steven B. Byrne + */ + + +public class RequestProcessor implements Runnable { + + private static Queue requestQueue; + private static Thread dispatcher; + + /** + * Queues a Request instance for execution by the request procesor + * thread. + */ + public static void postRequest(Request req) { + lazyInitialize(); + requestQueue.enqueue(req); + } + + /** + * Process requests as they are queued. + */ + public void run() { + lazyInitialize(); + while (true) { + try { + Request req = requestQueue.dequeue(); + try { + req.execute(); + } catch (Throwable t) { + // do nothing at the moment...maybe report an error + // in the future + } + } catch (InterruptedException e) { + // do nothing at the present time. + } + } + } + + + /** + * This method initiates the request processor thread. It is safe + * to call it after the thread has been started. It provides a way for + * clients to deliberately control the context in which the request + * processor thread is created + */ + public static synchronized void startProcessing() { + if (dispatcher == null) { + dispatcher = new Thread(new RequestProcessor(), "Request Processor"); + dispatcher.setPriority(Thread.NORM_PRIORITY + 2); + dispatcher.start(); + } + } + + + /** + * This method performs lazy initialization. + */ + private static synchronized void lazyInitialize() { + if (requestQueue == null) { + requestQueue = new Queue(); + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Service.java b/sources/net.sf.j2s.java.core/src/sun/misc/Service.java new file mode 100644 index 000000000..46b2660c7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Service.java @@ -0,0 +1,434 @@ +/* + * Copyright (c) 1999, 2012, 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.misc; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.URL; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.TreeSet; + + +/** + * A simple service-provider lookup mechanism. A service is a + * well-known set of interfaces and (usually abstract) classes. A service + * provider is a specific implementation of a service. The classes in a + * provider typically implement the interfaces and subclass the classes defined + * in the service itself. Service providers may be installed in an + * implementation of the Java platform in the form of extensions, that is, jar + * files placed into any of the usual extension directories. Providers may + * also be made available by adding them to the applet or application class + * path or by some other platform-specific means. + * + *

      In this lookup mechanism a service is represented by an interface or an + * abstract class. (A concrete class may be used, but this is not + * recommended.) A provider of a given service contains one or more concrete + * classes that extend this service class with data and code specific to + * the provider. This provider class will typically not be the entire + * provider itself but rather a proxy that contains enough information to + * decide whether the provider is able to satisfy a particular request together + * with code that can create the actual provider on demand. The details of + * provider classes tend to be highly service-specific; no single class or + * interface could possibly unify them, so no such class has been defined. The + * only requirement enforced here is that provider classes must have a + * zero-argument constructor so that they may be instantiated during lookup. + * + *

      A service provider identifies itself by placing a provider-configuration + * file in the resource directory META-INF/services. The file's name + * should consist of the fully-qualified name of the abstract service class. + * The file should contain a list of fully-qualified concrete provider-class + * names, one per line. Space and tab characters surrounding each name, as + * well as blank lines, are ignored. The comment character is '#' + * (0x23); on each line all characters following the first comment + * character are ignored. The file must be encoded in UTF-8. + * + *

      If a particular concrete provider class is named in more than one + * configuration file, or is named in the same configuration file more than + * once, then the duplicates will be ignored. The configuration file naming a + * particular provider need not be in the same jar file or other distribution + * unit as the provider itself. The provider must be accessible from the same + * class loader that was initially queried to locate the configuration file; + * note that this is not necessarily the class loader that found the file. + * + *

      Example: Suppose we have a service class named + * java.io.spi.CharCodec. It has two abstract methods: + * + *

      + *   public abstract CharEncoder getEncoder(String encodingName);
      + *   public abstract CharDecoder getDecoder(String encodingName);
      + * 
      + * + * Each method returns an appropriate object or null if it cannot + * translate the given encoding. Typical CharCodec providers will + * support more than one encoding. + * + *

      If sun.io.StandardCodec is a provider of the CharCodec + * service then its jar file would contain the file + * META-INF/services/java.io.spi.CharCodec. This file would contain + * the single line: + * + *

      + *   sun.io.StandardCodec    # Standard codecs for the platform
      + * 
      + * + * To locate an encoder for a given encoding name, the internal I/O code would + * do something like this: + * + *
      + *   CharEncoder getEncoder(String encodingName) {
      + *       Iterator ps = Service.providers(CharCodec.class);
      + *       while (ps.hasNext()) {
      + *           CharCodec cc = (CharCodec)ps.next();
      + *           CharEncoder ce = cc.getEncoder(encodingName);
      + *           if (ce != null)
      + *               return ce;
      + *       }
      + *       return null;
      + *   }
      + * 
      + * + * The provider-lookup mechanism always executes in the security context of the + * caller. Trusted system code should typically invoke the methods in this + * class from within a privileged security context. + * + * @author Mark Reinhold + * @since 1.3 + */ + +public final class Service { + + private static final String prefix = "META-INF/services/"; + + private Service() { } + + private static void fail(Class service, String msg, Throwable cause) + throws ServiceConfigurationError + { + ServiceConfigurationError sce + = new ServiceConfigurationError(service.getName() + ": " + msg); + sce.initCause(cause); + throw sce; + } + + private static void fail(Class service, String msg) + throws ServiceConfigurationError + { + throw new ServiceConfigurationError(service.getName() + ": " + msg); + } + + private static void fail(Class service, URL u, int line, String msg) + throws ServiceConfigurationError + { + fail(service, u + ":" + line + ": " + msg); + } + + /** + * Parse a single line from the given configuration file, adding the name + * on the line to both the names list and the returned set iff the name is + * not already a member of the returned set. + */ + private static int parseLine(Class service, URL u, BufferedReader r, int lc, + List names, Set returned) + throws IOException, ServiceConfigurationError + { + String ln = r.readLine(); + if (ln == null) { + return -1; + } + int ci = ln.indexOf('#'); + if (ci >= 0) ln = ln.substring(0, ci); + ln = ln.trim(); + int n = ln.length(); + if (n != 0) { + if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) + fail(service, u, lc, "Illegal configuration-file syntax"); + int cp = ln.codePointAt(0); + if (!Character.isJavaIdentifierStart(cp)) + fail(service, u, lc, "Illegal provider-class name: " + ln); + for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) { + cp = ln.codePointAt(i); + if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) + fail(service, u, lc, "Illegal provider-class name: " + ln); + } + if (!returned.contains(ln)) { + names.add(ln); + returned.add(ln); + } + } + return lc + 1; + } + + /** + * Parse the content of the given URL as a provider-configuration file. + * + * @param service + * The service class for which providers are being sought; + * used to construct error detail strings + * + * @param url + * The URL naming the configuration file to be parsed + * + * @param returned + * A Set containing the names of provider classes that have already + * been returned. This set will be updated to contain the names + * that will be yielded from the returned Iterator. + * + * @return A (possibly empty) Iterator that will yield the + * provider-class names in the given configuration file that are + * not yet members of the returned set + * + * @throws ServiceConfigurationError + * If an I/O error occurs while reading from the given URL, or + * if a configuration-file format error is detected + */ + private static Iterator parse(Class service, URL u, Set returned) + throws ServiceConfigurationError + { + InputStream in = null; + BufferedReader r = null; + ArrayList names = new ArrayList<>(); + try { + in = u.openStream(); + r = new BufferedReader(new InputStreamReader(in, "utf-8")); + int lc = 1; + while ((lc = parseLine(service, u, r, lc, names, returned)) >= 0); + } catch (IOException x) { + fail(service, ": " + x); + } finally { + try { + if (r != null) r.close(); + if (in != null) in.close(); + } catch (IOException y) { + fail(service, ": " + y); + } + } + return names.iterator(); + } + + + /** + * Private inner class implementing fully-lazy provider lookup + */ + private static class LazyIterator implements Iterator { + + Class service; + ClassLoader loader; + Enumeration configs = null; + Iterator pending = null; + Set returned = new TreeSet<>(); + String nextName = null; + + private LazyIterator(Class service, ClassLoader loader) { + this.service = service; + this.loader = loader; + } + + public boolean hasNext() throws ServiceConfigurationError { + if (nextName != null) { + return true; + } + if (configs == null) { + try { + String fullName = prefix + service.getName(); + if (loader == null) + configs = ClassLoader.getSystemResources(fullName); + else + configs = loader.getResources(fullName); + } catch (IOException x) { + fail(service, ": " + x); + } + } + while ((pending == null) || !pending.hasNext()) { + if (!configs.hasMoreElements()) { + return false; + } + pending = parse(service, configs.nextElement(), returned); + } + nextName = pending.next(); + return true; + } + + public S next() throws ServiceConfigurationError { + if (!hasNext()) { + throw new NoSuchElementException(); + } + String cn = nextName; + nextName = null; + Class c = null; + try { + c = Class.forName(cn, false, loader); + } catch (ClassNotFoundException x) { + fail(service, + "Provider " + cn + " not found"); + } + if (!service.isAssignableFrom(c)) { + fail(service, + "Provider " + cn + " not a subtype"); + } + try { + return service.cast(c.newInstance()); + } catch (Throwable x) { + fail(service, + "Provider " + cn + " could not be instantiated", + x); + } + return null; /* This cannot happen */ + } + + public void remove() { + throw new UnsupportedOperationException(); + } + + } + + + /** + * Locates and incrementally instantiates the available providers of a + * given service using the given class loader. + * + *

      This method transforms the name of the given service class into a + * provider-configuration filename as described above and then uses the + * getResources method of the given class loader to find all + * available files with that name. These files are then read and parsed to + * produce a list of provider-class names. The iterator that is returned + * uses the given class loader to lookup and then instantiate each element + * of the list. + * + *

      Because it is possible for extensions to be installed into a running + * Java virtual machine, this method may return different results each time + * it is invoked.

      + * + * @param service + * The service's abstract service class + * + * @param loader + * The class loader to be used to load provider-configuration files + * and instantiate provider classes, or null if the system + * class loader (or, failing that the bootstrap class loader) is to + * be used + * + * @return An Iterator that yields provider objects for the given + * service, in some arbitrary order. The iterator will throw a + * ServiceConfigurationError if a provider-configuration + * file violates the specified format or if a provider class cannot + * be found and instantiated. + * + * @throws ServiceConfigurationError + * If a provider-configuration file violates the specified format + * or names a provider class that cannot be found and instantiated + * + * @see #providers(java.lang.Class) + * @see #installedProviders(java.lang.Class) + */ + public static Iterator providers(Class service, ClassLoader loader) + throws ServiceConfigurationError + { + return new LazyIterator(service, loader); + } + + + /** + * Locates and incrementally instantiates the available providers of a + * given service using the context class loader. This convenience method + * is equivalent to + * + *

      +     *   ClassLoader cl = Thread.currentThread().getContextClassLoader();
      +     *   return Service.providers(service, cl);
      +     * 
      + * + * @param service + * The service's abstract service class + * + * @return An Iterator that yields provider objects for the given + * service, in some arbitrary order. The iterator will throw a + * ServiceConfigurationError if a provider-configuration + * file violates the specified format or if a provider class cannot + * be found and instantiated. + * + * @throws ServiceConfigurationError + * If a provider-configuration file violates the specified format + * or names a provider class that cannot be found and instantiated + * + * @see #providers(java.lang.Class, java.lang.ClassLoader) + */ + public static Iterator providers(Class service) + throws ServiceConfigurationError + { + ClassLoader cl = Thread.currentThread().getContextClassLoader(); + return Service.providers(service, cl); + } + + + /** + * Locates and incrementally instantiates the available providers of a + * given service using the extension class loader. This convenience method + * simply locates the extension class loader, call it + * extClassLoader, and then does + * + *
      +     *   return Service.providers(service, extClassLoader);
      +     * 
      + * + * If the extension class loader cannot be found then the system class + * loader is used; if there is no system class loader then the bootstrap + * class loader is used. + * + * @param service + * The service's abstract service class + * + * @return An Iterator that yields provider objects for the given + * service, in some arbitrary order. The iterator will throw a + * ServiceConfigurationError if a provider-configuration + * file violates the specified format or if a provider class cannot + * be found and instantiated. + * + * @throws ServiceConfigurationError + * If a provider-configuration file violates the specified format + * or names a provider class that cannot be found and instantiated + * + * @see #providers(java.lang.Class, java.lang.ClassLoader) + */ + public static Iterator installedProviders(Class service) + throws ServiceConfigurationError + { + ClassLoader cl = ClassLoader.getSystemClassLoader(); + ClassLoader prev = null; + while (cl != null) { + prev = cl; + cl = cl.getParent(); + } + return Service.providers(service, prev); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ServiceConfigurationError.java b/sources/net.sf.j2s.java.core/src/sun/misc/ServiceConfigurationError.java new file mode 100644 index 000000000..1060f2079 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ServiceConfigurationError.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 1999, 2011, 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.misc; + + +/** + * Error thrown when something goes wrong while looking up service providers. + * In particular, this error will be thrown in the following situations: + * + *
        + *
      • A concrete provider class cannot be found, + *
      • A concrete provider class cannot be instantiated, + *
      • The format of a provider-configuration file is illegal, or + *
      • An IOException occurs while reading a provider-configuration file. + *
      + * + * @author Mark Reinhold + * @since 1.3 + */ + +public class ServiceConfigurationError extends Error { + + static final long serialVersionUID = 8769866263384244465L; + + /** + * Constructs a new instance with the specified detail string. + */ + public ServiceConfigurationError(String msg) { + super(msg); + } + + /** + * Constructs a new instance that wraps the specified throwable. + */ + public ServiceConfigurationError(Throwable x) { + super(x); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/SharedSecrets.java b/sources/net.sf.j2s.java.core/src/sun/misc/SharedSecrets.java new file mode 100644 index 000000000..bc2ab2e9e --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/SharedSecrets.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 2002, 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.misc; + +import java.util.jar.JarFile; +import java.io.Console; +import java.io.FileDescriptor; +import java.security.ProtectionDomain; + +import java.security.AccessController; + +/** A repository of "shared secrets", which are a mechanism for + calling implementation-private methods in another package without + using reflection. A package-private class implements a public + interface and provides the ability to call package-private methods + within that package; the object implementing that interface is + provided through a third package to which access is restricted. + This framework avoids the primary disadvantage of using reflection + for this purpose, namely the loss of compile-time checking. */ + +public class SharedSecrets { + private static final Unsafe unsafe = Unsafe.getUnsafe(); + private static JavaUtilJarAccess javaUtilJarAccess; + private static JavaLangAccess javaLangAccess; + private static JavaIOAccess javaIOAccess; + private static JavaNetAccess javaNetAccess; + private static JavaNetHttpCookieAccess javaNetHttpCookieAccess; + private static JavaNioAccess javaNioAccess; + private static JavaIOFileDescriptorAccess javaIOFileDescriptorAccess; + private static JavaSecurityProtectionDomainAccess javaSecurityProtectionDomainAccess; + private static JavaSecurityAccess javaSecurityAccess; + private static JavaUtilZipFileAccess javaUtilZipFileAccess; + private static JavaAWTAccess javaAWTAccess; + + public static JavaUtilJarAccess javaUtilJarAccess() { + if (javaUtilJarAccess == null) { + // Ensure JarFile is initialized; we know that that class + // provides the shared secret + unsafe.ensureClassInitialized(JarFile.class); + } + return javaUtilJarAccess; + } + + public static void setJavaUtilJarAccess(JavaUtilJarAccess access) { + javaUtilJarAccess = access; + } + + public static void setJavaLangAccess(JavaLangAccess jla) { + javaLangAccess = jla; + } + + public static JavaLangAccess getJavaLangAccess() { + return javaLangAccess; + } + + public static void setJavaNetAccess(JavaNetAccess jna) { + javaNetAccess = jna; + } + + public static JavaNetAccess getJavaNetAccess() { + return javaNetAccess; + } + + public static void setJavaNetHttpCookieAccess(JavaNetHttpCookieAccess a) { + javaNetHttpCookieAccess = a; + } + + public static JavaNetHttpCookieAccess getJavaNetHttpCookieAccess() { + if (javaNetHttpCookieAccess == null) + unsafe.ensureClassInitialized(java.net.HttpCookie.class); + return javaNetHttpCookieAccess; + } + + public static void setJavaNioAccess(JavaNioAccess jna) { + javaNioAccess = jna; + } + + public static JavaNioAccess getJavaNioAccess() { + if (javaNioAccess == null) { + // Ensure java.nio.ByteOrder is initialized; we know that + // this class initializes java.nio.Bits that provides the + // shared secret. + unsafe.ensureClassInitialized(java.nio.ByteOrder.class); + } + return javaNioAccess; + } + + public static void setJavaIOAccess(JavaIOAccess jia) { + javaIOAccess = jia; + } + + public static JavaIOAccess getJavaIOAccess() { + if (javaIOAccess == null) { + unsafe.ensureClassInitialized(Console.class); + } + return javaIOAccess; + } + + public static void setJavaIOFileDescriptorAccess(JavaIOFileDescriptorAccess jiofda) { + javaIOFileDescriptorAccess = jiofda; + } + + public static JavaIOFileDescriptorAccess getJavaIOFileDescriptorAccess() { + if (javaIOFileDescriptorAccess == null) + unsafe.ensureClassInitialized(FileDescriptor.class); + + return javaIOFileDescriptorAccess; + } + + public static void setJavaSecurityProtectionDomainAccess + (JavaSecurityProtectionDomainAccess jspda) { + javaSecurityProtectionDomainAccess = jspda; + } + + public static JavaSecurityProtectionDomainAccess + getJavaSecurityProtectionDomainAccess() { + if (javaSecurityProtectionDomainAccess == null) + unsafe.ensureClassInitialized(ProtectionDomain.class); + return javaSecurityProtectionDomainAccess; + } + + public static void setJavaSecurityAccess(JavaSecurityAccess jsa) { + javaSecurityAccess = jsa; + } + + public static JavaSecurityAccess getJavaSecurityAccess() { + if (javaSecurityAccess == null) { + unsafe.ensureClassInitialized(AccessController.class); + } + return javaSecurityAccess; + } + + public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() { + if (javaUtilZipFileAccess == null) + unsafe.ensureClassInitialized(java.util.zip.ZipFile.class); + return javaUtilZipFileAccess; + } + + public static void setJavaUtilZipFileAccess(JavaUtilZipFileAccess access) { + javaUtilZipFileAccess = access; + } + + public static void setJavaAWTAccess(JavaAWTAccess jaa) { + javaAWTAccess = jaa; + } + + public static JavaAWTAccess getJavaAWTAccess() { + // this may return null in which case calling code needs to + // provision for. + if (javaAWTAccess == null) { + return null; + } + return javaAWTAccess; + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Signal.java b/sources/net.sf.j2s.java.core/src/sun/misc/Signal.java new file mode 100644 index 000000000..07557a8d7 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Signal.java @@ -0,0 +1,232 @@ +/* + * Copyright (c) 1998, 2011, 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.misc; +import java.util.Hashtable; + +/** + * This class provides ANSI/ISO C signal support. A Java program can register + * signal handlers for the current process. There are two restrictions: + *
        + *
      • + * Java code cannot register a handler for signals that are already used + * by the Java VM implementation. The Signal.handle + * function raises an IllegalArgumentException if such an attempt + * is made. + *
      • + * When Signal.handle is called, the VM internally registers a + * special C signal handler. There is no way to force the Java signal handler + * to run synchronously before the C signal handler returns. Instead, when the + * VM receives a signal, the special C signal handler creates a new thread + * (at priority Thread.MAX_PRIORITY) to + * run the registered Java signal handler. The C signal handler immediately + * returns. Note that because the Java signal handler runs in a newly created + * thread, it may not actually be executed until some time after the C signal + * handler returns. + *
      + *

      + * Signal objects are created based on their names. For example: + *

      + * new Signal("INT");
      + * 
      + * constructs a signal object corresponding to SIGINT, which is + * typically produced when the user presses Ctrl-C at the command line. + * The Signal constructor throws IllegalArgumentException + * when it is passed an unknown signal. + *

      + * This is an example of how Java code handles SIGINT: + *

      + * SignalHandler handler = new SignalHandler () {
      + *     public void handle(Signal sig) {
      + *       ... // handle SIGINT
      + *     }
      + * };
      + * Signal.handle(new Signal("INT"), handler);
      + * 
      + * + * @author Sheng Liang + * @author Bill Shannon + * @see sun.misc.SignalHandler + * @since 1.2 + */ +public final class Signal { + private static Hashtable handlers = new Hashtable<>(4); + private static Hashtable signals = new Hashtable<>(4); + + private int number; + private String name; + + /* Returns the signal number */ + public int getNumber() { + return number; + } + + /** + * Returns the signal name. + * + * @return the name of the signal. + * @see sun.misc.Signal#Signal(String name) + */ + public String getName() { + return name; + } + + /** + * Compares the equality of two Signal objects. + * + * @param other the object to compare with. + * @return whether two Signal objects are equal. + */ + public boolean equals(Object other) { + if (this == other) { + return true; + } + if (other == null || !(other instanceof Signal)) { + return false; + } + Signal other1 = (Signal)other; + return name.equals(other1.name) && (number == other1.number); + } + + /** + * Returns a hashcode for this Signal. + * + * @return a hash code value for this object. + */ + public int hashCode() { + return number; + } + + /** + * Returns a string representation of this signal. For example, "SIGINT" + * for an object constructed using new Signal ("INT"). + * + * @return a string representation of the signal + */ + public String toString() { + return "SIG" + name; + } + + /** + * Constructs a signal from its name. + * + * @param name the name of the signal. + * @exception IllegalArgumentException unknown signal + * @see sun.misc.Signal#getName() + */ + public Signal(String name) { + number = findSignal(name); + this.name = name; + if (number < 0) { + throw new IllegalArgumentException("Unknown signal: " + name); + } + } + + /** + * Registers a signal handler. + * + * @param sig a signal + * @param handler the handler to be registered with the given signal. + * @result the old handler + * @exception IllegalArgumentException the signal is in use by the VM + * @see sun.misc.Signal#raise(Signal sig) + * @see sun.misc.SignalHandler + * @see sun.misc.SignalHandler#SIG_DFL + * @see sun.misc.SignalHandler#SIG_IGN + */ + public static synchronized SignalHandler handle(Signal sig, + SignalHandler handler) + throws IllegalArgumentException { + long newH = (handler instanceof NativeSignalHandler) ? + ((NativeSignalHandler)handler).getHandler() : 2; + long oldH = handle0(sig.number, newH); + if (oldH == -1) { + throw new IllegalArgumentException + ("Signal already used by VM or OS: " + sig); + } + signals.put(sig.number, sig); + synchronized (handlers) { + SignalHandler oldHandler = handlers.get(sig); + handlers.remove(sig); + if (newH == 2) { + handlers.put(sig, handler); + } + if (oldH == 0) { + return SignalHandler.SIG_DFL; + } else if (oldH == 1) { + return SignalHandler.SIG_IGN; + } else if (oldH == 2) { + return oldHandler; + } else { + return new NativeSignalHandler(oldH); + } + } + } + + /** + * Raises a signal in the current process. + * + * @param sig a signal + * @see sun.misc.Signal#handle(Signal sig, SignalHandler handler) + */ + public static void raise(Signal sig) throws IllegalArgumentException { + if (handlers.get(sig) == null) { + throw new IllegalArgumentException("Unhandled signal: " + sig); + } + raise0(sig.number); + } + + /* Called by the VM to execute Java signal handlers. */ + private static void dispatch(final int number) { + final Signal sig = signals.get(number); + final SignalHandler handler = handlers.get(sig); + + Runnable runnable = new Runnable () { + public void run() { + // Don't bother to reset the priority. Signal handler will + // run at maximum priority inherited from the VM signal + // dispatch thread. + // Thread.currentThread().setPriority(Thread.NORM_PRIORITY); + handler.handle(sig); + } + }; + if (handler != null) { + new Thread(runnable, sig + " handler").start(); + } + } + + /* Find the signal number, given a name. Returns -1 for unknown signals. */ + private static native int findSignal(String sigName); + /* Registers a native signal handler, and returns the old handler. + * Handler values: + * 0 default handler + * 1 ignore the signal + * 2 call back to Signal.dispatch + * other arbitrary native signal handlers + */ + private static native long handle0(int sig, long nativeH); + /* Raise a given signal number */ + private static native void raise0(int sig); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/SignalHandler.java b/sources/net.sf.j2s.java.core/src/sun/misc/SignalHandler.java new file mode 100644 index 000000000..e6cc96e73 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/SignalHandler.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 1998, 2006, 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.misc; + +/** + * This is the signal handler interface expected in Signal.handle. + * + * @author Sheng Liang + * @author Bill Shannon + * @see sun.misc.Signal + * @since 1.2 + */ + +public interface SignalHandler { + + /** + * The default signal handler + */ + public static final SignalHandler SIG_DFL = new NativeSignalHandler(0); + /** + * Ignore the signal + */ + public static final SignalHandler SIG_IGN = new NativeSignalHandler(1); + + /** + * Handle the given signal + * + * @param sig a signal object + */ + public void handle(Signal sig); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/SoftCache.java b/sources/net.sf.j2s.java.core/src/sun/misc/SoftCache.java new file mode 100644 index 000000000..85dde7a65 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/SoftCache.java @@ -0,0 +1,462 @@ +/* + * Copyright (c) 1998, 2006, 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.misc; +// +//import java.lang.ref.SoftReference; +//import java.lang.ref.ReferenceQueue; + +import java.util.Iterator; +import java.util.Map; +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.Set; +import java.util.AbstractSet; +import java.util.NoSuchElementException; + + +/** + * + * BH unfortunately not usable in JavaScript + * + * A memory-sensitive implementation of the Map interface. + * + *

      A SoftCache object uses {@link java.lang.ref.SoftReference + * soft references} to implement a memory-sensitive hash map. If the garbage + * collector determines at a certain point in time that a value object in a + * SoftCache entry is no longer strongly reachable, then it may + * remove that entry in order to release the memory occupied by the value + * object. All SoftCache objects are guaranteed to be completely + * cleared before the virtual machine will throw an + * OutOfMemoryError. Because of this automatic clearing feature, + * the behavior of this class is somewhat different from that of other + * Map implementations. + * + *

      Both null values and the null key are supported. This class has the + * same performance characteristics as the HashMap class, and has + * the same efficiency parameters of initial capacity and load + * factor. + * + *

      Like most collection classes, this class is not synchronized. A + * synchronized SoftCache may be constructed using the + * Collections.synchronizedMap method. + * + *

      In typical usage this class will be subclassed and the fill + * method will be overridden. When the get method is invoked on a + * key for which there is no mapping in the cache, it will in turn invoke the + * fill method on that key in an attempt to construct a + * corresponding value. If the fill method returns such a value + * then the cache will be updated and the new value will be returned. Thus, + * for example, a simple URL-content cache can be constructed as follows: + * + *

      + *     public class URLCache extends SoftCache {
      + *         protected Object fill(Object key) {
      + *             return ((URL)key).getContent();
      + *         }
      + *     }
      + * 
      + * + *

      The behavior of the SoftCache class depends in part upon + * the actions of the garbage collector, so several familiar (though not + * required) Map invariants do not hold for this class.

      + * Because entries are removed from a SoftCache in response to + * dynamic advice from the garbage collector, a SoftCache may + * behave as though an unknown thread is silently removing entries. In + * particular, even if you synchronize on a SoftCache instance and + * invoke none of its mutator methods, it is possible for the size + * method to return smaller values over time, for the isEmpty + * method to return false and then true, for the + * containsKey method to return true and later + * false for a given key, for the get method to + * return a value for a given key but later return null, for the + * put method to return null and the + * remove method to return false for a key that + * previously appeared to be in the map, and for successive examinations of the + * key set, the value set, and the entry set to yield successively smaller + * numbers of elements. + * + * @author Mark Reinhold + * @since 1.2 + * @see java.util.HashMap + * @see java.lang.ref.SoftReference + */ + + +public class SoftCache extends AbstractMap implements Map { + + /* The basic idea of this implementation is to maintain an internal HashMap + that maps keys to soft references whose referents are the keys' values; + the various accessor methods dereference these soft references before + returning values. Because we don't have access to the innards of the + HashMap, each soft reference must contain the key that maps to it so + that the processQueue method can remove keys whose values have been + discarded. Thus the HashMap actually maps keys to instances of the + ValueCell class, which is a simple extension of the SoftReference class. + */ + + + static private class ValueCell {//extends SoftReference { + static private Object INVALID_KEY = new Object(); + static private int dropped = 0; + private Object key; + private Object value; + + private ValueCell(Object key, Object value) { + this.value = value; + this.key = key; + } + + private static ValueCell create(Object key, Object value) + { + if (value == null) return null; + return new ValueCell(key, value); + } + + private static Object strip(Object val, boolean drop) { + if (val == null) return null; + ValueCell vc = (ValueCell)val; + Object o = vc.value; + if (drop) vc.drop(); + return o; + } + + private boolean isValid() { + return (key != INVALID_KEY); + } + + private void drop() { + // super.clear(); + key = INVALID_KEY; + dropped++; + } + + } + + + /* Hash table mapping keys to ValueCells */ + private Map hash; + + /* Reference queue for cleared ValueCells */ + // private ReferenceQueue queue = new ReferenceQueue(); + + + /* Process any ValueCells that have been cleared and enqueued by the + garbage collector. This method should be invoked once by each public + mutator in this class. We don't invoke this method in public accessors + because that can lead to surprising ConcurrentModificationExceptions. + */ + private void processQueue() { +// ValueCell vc; +// while ((vc = (ValueCell)queue.poll()) != null) { +// if (vc.isValid()) hash.remove(vc.key); +// else ValueCell.dropped--; +// } + } + + + /* -- Constructors -- */ + + /** + * Construct a new, empty SoftCache with the given + * initial capacity and the given load factor. + * + * @param initialCapacity The initial capacity of the cache + * + * @param loadFactor A number between 0.0 and 1.0 + * + * @throws IllegalArgumentException If the initial capacity is less than + * or equal to zero, or if the load + * factor is less than zero + */ + public SoftCache(int initialCapacity, float loadFactor) { + hash = new HashMap(initialCapacity, loadFactor); + } + + /** + * Construct a new, empty SoftCache with the given + * initial capacity and the default load factor. + * + * @param initialCapacity The initial capacity of the cache + * + * @throws IllegalArgumentException If the initial capacity is less than + * or equal to zero + */ + public SoftCache(int initialCapacity) { + hash = new HashMap(initialCapacity); + } + + /** + * Construct a new, empty SoftCache with the default + * capacity and the default load factor. + */ + public SoftCache() { + hash = new HashMap(); + } + + + /* -- Simple queries -- */ + + /** + * Return the number of key-value mappings in this cache. The time + * required by this operation is linear in the size of the map. + */ + public int size() { + return entrySet().size(); + } + + /** + * Return true if this cache contains no key-value mappings. + */ + public boolean isEmpty() { + return entrySet().isEmpty(); + } + + /** + * Return true if this cache contains a mapping for the + * specified key. If there is no mapping for the key, this method will not + * attempt to construct one by invoking the fill method. + * + * @param key The key whose presence in the cache is to be tested + */ + public boolean containsKey(Object key) { + return ValueCell.strip(hash.get(key), false) != null; + } + + + /* -- Lookup and modification operations -- */ + + /** + * Create a value object for the given key. This method is + * invoked by the get method when there is no entry for + * key. If this method returns a non-null value, + * then the cache will be updated to map key to that value, + * and that value will be returned by the get method. + * + *

      The default implementation of this method simply returns + * null for every key value. A subclass may + * override this method to provide more useful behavior. + * + * @param key The key for which a value is to be computed + * + * @return A value for key, or null if one + * could not be computed + * @see #get + */ + protected Object fill(Object key) { + return null; + } + + /** + * Return the value to which this cache maps the specified + * key. If the cache does not presently contain a value for + * this key, then invoke the fill method in an attempt to + * compute such a value. If that method returns a non-null + * value, then update the cache and return the new value. Otherwise, + * return null. + * + *

      Note that because this method may update the cache, it is considered + * a mutator and may cause ConcurrentModificationExceptions to + * be thrown if invoked while an iterator is in use. + * + * @param key The key whose associated value, if any, is to be returned + * + * @see #fill + */ + public Object get(Object key) { + processQueue(); + Object v = hash.get(key); + if (v == null) { + v = fill(key); + if (v != null) { + hash.put(key, ValueCell.create(key, v)); + return v; + } + } + return ValueCell.strip(v, false); + } + + /** + * Update this cache so that the given key maps to the given + * value. If the cache previously contained a mapping for + * key then that mapping is replaced and the old value is + * returned. + * + * @param key The key that is to be mapped to the given + * value + * @param value The value to which the given key is to be + * mapped + * + * @return The previous value to which this key was mapped, or + * null if if there was no mapping for the key + */ + public Object put(Object key, Object value) { + processQueue(); + ValueCell vc = ValueCell.create(key, value); + return ValueCell.strip(hash.put(key, vc), true); + } + + /** + * Remove the mapping for the given key from this cache, if + * present. + * + * @param key The key whose mapping is to be removed + * + * @return The value to which this key was mapped, or null if + * there was no mapping for the key + */ + public Object remove(Object key) { + processQueue(); + return ValueCell.strip(hash.remove(key), true); + } + + /** + * Remove all mappings from this cache. + */ + public void clear() { + processQueue(); + hash.clear(); + } + + + /* -- Views -- */ + + private static boolean valEquals(Object o1, Object o2) { + return (o1 == null) ? (o2 == null) : o1.equals(o2); + } + + + /* Internal class for entries. + Because it uses SoftCache.this.queue, this class cannot be static. + */ + private class Entry implements Map.Entry { + private Map.Entry ent; + private Object value; /* Strong reference to value, to prevent the GC + from flushing the value while this Entry + exists */ + + Entry(Map.Entry ent, Object value) { + this.ent = ent; + this.value = value; + } + + public Object getKey() { + return ent.getKey(); + } + + public Object getValue() { + return value; + } + + public Object setValue(Object value) { + return ent.setValue(ValueCell.create(ent.getKey(), value)); + } + + public boolean equals(Object o) { + if (! (o instanceof Map.Entry)) return false; + Map.Entry e = (Map.Entry)o; + return (valEquals(ent.getKey(), e.getKey()) + && valEquals(value, e.getValue())); + } + + public int hashCode() { + Object k; + return ((((k = getKey()) == null) ? 0 : k.hashCode()) + ^ ((value == null) ? 0 : value.hashCode())); + } + + } + + + /* Internal class for entry sets */ + private class EntrySet extends AbstractSet { + Set hashEntries = hash.entrySet(); + + public Iterator iterator() { + + return new Iterator() { + Iterator hashIterator = hashEntries.iterator(); + Entry next = null; + + public boolean hasNext() { + while (hashIterator.hasNext()) { + Map.Entry ent = (Map.Entry)hashIterator.next(); + ValueCell vc = (ValueCell)ent.getValue(); + Object v = null; + if ((vc != null) && ((v = vc.value) == null)) { + /* Value has been flushed by GC */ + continue; + } + next = new Entry(ent, v); + return true; + } + return false; + } + + public Object next() { + if ((next == null) && !hasNext()) + throw new NoSuchElementException(); + Entry e = next; + next = null; + return e; + } + + public void remove() { + hashIterator.remove(); + } + + }; + } + + public boolean isEmpty() { + return !(iterator().hasNext()); + } + + public int size() { + int j = 0; + for (Iterator i = iterator(); i.hasNext(); i.next()) j++; + return j; + } + + public boolean remove(Object o) { + processQueue(); + if (o instanceof Entry) return hashEntries.remove(((Entry)o).ent); + else return false; + } + + } + + + private Set entrySet = null; + + /** + * Return a Set view of the mappings in this cache. + */ + public Set entrySet() { + if (entrySet == null) entrySet = new EntrySet(); + return entrySet; + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/ThreadGroupUtils.java b/sources/net.sf.j2s.java.core/src/sun/misc/ThreadGroupUtils.java new file mode 100644 index 000000000..066a8002f --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/ThreadGroupUtils.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2014, 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.misc; + +/** + * A utility class needed to access the root {@code ThreadGroup} + * + * The class should not depend on any others, because it' called from JNI_OnLoad of the AWT + * native library. Triggering class loading could could lead to a deadlock. + */ +public final class ThreadGroupUtils { + + private ThreadGroupUtils() { + // Avoid instantiation + } + + /** + * Returns a root thread group. + * Should be called with {@link sun.security.util.SecurityConstants#MODIFY_THREADGROUP_PERMISSION} + * + * @return a root {@code ThreadGroup} + */ + public static ThreadGroup getRootThreadGroup() { + ThreadGroup currentTG = Thread.currentThread().getThreadGroup(); + ThreadGroup parentTG = currentTG.getParent(); + while (parentTG != null) { + currentTG = parentTG; + parentTG = currentTG.getParent(); + } + return currentTG; + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Timeable.java b/sources/net.sf.j2s.java.core/src/sun/misc/Timeable.java new file mode 100644 index 000000000..da6c60dbf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Timeable.java @@ -0,0 +1,45 @@ +/* + * Copyright (c) 1995, 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.misc; + +/** + * This interface is used by the Timer class. A class that uses + * Timer objects must implement this interface. + * + * @see Timer + * @author Patrick Chan + */ +public interface Timeable { + /** + * This method is executed every time a timer owned by this + * object ticks. An object can own more than one timer but + * all timers call this method when they tick; + * you can use the supplied timer parameter to determine + * which timer has ticked. + * @param timer a handle to the timer that has just ticked. + */ + public void tick(Timer timer); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Timer.java b/sources/net.sf.j2s.java.core/src/sun/misc/Timer.java new file mode 100644 index 000000000..71e0881bd --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Timer.java @@ -0,0 +1,647 @@ +/* + * Copyright (c) 1995, 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.misc; + +/** + A Timer object is used by algorithms that require timed events. + For example, in an animation loop, a timer would help in + determining when to change frames. + + A timer has an interval which determines when it "ticks"; + that is, a timer delays for the specified interval and then + it calls the owner's tick() method. + + Here's an example of creating a timer with a 5 sec interval: + +

      +    class Main implements Timeable {
      +        public void tick(Timer timer) {
      +            System.out.println("tick");
      +        }
      +        public static void main(String args[]) {
      +            (new Timer(this, 5000)).cont();
      +        }
      +    }
      +    
      + + A timer can be stopped, continued, or reset at any time. + A timer's state is not stopped while it's calling the + owner's tick() method. + + A timer can be regular or irregular. If in regular mode, + a timer ticks at the specified interval, regardless of + how long the owner's tick() method takes. While the timer + is running, no ticks are ever discarded. That means that if + the owner's tick() method takes longer than the interval, + the ticks that would have occurred are delivered immediately. + + In irregular mode, a timer starts delaying for exactly + the specified interval only after the tick() method returns. + + Synchronization issues: do not hold the timer's monitor + while calling any of the Timer operations below otherwise + the Timer class will deadlock. + + @author Patrick Chan +*/ + +/* + Synchronization issues: there are two data structures that + require locking. A Timer object and the Timer queue + (described in the TimerThread class). To avoid deadlock, + the timer queue monitor is always acquired before the timer + object's monitor. However, the timer queue monitor is acquired + only if the timer operation will make use of the timer + queue, e.g. stop(). + + The class monitor on the class TimerThread severs as the monitor + to the timer queue. + + Possible feature: perhaps a timer should have an associated + thread priority. The thread that makes the callback temporarily + takes on that priority before calling the owner's tick() method. +*/ + +public class Timer { + /** + * This is the owner of the timer. Its tick method is + * called when the timer ticks. + */ + public Timeable owner; + + /* + * This is the interval of time in ms. + */ + long interval; + + /* + * This variable is used for two different purposes. + * This is done in order to save space. + * If 'stopped' is true, this variable holds the time + * that the timer was stopped; otherwise, this variable + * is used by the TimerThread to determine when the timer + * should tick. + */ + long sleepUntil; + + /* + * This is the time remaining before the timer ticks. It + * is only valid if 'stopped' is true. If the timer is + * continued, the next tick will happen remaingTime + * milliseconds later. + */ + long remainingTime; + + /* + * True iff the timer is in regular mode. + */ + boolean regular; + + /* + * True iff the timer has been stopped. + */ + boolean stopped; + + /* ************************************************************** + * Timer queue-related variables + * ************************************************************** */ + + /* + * A link to another timer object. This is used while the + * timer object is enqueued in the timer queue. + */ + Timer next; + + /* ************************************************************** + * Timer methods + * ************************************************************** */ + + /* + * This variable holds a handle to the TimerThread class for + * the purpose of getting at the class monitor. The reason + * why Class.forName("TimerThread") is not used is because it + * doesn't appear to work when loaded via a net class loader. + */ + static TimerThread timerThread = null; + + /** + * Creates a timer object that is owned by 'owner' and + * with the interval 'interval' milliseconds. The new timer + * object is stopped and is regular. getRemainingTime() + * return 'interval' at this point. getStopTime() returns + * the time this object was created. + * @param owner owner of the timer object + * @param interval interval of the timer in milliseconds + */ + public Timer(Timeable owner, long interval) { + this.owner = owner; + this.interval = interval; + remainingTime = interval; + regular = true; + sleepUntil = System.currentTimeMillis(); + stopped = true; + synchronized (getClass()) { + if (timerThread == null) { + timerThread = new TimerThread(); + } + } + } + + /** + * Returns true if this timer is stopped. + */ + public synchronized boolean isStopped() { + return stopped; + } + + /** + * Stops the timer. The amount of time the timer has already + * delayed is saved so if the timer is continued, it will only + * delay for the amount of time remaining. + * Note that even after stopping a timer, one more tick may + * still occur. + * This method is MT-safe; i.e. it is synchronized but for + * implementation reasons, the synchronized modifier cannot + * be included in the method declaration. + */ + public void stop() { + long now = System.currentTimeMillis(); + + synchronized (timerThread) { + synchronized (this) { + if (!stopped) { + TimerThread.dequeue(this); + remainingTime = Math.max(0, sleepUntil - now); + sleepUntil = now; // stop time + stopped = true; + } + } + } + } + + /** + * Continue the timer. The next tick will come at getRemainingTime() + * milliseconds later. If the timer is not stopped, this + * call will be a no-op. + * This method is MT-safe; i.e. it is synchronized but for + * implementation reasons, the synchronized modifier cannot + * be included in the method declaration. + */ + public void cont() { + synchronized (timerThread) { + synchronized (this) { + if (stopped) { + // The TimerTickThread avoids requeuing the + // timer only if the sleepUntil value has changed. + // The following guarantees that the sleepUntil + // value will be different; without this guarantee, + // it's theoretically possible for the timer to be + // inserted twice. + sleepUntil = Math.max(sleepUntil + 1, + System.currentTimeMillis() + remainingTime); + TimerThread.enqueue(this); + stopped = false; + } + } + } + } + + /** + * Resets the timer's remaining time to the timer's interval. + * If the timer's running state is not altered. + */ + public void reset() { + synchronized (timerThread) { + synchronized (this) { + setRemainingTime(interval); + } + } + } + + /** + * Returns the time at which the timer was last stopped. The + * return value is valid only if the timer is stopped. + */ + public synchronized long getStopTime() { + return sleepUntil; + } + + /** + * Returns the timer's interval. + */ + public synchronized long getInterval() { + return interval; + } + + /** + * Changes the timer's interval. The new interval setting + * does not take effect until after the next tick. + * This method does not alter the remaining time or the + * running state of the timer. + * @param interval new interval of the timer in milliseconds + */ + public synchronized void setInterval(long interval) { + this.interval = interval; + } + + /** + * Returns the remaining time before the timer's next tick. + * The return value is valid only if timer is stopped. + */ + public synchronized long getRemainingTime() { + return remainingTime; + } + + /** + * Sets the remaining time before the timer's next tick. + * This method does not alter the timer's running state. + * This method is MT-safe; i.e. it is synchronized but for + * implementation reasons, the synchronized modifier cannot + * be included in the method declaration. + * @param time new remaining time in milliseconds. + */ + public void setRemainingTime(long time) { + synchronized (timerThread) { + synchronized (this) { + if (stopped) { + remainingTime = time; + } else { + stop(); + remainingTime = time; + cont(); + } + } + } + } + + /** + * In regular mode, a timer ticks at the specified interval, + * regardless of how long the owner's tick() method takes. + * While the timer is running, no ticks are ever discarded. + * That means that if the owner's tick() method takes longer + * than the interval, the ticks that would have occurred are + * delivered immediately. + * + * In irregular mode, a timer starts delaying for exactly + * the specified interval only after the tick() method returns. + */ + public synchronized void setRegular(boolean regular) { + this.regular = regular; + } + + /* + * This method is used only for testing purposes. + */ + protected Thread getTimerThread() { + return TimerThread.timerThread; + } +} + + +/* + +This class implements the timer queue and is exclusively used by the +Timer class. There are only two methods exported to the Timer class - +enqueue, for inserting a timer into queue and dequeue, for removing +a timer from the queue. + +A timer in the timer queue is awaiting a tick. When a timer is to be +ticked, it is removed from the timer queue before the owner's tick() +method is called. + +A single timer thread manages the timer queue. This timer thread +looks at the head of the timer queue and delays until it's time for +the timer to tick. When the time comes, the timer thread creates a +callback thread to call the timer owner's tick() method. The timer +thread then processes the next timer in the queue. + +When a timer is inserted at the head of the queue, the timer thread is +notified. This causes the timer thread to prematurely wake up and +process the new head of the queue. + +*/ + +class TimerThread extends Thread { + /* + * Set to true to get debugging output. + */ + public static boolean debug = false; + + /* + * This is a handle to the thread managing the thread queue. + */ + static TimerThread timerThread; + + /* + * This flag is set if the timer thread has been notified + * while it was in the timed wait. This flag allows the + * timer thread to tell whether or not the wait completed. + */ + static boolean notified = false; + + protected TimerThread() { + super("TimerThread"); + timerThread = this; + start(); + } + + public synchronized void run() { + while (true) { + long delay; + + while (timerQueue == null) { + try { + wait(); + } catch (InterruptedException ex) { + // Just drop through and check timerQueue. + } + } + notified = false; + delay = timerQueue.sleepUntil - System.currentTimeMillis(); + if (delay > 0) { + try { + wait(delay); + } catch (InterruptedException ex) { + // Just drop through. + } + } + // remove from timer queue. + if (!notified) { + Timer timer = timerQueue; + timerQueue = timerQueue.next; + TimerTickThread thr = TimerTickThread.call( + timer, timer.sleepUntil); + if (debug) { + long delta = (System.currentTimeMillis() - timer.sleepUntil); + System.out.println("tick(" + thr.getName() + "," + + timer.interval + ","+delta+ ")"); + if (delta > 250) { + System.out.println("*** BIG DELAY ***"); + } + } + } + } + } + + /* ******************************************************* + Timer Queue + ******************************************************* */ + + /* + * The timer queue is a queue of timers waiting to tick. + */ + static Timer timerQueue = null; + + /* + * Uses timer.sleepUntil to determine where in the queue + * to insert the timer object. + * A new ticker thread is created only if the timer + * is inserted at the beginning of the queue. + * The timer must not already be in the queue. + * Assumes the caller has the TimerThread monitor. + */ + static protected void enqueue(Timer timer) { + Timer prev = null; + Timer cur = timerQueue; + + if (cur == null || timer.sleepUntil <= cur.sleepUntil) { + // insert at front of queue + timer.next = timerQueue; + timerQueue = timer; + notified = true; + timerThread.notify(); + } else { + do { + prev = cur; + cur = cur.next; + } while (cur != null && timer.sleepUntil > cur.sleepUntil); + // insert or append to the timer queue + timer.next = cur; + prev.next = timer; + } + if (debug) { + long now = System.currentTimeMillis(); + + System.out.print(Thread.currentThread().getName() + + ": enqueue " + timer.interval + ": "); + cur = timerQueue; + while(cur != null) { + long delta = cur.sleepUntil - now; + System.out.print(cur.interval + "(" + delta + ") "); + cur = cur.next; + } + System.out.println(); + } + } + + /* + * If the timer is not in the queue, returns false; + * otherwise removes the timer from the timer queue and returns true. + * Assumes the caller has the TimerThread monitor. + */ + static protected boolean dequeue(Timer timer) { + Timer prev = null; + Timer cur = timerQueue; + + while (cur != null && cur != timer) { + prev = cur; + cur = cur.next; + } + if (cur == null) { + if (debug) { + System.out.println(Thread.currentThread().getName() + + ": dequeue " + timer.interval + ": no-op"); + } + return false; + } if (prev == null) { + timerQueue = timer.next; + notified = true; + timerThread.notify(); + } else { + prev.next = timer.next; + } + timer.next = null; + if (debug) { + long now = System.currentTimeMillis(); + + System.out.print(Thread.currentThread().getName() + + ": dequeue " + timer.interval + ": "); + cur = timerQueue; + while(cur != null) { + long delta = cur.sleepUntil - now; + System.out.print(cur.interval + "(" + delta + ") "); + cur = cur.next; + } + System.out.println(); + } + return true; + } + + /* + * Inserts the timer back into the queue. This method + * is used by a callback thread after it has called the + * timer owner's tick() method. This method recomputes + * the sleepUntil field. + * Assumes the caller has the TimerThread and Timer monitor. + */ + protected static void requeue(Timer timer) { + if (!timer.stopped) { + long now = System.currentTimeMillis(); + if (timer.regular) { + timer.sleepUntil += timer.interval; + } else { + timer.sleepUntil = now + timer.interval; + } + enqueue(timer); + } else if (debug) { + System.out.println(Thread.currentThread().getName() + + ": requeue " + timer.interval + ": no-op"); + } + } +} + +/* + +This class implements a simple thread whose only purpose is to call a +timer owner's tick() method. A small fixed-sized pool of threads is +maintained and is protected by the class monitor. If the pool is +exhausted, a new thread is temporarily created and destroyed when +done. + +A thread that's in the pool waits on it's own monitor. When the +thread is retrieved from the pool, the retriever notifies the thread's +monitor. + +*/ + +class TimerTickThread extends Thread { + /* + * Maximum size of the thread pool. + */ + static final int MAX_POOL_SIZE = 3; + + /* + * Number of threads in the pool. + */ + static int curPoolSize = 0; + + /* + * The pool of timer threads. + */ + static TimerTickThread pool = null; + + /* + * Is used when linked into the thread pool. + */ + TimerTickThread next = null; + + /* + * This is the handle to the timer whose owner's + * tick() method will be called. + */ + Timer timer; + + /* + * The value of a timer's sleepUntil value is captured here. + * This is used to determine whether or not the timer should + * be reinserted into the queue. If the timer's sleepUntil + * value has changed, the timer is not reinserted. + */ + long lastSleepUntil; + + /* + * Creates a new callback thread to call the timer owner's + * tick() method. A thread is taken from the pool if one + * is available, otherwise, a new thread is created. + * The thread handle is returned. + */ + protected static synchronized TimerTickThread call( + Timer timer, long sleepUntil) { + TimerTickThread thread = pool; + + if (thread == null) { + // create one. + thread = new TimerTickThread(); + thread.timer = timer; + thread.lastSleepUntil = sleepUntil; + thread.start(); + } else { + pool = pool.next; + thread.timer = timer; + thread.lastSleepUntil = sleepUntil; + synchronized (thread) { + thread.notify(); + } + } + return thread; + } + + /* + * Returns false if the thread should simply exit; + * otherwise the thread is returned the pool, where + * it waits to be notified. (I did try to use the + * class monitor but the time between the notify + * and breaking out of the wait seemed to take + * significantly longer; need to look into this later.) + */ + private boolean returnToPool() { + synchronized (getClass()) { + if (curPoolSize >= MAX_POOL_SIZE) { + return false; + } + next = pool; + pool = this; + curPoolSize++; + timer = null; + } + while (timer == null) { + synchronized (this) { + try { + wait(); + } catch (InterruptedException ex) { + // Just drop through and retest timer. + } + } + } + synchronized (getClass()) { + curPoolSize--; + } + return true; + } + + public void run() { + do { + timer.owner.tick(timer); + synchronized (TimerThread.timerThread) { + synchronized (timer) { + if (lastSleepUntil == timer.sleepUntil) { + TimerThread.requeue(timer); + } + } + } + } while (returnToPool()); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/UCDecoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/UCDecoder.java new file mode 100644 index 000000000..81793a3cc --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/UCDecoder.java @@ -0,0 +1,233 @@ +/* + * Copyright (c) 1995, 2000, 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.misc; + +import java.io.OutputStream; +import java.io.ByteArrayOutputStream; +import java.io.PushbackInputStream; +import java.io.PrintStream; +import java.io.IOException; + +/** + * This class implements a robust character decoder. The decoder will + * converted encoded text into binary data. + * + * The basic encoding unit is a 3 character atom. It encodes two bytes + * of data. Bytes are encoded into a 64 character set, the characters + * were chosen specifically because they appear in all codesets. + * We don't care what their numerical equivalent is because + * we use a character array to map them. This is like UUencoding + * with the dependency on ASCII removed. + * + * The three chars that make up an atom are encoded as follows: + *
      + *      00xxxyyy 00axxxxx 00byyyyy
      + *      00 = leading zeros, all values are 0 - 63
      + *      xxxyyy - Top 3 bits of X, Top 3 bits of Y
      + *      axxxxx - a = X parity bit, xxxxx lower 5 bits of X
      + *      byyyyy - b = Y parity bit, yyyyy lower 5 bits of Y
      + * 
      + * + * The atoms are arranged into lines suitable for inclusion into an + * email message or text file. The number of bytes that are encoded + * per line is 48 which keeps the total line length under 80 chars) + * + * Each line has the form( + *
      + *  *(LLSS)(DDDD)(DDDD)(DDDD)...(CRC)
      + *  Where each (xxx) represents a three character atom.
      + *  (LLSS) - 8 bit length (high byte), and sequence number
      + *           modulo 256;
      + *  (DDDD) - Data byte atoms, if length is odd, last data
      + *           atom has (DD00) (high byte data, low byte 0)
      + *  (CRC)  - 16 bit CRC for the line, includes length,
      + *           sequence, and all data bytes. If there is a
      + *           zero pad byte (odd length) it is _NOT_
      + *           included in the CRC.
      + * 
      + * + * If an error is encountered during decoding this class throws a + * CEFormatException. The specific detail messages are: + * + *
      + *    "UCDecoder: High byte parity error."
      + *    "UCDecoder: Low byte parity error."
      + *    "UCDecoder: Out of sequence line."
      + *    "UCDecoder: CRC check failed."
      + * 
      + * + * @author Chuck McManis + * @see CharacterEncoder + * @see UCEncoder + */ +public class UCDecoder extends CharacterDecoder { + + /** This class encodes two bytes per atom. */ + protected int bytesPerAtom() { + return (2); + } + + /** this class encodes 48 bytes per line */ + protected int bytesPerLine() { + return (48); + } + + /* this is the UCE mapping of 0-63 to characters .. */ + private final static byte map_array[] = { + // 0 1 2 3 4 5 6 7 + (byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7', // 0 + (byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F', // 1 + (byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N', // 2 + (byte)'O',(byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V', // 3 + (byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', // 4 + (byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l', // 5 + (byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s',(byte)'t', // 6 + (byte)'u',(byte)'v',(byte)'w',(byte)'x',(byte)'y',(byte)'z',(byte)'(',(byte)')' // 7 + }; + + private int sequence; + private byte tmp[] = new byte[2]; + private CRC16 crc = new CRC16(); + + /** + * Decode one atom - reads the characters from the input stream, decodes + * them, and checks for valid parity. + */ + protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int l) throws IOException { + int i, p1, p2, np1, np2; + byte a = -1, b = -1, c = -1; + byte high_byte, low_byte; + byte tmp[] = new byte[3]; + + i = inStream.read(tmp); + if (i != 3) { + throw new CEStreamExhausted(); + } + for (i = 0; (i < 64) && ((a == -1) || (b == -1) || (c == -1)); i++) { + if (tmp[0] == map_array[i]) { + a = (byte) i; + } + if (tmp[1] == map_array[i]) { + b = (byte) i; + } + if (tmp[2] == map_array[i]) { + c = (byte) i; + } + } + high_byte = (byte) (((a & 0x38) << 2) + (b & 0x1f)); + low_byte = (byte) (((a & 0x7) << 5) + (c & 0x1f)); + p1 = 0; + p2 = 0; + for (i = 1; i < 256; i = i * 2) { + if ((high_byte & i) != 0) + p1++; + if ((low_byte & i) != 0) + p2++; + } + np1 = (b & 32) / 32; + np2 = (c & 32) / 32; + if ((p1 & 1) != np1) { + throw new CEFormatException("UCDecoder: High byte parity error."); + } + if ((p2 & 1) != np2) { + throw new CEFormatException("UCDecoder: Low byte parity error."); + } + outStream.write(high_byte); + crc.update(high_byte); + if (l == 2) { + outStream.write(low_byte); + crc.update(low_byte); + } + } + + private ByteArrayOutputStream lineAndSeq = new ByteArrayOutputStream(2); + + /** + * decodeBufferPrefix initializes the sequence number to zero. + */ + protected void decodeBufferPrefix(PushbackInputStream inStream, OutputStream outStream) { + sequence = 0; + } + + /** + * decodeLinePrefix reads the sequence number and the number of + * encoded bytes from the line. If the sequence number is not the + * previous sequence number + 1 then an exception is thrown. + * UCE lines are line terminator immune, they all start with * + * so the other thing this method does is scan for the next line + * by looking for the * character. + * + * @exception CEFormatException out of sequence lines detected. + */ + protected int decodeLinePrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException { + int i; + int nLen, nSeq; + byte xtmp[]; + int c; + + crc.value = 0; + while (true) { + c = inStream.read(tmp, 0, 1); + if (c == -1) { + throw new CEStreamExhausted(); + } + if (tmp[0] == '*') { + break; + } + } + lineAndSeq.reset(); + decodeAtom(inStream, lineAndSeq, 2); + xtmp = lineAndSeq.toByteArray(); + nLen = xtmp[0] & 0xff; + nSeq = xtmp[1] & 0xff; + if (nSeq != sequence) { + throw new CEFormatException("UCDecoder: Out of sequence line."); + } + sequence = (sequence + 1) & 0xff; + return (nLen); + } + + + /** + * this method reads the CRC that is at the end of every line and + * verifies that it matches the computed CRC. + * + * @exception CEFormatException if CRC check fails. + */ + protected void decodeLineSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException { + int i; + int lineCRC = crc.value; + int readCRC; + byte tmp[]; + + lineAndSeq.reset(); + decodeAtom(inStream, lineAndSeq, 2); + tmp = lineAndSeq.toByteArray(); + readCRC = ((tmp[0] << 8) & 0xFF00) + (tmp[1] & 0xff); + if (readCRC != lineCRC) { + throw new CEFormatException("UCDecoder: CRC check failed."); + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/UCEncoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/UCEncoder.java new file mode 100644 index 000000000..159da288a --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/UCEncoder.java @@ -0,0 +1,178 @@ +/* + * Copyright (c) 1995, 1997, 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.misc; + +import java.io.OutputStream; +import java.io.InputStream; +import java.io.PrintStream; +import java.io.IOException; + +/** + * This class implements a robust character encoder. The encoder is designed + * to convert binary data into printable characters. The characters are + * assumed to exist but they are not assumed to be ASCII, the complete set + * is 0-9, A-Z, a-z, "(", and ")". + * + * The basic encoding unit is a 3 character atom. It encodes two bytes + * of data. Bytes are encoded into a 64 character set, the characters + * were chosen specifically because they appear in all codesets. + * We don't care what their numerical equivalent is because + * we use a character array to map them. This is like UUencoding + * with the dependency on ASCII removed. + * + * The three chars that make up an atom are encoded as follows: + *
      + *      00xxxyyy 00axxxxx 00byyyyy
      + *      00 = leading zeros, all values are 0 - 63
      + *      xxxyyy - Top 3 bits of X, Top 3 bits of Y
      + *      axxxxx - a = X parity bit, xxxxx lower 5 bits of X
      + *      byyyyy - b = Y parity bit, yyyyy lower 5 bits of Y
      + * 
      + * + * The atoms are arranged into lines suitable for inclusion into an + * email message or text file. The number of bytes that are encoded + * per line is 48 which keeps the total line length under 80 chars) + * + * Each line has the form( + *
      + *  *(LLSS)(DDDD)(DDDD)(DDDD)...(CRC)
      + *  Where each (xxx) represents a three character atom.
      + *  (LLSS) - 8 bit length (high byte), and sequence number
      + *           modulo 256;
      + *  (DDDD) - Data byte atoms, if length is odd, last data
      + *           atom has (DD00) (high byte data, low byte 0)
      + *  (CRC)  - 16 bit CRC for the line, includes length,
      + *           sequence, and all data bytes. If there is a
      + *           zero pad byte (odd length) it is _NOT_
      + *           included in the CRC.
      + * 
      + * + * @author Chuck McManis + * @see CharacterEncoder + * @see UCDecoder + */ +public class UCEncoder extends CharacterEncoder { + + /** this clase encodes two bytes per atom */ + protected int bytesPerAtom() { + return (2); + } + + /** this class encodes 48 bytes per line */ + protected int bytesPerLine() { + return (48); + } + + /* this is the UCE mapping of 0-63 to characters .. */ + private final static byte map_array[] = { + // 0 1 2 3 4 5 6 7 + (byte)'0',(byte)'1',(byte)'2',(byte)'3',(byte)'4',(byte)'5',(byte)'6',(byte)'7', // 0 + (byte)'8',(byte)'9',(byte)'A',(byte)'B',(byte)'C',(byte)'D',(byte)'E',(byte)'F', // 1 + (byte)'G',(byte)'H',(byte)'I',(byte)'J',(byte)'K',(byte)'L',(byte)'M',(byte)'N', // 2 + (byte)'O',(byte)'P',(byte)'Q',(byte)'R',(byte)'S',(byte)'T',(byte)'U',(byte)'V', // 3 + (byte)'W',(byte)'X',(byte)'Y',(byte)'Z',(byte)'a',(byte)'b',(byte)'c',(byte)'d', // 4 + (byte)'e',(byte)'f',(byte)'g',(byte)'h',(byte)'i',(byte)'j',(byte)'k',(byte)'l', // 5 + (byte)'m',(byte)'n',(byte)'o',(byte)'p',(byte)'q',(byte)'r',(byte)'s',(byte)'t', // 6 + (byte)'u',(byte)'v',(byte)'w',(byte)'x',(byte)'y',(byte)'z',(byte)'(',(byte)')' // 7 + }; + + private int sequence; + private byte tmp[] = new byte[2]; + private CRC16 crc = new CRC16(); + + /** + * encodeAtom - take two bytes and encode them into the correct + * three characters. If only one byte is to be encoded, the other + * must be zero. The padding byte is not included in the CRC computation. + */ + protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len) throws IOException + { + int i; + int p1, p2; // parity bits + byte a, b; + + a = data[offset]; + if (len == 2) { + b = data[offset+1]; + } else { + b = 0; + } + crc.update(a); + if (len == 2) { + crc.update(b); + } + outStream.write(map_array[((a >>> 2) & 0x38) + ((b >>> 5) & 0x7)]); + p1 = 0; p2 = 0; + for (i = 1; i < 256; i = i * 2) { + if ((a & i) != 0) { + p1++; + } + if ((b & i) != 0) { + p2++; + } + } + p1 = (p1 & 1) * 32; + p2 = (p2 & 1) * 32; + outStream.write(map_array[(a & 31) + p1]); + outStream.write(map_array[(b & 31) + p2]); + return; + } + + /** + * Each UCE encoded line starts with a prefix of '*[XXX]', where + * the sequence number and the length are encoded in the first + * atom. + */ + protected void encodeLinePrefix(OutputStream outStream, int length) throws IOException { + outStream.write('*'); + crc.value = 0; + tmp[0] = (byte) length; + tmp[1] = (byte) sequence; + sequence = (sequence + 1) & 0xff; + encodeAtom(outStream, tmp, 0, 2); + } + + + /** + * each UCE encoded line ends with YYY and encoded version of the + * 16 bit checksum. The most significant byte of the check sum + * is always encoded FIRST. + */ + protected void encodeLineSuffix(OutputStream outStream) throws IOException { + tmp[0] = (byte) ((crc.value >>> 8) & 0xff); + tmp[1] = (byte) (crc.value & 0xff); + encodeAtom(outStream, tmp, 0, 2); + super.pStream.println(); + } + + /** + * The buffer prefix code is used to initialize the sequence number + * to zero. + */ + protected void encodeBufferPrefix(OutputStream a) throws IOException { + sequence = 0; + super.encodeBufferPrefix(a); + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/URLClassPath.java b/sources/net.sf.j2s.java.core/src/sun/misc/URLClassPath.java new file mode 100644 index 000000000..a66d33a98 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/URLClassPath.java @@ -0,0 +1,1263 @@ +/* + * Copyright (c) 1997, 2014, 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.misc; + +import java.util.*; +import java.util.jar.JarFile; +import sun.misc.JarIndex; +import sun.misc.InvalidJarIndexException; +import sun.net.www.ParseUtil; +import java.util.zip.ZipEntry; +import java.util.jar.JarEntry; +import java.util.jar.Manifest; +import java.util.jar.Attributes; +import java.util.jar.Attributes.Name; +import java.net.JarURLConnection; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLClassLoader; +import java.net.URLConnection; +import java.net.HttpURLConnection; +import java.net.URLStreamHandler; +import java.net.URLStreamHandlerFactory; +import java.io.*; +import java.security.AccessController; +import java.security.AccessControlException; +import java.security.CodeSigner; +import java.security.Permission; +import java.security.PrivilegedAction; +import java.security.PrivilegedExceptionAction; +import java.security.cert.Certificate; +import sun.misc.FileURLMapper; +import sun.net.util.URLUtil; +import sun.security.action.GetPropertyAction; + +/** + * This class is used to maintain a search path of URLs for loading classes + * and resources from both JAR files and directories. + * + * @author David Connelly + */ +public class URLClassPath { + final static String USER_AGENT_JAVA_VERSION = "UA-Java-Version"; + final static String JAVA_VERSION; + private static final boolean DEBUG; + private static final boolean DEBUG_LOOKUP_CACHE; + private static final boolean DISABLE_JAR_CHECKING; + + static { + JAVA_VERSION = java.security.AccessController.doPrivileged( + new GetPropertyAction("java.version")); + DEBUG = (java.security.AccessController.doPrivileged( + new GetPropertyAction("sun.misc.URLClassPath.debug")) != null); + DEBUG_LOOKUP_CACHE = (java.security.AccessController.doPrivileged( + new GetPropertyAction("sun.misc.URLClassPath.debugLookupCache")) != null); + String p = java.security.AccessController.doPrivileged( + new GetPropertyAction("sun.misc.URLClassPath.disableJarChecking")); + DISABLE_JAR_CHECKING = p != null ? p.equals("true") || p.equals("") : false; + } + + /* The original search path of URLs. */ + private ArrayList path = new ArrayList(); + + /* The stack of unopened URLs */ + Stack urls = new Stack(); + + /* The resulting search path of Loaders */ + ArrayList loaders = new ArrayList(); + + /* Map of each URL opened to its corresponding Loader */ + HashMap lmap = new HashMap(); + + /* The jar protocol handler to use when creating new URLs */ + private URLStreamHandler jarHandler; + + /* Whether this URLClassLoader has been closed yet */ + private boolean closed = false; + + /** + * Creates a new URLClassPath for the given URLs. The URLs will be + * searched in the order specified for classes and resources. A URL + * ending with a '/' is assumed to refer to a directory. Otherwise, + * the URL is assumed to refer to a JAR file. + * + * @param urls the directory and JAR file URLs to search for classes + * and resources + * @param factory the URLStreamHandlerFactory to use when creating new URLs + */ + public URLClassPath(URL[] urls, URLStreamHandlerFactory factory) { + for (int i = 0; i < urls.length; i++) { + path.add(urls[i]); + } + push(urls); + if (factory != null) { + jarHandler = factory.createURLStreamHandler("jar"); + } + } + + public URLClassPath(URL[] urls) { + this(urls, null); + } + + public synchronized List closeLoaders() { + if (closed) { + return Collections.emptyList(); + } + List result = new LinkedList(); + for (Loader loader : loaders) { + try { + loader.close(); + } catch (IOException e) { + result.add (e); + } + } + closed = true; + return result; + } + + /** + * Appends the specified URL to the search path of directory and JAR + * file URLs from which to load classes and resources. + *

      + * If the URL specified is null or is already in the list of + * URLs, then invoking this method has no effect. + */ + public synchronized void addURL(URL url) { + if (closed) + return; + synchronized (urls) { + if (url == null || path.contains(url)) + return; + + urls.add(0, url); + path.add(url); + + if (lookupCacheURLs != null) { + // The lookup cache is no longer valid, since getLookupCache() + // does not consider the newly added url. + disableAllLookupCaches(); + } + } + } + + /** + * Returns the original search path of URLs. + */ + public URL[] getURLs() { + synchronized (urls) { + return path.toArray(new URL[path.size()]); + } + } + + /** + * Finds the resource with the specified name on the URL search path + * or null if not found or security check fails. + * + * @param name the name of the resource + * @param check whether to perform a security check + * @return a URL for the resource, or null + * if the resource could not be found. + */ + public URL findResource(String name, boolean check) { + Loader loader; + int[] cache = getLookupCache(name); + for (int i = 0; (loader = getNextLoader(cache, i)) != null; i++) { + URL url = loader.findResource(name, check); + if (url != null) { + return url; + } + } + return null; + } + + /** + * Finds the first Resource on the URL search path which has the specified + * name. Returns null if no Resource could be found. + * + * @param name the name of the Resource + * @param check whether to perform a security check + * @return the Resource, or null if not found + */ + public Resource getResource(String name, boolean check) { + if (DEBUG) { + System.err.println("URLClassPath.getResource(\"" + name + "\")"); + } + + Loader loader; + int[] cache = getLookupCache(name); + for (int i = 0; (loader = getNextLoader(cache, i)) != null; i++) { + Resource res = loader.getResource(name, check); + if (res != null) { + return res; + } + } + return null; + } + + /** + * Finds all resources on the URL search path with the given name. + * Returns an enumeration of the URL objects. + * + * @param name the resource name + * @return an Enumeration of all the urls having the specified name + */ + public Enumeration findResources(final String name, + final boolean check) { + return new Enumeration() { + private int index = 0; + private int[] cache = getLookupCache(name); + private URL url = null; + + private boolean next() { + if (url != null) { + return true; + } else { + Loader loader; + while ((loader = getNextLoader(cache, index++)) != null) { + url = loader.findResource(name, check); + if (url != null) { + return true; + } + } + return false; + } + } + + public boolean hasMoreElements() { + return next(); + } + + public URL nextElement() { + if (!next()) { + throw new NoSuchElementException(); + } + URL u = url; + url = null; + return u; + } + }; + } + + public Resource getResource(String name) { + return getResource(name, true); + } + + /** + * Finds all resources on the URL search path with the given name. + * Returns an enumeration of the Resource objects. + * + * @param name the resource name + * @return an Enumeration of all the resources having the specified name + */ + public Enumeration getResources(final String name, + final boolean check) { + return new Enumeration() { + private int index = 0; + private int[] cache = getLookupCache(name); + private Resource res = null; + + private boolean next() { + if (res != null) { + return true; + } else { + Loader loader; + while ((loader = getNextLoader(cache, index++)) != null) { + res = loader.getResource(name, check); + if (res != null) { + return true; + } + } + return false; + } + } + + public boolean hasMoreElements() { + return next(); + } + + public Resource nextElement() { + if (!next()) { + throw new NoSuchElementException(); + } + Resource r = res; + res = null; + return r; + } + }; + } + + public Enumeration getResources(final String name) { + return getResources(name, true); + } + + private static volatile boolean lookupCacheEnabled + = "true".equals(VM.getSavedProperty("sun.cds.enableSharedLookupCache")); + private URL[] lookupCacheURLs; + private ClassLoader lookupCacheLoader; + + synchronized void initLookupCache(ClassLoader loader) { + if ((lookupCacheURLs = getLookupCacheURLs(loader)) != null) { + lookupCacheLoader = loader; + } else { + // This JVM instance does not support lookup cache. + disableAllLookupCaches(); + } + } + + static void disableAllLookupCaches() { + lookupCacheEnabled = false; + } + + private static native URL[] getLookupCacheURLs(ClassLoader loader); + private static native int[] getLookupCacheForClassLoader(ClassLoader loader, + String name); + private static native boolean knownToNotExist0(ClassLoader loader, + String className); + + synchronized boolean knownToNotExist(String className) { + if (lookupCacheURLs != null && lookupCacheEnabled) { + return knownToNotExist0(lookupCacheLoader, className); + } + + // Don't know if this class exists or not -- need to do a full search. + return false; + } + + /** + * Returns an array of the index to lookupCacheURLs that may + * contain the specified resource. The values in the returned + * array are in strictly ascending order and must be a valid index + * to lookupCacheURLs array. + * + * This method returns an empty array if the specified resource + * cannot be found in this URLClassPath. If there is no lookup + * cache or it's disabled, this method returns null and the lookup + * should search the entire classpath. + * + * Example: if lookupCacheURLs contains {a.jar, b.jar, c.jar, d.jar} + * and package "foo" only exists in a.jar and c.jar, + * getLookupCache("foo/Bar.class") will return {0, 2} + * + * @param name the resource name + * @return an array of the index to lookupCacheURLs that may contain the + * specified resource; or null if no lookup cache is used. + */ + private synchronized int[] getLookupCache(String name) { + if (lookupCacheURLs == null || !lookupCacheEnabled) { + return null; + } + + int[] cache = getLookupCacheForClassLoader(lookupCacheLoader, name); + if (cache != null && cache.length > 0) { + int maxindex = cache[cache.length - 1]; // cache[] is strictly ascending. + if (!ensureLoaderOpened(maxindex)) { + if (DEBUG_LOOKUP_CACHE) { + System.out.println("Expanded loaders FAILED " + + loaders.size() + " for maxindex=" + maxindex); + } + return null; + } + } + + return cache; + } + + private boolean ensureLoaderOpened(int index) { + if (loaders.size() <= index) { + // Open all Loaders up to, and including, index + if (getLoader(index) == null) { + return false; + } + if (!lookupCacheEnabled) { + // cache was invalidated as the result of the above call. + return false; + } + if (DEBUG_LOOKUP_CACHE) { + System.out.println("Expanded loaders " + loaders.size() + + " to index=" + index); + } + } + return true; + } + + /* + * The CLASS-PATH attribute was expanded by the VM when building + * the resource lookup cache in the same order as the getLoader + * method does. This method validates if the URL from the lookup + * cache matches the URL of the Loader at the given index; + * otherwise, this method disables the lookup cache. + */ + private synchronized void validateLookupCache(int index, + String urlNoFragString) { + if (lookupCacheURLs != null && lookupCacheEnabled) { + if (index < lookupCacheURLs.length && + urlNoFragString.equals( + URLUtil.urlNoFragString(lookupCacheURLs[index]))) { + return; + } + if (DEBUG || DEBUG_LOOKUP_CACHE) { + System.out.println("WARNING: resource lookup cache invalidated " + + "for lookupCacheLoader at " + index); + } + disableAllLookupCaches(); + } + } + + /** + * Returns the next Loader that may contain the resource to + * lookup. If the given cache is null, return loaders.get(index) + * that may be lazily created; otherwise, cache[index] is the next + * Loader that may contain the resource to lookup and so returns + * loaders.get(cache[index]). + * + * If cache is non-null, loaders.get(cache[index]) must be present. + * + * @param cache lookup cache. If null, search the entire class path + * @param index index to the given cache array; or to the loaders list. + */ + private synchronized Loader getNextLoader(int[] cache, int index) { + if (closed) { + return null; + } + if (cache != null) { + if (index < cache.length) { + Loader loader = loaders.get(cache[index]); + if (DEBUG_LOOKUP_CACHE) { + System.out.println("HASCACHE: Loading from : " + cache[index] + + " = " + loader.getBaseURL()); + } + return loader; + } else { + return null; // finished iterating over cache[] + } + } else { + return getLoader(index); + } + } + + /* + * Returns the Loader at the specified position in the URL search + * path. The URLs are opened and expanded as needed. Returns null + * if the specified index is out of range. + */ + private synchronized Loader getLoader(int index) { + if (closed) { + return null; + } + // Expand URL search path until the request can be satisfied + // or the URL stack is empty. + while (loaders.size() < index + 1) { + // Pop the next URL from the URL stack + URL url; + synchronized (urls) { + if (urls.empty()) { + return null; + } else { + url = urls.pop(); + } + } + // Skip this URL if it already has a Loader. (Loader + // may be null in the case where URL has not been opened + // but is referenced by a JAR index.) + String urlNoFragString = URLUtil.urlNoFragString(url); + if (lmap.containsKey(urlNoFragString)) { + continue; + } + // Otherwise, create a new Loader for the URL. + Loader loader; + try { + loader = getLoader(url); + // If the loader defines a local class path then add the + // URLs to the list of URLs to be opened. + URL[] urls = loader.getClassPath(); + if (urls != null) { + push(urls); + } + } catch (IOException e) { + // Silently ignore for now... + continue; + } + // Finally, add the Loader to the search path. + validateLookupCache(loaders.size(), urlNoFragString); + loaders.add(loader); + lmap.put(urlNoFragString, loader); + } + if (DEBUG_LOOKUP_CACHE) { + System.out.println("NOCACHE: Loading from : " + index ); + } + return loaders.get(index); + } + + /* + * Returns the Loader for the specified base URL. + */ + private Loader getLoader(final URL url) throws IOException { + try { + return java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public Loader run() throws IOException { + String file = url.getFile(); + if (file != null && file.endsWith("/")) { + if ("file".equals(url.getProtocol())) { + return new FileLoader(url); + } else { + return new Loader(url); + } + } else { + return new JarLoader(url, jarHandler, lmap); + } + } + }); + } catch (java.security.PrivilegedActionException pae) { + throw (IOException)pae.getException(); + } + } + + /* + * Pushes the specified URLs onto the list of unopened URLs. + */ + private void push(URL[] us) { + synchronized (urls) { + for (int i = us.length - 1; i >= 0; --i) { + urls.push(us[i]); + } + } + } + + /** + * Convert class path specification into an array of file URLs. + * + * The path of the file is encoded before conversion into URL + * form so that reserved characters can safely appear in the path. + */ + public static URL[] pathToURLs(String path) { + StringTokenizer st = new StringTokenizer(path, File.pathSeparator); + URL[] urls = new URL[st.countTokens()]; + int count = 0; + while (st.hasMoreTokens()) { + File f = new File(st.nextToken()); + try { + f = new File(f.getCanonicalPath()); + } catch (IOException x) { + // use the non-canonicalized filename + } + try { + urls[count++] = ParseUtil.fileToEncodedURL(f); + } catch (IOException x) { } + } + + if (urls.length != count) { + URL[] tmp = new URL[count]; + System.arraycopy(urls, 0, tmp, 0, count); + urls = tmp; + } + return urls; + } + + /* + * Check whether the resource URL should be returned. + * Return null on security check failure. + * Called by java.net.URLClassLoader. + */ + public URL checkURL(URL url) { + try { + check(url); + } catch (Exception e) { + return null; + } + + return url; + } + + /* + * Check whether the resource URL should be returned. + * Throw exception on failure. + * Called internally within this file. + */ + static void check(URL url) throws IOException { + return; +// SecurityManager security = System.getSecurityManager(); +// if (security != null) { +// URLConnection urlConnection = url.openConnection(); +// Permission perm = urlConnection.getPermission(); +// if (perm != null) { +// try { +// security.checkPermission(perm); +// } catch (SecurityException se) { +// // fallback to checkRead/checkConnect for pre 1.2 +// // security managers +// if ((perm instanceof java.io.FilePermission) && +// perm.getActions().indexOf("read") != -1) { +// security.checkRead(perm.getName()); +// } else if ((perm instanceof +// java.net.SocketPermission) && +// perm.getActions().indexOf("connect") != -1) { +// URL locUrl = url; +// if (urlConnection instanceof JarURLConnection) { +// locUrl = ((JarURLConnection)urlConnection).getJarFileURL(); +// } +// security.checkConnect(locUrl.getHost(), +// locUrl.getPort()); +// } else { +// throw se; +// } +// } +// } +// } + } + + /** + * Inner class used to represent a loader of resources and classes + * from a base URL. + */ + private static class Loader implements Closeable { + private final URL base; + private JarFile jarfile; // if this points to a jar file + + /* + * Creates a new Loader for the specified URL. + */ + Loader(URL url) { + base = url; + } + + /* + * Returns the base URL for this Loader. + */ + URL getBaseURL() { + return base; + } + + URL findResource(final String name, boolean check) { + URL url; + try { + url = new URL(base, ParseUtil.encodePath(name, false)); + } catch (MalformedURLException e) { + throw new IllegalArgumentException("name"); + } + + try { + if (check) { + URLClassPath.check(url); + } + + /* + * For a HTTP connection we use the HEAD method to + * check if the resource exists. + */ + URLConnection uc = url.openConnection(); + if (uc instanceof HttpURLConnection) { + HttpURLConnection hconn = (HttpURLConnection)uc; + hconn.setRequestMethod("HEAD"); + if (hconn.getResponseCode() >= HttpURLConnection.HTTP_BAD_REQUEST) { + return null; + } + } else { + // our best guess for the other cases + uc.setUseCaches(false); + InputStream is = uc.getInputStream(); + is.close(); + } + return url; + } catch (Exception e) { + return null; + } + } + + Resource getResource(final String name, boolean check) { + final URL url; + try { + url = new URL(base, ParseUtil.encodePath(name, false)); + } catch (MalformedURLException e) { + throw new IllegalArgumentException("name"); + } + final URLConnection uc; + try { + if (check) { + URLClassPath.check(url); + } + uc = url.openConnection(); + InputStream in = uc.getInputStream(); + if (uc instanceof JarURLConnection) { + /* Need to remember the jar file so it can be closed + * in a hurry. + */ + JarURLConnection juc = (JarURLConnection)uc; + jarfile = JarLoader.checkJar(juc.getJarFile()); + } + } catch (Exception e) { + return null; + } + return new Resource() { + public String getName() { return name; } + public URL getURL() { return url; } + public URL getCodeSourceURL() { return base; } + public InputStream getInputStream() throws IOException { + return uc.getInputStream(); + } + public int getContentLength() throws IOException { + return uc.getContentLength(); + } + }; + } + + /* + * Returns the Resource for the specified name, or null if not + * found or the caller does not have the permission to get the + * resource. + */ + Resource getResource(final String name) { + return getResource(name, true); + } + + /* + * close this loader and release all resources + * method overridden in sub-classes + */ + public void close () throws IOException { + if (jarfile != null) { + jarfile.close(); + } + } + + /* + * Returns the local class path for this loader, or null if none. + */ + URL[] getClassPath() throws IOException { + return null; + } + } + + /* + * Inner class used to represent a Loader of resources from a JAR URL. + */ + static class JarLoader extends Loader { + private JarFile jar; + private URL csu; + private JarIndex index; + private MetaIndex metaIndex; + private URLStreamHandler handler; + private HashMap lmap; + private boolean closed = false; + private static final sun.misc.JavaUtilZipFileAccess zipAccess = + sun.misc.SharedSecrets.getJavaUtilZipFileAccess(); + + /* + * Creates a new JarLoader for the specified URL referring to + * a JAR file. + */ + JarLoader(URL url, URLStreamHandler jarHandler, + HashMap loaderMap) + throws IOException + { + super(new URL("jar", "", -1, url + "!/", jarHandler)); + csu = url; + handler = jarHandler; + lmap = loaderMap; + + if (!isOptimizable(url)) { + ensureOpen(); + } else { + String fileName = url.getFile(); + if (fileName != null) { + fileName = ParseUtil.decode(fileName); + File f = new File(fileName); + metaIndex = MetaIndex.forJar(f); + // If the meta index is found but the file is not + // installed, set metaIndex to null. A typical + // senario is charsets.jar which won't be installed + // when the user is running in certain locale environment. + // The side effect of null metaIndex will cause + // ensureOpen get called so that IOException is thrown. + if (metaIndex != null && !f.exists()) { + metaIndex = null; + } + } + + // metaIndex is null when either there is no such jar file + // entry recorded in meta-index file or such jar file is + // missing in JRE. See bug 6340399. + if (metaIndex == null) { + ensureOpen(); + } + } + } + + @Override + public void close () throws IOException { + // closing is synchronized at higher level + if (!closed) { + closed = true; + // in case not already open. + ensureOpen(); + jar.close(); + } + } + + JarFile getJarFile () { + return jar; + } + + private boolean isOptimizable(URL url) { + return "file".equals(url.getProtocol()); + } + + private void ensureOpen() throws IOException { + if (jar == null) { + try { + java.security.AccessController.doPrivileged( + new java.security.PrivilegedExceptionAction() { + public Void run() throws IOException { + if (DEBUG) { + System.err.println("Opening " + csu); + Thread.dumpStack(); + } + + jar = getJarFile(csu); + index = JarIndex.getJarIndex(jar, metaIndex); + if (index != null) { + String[] jarfiles = index.getJarFiles(); + // Add all the dependent URLs to the lmap so that loaders + // will not be created for them by URLClassPath.getLoader(int) + // if the same URL occurs later on the main class path. We set + // Loader to null here to avoid creating a Loader for each + // URL until we actually need to try to load something from them. + for(int i = 0; i < jarfiles.length; i++) { + try { + URL jarURL = new URL(csu, jarfiles[i]); + // If a non-null loader already exists, leave it alone. + String urlNoFragString = URLUtil.urlNoFragString(jarURL); + if (!lmap.containsKey(urlNoFragString)) { + lmap.put(urlNoFragString, null); + } + } catch (MalformedURLException e) { + continue; + } + } + } + return null; + } + } + ); + } catch (java.security.PrivilegedActionException pae) { + throw (IOException)pae.getException(); + } + } + } + + /* Throws if the given jar file is does not start with the correct LOC */ + static JarFile checkJar(JarFile jar) throws IOException { + if (System.getSecurityManager() != null && !DISABLE_JAR_CHECKING + && !zipAccess.startsWithLocHeader(jar)) { + IOException x = new IOException("Invalid Jar file"); + try { + jar.close(); + } catch (IOException ex) { + x.addSuppressed(ex); + } + throw x; + } + + return jar; + } + + private JarFile getJarFile(URL url) throws IOException { + // Optimize case where url refers to a local jar file + if (isOptimizable(url)) { + FileURLMapper p = new FileURLMapper (url); + if (!p.exists()) { + throw new FileNotFoundException(p.getPath()); + } + return checkJar(new JarFile(p.getPath())); + } + URLConnection uc = getBaseURL().openConnection(); + uc.setRequestProperty(USER_AGENT_JAVA_VERSION, JAVA_VERSION); + JarFile jarFile = ((JarURLConnection)uc).getJarFile(); + return checkJar(jarFile); + } + + /* + * Returns the index of this JarLoader if it exists. + */ + JarIndex getIndex() { + try { + ensureOpen(); + } catch (IOException e) { + throw new InternalError(e); + } + return index; + } + + /* + * Creates the resource and if the check flag is set to true, checks if + * is its okay to return the resource. + */ + Resource checkResource(final String name, boolean check, + final JarEntry entry) { + + final URL url; + try { + url = new URL(getBaseURL(), ParseUtil.encodePath(name, false)); + if (check) { + URLClassPath.check(url); + } + } catch (MalformedURLException e) { + return null; + // throw new IllegalArgumentException("name"); + } catch (IOException e) { + return null; + } catch (AccessControlException e) { + return null; + } + + return new Resource() { + public String getName() { return name; } + public URL getURL() { return url; } + public URL getCodeSourceURL() { return csu; } + public InputStream getInputStream() throws IOException + { return jar.getInputStream(entry); } + public int getContentLength() + { return (int)entry.getSize(); } + public Manifest getManifest() throws IOException + { return jar.getManifest(); }; + public Certificate[] getCertificates() + { return entry.getCertificates(); }; + public CodeSigner[] getCodeSigners() + { return entry.getCodeSigners(); }; + }; + } + + + /* + * Returns true iff atleast one resource in the jar file has the same + * package name as that of the specified resource name. + */ + boolean validIndex(final String name) { + String packageName = name; + int pos; + if((pos = name.lastIndexOf("/")) != -1) { + packageName = name.substring(0, pos); + } + + String entryName; + ZipEntry entry; + Enumeration enum_ = jar.entries(); + while (enum_.hasMoreElements()) { + entry = enum_.nextElement(); + entryName = entry.getName(); + if((pos = entryName.lastIndexOf("/")) != -1) + entryName = entryName.substring(0, pos); + if (entryName.equals(packageName)) { + return true; + } + } + return false; + } + + /* + * Returns the URL for a resource with the specified name + */ + URL findResource(final String name, boolean check) { + Resource rsc = getResource(name, check); + if (rsc != null) { + return rsc.getURL(); + } + return null; + } + + /* + * Returns the JAR Resource for the specified name. + */ + Resource getResource(final String name, boolean check) { + if (metaIndex != null) { + if (!metaIndex.mayContain(name)) { + return null; + } + } + + try { + ensureOpen(); + } catch (IOException e) { + throw new InternalError(e); + } + final JarEntry entry = jar.getJarEntry(name); + if (entry != null) + return checkResource(name, check, entry); + + if (index == null) + return null; + + HashSet visited = new HashSet(); + return getResource(name, check, visited); + } + + /* + * Version of getResource() that tracks the jar files that have been + * visited by linking through the index files. This helper method uses + * a HashSet to store the URLs of jar files that have been searched and + * uses it to avoid going into an infinite loop, looking for a + * non-existent resource + */ + Resource getResource(final String name, boolean check, + Set visited) { + + Resource res; + String[] jarFiles; + int count = 0; + LinkedList jarFilesList = null; + + /* If there no jar files in the index that can potential contain + * this resource then return immediately. + */ + if((jarFilesList = index.get(name)) == null) + return null; + + do { + int size = jarFilesList.size(); + jarFiles = jarFilesList.toArray(new String[size]); + /* loop through the mapped jar file list */ + while(count < size) { + String jarName = jarFiles[count++]; + JarLoader newLoader; + final URL url; + + try{ + url = new URL(csu, jarName); + String urlNoFragString = URLUtil.urlNoFragString(url); + if ((newLoader = (JarLoader)lmap.get(urlNoFragString)) == null) { + /* no loader has been set up for this jar file + * before + */ + newLoader = AccessController.doPrivileged( + new PrivilegedExceptionAction() { + public JarLoader run() throws IOException { + return new JarLoader(url, handler, + lmap); + } + }); + + /* this newly opened jar file has its own index, + * merge it into the parent's index, taking into + * account the relative path. + */ + JarIndex newIndex = newLoader.getIndex(); + if(newIndex != null) { + int pos = jarName.lastIndexOf("/"); + newIndex.merge(this.index, (pos == -1 ? + null : jarName.substring(0, pos + 1))); + } + + /* put it in the global hashtable */ + lmap.put(urlNoFragString, newLoader); + } + } catch (java.security.PrivilegedActionException pae) { + continue; + } catch (MalformedURLException e) { + continue; + } + + + /* Note that the addition of the url to the list of visited + * jars incorporates a check for presence in the hashmap + */ + boolean visitedURL = !visited.add(URLUtil.urlNoFragString(url)); + if (!visitedURL) { + try { + newLoader.ensureOpen(); + } catch (IOException e) { + throw new InternalError(e); + } + final JarEntry entry = newLoader.jar.getJarEntry(name); + if (entry != null) { + return newLoader.checkResource(name, check, entry); + } + + /* Verify that at least one other resource with the + * same package name as the lookedup resource is + * present in the new jar + */ + if (!newLoader.validIndex(name)) { + /* the mapping is wrong */ + throw new InvalidJarIndexException("Invalid index"); + } + } + + /* If newLoader is the current loader or if it is a + * loader that has already been searched or if the new + * loader does not have an index then skip it + * and move on to the next loader. + */ + if (visitedURL || newLoader == this || + newLoader.getIndex() == null) { + continue; + } + + /* Process the index of the new loader + */ + if((res = newLoader.getResource(name, check, visited)) + != null) { + return res; + } + } + // Get the list of jar files again as the list could have grown + // due to merging of index files. + jarFilesList = index.get(name); + + // If the count is unchanged, we are done. + } while(count < jarFilesList.size()); + return null; + } + + + /* + * Returns the JAR file local class path, or null if none. + */ + URL[] getClassPath() throws IOException { + if (index != null) { + return null; + } + + if (metaIndex != null) { + return null; + } + + ensureOpen(); + parseExtensionsDependencies(); + + if (SharedSecrets.javaUtilJarAccess().jarFileHasClassPathAttribute(jar)) { // Only get manifest when necessary + Manifest man = jar.getManifest(); + if (man != null) { + Attributes attr = man.getMainAttributes(); + if (attr != null) { + String value = attr.getValue(Name.CLASS_PATH); + if (value != null) { + return parseClassPath(csu, value); + } + } + } + } + return null; + } + + /* + * parse the standard extension dependencies + */ + private void parseExtensionsDependencies() throws IOException { + ExtensionDependency.checkExtensionsDependencies(jar); + } + + /* + * Parses value of the Class-Path manifest attribute and returns + * an array of URLs relative to the specified base URL. + */ + private URL[] parseClassPath(URL base, String value) + throws MalformedURLException + { + StringTokenizer st = new StringTokenizer(value); + URL[] urls = new URL[st.countTokens()]; + int i = 0; + while (st.hasMoreTokens()) { + String path = st.nextToken(); + urls[i] = new URL(base, path); + i++; + } + return urls; + } + } + + /* + * Inner class used to represent a loader of classes and resources + * from a file URL that refers to a directory. + */ + private static class FileLoader extends Loader { + /* Canonicalized File */ + private File dir; + + FileLoader(URL url) throws IOException { + super(url); + if (!"file".equals(url.getProtocol())) { + throw new IllegalArgumentException("url"); + } + String path = url.getFile().replace('/', File.separatorChar); + path = ParseUtil.decode(path); + dir = (new File(path)).getCanonicalFile(); + } + + /* + * Returns the URL for a resource with the specified name + */ + URL findResource(final String name, boolean check) { + Resource rsc = getResource(name, check); + if (rsc != null) { + return rsc.getURL(); + } + return null; + } + + Resource getResource(final String name, boolean check) { + final URL url; + try { + URL normalizedBase = new URL(getBaseURL(), "."); + url = new URL(getBaseURL(), ParseUtil.encodePath(name, false)); + + if (url.getFile().startsWith(normalizedBase.getFile()) == false) { + // requested resource had ../..'s in path + return null; + } + + if (check) + URLClassPath.check(url); + + final File file; + if (name.indexOf("..") != -1) { + file = (new File(dir, name.replace('/', File.separatorChar))) + .getCanonicalFile(); + if ( !((file.getPath()).startsWith(dir.getPath())) ) { + /* outside of base dir */ + return null; + } + } else { + file = new File(dir, name.replace('/', File.separatorChar)); + } + + if (file.exists()) { + return new Resource() { + public String getName() { return name; }; + public URL getURL() { return url; }; + public URL getCodeSourceURL() { return getBaseURL(); }; + public InputStream getInputStream() throws IOException + { return new FileInputStream(file); }; + public int getContentLength() throws IOException + { return (int)file.length(); }; + }; + } + } catch (Exception e) { + return null; + } + return null; + } + } +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/UUDecoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/UUDecoder.java new file mode 100644 index 000000000..57cc6a4ee --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/UUDecoder.java @@ -0,0 +1,274 @@ +/* + * Copyright (c) 1995, 2001, 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.misc; + +import java.io.PushbackInputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.IOException; + +/** + * This class implements a Berkeley uu character decoder. This decoder + * was made famous by the uudecode program. + * + * The basic character coding is algorithmic, taking 6 bits of binary + * data and adding it to an ASCII ' ' (space) character. This converts + * these six bits into a printable representation. Note that it depends + * on the ASCII character encoding standard for english. Groups of three + * bytes are converted into 4 characters by treating the three bytes + * a four 6 bit groups, group 1 is byte 1's most significant six bits, + * group 2 is byte 1's least significant two bits plus byte 2's four + * most significant bits. etc. + * + * In this encoding, the buffer prefix is: + *

      + *     begin [mode] [filename]
      + * 
      + * + * This is followed by one or more lines of the form: + *
      + *      (len)(data)(data)(data) ...
      + * 
      + * where (len) is the number of bytes on this line. Note that groupings + * are always four characters, even if length is not a multiple of three + * bytes. When less than three characters are encoded, the values of the + * last remaining bytes is undefined and should be ignored. + * + * The last line of data in a uuencoded buffer is represented by a single + * space character. This is translated by the decoding engine to a line + * length of zero. This is immediately followed by a line which contains + * the word 'end[newline]' + * + * If an error is encountered during decoding this class throws a + * CEFormatException. The specific detail messages are: + * + *
      + *      "UUDecoder: No begin line."
      + *      "UUDecoder: Malformed begin line."
      + *      "UUDecoder: Short Buffer."
      + *      "UUDecoder: Bad Line Length."
      + *      "UUDecoder: Missing 'end' line."
      + * 
      + * + * @author Chuck McManis + * @see CharacterDecoder + * @see UUEncoder + */ +public class UUDecoder extends CharacterDecoder { + + /** + * This string contains the name that was in the buffer being decoded. + */ + public String bufferName; + + /** + * Represents UNIX(tm) mode bits. Generally three octal digits + * representing read, write, and execute permission of the owner, + * group owner, and others. They should be interpreted as the bit groups: + *
      +     * (owner) (group) (others)
      +     *  rwx      rwx     rwx    (r = read, w = write, x = execute)
      +     *
      + * + */ + public int mode; + + + /** + * UU encoding specifies 3 bytes per atom. + */ + protected int bytesPerAtom() { + return (3); + } + + /** + * All UU lines have 45 bytes on them, for line length of 15*4+1 or 61 + * characters per line. + */ + protected int bytesPerLine() { + return (45); + } + + /** This is used to decode the atoms */ + private byte decoderBuffer[] = new byte[4]; + + /** + * Decode a UU atom. Note that if l is less than 3 we don't write + * the extra bits, however the encoder always encodes 4 character + * groups even when they are not needed. + */ + protected void decodeAtom(PushbackInputStream inStream, OutputStream outStream, int l) + throws IOException { + int i, c1, c2, c3, c4; + int a, b, c; + StringBuffer x = new StringBuffer(); + + for (i = 0; i < 4; i++) { + c1 = inStream.read(); + if (c1 == -1) { + throw new CEStreamExhausted(); + } + x.append((char)c1); + decoderBuffer[i] = (byte) ((c1 - ' ') & 0x3f); + } + a = ((decoderBuffer[0] << 2) & 0xfc) | ((decoderBuffer[1] >>> 4) & 3); + b = ((decoderBuffer[1] << 4) & 0xf0) | ((decoderBuffer[2] >>> 2) & 0xf); + c = ((decoderBuffer[2] << 6) & 0xc0) | (decoderBuffer[3] & 0x3f); + outStream.write((byte)(a & 0xff)); + if (l > 1) { + outStream.write((byte)( b & 0xff)); + } + if (l > 2) { + outStream.write((byte)(c&0xff)); + } + } + + /** + * For uuencoded buffers, the data begins with a line of the form: + * begin MODE FILENAME + * This line always starts in column 1. + */ + protected void decodeBufferPrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException { + int c; + StringBuffer q = new StringBuffer(32); + String r; + boolean sawNewLine; + + /* + * This works by ripping through the buffer until it finds a 'begin' + * line or the end of the buffer. + */ + sawNewLine = true; + while (true) { + c = inStream.read(); + if (c == -1) { + throw new CEFormatException("UUDecoder: No begin line."); + } + if ((c == 'b') && sawNewLine){ + c = inStream.read(); + if (c == 'e') { + break; + } + } + sawNewLine = (c == '\n') || (c == '\r'); + } + + /* + * Now we think its begin, (we've seen ^be) so verify it here. + */ + while ((c != '\n') && (c != '\r')) { + c = inStream.read(); + if (c == -1) { + throw new CEFormatException("UUDecoder: No begin line."); + } + if ((c != '\n') && (c != '\r')) { + q.append((char)c); + } + } + r = q.toString(); + if (r.indexOf(' ') != 3) { + throw new CEFormatException("UUDecoder: Malformed begin line."); + } + mode = Integer.parseInt(r.substring(4,7)); + bufferName = r.substring(r.indexOf(' ',6)+1); + /* + * Check for \n after \r + */ + if (c == '\r') { + c = inStream.read (); + if ((c != '\n') && (c != -1)) + inStream.unread (c); + } + } + + /** + * In uuencoded buffers, encoded lines start with a character that + * represents the number of bytes encoded in this line. The last + * line of input is always a line that starts with a single space + * character, which would be a zero length line. + */ + protected int decodeLinePrefix(PushbackInputStream inStream, OutputStream outStream) throws IOException { + int c; + + c = inStream.read(); + if (c == ' ') { + c = inStream.read(); /* discard the (first)trailing CR or LF */ + c = inStream.read(); /* check for a second one */ + if ((c != '\n') && (c != -1)) + inStream.unread (c); + throw new CEStreamExhausted(); + } else if (c == -1) { + throw new CEFormatException("UUDecoder: Short Buffer."); + } + + c = (c - ' ') & 0x3f; + if (c > bytesPerLine()) { + throw new CEFormatException("UUDecoder: Bad Line Length."); + } + return (c); + } + + + /** + * Find the end of the line for the next operation. + * The following sequences are recognized as end-of-line + * CR, CR LF, or LF + */ + protected void decodeLineSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException { + int c; + while (true) { + c = inStream.read(); + if (c == -1) { + throw new CEStreamExhausted(); + } + if (c == '\n') { + break; + } + if (c == '\r') { + c = inStream.read(); + if ((c != '\n') && (c != -1)) { + inStream.unread (c); + } + break; + } + } + } + + /** + * UUencoded files have a buffer suffix which consists of the word + * end. This line should immediately follow the line with a single + * space in it. + */ + protected void decodeBufferSuffix(PushbackInputStream inStream, OutputStream outStream) throws IOException { + int c; + + c = inStream.read(decoderBuffer); + if ((decoderBuffer[0] != 'e') || (decoderBuffer[1] != 'n') || + (decoderBuffer[2] != 'd')) { + throw new CEFormatException("UUDecoder: Missing 'end' line."); + } + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/UUEncoder.java b/sources/net.sf.j2s.java.core/src/sun/misc/UUEncoder.java new file mode 100644 index 000000000..a52f235b3 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/UUEncoder.java @@ -0,0 +1,200 @@ +/* + * Copyright (c) 1995, 2004, 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.misc; + +import java.io.InputStream; +import java.io.OutputStream; +import java.io.PrintStream; +import java.io.IOException; + +/** + * This class implements a Berkeley uu character encoder. This encoder + * was made famous by uuencode program. + * + * The basic character coding is algorithmic, taking 6 bits of binary + * data and adding it to an ASCII ' ' (space) character. This converts + * these six bits into a printable representation. Note that it depends + * on the ASCII character encoding standard for english. Groups of three + * bytes are converted into 4 characters by treating the three bytes + * a four 6 bit groups, group 1 is byte 1's most significant six bits, + * group 2 is byte 1's least significant two bits plus byte 2's four + * most significant bits. etc. + * + * In this encoding, the buffer prefix is: + *
      + *     begin [mode] [filename]
      + * 
      + * + * This is followed by one or more lines of the form: + *
      + *      (len)(data)(data)(data) ...
      + * 
      + * where (len) is the number of bytes on this line. Note that groupings + * are always four characters, even if length is not a multiple of three + * bytes. When less than three characters are encoded, the values of the + * last remaining bytes is undefined and should be ignored. + * + * The last line of data in a uuencoded file is represented by a single + * space character. This is translated by the decoding engine to a line + * length of zero. This is immediately followed by a line which contains + * the word 'end[newline]' + * + * @author Chuck McManis + * @see CharacterEncoder + * @see UUDecoder + */ +public class UUEncoder extends CharacterEncoder { + + /** + * This name is stored in the begin line. + */ + private String bufferName; + + /** + * Represents UNIX(tm) mode bits. Generally three octal digits representing + * read, write, and execute permission of the owner, group owner, and + * others. They should be interpreted as the bit groups: + * (owner) (group) (others) + * rwx rwx rwx (r = read, w = write, x = execute) + * + * By default these are set to 644 (UNIX rw-r--r-- permissions). + */ + private int mode; + + + /** + * Default - buffer begin line will be: + *
      +     *  begin 644 encoder.buf
      +     * 
      + */ + public UUEncoder() { + bufferName = "encoder.buf"; + mode = 644; + } + + /** + * Specifies a name for the encoded buffer, begin line will be: + *
      +     *  begin 644 [FNAME]
      +     * 
      + */ + public UUEncoder(String fname) { + bufferName = fname; + mode = 644; + } + + /** + * Specifies a name and mode for the encoded buffer, begin line will be: + *
      +     *  begin [MODE] [FNAME]
      +     * 
      + */ + public UUEncoder(String fname, int newMode) { + bufferName = fname; + mode = newMode; + } + + /** number of bytes per atom in uuencoding is 3 */ + protected int bytesPerAtom() { + return (3); + } + + /** number of bytes per line in uuencoding is 45 */ + protected int bytesPerLine() { + return (45); + } + + /** + * encodeAtom - take three bytes and encodes them into 4 characters + * If len is less than 3 then remaining bytes are filled with '1'. + * This insures that the last line won't end in spaces and potentiallly + * be truncated. + */ + protected void encodeAtom(OutputStream outStream, byte data[], int offset, int len) + throws IOException { + byte a, b = 1, c = 1; + int c1, c2, c3, c4; + + a = data[offset]; + if (len > 1) { + b = data[offset+1]; + } + if (len > 2) { + c = data[offset+2]; + } + + c1 = (a >>> 2) & 0x3f; + c2 = ((a << 4) & 0x30) | ((b >>> 4) & 0xf); + c3 = ((b << 2) & 0x3c) | ((c >>> 6) & 0x3); + c4 = c & 0x3f; + outStream.write(c1 + ' '); + outStream.write(c2 + ' '); + outStream.write(c3 + ' '); + outStream.write(c4 + ' '); + return; + } + + /** + * Encode the line prefix which consists of the single character. The + * lenght is added to the value of ' ' (32 decimal) and printed. + */ + protected void encodeLinePrefix(OutputStream outStream, int length) + throws IOException { + outStream.write((length & 0x3f) + ' '); + } + + + /** + * The line suffix for uuencoded files is simply a new line. + */ + protected void encodeLineSuffix(OutputStream outStream) throws IOException { + pStream.println(); + } + + /** + * encodeBufferPrefix writes the begin line to the output stream. + */ + protected void encodeBufferPrefix(OutputStream a) throws IOException { + super.pStream = new PrintStream(a); + super.pStream.print("begin "+mode+" "); + if (bufferName != null) { + super.pStream.println(bufferName); + } else { + super.pStream.println("encoder.bin"); + } + super.pStream.flush(); + } + + /** + * encodeBufferSuffix writes the single line containing space (' ') and + * the line containing the word 'end' to the output stream. + */ + protected void encodeBufferSuffix(OutputStream a) throws IOException { + super.pStream.println(" \nend"); + super.pStream.flush(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Unsafe.java b/sources/net.sf.j2s.java.core/src/sun/misc/Unsafe.java new file mode 100644 index 000000000..47f74a9e5 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Unsafe.java @@ -0,0 +1,1145 @@ +/* + * Copyright (c) 2000, 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.misc; + +import java.security.*; +import java.lang.reflect.*; + +import sun.reflect.CallerSensitive; +import sun.reflect.Reflection; + + +/** + * A collection of methods for performing low-level, unsafe operations. + * Although the class and all methods are public, use of this class is + * limited because only trusted code can obtain instances of it. + * + * @author John R. Rose + * @see #getUnsafe + */ + +public final class Unsafe { + +// private static native void registerNatives(); +// static { +// registerNatives(); +// sun.reflect.Reflection.registerMethodsToFilter(Unsafe.class, "getUnsafe"); +// } + + private Unsafe() {} + + private static final Unsafe theUnsafe = new Unsafe(); + + /** + * Provides the caller with the capability of performing unsafe + * operations. + * + *

      The returned Unsafe object should be carefully guarded + * by the caller, since it can be used to read and write data at arbitrary + * memory addresses. It must never be passed to untrusted code. + * + *

      Most methods in this class are very low-level, and correspond to a + * small number of hardware instructions (on typical machines). Compilers + * are encouraged to optimize these methods accordingly. + * + *

      Here is a suggested idiom for using unsafe operations: + * + *

      +     * class MyTrustedClass {
      +     *   private static final Unsafe unsafe = Unsafe.getUnsafe();
      +     *   ...
      +     *   private long myCountAddress = ...;
      +     *   public int getCount() { return unsafe.getByte(myCountAddress); }
      +     * }
      +     * 
      + * + * (It may assist compilers to make the local variable be + * final.) + * + * @exception SecurityException if a security manager exists and its + * checkPropertiesAccess method doesn't allow + * access to the system properties. + */ + @CallerSensitive + public static Unsafe getUnsafe() { + Class caller = Reflection.getCallerClass(); + if (!VM.isSystemDomainLoader(caller.getClassLoader())) + throw new SecurityException("Unsafe"); + return theUnsafe; + } + + /// peek and poke operations + /// (compilers should optimize these to memory ops) + + // These work on object fields in the Java heap. + // They will not work on elements of packed arrays. + + /** + * Fetches a value from a given Java variable. + * More specifically, fetches a field or array element within the given + * object o at the given offset, or (if o is + * null) from the memory address whose numerical value is the given + * offset. + *

      + * The results are undefined unless one of the following cases is true: + *

        + *
      • The offset was obtained from {@link #objectFieldOffset} on + * the {@link java.lang.reflect.Field} of some Java field and the object + * referred to by o is of a class compatible with that + * field's class. + * + *
      • The offset and object reference o (either null or + * non-null) were both obtained via {@link #staticFieldOffset} + * and {@link #staticFieldBase} (respectively) from the + * reflective {@link Field} representation of some Java field. + * + *
      • The object referred to by o is an array, and the offset + * is an integer of the form B+N*S, where N is + * a valid index into the array, and B and S are + * the values obtained by {@link #arrayBaseOffset} and {@link + * #arrayIndexScale} (respectively) from the array's class. The value + * referred to is the Nth element of the array. + * + *
      + *

      + * If one of the above cases is true, the call references a specific Java + * variable (field or array element). However, the results are undefined + * if that variable is not in fact of the type returned by this method. + *

      + * This method refers to a variable by means of two parameters, and so + * it provides (in effect) a double-register addressing mode + * for Java variables. When the object reference is null, this method + * uses its offset as an absolute address. This is similar in operation + * to methods such as {@link #getInt(long)}, which provide (in effect) a + * single-register addressing mode for non-Java variables. + * However, because Java variables may have a different layout in memory + * from non-Java variables, programmers should not assume that these + * two addressing modes are ever equivalent. Also, programmers should + * remember that offsets from the double-register addressing mode cannot + * be portably confused with longs used in the single-register addressing + * mode. + * + * @param o Java heap object in which the variable resides, if any, else + * null + * @param offset indication of where the variable resides in a Java heap + * object, if any, else a memory address locating the variable + * statically + * @return the value fetched from the indicated Java variable + * @throws RuntimeException No defined exceptions are thrown, not even + * {@link NullPointerException} + */ + public native int getInt(Object o, long offset); + + /** + * Stores a value into a given Java variable. + *

      + * The first two parameters are interpreted exactly as with + * {@link #getInt(Object, long)} to refer to a specific + * Java variable (field or array element). The given value + * is stored into that variable. + *

      + * The variable must be of the same type as the method + * parameter x. + * + * @param o Java heap object in which the variable resides, if any, else + * null + * @param offset indication of where the variable resides in a Java heap + * object, if any, else a memory address locating the variable + * statically + * @param x the value to store into the indicated Java variable + * @throws RuntimeException No defined exceptions are thrown, not even + * {@link NullPointerException} + */ + public native void putInt(Object o, long offset, int x); + + /** + * Fetches a reference value from a given Java variable. + * @see #getInt(Object, long) + */ + public native Object getObject(Object o, long offset); + + /** + * Stores a reference value into a given Java variable. + *

      + * Unless the reference x being stored is either null + * or matches the field type, the results are undefined. + * If the reference o is non-null, car marks or + * other store barriers for that object (if the VM requires them) + * are updated. + * @see #putInt(Object, int, int) + */ + public native void putObject(Object o, long offset, Object x); + + /** @see #getInt(Object, long) */ + public native boolean getBoolean(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putBoolean(Object o, long offset, boolean x); + /** @see #getInt(Object, long) */ + public native byte getByte(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putByte(Object o, long offset, byte x); + /** @see #getInt(Object, long) */ + public native short getShort(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putShort(Object o, long offset, short x); + /** @see #getInt(Object, long) */ + public native char getChar(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putChar(Object o, long offset, char x); + /** @see #getInt(Object, long) */ + public native long getLong(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putLong(Object o, long offset, long x); + /** @see #getInt(Object, long) */ + public native float getFloat(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putFloat(Object o, long offset, float x); + /** @see #getInt(Object, long) */ + public native double getDouble(Object o, long offset); + /** @see #putInt(Object, int, int) */ + public native void putDouble(Object o, long offset, double x); + + /** + * This method, like all others with 32-bit offsets, was native + * in a previous release but is now a wrapper which simply casts + * the offset to a long value. It provides backward compatibility + * with bytecodes compiled against 1.4. + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public int getInt(Object o, int offset) { + return getInt(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putInt(Object o, int offset, int x) { + putInt(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public Object getObject(Object o, int offset) { + return getObject(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putObject(Object o, int offset, Object x) { + putObject(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public boolean getBoolean(Object o, int offset) { + return getBoolean(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putBoolean(Object o, int offset, boolean x) { + putBoolean(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public byte getByte(Object o, int offset) { + return getByte(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putByte(Object o, int offset, byte x) { + putByte(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public short getShort(Object o, int offset) { + return getShort(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putShort(Object o, int offset, short x) { + putShort(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public char getChar(Object o, int offset) { + return getChar(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putChar(Object o, int offset, char x) { + putChar(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public long getLong(Object o, int offset) { + return getLong(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putLong(Object o, int offset, long x) { + putLong(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public float getFloat(Object o, int offset) { + return getFloat(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putFloat(Object o, int offset, float x) { + putFloat(o, (long)offset, x); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public double getDouble(Object o, int offset) { + return getDouble(o, (long)offset); + } + + /** + * @deprecated As of 1.4.1, cast the 32-bit offset argument to a long. + * See {@link #staticFieldOffset}. + */ + @Deprecated + public void putDouble(Object o, int offset, double x) { + putDouble(o, (long)offset, x); + } + + // These work on values in the C heap. + + /** + * Fetches a value from a given memory address. If the address is zero, or + * does not point into a block obtained from {@link #allocateMemory}, the + * results are undefined. + * + * @see #allocateMemory + */ + public native byte getByte(long address); + + /** + * Stores a value into a given memory address. If the address is zero, or + * does not point into a block obtained from {@link #allocateMemory}, the + * results are undefined. + * + * @see #getByte(long) + */ + public native void putByte(long address, byte x); + + /** @see #getByte(long) */ + public native short getShort(long address); + /** @see #putByte(long, byte) */ + public native void putShort(long address, short x); + /** @see #getByte(long) */ + public native char getChar(long address); + /** @see #putByte(long, byte) */ + public native void putChar(long address, char x); + /** @see #getByte(long) */ + public native int getInt(long address); + /** @see #putByte(long, byte) */ + public native void putInt(long address, int x); + /** @see #getByte(long) */ + public native long getLong(long address); + /** @see #putByte(long, byte) */ + public native void putLong(long address, long x); + /** @see #getByte(long) */ + public native float getFloat(long address); + /** @see #putByte(long, byte) */ + public native void putFloat(long address, float x); + /** @see #getByte(long) */ + public native double getDouble(long address); + /** @see #putByte(long, byte) */ + public native void putDouble(long address, double x); + + /** + * Fetches a native pointer from a given memory address. If the address is + * zero, or does not point into a block obtained from {@link + * #allocateMemory}, the results are undefined. + * + *

      If the native pointer is less than 64 bits wide, it is extended as + * an unsigned number to a Java long. The pointer may be indexed by any + * given byte offset, simply by adding that offset (as a simple integer) to + * the long representing the pointer. The number of bytes actually read + * from the target address maybe determined by consulting {@link + * #addressSize}. + * + * @see #allocateMemory + */ + public native long getAddress(long address); + + /** + * Stores a native pointer into a given memory address. If the address is + * zero, or does not point into a block obtained from {@link + * #allocateMemory}, the results are undefined. + * + *

      The number of bytes actually written at the target address maybe + * determined by consulting {@link #addressSize}. + * + * @see #getAddress(long) + */ + public native void putAddress(long address, long x); + + /// wrappers for malloc, realloc, free: + + /** + * Allocates a new block of native memory, of the given size in bytes. The + * contents of the memory are uninitialized; they will generally be + * garbage. The resulting native pointer will never be zero, and will be + * aligned for all value types. Dispose of this memory by calling {@link + * #freeMemory}, or resize it with {@link #reallocateMemory}. + * + * @throws IllegalArgumentException if the size is negative or too large + * for the native size_t type + * + * @throws OutOfMemoryError if the allocation is refused by the system + * + * @see #getByte(long) + * @see #putByte(long, byte) + */ + public native long allocateMemory(long bytes); + + /** + * Resizes a new block of native memory, to the given size in bytes. The + * contents of the new block past the size of the old block are + * uninitialized; they will generally be garbage. The resulting native + * pointer will be zero if and only if the requested size is zero. The + * resulting native pointer will be aligned for all value types. Dispose + * of this memory by calling {@link #freeMemory}, or resize it with {@link + * #reallocateMemory}. The address passed to this method may be null, in + * which case an allocation will be performed. + * + * @throws IllegalArgumentException if the size is negative or too large + * for the native size_t type + * + * @throws OutOfMemoryError if the allocation is refused by the system + * + * @see #allocateMemory + */ + public native long reallocateMemory(long address, long bytes); + + /** + * Sets all bytes in a given block of memory to a fixed value + * (usually zero). + * + *

      This method determines a block's base address by means of two parameters, + * and so it provides (in effect) a double-register addressing mode, + * as discussed in {@link #getInt(Object,long)}. When the object reference is null, + * the offset supplies an absolute base address. + * + *

      The stores are in coherent (atomic) units of a size determined + * by the address and length parameters. If the effective address and + * length are all even modulo 8, the stores take place in 'long' units. + * If the effective address and length are (resp.) even modulo 4 or 2, + * the stores take place in units of 'int' or 'short'. + * + * @since 1.7 + */ + public native void setMemory(Object o, long offset, long bytes, byte value); + + /** + * Sets all bytes in a given block of memory to a fixed value + * (usually zero). This provides a single-register addressing mode, + * as discussed in {@link #getInt(Object,long)}. + * + *

      Equivalent to setMemory(null, address, bytes, value). + */ + public void setMemory(long address, long bytes, byte value) { + setMemory(null, address, bytes, value); + } + + /** + * Sets all bytes in a given block of memory to a copy of another + * block. + * + *

      This method determines each block's base address by means of two parameters, + * and so it provides (in effect) a double-register addressing mode, + * as discussed in {@link #getInt(Object,long)}. When the object reference is null, + * the offset supplies an absolute base address. + * + *

      The transfers are in coherent (atomic) units of a size determined + * by the address and length parameters. If the effective addresses and + * length are all even modulo 8, the transfer takes place in 'long' units. + * If the effective addresses and length are (resp.) even modulo 4 or 2, + * the transfer takes place in units of 'int' or 'short'. + * + * @since 1.7 + */ + public native void copyMemory(Object srcBase, long srcOffset, + Object destBase, long destOffset, + long bytes); + /** + * Sets all bytes in a given block of memory to a copy of another + * block. This provides a single-register addressing mode, + * as discussed in {@link #getInt(Object,long)}. + * + * Equivalent to copyMemory(null, srcAddress, null, destAddress, bytes). + */ + public void copyMemory(long srcAddress, long destAddress, long bytes) { + copyMemory(null, srcAddress, null, destAddress, bytes); + } + + /** + * Disposes of a block of native memory, as obtained from {@link + * #allocateMemory} or {@link #reallocateMemory}. The address passed to + * this method may be null, in which case no action is taken. + * + * @see #allocateMemory + */ + public native void freeMemory(long address); + + /// random queries + + /** + * This constant differs from all results that will ever be returned from + * {@link #staticFieldOffset}, {@link #objectFieldOffset}, + * or {@link #arrayBaseOffset}. + */ + public static final int INVALID_FIELD_OFFSET = -1; + + /** + * Returns the offset of a field, truncated to 32 bits. + * This method is implemented as follows: + *

      +     * public int fieldOffset(Field f) {
      +     *     if (Modifier.isStatic(f.getModifiers()))
      +     *         return (int) staticFieldOffset(f);
      +     *     else
      +     *         return (int) objectFieldOffset(f);
      +     * }
      +     * 
      + * @deprecated As of 1.4.1, use {@link #staticFieldOffset} for static + * fields and {@link #objectFieldOffset} for non-static fields. + */ + @Deprecated + public int fieldOffset(Field f) { + if (Modifier.isStatic(f.getModifiers())) + return (int) staticFieldOffset(f); + else + return (int) objectFieldOffset(f); + } + + /** + * Returns the base address for accessing some static field + * in the given class. This method is implemented as follows: + *
      +     * public Object staticFieldBase(Class c) {
      +     *     Field[] fields = c.getDeclaredFields();
      +     *     for (int i = 0; i < fields.length; i++) {
      +     *         if (Modifier.isStatic(fields[i].getModifiers())) {
      +     *             return staticFieldBase(fields[i]);
      +     *         }
      +     *     }
      +     *     return null;
      +     * }
      +     * 
      + * @deprecated As of 1.4.1, use {@link #staticFieldBase(Field)} + * to obtain the base pertaining to a specific {@link Field}. + * This method works only for JVMs which store all statics + * for a given class in one place. + */ + @Deprecated + public Object staticFieldBase(Class c) { + Field[] fields = c.getDeclaredFields(); + for (int i = 0; i < fields.length; i++) { + if (Modifier.isStatic(fields[i].getModifiers())) { + return staticFieldBase(fields[i]); + } + } + return null; + } + + /** + * Report the location of a given field in the storage allocation of its + * class. Do not expect to perform any sort of arithmetic on this offset; + * it is just a cookie which is passed to the unsafe heap memory accessors. + * + *

      Any given field will always have the same offset and base, and no + * two distinct fields of the same class will ever have the same offset + * and base. + * + *

      As of 1.4.1, offsets for fields are represented as long values, + * although the Sun JVM does not use the most significant 32 bits. + * However, JVM implementations which store static fields at absolute + * addresses can use long offsets and null base pointers to express + * the field locations in a form usable by {@link #getInt(Object,long)}. + * Therefore, code which will be ported to such JVMs on 64-bit platforms + * must preserve all bits of static field offsets. + * @see #getInt(Object, long) + */ + public native long staticFieldOffset(Field f); + + /** + * Report the location of a given static field, in conjunction with {@link + * #staticFieldBase}. + *

      Do not expect to perform any sort of arithmetic on this offset; + * it is just a cookie which is passed to the unsafe heap memory accessors. + * + *

      Any given field will always have the same offset, and no two distinct + * fields of the same class will ever have the same offset. + * + *

      As of 1.4.1, offsets for fields are represented as long values, + * although the Sun JVM does not use the most significant 32 bits. + * It is hard to imagine a JVM technology which needs more than + * a few bits to encode an offset within a non-array object, + * However, for consistency with other methods in this class, + * this method reports its result as a long value. + * @see #getInt(Object, long) + */ + public native long objectFieldOffset(Field f); + + /** + * Report the location of a given static field, in conjunction with {@link + * #staticFieldOffset}. + *

      Fetch the base "Object", if any, with which static fields of the + * given class can be accessed via methods like {@link #getInt(Object, + * long)}. This value may be null. This value may refer to an object + * which is a "cookie", not guaranteed to be a real Object, and it should + * not be used in any way except as argument to the get and put routines in + * this class. + */ + public native Object staticFieldBase(Field f); + + /** + * Detect if the given class may need to be initialized. This is often + * needed in conjunction with obtaining the static field base of a + * class. + * @return false only if a call to {@code ensureClassInitialized} would have no effect + */ + public native boolean shouldBeInitialized(Class c); + + /** + * Ensure the given class has been initialized. This is often + * needed in conjunction with obtaining the static field base of a + * class. + */ + public native void ensureClassInitialized(Class c); + + /** + * Report the offset of the first element in the storage allocation of a + * given array class. If {@link #arrayIndexScale} returns a non-zero value + * for the same class, you may use that scale factor, together with this + * base offset, to form new offsets to access elements of arrays of the + * given class. + * + * @see #getInt(Object, long) + * @see #putInt(Object, long, int) + */ + public native int arrayBaseOffset(Class arrayClass); + + /** The value of {@code arrayBaseOffset(boolean[].class)} */ + public static final int ARRAY_BOOLEAN_BASE_OFFSET + = theUnsafe.arrayBaseOffset(boolean[].class); + + /** The value of {@code arrayBaseOffset(byte[].class)} */ + public static final int ARRAY_BYTE_BASE_OFFSET + = theUnsafe.arrayBaseOffset(byte[].class); + + /** The value of {@code arrayBaseOffset(short[].class)} */ + public static final int ARRAY_SHORT_BASE_OFFSET + = theUnsafe.arrayBaseOffset(short[].class); + + /** The value of {@code arrayBaseOffset(char[].class)} */ + public static final int ARRAY_CHAR_BASE_OFFSET + = theUnsafe.arrayBaseOffset(char[].class); + + /** The value of {@code arrayBaseOffset(int[].class)} */ + public static final int ARRAY_INT_BASE_OFFSET + = theUnsafe.arrayBaseOffset(int[].class); + + /** The value of {@code arrayBaseOffset(long[].class)} */ + public static final int ARRAY_LONG_BASE_OFFSET + = theUnsafe.arrayBaseOffset(long[].class); + + /** The value of {@code arrayBaseOffset(float[].class)} */ + public static final int ARRAY_FLOAT_BASE_OFFSET + = theUnsafe.arrayBaseOffset(float[].class); + + /** The value of {@code arrayBaseOffset(double[].class)} */ + public static final int ARRAY_DOUBLE_BASE_OFFSET + = theUnsafe.arrayBaseOffset(double[].class); + + /** The value of {@code arrayBaseOffset(Object[].class)} */ + public static final int ARRAY_OBJECT_BASE_OFFSET + = theUnsafe.arrayBaseOffset(Object[].class); + + /** + * Report the scale factor for addressing elements in the storage + * allocation of a given array class. However, arrays of "narrow" types + * will generally not work properly with accessors like {@link + * #getByte(Object, int)}, so the scale factor for such classes is reported + * as zero. + * + * @see #arrayBaseOffset + * @see #getInt(Object, long) + * @see #putInt(Object, long, int) + */ + public native int arrayIndexScale(Class arrayClass); + + /** The value of {@code arrayIndexScale(boolean[].class)} */ + public static final int ARRAY_BOOLEAN_INDEX_SCALE + = theUnsafe.arrayIndexScale(boolean[].class); + + /** The value of {@code arrayIndexScale(byte[].class)} */ + public static final int ARRAY_BYTE_INDEX_SCALE + = theUnsafe.arrayIndexScale(byte[].class); + + /** The value of {@code arrayIndexScale(short[].class)} */ + public static final int ARRAY_SHORT_INDEX_SCALE + = theUnsafe.arrayIndexScale(short[].class); + + /** The value of {@code arrayIndexScale(char[].class)} */ + public static final int ARRAY_CHAR_INDEX_SCALE + = theUnsafe.arrayIndexScale(char[].class); + + /** The value of {@code arrayIndexScale(int[].class)} */ + public static final int ARRAY_INT_INDEX_SCALE + = theUnsafe.arrayIndexScale(int[].class); + + /** The value of {@code arrayIndexScale(long[].class)} */ + public static final int ARRAY_LONG_INDEX_SCALE + = theUnsafe.arrayIndexScale(long[].class); + + /** The value of {@code arrayIndexScale(float[].class)} */ + public static final int ARRAY_FLOAT_INDEX_SCALE + = theUnsafe.arrayIndexScale(float[].class); + + /** The value of {@code arrayIndexScale(double[].class)} */ + public static final int ARRAY_DOUBLE_INDEX_SCALE + = theUnsafe.arrayIndexScale(double[].class); + + /** The value of {@code arrayIndexScale(Object[].class)} */ + public static final int ARRAY_OBJECT_INDEX_SCALE + = theUnsafe.arrayIndexScale(Object[].class); + + /** + * Report the size in bytes of a native pointer, as stored via {@link + * #putAddress}. This value will be either 4 or 8. Note that the sizes of + * other primitive types (as stored in native memory blocks) is determined + * fully by their information content. + */ + public native int addressSize(); + + /** The value of {@code addressSize()} */ + public static final int ADDRESS_SIZE = theUnsafe.addressSize(); + + /** + * Report the size in bytes of a native memory page (whatever that is). + * This value will always be a power of two. + */ + public native int pageSize(); + + + /// random trusted operations from JNI: + + /** + * Tell the VM to define a class, without security checks. By default, the + * class loader and protection domain come from the caller's class. + */ + public native Class defineClass(String name, byte[] b, int off, int len, + ClassLoader loader, + ProtectionDomain protectionDomain); + + /** + * Define a class but do not make it known to the class loader or system dictionary. + *

      + * For each CP entry, the corresponding CP patch must either be null or have + * the a format that matches its tag: + *

        + *
      • Integer, Long, Float, Double: the corresponding wrapper object type from java.lang + *
      • Utf8: a string (must have suitable syntax if used as signature or name) + *
      • Class: any java.lang.Class object + *
      • String: any object (not just a java.lang.String) + *
      • InterfaceMethodRef: (NYI) a method handle to invoke on that call site's arguments + *
      + * @params hostClass context for linkage, access control, protection domain, and class loader + * @params data bytes of a class file + * @params cpPatches where non-null entries exist, they replace corresponding CP entries in data + */ + public native Class defineAnonymousClass(Class hostClass, byte[] data, Object[] cpPatches); + + + /** Allocate an instance but do not run any constructor. + Initializes the class if it has not yet been. */ + public native Object allocateInstance(Class cls) + throws InstantiationException; + + /** Lock the object. It must get unlocked via {@link #monitorExit}. */ + @Deprecated + public native void monitorEnter(Object o); + + /** + * Unlock the object. It must have been locked via {@link + * #monitorEnter}. + */ + @Deprecated + public native void monitorExit(Object o); + + /** + * Tries to lock the object. Returns true or false to indicate + * whether the lock succeeded. If it did, the object must be + * unlocked via {@link #monitorExit}. + */ + @Deprecated + public native boolean tryMonitorEnter(Object o); + + /** Throw the exception without telling the verifier. */ + public native void throwException(Throwable ee); + + + /** + * Atomically update Java variable to x if it is currently + * holding expected. + * @return true if successful + */ + public final native boolean compareAndSwapObject(Object o, long offset, + Object expected, + Object x); + + /** + * Atomically update Java variable to x if it is currently + * holding expected. + * @return true if successful + */ + public final native boolean compareAndSwapInt(Object o, long offset, + int expected, + int x); + + /** + * Atomically update Java variable to x if it is currently + * holding expected. + * @return true if successful + */ + public final native boolean compareAndSwapLong(Object o, long offset, + long expected, + long x); + + /** + * Fetches a reference value from a given Java variable, with volatile + * load semantics. Otherwise identical to {@link #getObject(Object, long)} + */ + public native Object getObjectVolatile(Object o, long offset); + + /** + * Stores a reference value into a given Java variable, with + * volatile store semantics. Otherwise identical to {@link #putObject(Object, long, Object)} + */ + public native void putObjectVolatile(Object o, long offset, Object x); + + /** Volatile version of {@link #getInt(Object, long)} */ + public native int getIntVolatile(Object o, long offset); + + /** Volatile version of {@link #putInt(Object, long, int)} */ + public native void putIntVolatile(Object o, long offset, int x); + + /** Volatile version of {@link #getBoolean(Object, long)} */ + public native boolean getBooleanVolatile(Object o, long offset); + + /** Volatile version of {@link #putBoolean(Object, long, boolean)} */ + public native void putBooleanVolatile(Object o, long offset, boolean x); + + /** Volatile version of {@link #getByte(Object, long)} */ + public native byte getByteVolatile(Object o, long offset); + + /** Volatile version of {@link #putByte(Object, long, byte)} */ + public native void putByteVolatile(Object o, long offset, byte x); + + /** Volatile version of {@link #getShort(Object, long)} */ + public native short getShortVolatile(Object o, long offset); + + /** Volatile version of {@link #putShort(Object, long, short)} */ + public native void putShortVolatile(Object o, long offset, short x); + + /** Volatile version of {@link #getChar(Object, long)} */ + public native char getCharVolatile(Object o, long offset); + + /** Volatile version of {@link #putChar(Object, long, char)} */ + public native void putCharVolatile(Object o, long offset, char x); + + /** Volatile version of {@link #getLong(Object, long)} */ + public native long getLongVolatile(Object o, long offset); + + /** Volatile version of {@link #putLong(Object, long, long)} */ + public native void putLongVolatile(Object o, long offset, long x); + + /** Volatile version of {@link #getFloat(Object, long)} */ + public native float getFloatVolatile(Object o, long offset); + + /** Volatile version of {@link #putFloat(Object, long, float)} */ + public native void putFloatVolatile(Object o, long offset, float x); + + /** Volatile version of {@link #getDouble(Object, long)} */ + public native double getDoubleVolatile(Object o, long offset); + + /** Volatile version of {@link #putDouble(Object, long, double)} */ + public native void putDoubleVolatile(Object o, long offset, double x); + + /** + * Version of {@link #putObjectVolatile(Object, long, Object)} + * that does not guarantee immediate visibility of the store to + * other threads. This method is generally only useful if the + * underlying field is a Java volatile (or if an array cell, one + * that is otherwise only accessed using volatile accesses). + */ + public native void putOrderedObject(Object o, long offset, Object x); + + /** Ordered/Lazy version of {@link #putIntVolatile(Object, long, int)} */ + public native void putOrderedInt(Object o, long offset, int x); + + /** Ordered/Lazy version of {@link #putLongVolatile(Object, long, long)} */ + public native void putOrderedLong(Object o, long offset, long x); + + /** + * Unblock the given thread blocked on park, or, if it is + * not blocked, cause the subsequent call to park not to + * block. Note: this operation is "unsafe" solely because the + * caller must somehow ensure that the thread has not been + * destroyed. Nothing special is usually required to ensure this + * when called from Java (in which there will ordinarily be a live + * reference to the thread) but this is not nearly-automatically + * so when calling from native code. + * @param thread the thread to unpark. + * + */ + public native void unpark(Object thread); + + /** + * Block current thread, returning when a balancing + * unpark occurs, or a balancing unpark has + * already occurred, or the thread is interrupted, or, if not + * absolute and time is not zero, the given time nanoseconds have + * elapsed, or if absolute, the given deadline in milliseconds + * since Epoch has passed, or spuriously (i.e., returning for no + * "reason"). Note: This operation is in the Unsafe class only + * because unpark is, so it would be strange to place it + * elsewhere. + */ + public native void park(boolean isAbsolute, long time); + + /** + * Gets the load average in the system run queue assigned + * to the available processors averaged over various periods of time. + * This method retrieves the given nelem samples and + * assigns to the elements of the given loadavg array. + * The system imposes a maximum of 3 samples, representing + * averages over the last 1, 5, and 15 minutes, respectively. + * + * @params loadavg an array of double of size nelems + * @params nelems the number of samples to be retrieved and + * must be 1 to 3. + * + * @return the number of samples actually retrieved; or -1 + * if the load average is unobtainable. + */ + public native int getLoadAverage(double[] loadavg, int nelems); + + // The following contain CAS-based Java implementations used on + // platforms not supporting native instructions + + /** + * Atomically adds the given value to the current value of a field + * or array element within the given object o + * at the given offset. + * + * @param o object/array to update the field/element in + * @param offset field/element offset + * @param delta the value to add + * @return the previous value + * @since 1.8 + */ + public final int getAndAddInt(Object o, long offset, int delta) { + int v; + do { + v = getIntVolatile(o, offset); + } while (!compareAndSwapInt(o, offset, v, v + delta)); + return v; + } + + /** + * Atomically adds the given value to the current value of a field + * or array element within the given object o + * at the given offset. + * + * @param o object/array to update the field/element in + * @param offset field/element offset + * @param delta the value to add + * @return the previous value + * @since 1.8 + */ + public final long getAndAddLong(Object o, long offset, long delta) { + long v; + do { + v = getLongVolatile(o, offset); + } while (!compareAndSwapLong(o, offset, v, v + delta)); + return v; + } + + /** + * Atomically exchanges the given value with the current value of + * a field or array element within the given object o + * at the given offset. + * + * @param o object/array to update the field/element in + * @param offset field/element offset + * @param newValue new value + * @return the previous value + * @since 1.8 + */ + public final int getAndSetInt(Object o, long offset, int newValue) { + int v; + do { + v = getIntVolatile(o, offset); + } while (!compareAndSwapInt(o, offset, v, newValue)); + return v; + } + + /** + * Atomically exchanges the given value with the current value of + * a field or array element within the given object o + * at the given offset. + * + * @param o object/array to update the field/element in + * @param offset field/element offset + * @param newValue new value + * @return the previous value + * @since 1.8 + */ + public final long getAndSetLong(Object o, long offset, long newValue) { + long v; + do { + v = getLongVolatile(o, offset); + } while (!compareAndSwapLong(o, offset, v, newValue)); + return v; + } + + /** + * Atomically exchanges the given reference value with the current + * reference value of a field or array element within the given + * object o at the given offset. + * + * @param o object/array to update the field/element in + * @param offset field/element offset + * @param newValue new value + * @return the previous value + * @since 1.8 + */ + public final Object getAndSetObject(Object o, long offset, Object newValue) { + Object v; + do { + v = getObjectVolatile(o, offset); + } while (!compareAndSwapObject(o, offset, v, newValue)); + return v; + } + + + /** + * Ensures lack of reordering of loads before the fence + * with loads or stores after the fence. + * @since 1.8 + */ + public native void loadFence(); + + /** + * Ensures lack of reordering of stores before the fence + * with loads or stores after the fence. + * @since 1.8 + */ + public native void storeFence(); + + /** + * Ensures lack of reordering of loads or stores before the fence + * with loads or stores after the fence. + * @since 1.8 + */ + public native void fullFence(); + + /** + * Throws IllegalAccessError; for use by the VM. + * @since 1.8 + */ + private static void throwIllegalAccessError() { + throw new IllegalAccessError(); + } + +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/VM.java b/sources/net.sf.j2s.java.core/src/sun/misc/VM.java new file mode 100644 index 000000000..a384c3c60 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/VM.java @@ -0,0 +1,411 @@ +/* + * Copyright (c) 1996, 2014, 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.misc; + +import static java.lang.Thread.State.*; +import java.util.Properties; +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class VM { + + /* The following methods used to be native methods that instruct + * the VM to selectively suspend certain threads in low-memory + * situations. They are inherently dangerous and not implementable + * on native threads. We removed them in JDK 1.2. The skeletons + * remain so that existing applications that use these methods + * will still work. + */ + private static boolean suspended = false; + + /** @deprecated */ + @Deprecated + public static boolean threadsSuspended() { + return suspended; + } + + @SuppressWarnings("deprecation") + public static boolean allowThreadSuspension(ThreadGroup g, boolean b) { + return true;//g.allowThreadSuspension(b); + } + + /** @deprecated */ + @Deprecated + public static boolean suspendThreads() { + suspended = true; + return true; + } + + // Causes any suspended threadgroups to be resumed. + /** @deprecated */ + @Deprecated + public static void unsuspendThreads() { + suspended = false; + } + + // Causes threadgroups no longer marked suspendable to be resumed. + /** @deprecated */ + @Deprecated + public static void unsuspendSomeThreads() { + } + + /* Deprecated fields and methods -- Memory advice not supported in 1.2 */ + + /** @deprecated */ + @Deprecated + public static final int STATE_GREEN = 1; + + /** @deprecated */ + @Deprecated + public static final int STATE_YELLOW = 2; + + /** @deprecated */ + @Deprecated + public static final int STATE_RED = 3; + + /** @deprecated */ + @Deprecated + public static final int getState() { + return STATE_GREEN; + } + + /** @deprecated */ + @Deprecated + public static void registerVMNotification(VMNotification n) { } + + /** @deprecated */ + @Deprecated + public static void asChange(int as_old, int as_new) { } + + /** @deprecated */ + @Deprecated + public static void asChange_otherthread(int as_old, int as_new) { } + + /* + * Not supported in 1.2 because these will have to be exported as + * JVM functions, and we are not sure we want do that. Leaving + * here so it can be easily resurrected -- just remove the // + * comments. + */ + + /** + * Resume Java profiling. All profiling data is added to any + * earlier profiling, unless resetJavaProfiler is + * called in between. If profiling was not started from the + * command line, resumeJavaProfiler will start it. + *

      + * + * NOTE: Profiling must be enabled from the command line for a + * java.prof report to be automatically generated on exit; if not, + * writeJavaProfilerReport must be invoked to write a report. + * + * @see resetJavaProfiler + * @see writeJavaProfilerReport + */ + + // public native static void resumeJavaProfiler(); + + /** + * Suspend Java profiling. + */ + // public native static void suspendJavaProfiler(); + + /** + * Initialize Java profiling. Any accumulated profiling + * information is discarded. + */ + // public native static void resetJavaProfiler(); + + /** + * Write the current profiling contents to the file "java.prof". + * If the file already exists, it will be overwritten. + */ + // public native static void writeJavaProfilerReport(); + + + private static volatile boolean booted = false; + private static final Object lock = new Object(); + + // Invoked by by System.initializeSystemClass just before returning. + // Subsystems that are invoked during initialization can check this + // property in order to avoid doing things that should wait until the + // application class loader has been set up. + // + public static void booted() { + synchronized (lock) { + booted = true; + lock.notifyAll(); + } + } + + public static boolean isBooted() { + return booted; + } + + // Waits until VM completes initialization + // + // This method is invoked by the Finalizer thread + public static void awaitBooted() throws InterruptedException { + synchronized (lock) { + while (!booted) { + lock.wait(); + } + } + } + + // A user-settable upper limit on the maximum amount of allocatable direct + // buffer memory. This value may be changed during VM initialization if + // "java" is launched with "-XX:MaxDirectMemorySize=". + // + // The initial value of this field is arbitrary; during JRE initialization + // it will be reset to the value specified on the command line, if any, + // otherwise to Runtime.getRuntime().maxMemory(). + // + private static long directMemory = 64 * 1024 * 1024; + + // Returns the maximum amount of allocatable direct buffer memory. + // The directMemory variable is initialized during system initialization + // in the saveAndRemoveProperties method. + // + public static long maxDirectMemory() { + return directMemory; + } + + // User-controllable flag that determines if direct buffers should be page + // aligned. The "-XX:+PageAlignDirectMemory" option can be used to force + // buffers, allocated by ByteBuffer.allocateDirect, to be page aligned. + private static boolean pageAlignDirectMemory; + + // Returns {@code true} if the direct buffers should be page aligned. This + // variable is initialized by saveAndRemoveProperties. + public static boolean isDirectMemoryPageAligned() { + return pageAlignDirectMemory; + } + + // A user-settable boolean to determine whether ClassLoader.loadClass should + // accept array syntax. This value may be changed during VM initialization + // via the system property "sun.lang.ClassLoader.allowArraySyntax". + // + // The default for 1.5 is "true", array syntax is allowed. In 1.6, the + // default will be "false". The presence of this system property to + // control array syntax allows applications the ability to preview this new + // behaviour. + // + private static boolean defaultAllowArraySyntax = false; + private static boolean allowArraySyntax = defaultAllowArraySyntax; + + // The allowArraySyntax boolean is initialized during system initialization + // in the saveAndRemoveProperties method. + // + // It is initialized based on the value of the system property + // "sun.lang.ClassLoader.allowArraySyntax". If the system property is not + // provided, the default for 1.5 is "true". In 1.6, the default will be + // "false". If the system property is provided, then the value of + // allowArraySyntax will be equal to "true" if Boolean.parseBoolean() + // returns "true". Otherwise, the field will be set to "false". + // + public static boolean allowArraySyntax() { + return allowArraySyntax; + } + + /** + * Returns true if the given class loader is in the system domain + * in which all permissions are granted. + */ + public static boolean isSystemDomainLoader(ClassLoader loader) { + return loader == null; + } + + /** + * Returns the system property of the specified key saved at + * system initialization time. This method should only be used + * for the system properties that are not changed during runtime. + * It accesses a private copy of the system properties so + * that user's locking of the system properties object will not + * cause the library to deadlock. + * + * Note that the saved system properties do not include + * the ones set by sun.misc.Version.init(). + * + */ + public static String getSavedProperty(String key) { + if (savedProps.isEmpty()) + throw new IllegalStateException("Should be non-empty if initialized"); + + return savedProps.getProperty(key); + } + + // TODO: the Property Management needs to be refactored and + // the appropriate prop keys need to be accessible to the + // calling classes to avoid duplication of keys. + private static final Properties savedProps = new Properties(); + + // Save a private copy of the system properties and remove + // the system properties that are not intended for public access. + // + // This method can only be invoked during system initialization. + public static void saveAndRemoveProperties(Properties props) { + if (booted) + throw new IllegalStateException("System initialization has completed"); + + savedProps.putAll(props); + + // Set the maximum amount of direct memory. This value is controlled + // by the vm option -XX:MaxDirectMemorySize=. + // The maximum amount of allocatable direct buffer memory (in bytes) + // from the system property sun.nio.MaxDirectMemorySize set by the VM. + // The system property will be removed. + String s = (String)props.remove("sun.nio.MaxDirectMemorySize"); + if (s != null) { + if (s.equals("-1")) { + // -XX:MaxDirectMemorySize not given, take default + directMemory = Runtime.getRuntime().maxMemory(); + } else { + long l = Long.parseLong(s); + if (l > -1) + directMemory = l; + } + } + + // Check if direct buffers should be page aligned + s = (String)props.remove("sun.nio.PageAlignDirectMemory"); + if ("true".equals(s)) + pageAlignDirectMemory = true; + + // Set a boolean to determine whether ClassLoader.loadClass accepts + // array syntax. This value is controlled by the system property + // "sun.lang.ClassLoader.allowArraySyntax". + s = props.getProperty("sun.lang.ClassLoader.allowArraySyntax"); + allowArraySyntax = (s == null + ? defaultAllowArraySyntax + : Boolean.parseBoolean(s)); + + // Remove other private system properties + // used by java.lang.Integer.IntegerCache + props.remove("java.lang.Integer.IntegerCache.high"); + + // used by java.util.zip.ZipFile + props.remove("sun.zip.disableMemoryMapping"); + + // used by sun.launcher.LauncherHelper + props.remove("sun.java.launcher.diag"); + + // used by sun.misc.URLClassPath + props.remove("sun.cds.enableSharedLookupCache"); + } + + // Initialize any miscellenous operating system settings that need to be + // set for the class libraries. + // + public static void initializeOSEnvironment() { + if (!booted) { + OSEnvironment.initialize(); + } + } + + /* Current count of objects pending for finalization */ + private static volatile int finalRefCount = 0; + + /* Peak count of objects pending for finalization */ + private static volatile int peakFinalRefCount = 0; + + /* + * Gets the number of objects pending for finalization. + * + * @return the number of objects pending for finalization. + */ + public static int getFinalRefCount() { + return finalRefCount; + } + + /* + * Gets the peak number of objects pending for finalization. + * + * @return the peak number of objects pending for finalization. + */ + public static int getPeakFinalRefCount() { + return peakFinalRefCount; + } + + /* + * Add n to the objects pending for finalization count. + * + * @param n an integer value to be added to the objects pending + * for finalization count + */ + public static void addFinalRefCount(int n) { + // The caller must hold lock to synchronize the update. + + finalRefCount += n; + if (finalRefCount > peakFinalRefCount) { + peakFinalRefCount = finalRefCount; + } + } + + /** + * Returns Thread.State for the given threadStatus + */ + public static Thread.State toThreadState(int threadStatus) { + if ((threadStatus & JVMTI_THREAD_STATE_RUNNABLE) != 0) { + return RUNNABLE; + } else if ((threadStatus & JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER) != 0) { + return BLOCKED; + } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_INDEFINITELY) != 0) { + return WAITING; + } else if ((threadStatus & JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT) != 0) { + return TIMED_WAITING; + } else if ((threadStatus & JVMTI_THREAD_STATE_TERMINATED) != 0) { + return TERMINATED; + } else if ((threadStatus & JVMTI_THREAD_STATE_ALIVE) == 0) { + return NEW; + } else { + return RUNNABLE; + } + } + + /* The threadStatus field is set by the VM at state transition + * in the hotspot implementation. Its value is set according to + * the JVM TI specification GetThreadState function. + */ + private final static int JVMTI_THREAD_STATE_ALIVE = 0x0001; + private final static int JVMTI_THREAD_STATE_TERMINATED = 0x0002; + private final static int JVMTI_THREAD_STATE_RUNNABLE = 0x0004; + private final static int JVMTI_THREAD_STATE_BLOCKED_ON_MONITOR_ENTER = 0x0400; + private final static int JVMTI_THREAD_STATE_WAITING_INDEFINITELY = 0x0010; + private final static int JVMTI_THREAD_STATE_WAITING_WITH_TIMEOUT = 0x0020; + + /* + * Returns the first non-null class loader up the execution stack, + * or null if only code from the null class loader is on the stack. + */ + public static native ClassLoader latestUserDefinedLoader(); + + static { + initialize(); + } + private native static void initialize(); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/VMNotification.java b/sources/net.sf.j2s.java.core/src/sun/misc/VMNotification.java new file mode 100644 index 000000000..bf4abef34 --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/VMNotification.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 1996, 2004, 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.misc; + +/** @deprecated */ +@Deprecated +public interface VMNotification { + + // when the vm switches allocation states, we get notified + // (possible semantics: if the state changes while in this + // notification, don't recursively notify). + // oldState and newState may be the same if we are just releasing + // suspended threads. + void newAllocState(int oldState, int newState, + boolean threadsSuspended); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/VMSupport.java b/sources/net.sf.j2s.java.core/src/sun/misc/VMSupport.java new file mode 100644 index 000000000..68faba7bf --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/VMSupport.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2005, 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.misc; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Properties; +import java.util.Set; +import java.util.jar.JarFile; +import java.util.jar.Manifest; +import java.util.jar.Attributes; + +/* + * Support class used by JVMTI and VM attach mechanism. + */ +public class VMSupport { + + private static Properties agentProps = null; + /** + * Returns the agent properties. + */ + public static synchronized Properties getAgentProperties() { + if (agentProps == null) { + agentProps = new Properties(); + initAgentProperties(agentProps); + } + return agentProps; + } + private static native Properties initAgentProperties(Properties props); + + /** + * Write the given properties list to a byte array and return it. Properties with + * a key or value that is not a String is filtered out. The stream written to the byte + * array is ISO 8859-1 encoded. + */ + private static byte[] serializePropertiesToByteArray(Properties p) throws IOException { + ByteArrayOutputStream out = new ByteArrayOutputStream(4096); + + Properties props = new Properties(); + + // stringPropertyNames() returns a snapshot of the property keys + Set keyset = p.stringPropertyNames(); + for (String key : keyset) { + String value = p.getProperty(key); + props.put(key, value); + } + + props.store(out, null); + return out.toByteArray(); + } + + public static byte[] serializePropertiesToByteArray() throws IOException { + return serializePropertiesToByteArray(System.getProperties()); + } + + public static byte[] serializeAgentPropertiesToByteArray() throws IOException { + return serializePropertiesToByteArray(getAgentProperties()); + } + + /* + * Returns true if the given JAR file has the Class-Path attribute in the + * main section of the JAR manifest. Throws RuntimeException if the given + * path is not a JAR file or some other error occurs. + */ + public static boolean isClassPathAttributePresent(String path) { + try { + Manifest man = (new JarFile(path)).getManifest(); + if (man != null) { + if (man.getMainAttributes().getValue(Attributes.Name.CLASS_PATH) != null) { + return true; + } + } + return false; + } catch (IOException ioe) { + throw new RuntimeException(ioe.getMessage()); + } + } + + /* + * Return the temporary directory that the VM uses for the attach + * and perf data files. + * + * It is important that this directory is well-known and the + * same for all VM instances. It cannot be affected by configuration + * variables such as java.io.tmpdir. + */ + public static native String getVMTemporaryDirectory(); +} diff --git a/sources/net.sf.j2s.java.core/src/sun/misc/Version.java.template b/sources/net.sf.j2s.java.core/src/sun/misc/Version.java.template new file mode 100644 index 000000000..dd47869ac --- /dev/null +++ b/sources/net.sf.j2s.java.core/src/sun/misc/Version.java.template @@ -0,0 +1,348 @@ +/* + * Copyright (c) 1999, 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.misc; +import java.io.PrintStream; + +public class Version { + + + private static final String launcher_name = + "@@launcher_name@@"; + + private static final String java_version = + "@@java_version@@"; + + private static final String java_runtime_name = + "@@java_runtime_name@@"; + + private static final String java_profile_name = + "@@java_profile_name@@"; + + private static final String java_runtime_version = + "@@java_runtime_version@@"; + + static { + init(); + } + + public static void init() { + System.setProperty("java.version", java_version); + System.setProperty("java.runtime.version", java_runtime_version); + System.setProperty("java.runtime.name", java_runtime_name); + } + + private static boolean versionsInitialized = false; + private static int jvm_major_version = 0; + private static int jvm_minor_version = 0; + private static int jvm_micro_version = 0; + private static int jvm_update_version = 0; + private static int jvm_build_number = 0; + private static String jvm_special_version = null; + private static int jdk_major_version = 0; + private static int jdk_minor_version = 0; + private static int jdk_micro_version = 0; + private static int jdk_update_version = 0; + private static int jdk_build_number = 0; + private static String jdk_special_version = null; + + /** + * In case you were wondering this method is called by java -version. + * Sad that it prints to stderr; would be nicer if default printed on + * stdout. + */ + public static void print() { + print(System.err); + } + + /** + * This is the same as print except that it adds an extra line-feed + * at the end, typically used by the -showversion in the launcher + */ + public static void println() { + print(System.err); + System.err.println(); + } + + /** + * Give a stream, it will print version info on it. + */ + public static void print(PrintStream ps) { + boolean isHeadless = false; + + /* Report that we're running headless if the property is true */ + String headless = System.getProperty("java.awt.headless"); + if ( (headless != null) && (headless.equalsIgnoreCase("true")) ) { + isHeadless = true; + } + + /* First line: platform version. */ + ps.println(launcher_name + " version \"" + java_version + "\""); + + /* Second line: runtime version (ie, libraries). */ + + ps.print(java_runtime_name + " (build " + java_runtime_version); + + if (java_profile_name.length() > 0) { + // profile name + ps.print(", profile " + java_profile_name); + } + + if (java_runtime_name.indexOf("Embedded") != -1 && isHeadless) { + // embedded builds report headless state + ps.print(", headless"); + } + ps.println(')'); + + /* Third line: JVM information. */ + String java_vm_name = System.getProperty("java.vm.name"); + String java_vm_version = System.getProperty("java.vm.version"); + String java_vm_info = System.getProperty("java.vm.info"); + ps.println(java_vm_name + " (build " + java_vm_version + ", " + + java_vm_info + ")"); + } + + + /** + * Returns the major version of the running JVM if it's 1.6 or newer + * or any RE VM build. It will return 0 if it's an internal 1.5 or + * 1.4.x build. + * + * @since 1.6 + */ + public static synchronized int jvmMajorVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jvm_major_version; + } + + /** + * Returns the minor version of the running JVM if it's 1.6 or newer + * or any RE VM build. It will return 0 if it's an internal 1.5 or + * 1.4.x build. + * @since 1.6 + */ + public static synchronized int jvmMinorVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jvm_minor_version; + } + + + /** + * Returns the micro version of the running JVM if it's 1.6 or newer + * or any RE VM build. It will return 0 if it's an internal 1.5 or + * 1.4.x build. + * @since 1.6 + */ + public static synchronized int jvmMicroVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jvm_micro_version; + } + + /** + * Returns the update release version of the running JVM if it's + * a RE build. It will return 0 if it's an internal build. + * @since 1.6 + */ + public static synchronized int jvmUpdateVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jvm_update_version; + } + + public static synchronized String jvmSpecialVersion() { + if (!versionsInitialized) { + initVersions(); + } + if (jvm_special_version == null) { + jvm_special_version = getJvmSpecialVersion(); + } + return jvm_special_version; + } + public static native String getJvmSpecialVersion(); + + /** + * Returns the build number of the running JVM if it's a RE build + * It will return 0 if it's an internal build. + * @since 1.6 + */ + public static synchronized int jvmBuildNumber() { + if (!versionsInitialized) { + initVersions(); + } + return jvm_build_number; + } + + /** + * Returns the major version of the running JDK. + * + * @since 1.6 + */ + public static synchronized int jdkMajorVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jdk_major_version; + } + + /** + * Returns the minor version of the running JDK. + * @since 1.6 + */ + public static synchronized int jdkMinorVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jdk_minor_version; + } + + /** + * Returns the micro version of the running JDK. + * @since 1.6 + */ + public static synchronized int jdkMicroVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jdk_micro_version; + } + + /** + * Returns the update release version of the running JDK if it's + * a RE build. It will return 0 if it's an internal build. + * @since 1.6 + */ + public static synchronized int jdkUpdateVersion() { + if (!versionsInitialized) { + initVersions(); + } + return jdk_update_version; + } + + public static synchronized String jdkSpecialVersion() { + if (!versionsInitialized) { + initVersions(); + } + if (jdk_special_version == null) { + jdk_special_version = getJdkSpecialVersion(); + } + return jdk_special_version; + } + public static native String getJdkSpecialVersion(); + + /** + * Returns the build number of the running JDK if it's a RE build + * It will return 0 if it's an internal build. + * @since 1.6 + */ + public static synchronized int jdkBuildNumber() { + if (!versionsInitialized) { + initVersions(); + } + return jdk_build_number; + } + + // true if JVM exports the version info including the capabilities + private static boolean jvmVersionInfoAvailable; + private static synchronized void initVersions() { + if (versionsInitialized) { + return; + } + jvmVersionInfoAvailable = getJvmVersionInfo(); + if (!jvmVersionInfoAvailable) { + // parse java.vm.version for older JVM before the + // new JVM_GetVersionInfo is added. + // valid format of the version string is: + // n.n.n[_uu[c]][-]-bxx + CharSequence cs = System.getProperty("java.vm.version"); + if (cs.length() >= 5 && + Character.isDigit(cs.charAt(0)) && cs.charAt(1) == '.' && + Character.isDigit(cs.charAt(2)) && cs.charAt(3) == '.' && + Character.isDigit(cs.charAt(4))) { + jvm_major_version = Character.digit(cs.charAt(0), 10); + jvm_minor_version = Character.digit(cs.charAt(2), 10); + jvm_micro_version = Character.digit(cs.charAt(4), 10); + cs = cs.subSequence(5, cs.length()); + if (cs.charAt(0) == '_' && cs.length() >= 3 && + Character.isDigit(cs.charAt(1)) && + Character.isDigit(cs.charAt(2))) { + int nextChar = 3; + try { + String uu = cs.subSequence(1, 3).toString(); + jvm_update_version = Integer.valueOf(uu).intValue(); + if (cs.length() >= 4) { + char c = cs.charAt(3); + if (c >= 'a' && c <= 'z') { + jvm_special_version = Character.toString(c); + nextChar++; + } + } + } catch (NumberFormatException e) { + // not conforming to the naming convention + return; + } + cs = cs.subSequence(nextChar, cs.length()); + } + if (cs.charAt(0) == '-') { + // skip the first character + // valid format: -bxx or bxx + // non-product VM will have -debug|-release appended + cs = cs.subSequence(1, cs.length()); + String[] res = cs.toString().split("-"); + for (String s : res) { + if (s.charAt(0) == 'b' && s.length() == 3 && + Character.isDigit(s.charAt(1)) && + Character.isDigit(s.charAt(2))) { + jvm_build_number = + Integer.valueOf(s.substring(1, 3)).intValue(); + break; + } + } + } + } + } + getJdkVersionInfo(); + versionsInitialized = true; + } + + // Gets the JVM version info if available and sets the jvm_*_version fields + // and its capabilities. + // + // Return false if not available which implies an old VM (Tiger or before). + private static native boolean getJvmVersionInfo(); + private static native void getJdkVersionInfo(); +} + +// Help Emacs a little because this file doesn't end in .java. +// +// Local Variables: *** +// mode: java *** +// End: *** diff --git a/sources/net.sf.j2s.java.core/src/sun/net/www/ParseUtil.java b/sources/net.sf.j2s.java.core/src/sun/net/www/ParseUtil.java index 049add3f9..d671c0772 100644 --- a/sources/net.sf.j2s.java.core/src/sun/net/www/ParseUtil.java +++ b/sources/net.sf.j2s.java.core/src/sun/net/www/ParseUtil.java @@ -1,7 +1,4 @@ /* - * Some portions of this file have been modified by Robert Hanson hansonr.at.stolaf.edu 2012-2017 - * for use in SwingJS via transpilation into JavaScript using Java2Script. - * * Copyright (c) 1998, 2007, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -28,10 +25,20 @@ package sun.net.www; +import java.util.BitSet; +import java.io.UnsupportedEncodingException; import java.io.File; -import java.net.MalformedURLException; import java.net.URL; -import java.util.BitSet; +import java.net.MalformedURLException; +import java.net.URI; +import java.net.URISyntaxException; +import java.nio.ByteBuffer; +import java.nio.CharBuffer; +import java.nio.charset.CharacterCodingException; +import sun.nio.cs.ThreadLocalCoders; +import java.nio.charset.CharsetDecoder; +import java.nio.charset.CoderResult; +import java.nio.charset.CodingErrorAction; /** * A class that contains useful routines common to sun.net.www @@ -150,106 +157,106 @@ private static int escape(char[] cc, char c, int index) { return index; } -// /** -// * Un-escape and return the character at position i in string s. -// */ -// private static byte unescape(String s, int i) { -// return (byte) Integer.parseInt(s.substring(i+1,i+3),16); -// } -// -// -// /** -// * Returns a new String constructed from the specified String by replacing -// * the URL escape sequences and UTF8 encoding with the characters they -// * represent. -// */ -// public static String decode(String s) { -// int n = s.length(); -// if ((n == 0) || (s.indexOf('%') < 0)) -// return s; -// -// StringBuilder sb = new StringBuilder(n); -// ByteBuffer bb = ByteBuffer.allocate(n); -// CharBuffer cb = CharBuffer.allocate(n); -// CharsetDecoder dec = null;//ThreadLocalCoders.decoderFor("UTF-8") -// //.onMalformedInput(CodingErrorAction.REPORT) -// ///.onUnmappableCharacter(CodingErrorAction.REPORT); -// -// char c = s.charAt(0); -// for (int i = 0; i < n;) { -// //assert c == s.charAt(i); -// if (c != '%') { -// sb.append(c); -// if (++i >= n) -// break; -// c = s.charAt(i); -// continue; -// } -// bb.clear(); -// int ui = i; -// for (;;) { -// //assert (n - i >= 2); -// try { -// bb.put(unescape(s, i)); -// } catch (NumberFormatException e) { -// throw new IllegalArgumentException(); -// } -// i += 3; -// if (i >= n) -// break; -// c = s.charAt(i); -// if (c != '%') -// break; -// } -// bb.flip(); -// cb.clear(); -// dec.reset(); -// CoderResult cr = dec.decode(bb, cb, true); -// if (cr.isError()) -// throw new IllegalArgumentException("Error decoding percent encoded characters"); -// cr = dec.flush(cb); -// if (cr.isError()) -// throw new IllegalArgumentException("Error decoding percent encoded characters"); -// sb.append(cb.flip().toString()); -// } -// -// return sb.toString(); -// } - -// /** -// * Returns a canonical version of the specified string. -// */ -// public String canonizeString(String file) { -// int i = 0; -// int lim = file.length(); -// -// // Remove embedded /../ -// while ((i = file.indexOf("/../")) >= 0) { -// if ((lim = file.lastIndexOf('/', i - 1)) >= 0) { -// file = file.substring(0, lim) + file.substring(i + 3); -// } else { -// file = file.substring(i + 3); -// } -// } -// // Remove embedded /./ -// while ((i = file.indexOf("/./")) >= 0) { -// file = file.substring(0, i) + file.substring(i + 2); -// } -// // Remove trailing .. -// while (file.endsWith("/..")) { -// i = file.indexOf("/.."); -// if ((lim = file.lastIndexOf('/', i - 1)) >= 0) { -// file = file.substring(0, lim+1); -// } else { -// file = file.substring(0, i); -// } -// } -// // Remove trailing . -// if (file.endsWith("/.")) -// file = file.substring(0, file.length() -1); -// -// return file; -// } + /** + * Un-escape and return the character at position i in string s. + */ + private static byte unescape(String s, int i) { + return (byte) Integer.parseInt(s.substring(i+1,i+3),16); + } + + + /** + * Returns a new String constructed from the specified String by replacing + * the URL escape sequences and UTF8 encoding with the characters they + * represent. + */ + public static String decode(String s) { + int n = s.length(); + if ((n == 0) || (s.indexOf('%') < 0)) + return s; + + StringBuilder sb = new StringBuilder(n); + ByteBuffer bb = ByteBuffer.allocate(n); + CharBuffer cb = CharBuffer.allocate(n); + CharsetDecoder dec = ThreadLocalCoders.decoderFor("UTF-8") + .onMalformedInput(CodingErrorAction.REPORT) + .onUnmappableCharacter(CodingErrorAction.REPORT); + + char c = s.charAt(0); + for (int i = 0; i < n;) { + assert c == s.charAt(i); + if (c != '%') { + sb.append(c); + if (++i >= n) + break; + c = s.charAt(i); + continue; + } + bb.clear(); + int ui = i; + for (;;) { + assert (n - i >= 2); + try { + bb.put(unescape(s, i)); + } catch (NumberFormatException e) { + throw new IllegalArgumentException(); + } + i += 3; + if (i >= n) + break; + c = s.charAt(i); + if (c != '%') + break; + } + bb.flip(); + cb.clear(); + dec.reset(); + CoderResult cr = dec.decode(bb, cb, true); + if (cr.isError()) + throw new IllegalArgumentException("Error decoding percent encoded characters"); + cr = dec.flush(cb); + if (cr.isError()) + throw new IllegalArgumentException("Error decoding percent encoded characters"); + sb.append(cb.flip().toString()); + } + + return sb.toString(); + } + + /** + * Returns a canonical version of the specified string. + */ + public String canonizeString(String file) { + int i = 0; + int lim = file.length(); + + // Remove embedded /../ + while ((i = file.indexOf("/../")) >= 0) { + if ((lim = file.lastIndexOf('/', i - 1)) >= 0) { + file = file.substring(0, lim) + file.substring(i + 3); + } else { + file = file.substring(i + 3); + } + } + // Remove embedded /./ + while ((i = file.indexOf("/./")) >= 0) { + file = file.substring(0, i) + file.substring(i + 2); + } + // Remove trailing .. + while (file.endsWith("/..")) { + i = file.indexOf("/.."); + if ((lim = file.lastIndexOf('/', i - 1)) >= 0) { + file = file.substring(0, lim+1); + } else { + file = file.substring(0, i); + } + } + // Remove trailing . + if (file.endsWith("/.")) + file = file.substring(0, file.length() -1); + + return file; + } public static URL fileToEncodedURL(File file) throws MalformedURLException @@ -265,409 +272,409 @@ public static URL fileToEncodedURL(File file) return new URL("file", "", path); } -// public static java.net.URI toURI(URL url) { -// String protocol = url.getProtocol(); -// String auth = url.getAuthority(); -// String path = url.getPath(); -// String query = url.getQuery(); -// String ref = url.getRef(); -// if (path != null && !(path.startsWith("/"))) -// path = "/" + path; -// -// // -// // In java.net.URI class, a port number of -1 implies the default -// // port number. So get it stripped off before creating URI instance. -// // -// if (auth != null && auth.endsWith(":-1")) -// auth = auth.substring(0, auth.length() - 3); -// -// java.net.URI uri; -// try { -// uri = createURI(protocol, auth, path, query, ref); -// } catch (java.net.URISyntaxException e) { -// uri = null; -// } -// return uri; -// } - -// // -// // createURI() and its auxiliary code are cloned from java.net.URI. -// // Most of the code are just copy and paste, except that quote() -// // has been modified to avoid double-escape. -// // -// // Usually it is unacceptable, but we're forced to do it because -// // otherwise we need to change public API, namely java.net.URI's -// // multi-argument constructors. It turns out that the changes cause -// // incompatibilities so can't be done. -// // -// private static URI createURI(String scheme, -// String authority, -// String path, -// String query, -// String fragment) throws URISyntaxException -// { -// String s = toString(scheme, null, -// authority, null, null, -1, -// path, query, fragment); -// checkPath(s, scheme, path); -// return new URI(s); -// } -// -// private static String toString(String scheme, -// String opaquePart, -// String authority, -// String userInfo, -// String host, -// int port, -// String path, -// String query, -// String fragment) -// { -// StringBuffer sb = new StringBuffer(); -// if (scheme != null) { -// sb.append(scheme); -// sb.append(':'); -// } -// appendSchemeSpecificPart(sb, opaquePart, -// authority, userInfo, host, port, -// path, query); -// appendFragment(sb, fragment); -// return sb.toString(); -// } -// -// private static void appendSchemeSpecificPart(StringBuffer sb, -// String opaquePart, -// String authority, -// String userInfo, -// String host, -// int port, -// String path, -// String query) -// { -// if (opaquePart != null) { -// /* check if SSP begins with an IPv6 address -// * because we must not quote a literal IPv6 address -// */ -// if (opaquePart.startsWith("//[")) { -// int end = opaquePart.indexOf("]"); -// if (end != -1 && opaquePart.indexOf(":")!=-1) { -// String doquote, dontquote; -// if (end == opaquePart.length()) { -// dontquote = opaquePart; -// doquote = ""; -// } else { -// dontquote = opaquePart.substring(0,end+1); -// doquote = opaquePart.substring(end+1); -// } -// sb.append (dontquote); -// sb.append(quote(doquote, L_URIC, H_URIC)); -// } -// } else { -// sb.append(quote(opaquePart, L_URIC, H_URIC)); -// } -// } else { -// appendAuthority(sb, authority, userInfo, host, port); -// if (path != null) -// sb.append(quote(path, L_PATH, H_PATH)); -// if (query != null) { -// sb.append('?'); -// sb.append(quote(query, L_URIC, H_URIC)); -// } -// } -// } -// -// private static void appendAuthority(StringBuffer sb, -// String authority, -// String userInfo, -// String host, -// int port) -// { -// if (host != null) { -// sb.append("//"); -// if (userInfo != null) { -// sb.append(quote(userInfo, L_USERINFO, H_USERINFO)); -// sb.append('@'); -// } -// boolean needBrackets = ((host.indexOf(':') >= 0) -// && !host.startsWith("[") -// && !host.endsWith("]")); -// if (needBrackets) sb.append('['); -// sb.append(host); -// if (needBrackets) sb.append(']'); -// if (port != -1) { -// sb.append(':'); -// sb.append(port); -// } -// } else if (authority != null) { -// sb.append("//"); -// if (authority.startsWith("[")) { -// int end = authority.indexOf("]"); -// if (end != -1 && authority.indexOf(":")!=-1) { -// String doquote, dontquote; -// if (end == authority.length()) { -// dontquote = authority; -// doquote = ""; -// } else { -// dontquote = authority.substring(0,end+1); -// doquote = authority.substring(end+1); -// } -// sb.append (dontquote); -// sb.append(quote(doquote, -// L_REG_NAME | L_SERVER, -// H_REG_NAME | H_SERVER)); -// } -// } else { -// sb.append(quote(authority, -// L_REG_NAME | L_SERVER, -// H_REG_NAME | H_SERVER)); -// } -// } -// } -// -// private static void appendFragment(StringBuffer sb, String fragment) { -// if (fragment != null) { -// sb.append('#'); -// sb.append(quote(fragment, L_URIC, H_URIC)); -// } -// } -// -// // Quote any characters in s that are not permitted -// // by the given mask pair -// // -// private static String quote(String s, long lowMask, long highMask) { -// int n = s.length(); -// StringBuffer sb = null; -// boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0); -// for (int i = 0; i < s.length(); i++) { -// char c = s.charAt(i); -// if (c < '\u0080') { -// if (!match(c, lowMask, highMask) && !isEscaped(s, i)) { -// if (sb == null) { -// sb = new StringBuffer(); -// sb.append(s.substring(0, i)); -// } -// appendEscape(sb, (byte)c); -// } else { -// if (sb != null) -// sb.append(c); -// } -// } else if (allowNonASCII -// && (Character.isSpaceChar(c) -// || Character.isISOControl(c))) { -// if (sb == null) { -// sb = new StringBuffer(); -// sb.append(s.substring(0, i)); -// } -// appendEncoded(sb, c); -// } else { -// if (sb != null) -// sb.append(c); -// } -// } -// return (sb == null) ? s : sb.toString(); -// } - -// // -// // To check if the given string has an escaped triplet -// // at the given position -// // -// private static boolean isEscaped(String s, int pos) { -// if (s == null || (s.length() <= (pos + 2))) -// return false; -// -// return s.charAt(pos) == '%' -// && match(s.charAt(pos + 1), L_HEX, H_HEX) -// && match(s.charAt(pos + 2), L_HEX, H_HEX); -// } -// -// private static void appendEncoded(StringBuffer sb, char c) { -// ByteBuffer bb = null; -// //try { -// bb = null;//ThreadLocalCoders.encoderFor("UTF-8") -// //.encode(CharBuffer.wrap("" + c)); -// //} catch (CharacterCodingException x) { -// // assert false; -// // } -// while (bb.hasRemaining()) { -// int b = bb.get() & 0xff; -// if (b >= 0x80) -// appendEscape(sb, (byte)b); -// else -// sb.append((char)b); -// } -// } -// -// private final static char[] hexDigits = { -// '0', '1', '2', '3', '4', '5', '6', '7', -// '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' -// }; -// -// private static void appendEscape(StringBuffer sb, byte b) { -// sb.append('%'); -// sb.append(hexDigits[(b >> 4) & 0x0f]); -// sb.append(hexDigits[(b >> 0) & 0x0f]); -// } -// -// // Tell whether the given character is permitted by the given mask pair -// private static boolean match(char c, long lowMask, long highMask) { -// if (c < 64) -// return ((1L << c) & lowMask) != 0; -// if (c < 128) -// return ((1L << (c - 64)) & highMask) != 0; -// return false; -// } -// -// // If a scheme is given then the path, if given, must be absolute -// // -// private static void checkPath(String s, String scheme, String path) -// throws URISyntaxException -// { -// if (scheme != null) { -// if ((path != null) -// && ((path.length() > 0) && (path.charAt(0) != '/'))) -// throw new URISyntaxException(s, -// "Relative path in absolute URI"); -// } -// } -// -// + public static java.net.URI toURI(URL url) { + String protocol = url.getProtocol(); + String auth = url.getAuthority(); + String path = url.getPath(); + String query = url.getQuery(); + String ref = url.getRef(); + if (path != null && !(path.startsWith("/"))) + path = "/" + path; + + // + // In java.net.URI class, a port number of -1 implies the default + // port number. So get it stripped off before creating URI instance. + // + if (auth != null && auth.endsWith(":-1")) + auth = auth.substring(0, auth.length() - 3); + + java.net.URI uri; + try { + uri = createURI(protocol, auth, path, query, ref); + } catch (java.net.URISyntaxException e) { + uri = null; + } + return uri; + } + + // + // createURI() and its auxiliary code are cloned from java.net.URI. + // Most of the code are just copy and paste, except that quote() + // has been modified to avoid double-escape. + // + // Usually it is unacceptable, but we're forced to do it because + // otherwise we need to change public API, namely java.net.URI's + // multi-argument constructors. It turns out that the changes cause + // incompatibilities so can't be done. + // + private static URI createURI(String scheme, + String authority, + String path, + String query, + String fragment) throws URISyntaxException + { + String s = toString(scheme, null, + authority, null, null, -1, + path, query, fragment); + checkPath(s, scheme, path); + return new URI(s); + } + + private static String toString(String scheme, + String opaquePart, + String authority, + String userInfo, + String host, + int port, + String path, + String query, + String fragment) + { + StringBuffer sb = new StringBuffer(); + if (scheme != null) { + sb.append(scheme); + sb.append(':'); + } + appendSchemeSpecificPart(sb, opaquePart, + authority, userInfo, host, port, + path, query); + appendFragment(sb, fragment); + return sb.toString(); + } + + private static void appendSchemeSpecificPart(StringBuffer sb, + String opaquePart, + String authority, + String userInfo, + String host, + int port, + String path, + String query) + { + if (opaquePart != null) { + /* check if SSP begins with an IPv6 address + * because we must not quote a literal IPv6 address + */ + if (opaquePart.startsWith("//[")) { + int end = opaquePart.indexOf("]"); + if (end != -1 && opaquePart.indexOf(":")!=-1) { + String doquote, dontquote; + if (end == opaquePart.length()) { + dontquote = opaquePart; + doquote = ""; + } else { + dontquote = opaquePart.substring(0,end+1); + doquote = opaquePart.substring(end+1); + } + sb.append (dontquote); + sb.append(quote(doquote, L_URIC, H_URIC)); + } + } else { + sb.append(quote(opaquePart, L_URIC, H_URIC)); + } + } else { + appendAuthority(sb, authority, userInfo, host, port); + if (path != null) + sb.append(quote(path, L_PATH, H_PATH)); + if (query != null) { + sb.append('?'); + sb.append(quote(query, L_URIC, H_URIC)); + } + } + } + + private static void appendAuthority(StringBuffer sb, + String authority, + String userInfo, + String host, + int port) + { + if (host != null) { + sb.append("//"); + if (userInfo != null) { + sb.append(quote(userInfo, L_USERINFO, H_USERINFO)); + sb.append('@'); + } + boolean needBrackets = ((host.indexOf(':') >= 0) + && !host.startsWith("[") + && !host.endsWith("]")); + if (needBrackets) sb.append('['); + sb.append(host); + if (needBrackets) sb.append(']'); + if (port != -1) { + sb.append(':'); + sb.append(port); + } + } else if (authority != null) { + sb.append("//"); + if (authority.startsWith("[")) { + int end = authority.indexOf("]"); + if (end != -1 && authority.indexOf(":")!=-1) { + String doquote, dontquote; + if (end == authority.length()) { + dontquote = authority; + doquote = ""; + } else { + dontquote = authority.substring(0,end+1); + doquote = authority.substring(end+1); + } + sb.append (dontquote); + sb.append(quote(doquote, + L_REG_NAME | L_SERVER, + H_REG_NAME | H_SERVER)); + } + } else { + sb.append(quote(authority, + L_REG_NAME | L_SERVER, + H_REG_NAME | H_SERVER)); + } + } + } + + private static void appendFragment(StringBuffer sb, String fragment) { + if (fragment != null) { + sb.append('#'); + sb.append(quote(fragment, L_URIC, H_URIC)); + } + } + + // Quote any characters in s that are not permitted + // by the given mask pair + // + private static String quote(String s, long lowMask, long highMask) { + int n = s.length(); + StringBuffer sb = null; + boolean allowNonASCII = ((lowMask & L_ESCAPED) != 0); + for (int i = 0; i < s.length(); i++) { + char c = s.charAt(i); + if (c < '\u0080') { + if (!match(c, lowMask, highMask) && !isEscaped(s, i)) { + if (sb == null) { + sb = new StringBuffer(); + sb.append(s.substring(0, i)); + } + appendEscape(sb, (byte)c); + } else { + if (sb != null) + sb.append(c); + } + } else if (allowNonASCII + && (Character.isSpaceChar(c) + || Character.isISOControl(c))) { + if (sb == null) { + sb = new StringBuffer(); + sb.append(s.substring(0, i)); + } + appendEncoded(sb, c); + } else { + if (sb != null) + sb.append(c); + } + } + return (sb == null) ? s : sb.toString(); + } + + // + // To check if the given string has an escaped triplet + // at the given position + // + private static boolean isEscaped(String s, int pos) { + if (s == null || (s.length() <= (pos + 2))) + return false; + + return s.charAt(pos) == '%' + && match(s.charAt(pos + 1), L_HEX, H_HEX) + && match(s.charAt(pos + 2), L_HEX, H_HEX); + } + + private static void appendEncoded(StringBuffer sb, char c) { + ByteBuffer bb = null; + try { + bb = ThreadLocalCoders.encoderFor("UTF-8") + .encode(CharBuffer.wrap("" + c)); + } catch (CharacterCodingException x) { + assert false; + } + while (bb.hasRemaining()) { + int b = bb.get() & 0xff; + if (b >= 0x80) + appendEscape(sb, (byte)b); + else + sb.append((char)b); + } + } + + private final static char[] hexDigits = { + '0', '1', '2', '3', '4', '5', '6', '7', + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + }; + + private static void appendEscape(StringBuffer sb, byte b) { + sb.append('%'); + sb.append(hexDigits[(b >> 4) & 0x0f]); + sb.append(hexDigits[(b >> 0) & 0x0f]); + } + + // Tell whether the given character is permitted by the given mask pair + private static boolean match(char c, long lowMask, long highMask) { + if (c < 64) + return ((1L << c) & lowMask) != 0; + if (c < 128) + return ((1L << (c - 64)) & highMask) != 0; + return false; + } + + // If a scheme is given then the path, if given, must be absolute + // + private static void checkPath(String s, String scheme, String path) + throws URISyntaxException + { + if (scheme != null) { + if ((path != null) + && ((path.length() > 0) && (path.charAt(0) != '/'))) + throw new URISyntaxException(s, + "Relative path in absolute URI"); + } + } + + // -- Character classes for parsing -- -// // Compute a low-order mask for the characters -// // between first and last, inclusive -// private static long lowMask(char first, char last) { -// long m = 0; -// int f = Math.max(Math.min(first, 63), 0); -// int l = Math.max(Math.min(last, 63), 0); -// for (int i = f; i <= l; i++) -// m |= 1L << i; -// return m; -// } - -// // Compute the low-order mask for the characters in the given string -// private static long lowMask(String chars) { -// int n = chars.length(); -// long m = 0; -// for (int i = 0; i < n; i++) { -// char c = chars.charAt(i); -// if (c < 64) -// m |= (1L << c); -// } -// return m; -// } -// -// // Compute a high-order mask for the characters -// // between first and last, inclusive -// private static long highMask(char first, char last) { -// long m = 0; -// int f = Math.max(Math.min(first, 127), 64) - 64; -// int l = Math.max(Math.min(last, 127), 64) - 64; -// for (int i = f; i <= l; i++) -// m |= 1L << i; -// return m; -// } - -// // Compute the high-order mask for the characters in the given string -// private static long highMask(String chars) { -// int n = chars.length(); -// long m = 0; -// for (int i = 0; i < n; i++) { -// char c = chars.charAt(i); -// if ((c >= 64) && (c < 128)) -// m |= (1L << (c - 64)); -// } -// return m; -// } -// + // Compute a low-order mask for the characters + // between first and last, inclusive + private static long lowMask(char first, char last) { + long m = 0; + int f = Math.max(Math.min(first, 63), 0); + int l = Math.max(Math.min(last, 63), 0); + for (int i = f; i <= l; i++) + m |= 1L << i; + return m; + } + + // Compute the low-order mask for the characters in the given string + private static long lowMask(String chars) { + int n = chars.length(); + long m = 0; + for (int i = 0; i < n; i++) { + char c = chars.charAt(i); + if (c < 64) + m |= (1L << c); + } + return m; + } + + // Compute a high-order mask for the characters + // between first and last, inclusive + private static long highMask(char first, char last) { + long m = 0; + int f = Math.max(Math.min(first, 127), 64) - 64; + int l = Math.max(Math.min(last, 127), 64) - 64; + for (int i = f; i <= l; i++) + m |= 1L << i; + return m; + } + + // Compute the high-order mask for the characters in the given string + private static long highMask(String chars) { + int n = chars.length(); + long m = 0; + for (int i = 0; i < n; i++) { + char c = chars.charAt(i); + if ((c >= 64) && (c < 128)) + m |= (1L << (c - 64)); + } + return m; + } + // Character-class masks -// // digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | -// // "8" | "9" -// private static final long L_DIGIT = lowMask('0', '9'); -// private static final long H_DIGIT = 0L; -// + // digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | + // "8" | "9" + private static final long L_DIGIT = lowMask('0', '9'); + private static final long H_DIGIT = 0L; + // hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | // "a" | "b" | "c" | "d" | "e" | "f" -// private static final long L_HEX = L_DIGIT; -// private static final long H_HEX = highMask('A', 'F') | highMask('a', 'f'); -// -// // upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | -// // "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | -// // "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" -// private static final long L_UPALPHA = 0L; -// private static final long H_UPALPHA = highMask('A', 'Z'); -// -// // lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | -// // "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | -// // "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" -// private static final long L_LOWALPHA = 0L; -// private static final long H_LOWALPHA = highMask('a', 'z'); -// -// // alpha = lowalpha | upalpha -// private static final long L_ALPHA = L_LOWALPHA | L_UPALPHA; -// private static final long H_ALPHA = H_LOWALPHA | H_UPALPHA; -// -// // alphanum = alpha | digit -// private static final long L_ALPHANUM = L_DIGIT | L_ALPHA; -// private static final long H_ALPHANUM = H_DIGIT | H_ALPHA; -// -// // mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | -// // "(" | ")" -// private static final long L_MARK = lowMask("-_.!~*'()"); -// private static final long H_MARK = highMask("-_.!~*'()"); -// -// // unreserved = alphanum | mark -// private static final long L_UNRESERVED = L_ALPHANUM | L_MARK; -// private static final long H_UNRESERVED = H_ALPHANUM | H_MARK; -// -// // reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | -// // "$" | "," | "[" | "]" -// // Added per RFC2732: "[", "]" -// private static final long L_RESERVED = lowMask(";/?:@&=+$,[]"); -// private static final long H_RESERVED = highMask(";/?:@&=+$,[]"); -// -// // The zero'th bit is used to indicate that escape pairs and non-US-ASCII -// // characters are allowed; this is handled by the scanEscape method below. -// private static final long L_ESCAPED = 1L; -// private static final long H_ESCAPED = 0L; -// -// // Dash, for use in domainlabel and toplabel -// private static final long L_DASH = lowMask("-"); -// private static final long H_DASH = highMask("-"); + private static final long L_HEX = L_DIGIT; + private static final long H_HEX = highMask('A', 'F') | highMask('a', 'f'); + + // upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | + // "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | + // "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z" + private static final long L_UPALPHA = 0L; + private static final long H_UPALPHA = highMask('A', 'Z'); + + // lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | + // "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | + // "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z" + private static final long L_LOWALPHA = 0L; + private static final long H_LOWALPHA = highMask('a', 'z'); + + // alpha = lowalpha | upalpha + private static final long L_ALPHA = L_LOWALPHA | L_UPALPHA; + private static final long H_ALPHA = H_LOWALPHA | H_UPALPHA; + + // alphanum = alpha | digit + private static final long L_ALPHANUM = L_DIGIT | L_ALPHA; + private static final long H_ALPHANUM = H_DIGIT | H_ALPHA; + + // mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | + // "(" | ")" + private static final long L_MARK = lowMask("-_.!~*'()"); + private static final long H_MARK = highMask("-_.!~*'()"); + + // unreserved = alphanum | mark + private static final long L_UNRESERVED = L_ALPHANUM | L_MARK; + private static final long H_UNRESERVED = H_ALPHANUM | H_MARK; + + // reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | + // "$" | "," | "[" | "]" + // Added per RFC2732: "[", "]" + private static final long L_RESERVED = lowMask(";/?:@&=+$,[]"); + private static final long H_RESERVED = highMask(";/?:@&=+$,[]"); + + // The zero'th bit is used to indicate that escape pairs and non-US-ASCII + // characters are allowed; this is handled by the scanEscape method below. + private static final long L_ESCAPED = 1L; + private static final long H_ESCAPED = 0L; + + // Dash, for use in domainlabel and toplabel + private static final long L_DASH = lowMask("-"); + private static final long H_DASH = highMask("-"); // uric = reserved | unreserved | escaped -// private static final long L_URIC = L_RESERVED | L_UNRESERVED | L_ESCAPED; -// private static final long H_URIC = H_RESERVED | H_UNRESERVED | H_ESCAPED; + private static final long L_URIC = L_RESERVED | L_UNRESERVED | L_ESCAPED; + private static final long H_URIC = H_RESERVED | H_UNRESERVED | H_ESCAPED; // pchar = unreserved | escaped | // ":" | "@" | "&" | "=" | "+" | "$" | "," -// private static final long L_PCHAR -// = L_UNRESERVED | L_ESCAPED | lowMask(":@&=+$,"); -// private static final long H_PCHAR -// = H_UNRESERVED | H_ESCAPED | highMask(":@&=+$,"); + private static final long L_PCHAR + = L_UNRESERVED | L_ESCAPED | lowMask(":@&=+$,"); + private static final long H_PCHAR + = H_UNRESERVED | H_ESCAPED | highMask(":@&=+$,"); // All valid path characters -// private static final long L_PATH = L_PCHAR | lowMask(";/"); -// private static final long H_PATH = H_PCHAR | highMask(";/"); + private static final long L_PATH = L_PCHAR | lowMask(";/"); + private static final long H_PATH = H_PCHAR | highMask(";/"); // userinfo = *( unreserved | escaped | // ";" | ":" | "&" | "=" | "+" | "$" | "," ) -// private static final long L_USERINFO -// = L_UNRESERVED | L_ESCAPED | lowMask(";:&=+$,"); -// private static final long H_USERINFO -// = H_UNRESERVED | H_ESCAPED | highMask(";:&=+$,"); + private static final long L_USERINFO + = L_UNRESERVED | L_ESCAPED | lowMask(";:&=+$,"); + private static final long H_USERINFO + = H_UNRESERVED | H_ESCAPED | highMask(";:&=+$,"); // reg_name = 1*( unreserved | escaped | "$" | "," | // ";" | ":" | "@" | "&" | "=" | "+" ) -// private static final long L_REG_NAME -// = L_UNRESERVED | L_ESCAPED | lowMask("$,;:@&=+"); -// private static final long H_REG_NAME -// = H_UNRESERVED | H_ESCAPED | highMask("$,;:@&=+"); - -// // All valid characters for server-based authorities -// private static final long L_SERVER -// = L_USERINFO | L_ALPHANUM | L_DASH | lowMask(".:@[]"); -// private static final long H_SERVER -// = H_USERINFO | H_ALPHANUM | H_DASH | highMask(".:@[]"); + private static final long L_REG_NAME + = L_UNRESERVED | L_ESCAPED | lowMask("$,;:@&=+"); + private static final long H_REG_NAME + = H_UNRESERVED | H_ESCAPED | highMask("$,;:@&=+"); + + // All valid characters for server-based authorities + private static final long L_SERVER + = L_USERINFO | L_ALPHANUM | L_DASH | lowMask(".:@[]"); + private static final long H_SERVER + = H_USERINFO | H_ALPHANUM | H_DASH | highMask(".:@[]"); } diff --git a/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffer.java b/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffer.java index 1009bda5d..c3c68c032 100644 --- a/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffer.java +++ b/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffer.java @@ -33,55 +33,55 @@ */ class NativeBuffer { - private static final Unsafe unsafe = Unsafe.getUnsafe(); - - private final long address; - private final int size; - private final Cleaner cleaner; - - // optional "owner" to avoid copying - // (only safe for use by thread-local caches) - private Object owner; - - private static class Deallocator implements Runnable { - private final long address; - Deallocator(long address) { - this.address = address; - } - public void run() { - unsafe.freeMemory(address); - } - } - - NativeBuffer(int size) { - this.address = unsafe.allocateMemory(size); - this.size = size; - this.cleaner = Cleaner.create(this, new Deallocator(address)); - } - - void release() { - NativeBuffers.releaseNativeBuffer(this); - } - - long address() { - return address; - } - - int size() { - return size; - } - - Cleaner cleaner() { - return cleaner; - } - - // not synchronized; only safe for use by thread-local caches - void setOwner(Object owner) { - this.owner = owner; - } - - // not synchronized; only safe for use by thread-local caches - Object owner() { - return owner; - } +// private static final Unsafe unsafe = Unsafe.getUnsafe(); +// +// private final long address; +// private final int size; +// private final Cleaner cleaner; +// +// // optional "owner" to avoid copying +// // (only safe for use by thread-local caches) +// private Object owner; +// +// private static class Deallocator implements Runnable { +// private final long address; +// Deallocator(long address) { +// this.address = address; +// } +// public void run() { +// unsafe.freeMemory(address); +// } +// } +// +// NativeBuffer(int size) { +// this.address = unsafe.allocateMemory(size); +// this.size = size; +// this.cleaner = Cleaner.create(this, new Deallocator(address)); +// } +// +// void release() { +// NativeBuffers.releaseNativeBuffer(this); +// } +// +// long address() { +// return address; +// } +// +// int size() { +// return size; +// } +// +// Cleaner cleaner() { +// return cleaner; +// } +// +// // not synchronized; only safe for use by thread-local caches +// void setOwner(Object owner) { +// this.owner = owner; +// } +// +// // not synchronized; only safe for use by thread-local caches +// Object owner() { +// return owner; +// } } diff --git a/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffers.java b/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffers.java index e801b0f0d..25cd84efb 100644 --- a/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffers.java +++ b/sources/net.sf.j2s.java.core/src/sun/nio/fs/NativeBuffers.java @@ -32,109 +32,109 @@ */ class NativeBuffers { - private NativeBuffers() { } - - private static final Unsafe unsafe = Unsafe.getUnsafe(); - - private static final int TEMP_BUF_POOL_SIZE = 3; - private static /*ThreadLocal<*/NativeBuffer[]/*> */threadLocal/*= - new ThreadLocal()*/; - - /** - * Allocates a native buffer, of at least the given size, from the heap. - */ - static NativeBuffer allocNativeBuffer(int size) { - // Make a new one of at least 2k - if (size < 2048) size = 2048; - return new NativeBuffer(size); - } - - /** - * Returns a native buffer, of at least the given size, from the thread - * local cache. - */ - static NativeBuffer getNativeBufferFromCache(int size) { - // return from cache if possible - NativeBuffer[] buffers = threadLocal;//.get(); - if (buffers != null) { - for (int i=0; i= size) { - buffers[i] = null; - return buffer; - } - } - } - return null; - } - - /** - * Returns a native buffer, of at least the given size. The native buffer - * is taken from the thread local cache if possible; otherwise it is - * allocated from the heap. - */ - static NativeBuffer getNativeBuffer(int size) { - NativeBuffer buffer = getNativeBufferFromCache(size); - if (buffer != null) { - buffer.setOwner(null); - return buffer; - } else { - return allocNativeBuffer(size); - } - } - - /** - * Releases the given buffer. If there is space in the thread local cache - * then the buffer goes into the cache; otherwise the memory is deallocated. - */ - static void releaseNativeBuffer(NativeBuffer buffer) { - // create cache if it doesn't exist - NativeBuffer[] buffers = threadLocal;//.get(); - if (buffers == null) { - buffers = new NativeBuffer[TEMP_BUF_POOL_SIZE]; - buffers[0] = buffer; - threadLocal = /*.set*/(buffers); - return; - } - // Put it in an empty slot if such exists - for (int i=0; i= (len + 1); - unsafe.copyMemory(cstr, offset, null, buffer.address(), len); - unsafe.putByte(buffer.address() + len, (byte)0); - } - - /** - * Copies a byte array and zero terminator into a native buffer, returning - * the buffer. - */ - static NativeBuffer asNativeBuffer(byte[] cstr) { - NativeBuffer buffer = getNativeBuffer(cstr.length+1); - copyCStringToNativeBuffer(cstr, buffer); - return buffer; - } +// private NativeBuffers() { } +// +// private static final Unsafe unsafe = Unsafe.getUnsafe(); +// +// private static final int TEMP_BUF_POOL_SIZE = 3; +// private static /*ThreadLocal<*/NativeBuffer[]/*> */threadLocal/*= +// new ThreadLocal()*/; +// +// /** +// * Allocates a native buffer, of at least the given size, from the heap. +// */ +// static NativeBuffer allocNativeBuffer(int size) { +// // Make a new one of at least 2k +// if (size < 2048) size = 2048; +// return new NativeBuffer(size); +// } +// +// /** +// * Returns a native buffer, of at least the given size, from the thread +// * local cache. +// */ +// static NativeBuffer getNativeBufferFromCache(int size) { +// // return from cache if possible +// NativeBuffer[] buffers = threadLocal;//.get(); +// if (buffers != null) { +// for (int i=0; i= size) { +// buffers[i] = null; +// return buffer; +// } +// } +// } +// return null; +// } +// +// /** +// * Returns a native buffer, of at least the given size. The native buffer +// * is taken from the thread local cache if possible; otherwise it is +// * allocated from the heap. +// */ +// static NativeBuffer getNativeBuffer(int size) { +// NativeBuffer buffer = getNativeBufferFromCache(size); +// if (buffer != null) { +// buffer.setOwner(null); +// return buffer; +// } else { +// return allocNativeBuffer(size); +// } +// } +// +// /** +// * Releases the given buffer. If there is space in the thread local cache +// * then the buffer goes into the cache; otherwise the memory is deallocated. +// */ +// static void releaseNativeBuffer(NativeBuffer buffer) { +// // create cache if it doesn't exist +// NativeBuffer[] buffers = threadLocal;//.get(); +// if (buffers == null) { +// buffers = new NativeBuffer[TEMP_BUF_POOL_SIZE]; +// buffers[0] = buffer; +// threadLocal = /*.set*/(buffers); +// return; +// } +// // Put it in an empty slot if such exists +// for (int i=0; i= (len + 1); +// unsafe.copyMemory(cstr, offset, null, buffer.address(), len); +// unsafe.putByte(buffer.address() + len, (byte)0); +// } +// +// /** +// * Copies a byte array and zero terminator into a native buffer, returning +// * the buffer. +// */ +// static NativeBuffer asNativeBuffer(byte[] cstr) { +// NativeBuffer buffer = getNativeBuffer(cstr.length+1); +// copyCStringToNativeBuffer(cstr, buffer); +// return buffer; +// } } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSFileSystem.java b/sources/net.sf.j2s.java.core/src/swingjs/JSFileSystem.java index 21793a98e..3cbbd2836 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSFileSystem.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSFileSystem.java @@ -9,7 +9,6 @@ import java.net.URI; import java.net.URISyntaxException; import java.nio.ByteBuffer; -import java.nio.CharBuffer; import java.nio.MappedByteBuffer; import java.nio.channels.AsynchronousFileChannel; import java.nio.channels.FileChannel; @@ -48,7 +47,6 @@ import java.util.Set; import javajs.util.AU; -import swingjs.JSFileSystem.JSMappedByteBuffer; /** * very rough - not fleshed out. @@ -530,6 +528,10 @@ public Path next() { } } + + public String[] list(File f) { + return new String[0]; + } public class JSPath implements Path { diff --git a/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java b/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java index 60c099fdb..49f53c837 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/JSUtil.java @@ -655,5 +655,6 @@ public static Color getColorFromName(String c) { */ return new Color(rgb[0], rgb[1], rgb[2]); } + } diff --git a/sources/net.sf.j2s.java.core/src/swingjs/api/js/DOMNode.java b/sources/net.sf.j2s.java.core/src/swingjs/api/js/DOMNode.java index 9441c92f3..ca8bcb3e6 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/api/js/DOMNode.java +++ b/sources/net.sf.j2s.java.core/src/swingjs/api/js/DOMNode.java @@ -124,7 +124,7 @@ public static DOMNode setAttr(DOMNode node, String attr, Object val) { /** * @j2sNative * - * node[attr] = (val == "TRUE" ? true : val == "FALSE" ? false : val); + * attr && (node[attr] = (val == "TRUE" ? true : val == "FALSE" ? false : val)); * */ return node; @@ -153,9 +153,7 @@ public static DOMNode setAttrs(DOMNode node, Object... attr) { * @j2sNative * * for (var i = 0; i < attr.length;) { - * var key = attr[i++]; - * var val = attr[i++]; - * key && (node[key] = val); + * C$.setAttr(node, attr[i++],attr[i++]); * } */ return node; @@ -166,9 +164,7 @@ public static DOMNode setStyles(DOMNode node, String... attr) { * @j2sNative * * if (node) for (var i = 0; i < attr.length;) { - * // - * node.style[attr[i++]] = attr[i++]; - * // + * node.style[attr[i++]] = attr[i++]; * } * */ diff --git a/sources/net.sf.j2s.java.core/src/swingjs/jquery/j2sComboBox.js b/sources/net.sf.j2s.java.core/src/swingjs/jquery/j2sComboBox.js index c100f6f4a..d4d0f9208 100644 --- a/sources/net.sf.j2s.java.core/src/swingjs/jquery/j2sComboBox.js +++ b/sources/net.sf.j2s.java.core/src/swingjs/jquery/j2sComboBox.js @@ -1,9 +1,12 @@ /** + * * @author Bob Hanson 2019.07.06 * + * * A relatively simple ComboBox that supports actual objects, not just strings * */ +// BH 2019.08.26 text area set to