8000970: break out auxiliary classes that will prevent multi-core compilation of the JDK

Reviewed-by: alanb, wetmore
This commit is contained in:
Fredrik Öhrström 2012-10-29 14:12:37 +01:00
parent dc9bf2de74
commit f5e72e432e
54 changed files with 3976 additions and 2784 deletions

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
class AbstractGradient extends Paint {
public static enum CycleMethod {
NO_CYCLE, REFLECT, REPEAT
}
@XmlElement(name="stop") private ArrayList<GradientStop> stops;
public List<GradientStop> getStops() { return stops; }
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlEnumValue;
class Border {
enum BorderType {
@XmlEnumValue("empty") EMPTY,
@XmlEnumValue("painter") PAINTER
}
@XmlAttribute private BorderType type;
@XmlAttribute private String painter;
@XmlAttribute private int top;
@XmlAttribute private int left;
@XmlAttribute private int bottom;
@XmlAttribute private int right;
public String write() {
switch (type) {
case PAINTER:
return String.format("new PainterBorder(\"%s\", new Insets(%d, %d, %d, %d))",
painter, top, left, bottom, right);
case EMPTY:
return String.format("BorderFactory.createEmptyBorder(%d, %d, %d, %d)",
top, left, bottom, right);
default:
return "### Look, here's an unknown border! $$$";
}
}
}

View File

@ -0,0 +1,45 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
class Canvas {
@XmlElement private Dimension size;
public Dimension getSize() { return size; }
@XmlElement(name="layer") private List<Layer> layers;
public List<Layer> getLayers() { return layers; }
@XmlElement private Insets stretchingInsets = null;
public Insets getStretchingInsets() { return stretchingInsets; }
public boolean isBlank() {
return layers.size() == 0 || (layers.size() == 1 && layers.get(0).isEmpty());
}
}

View File

@ -0,0 +1,93 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
class ComponentColor {
private String propertyName;
private String defaultColorVariableName;
private float saturationOffset = 0, brightnessOffset = 0;
private int alphaOffset = 0;
ComponentColor(String propertyName,
String defaultColorVariableName,
float saturationOffset,
float brightnessOffset,
int alphaOffset) {
this.propertyName = propertyName;
this.defaultColorVariableName = defaultColorVariableName;
this.saturationOffset = saturationOffset;
this.brightnessOffset = brightnessOffset;
this.alphaOffset = alphaOffset;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ComponentColor c = (ComponentColor) o;
if (alphaOffset != c.alphaOffset) {
return false;
}
if (Float.compare(saturationOffset, c.saturationOffset) != 0) {
return false;
}
if (Float.compare(brightnessOffset, c.brightnessOffset) != 0) {
return false;
}
if (defaultColorVariableName != null ? !defaultColorVariableName.equals(c.defaultColorVariableName) : c.defaultColorVariableName != null) {
return false;
}
if (propertyName != null ? !propertyName.equals(c.propertyName) : c.propertyName != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 61 * hash + (this.propertyName != null ? this.propertyName.hashCode() : 0);
hash = 61 * hash + (this.defaultColorVariableName != null ? this.defaultColorVariableName.hashCode() : 0);
hash = 61 * hash + Float.floatToIntBits(this.saturationOffset);
hash = 61 * hash + Float.floatToIntBits(this.brightnessOffset);
hash = 61 * hash + this.alphaOffset;
return hash;
}
public void write(StringBuilder sb) {
sb.append(" getComponentColor(c, \"").
append(propertyName).append("\", ").
append(defaultColorVariableName).append(", ").
append(saturationOffset).append("f, ").
append(brightnessOffset).append("f, ").
append(alphaOffset);
}
}

View File

@ -0,0 +1,38 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
class Dimension {
@XmlAttribute int width;
@XmlAttribute int height;
public String write(boolean uiResource) {
String uiSuffix = (uiResource ? "UIResource" : "");
return String.format("new Dimension%s(%d, %d)", uiSuffix, width, height);
}
}

View File

@ -0,0 +1,42 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
class Ellipse extends Shape {
@XmlAttribute private double x1;
public double getX1() { return x1; }
@XmlAttribute private double x2;
public double getX2() { return x2; }
@XmlAttribute private double y1;
public double getY1() { return y1; }
@XmlAttribute private double y2;
public double getY2() { return y2; }
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
class Gradient extends AbstractGradient {
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
class GradientStop {
@XmlAttribute private float position;
public float getPosition() { return position; }
@XmlAttribute private float midpoint;
public float getMidpoint() { return midpoint; }
@XmlElement private Matte matte;
public Matte getColor() { return matte; }
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
class Insets {
@XmlAttribute int top;
@XmlAttribute int left;
@XmlAttribute int bottom;
@XmlAttribute int right;
public Insets() {
this(0, 0, 0, 0);
}
public Insets(int top, int left, int bottom, int right) {
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
public String write(boolean uiResource) {
String uiSuffix = (uiResource ? "UIResource" : "");
return String.format("new Insets%s(%d, %d, %d, %d)",
uiSuffix, top, left, bottom, right);
}
}

View File

@ -0,0 +1,49 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
class Layer {
/** List of shapes in this layer, first shape is painted on top */
@XmlElements({
@XmlElement(name = "ellipse", type = Ellipse.class),
@XmlElement(name = "path", type = Path.class),
@XmlElement(name = "rectangle", type = Rectangle.class)
})
@XmlElementWrapper(name="shapes")
private List<Shape> shapes = new ArrayList<Shape>();
public List<Shape> getShapes() { return shapes; }
public boolean isEmpty() {
return shapes.isEmpty();
}
}

View File

@ -0,0 +1,82 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
class Matte extends Paint {
@XmlAttribute private int red;
@XmlAttribute private int green;
@XmlAttribute private int blue;
@XmlAttribute private int alpha;
@XmlAttribute private String uiDefaultParentName = null;
@XmlAttribute private float hueOffset = 0;
@XmlAttribute private float saturationOffset = 0;
@XmlAttribute private float brightnessOffset = 0;
@XmlAttribute private int alphaOffset = 0;
@XmlAttribute private String componentPropertyName = null;
public String getComponentPropertyName() { return componentPropertyName; }
@XmlAttribute private boolean uiResource = true;
public boolean isAbsolute() {
return uiDefaultParentName == null;
}
public String getDeclaration() {
if (isAbsolute()) {
return String.format("new Color(%d, %d, %d, %d)",
red, green, blue, alpha);
} else {
return String.format("decodeColor(\"%s\", %sf, %sf, %sf, %d)",
uiDefaultParentName, String.valueOf(hueOffset),
String.valueOf(saturationOffset),
String.valueOf(brightnessOffset), alphaOffset);
}
}
public String write() {
if (isAbsolute()) {
return String.format("%s, %s, %s, %s", red, green, blue, alpha);
} else {
String s = String.format("\"%s\", %sf, %sf, %sf, %d",
uiDefaultParentName, String.valueOf(hueOffset),
String.valueOf(saturationOffset),
String.valueOf(brightnessOffset), alphaOffset);
if (! uiResource) {
s += ", false";
}
return s;
}
}
public ComponentColor createComponentColor(String variableName) {
return new ComponentColor(componentPropertyName, variableName,
saturationOffset, brightnessOffset, alphaOffset);
}
}

View File

@ -25,157 +25,6 @@
package build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
public abstract class Paint {
}
class Matte extends Paint {
@XmlAttribute private int red;
@XmlAttribute private int green;
@XmlAttribute private int blue;
@XmlAttribute private int alpha;
@XmlAttribute private String uiDefaultParentName = null;
@XmlAttribute private float hueOffset = 0;
@XmlAttribute private float saturationOffset = 0;
@XmlAttribute private float brightnessOffset = 0;
@XmlAttribute private int alphaOffset = 0;
@XmlAttribute private String componentPropertyName = null;
public String getComponentPropertyName() { return componentPropertyName; }
@XmlAttribute private boolean uiResource = true;
public boolean isAbsolute() {
return uiDefaultParentName == null;
}
public String getDeclaration() {
if (isAbsolute()) {
return String.format("new Color(%d, %d, %d, %d)",
red, green, blue, alpha);
} else {
return String.format("decodeColor(\"%s\", %sf, %sf, %sf, %d)",
uiDefaultParentName, String.valueOf(hueOffset),
String.valueOf(saturationOffset),
String.valueOf(brightnessOffset), alphaOffset);
}
}
public String write() {
if (isAbsolute()) {
return String.format("%s, %s, %s, %s", red, green, blue, alpha);
} else {
String s = String.format("\"%s\", %sf, %sf, %sf, %d",
uiDefaultParentName, String.valueOf(hueOffset),
String.valueOf(saturationOffset),
String.valueOf(brightnessOffset), alphaOffset);
if (! uiResource) {
s += ", false";
}
return s;
}
}
public ComponentColor createComponentColor(String variableName) {
return new ComponentColor(componentPropertyName, variableName,
saturationOffset, brightnessOffset, alphaOffset);
}
}
class ComponentColor {
private String propertyName;
private String defaultColorVariableName;
private float saturationOffset = 0, brightnessOffset = 0;
private int alphaOffset = 0;
ComponentColor(String propertyName,
String defaultColorVariableName,
float saturationOffset,
float brightnessOffset,
int alphaOffset) {
this.propertyName = propertyName;
this.defaultColorVariableName = defaultColorVariableName;
this.saturationOffset = saturationOffset;
this.brightnessOffset = brightnessOffset;
this.alphaOffset = alphaOffset;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
ComponentColor c = (ComponentColor) o;
if (alphaOffset != c.alphaOffset) {
return false;
}
if (Float.compare(saturationOffset, c.saturationOffset) != 0) {
return false;
}
if (Float.compare(brightnessOffset, c.brightnessOffset) != 0) {
return false;
}
if (defaultColorVariableName != null ? !defaultColorVariableName.equals(c.defaultColorVariableName) : c.defaultColorVariableName != null) {
return false;
}
if (propertyName != null ? !propertyName.equals(c.propertyName) : c.propertyName != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int hash = 5;
hash = 61 * hash + (this.propertyName != null ? this.propertyName.hashCode() : 0);
hash = 61 * hash + (this.defaultColorVariableName != null ? this.defaultColorVariableName.hashCode() : 0);
hash = 61 * hash + Float.floatToIntBits(this.saturationOffset);
hash = 61 * hash + Float.floatToIntBits(this.brightnessOffset);
hash = 61 * hash + this.alphaOffset;
return hash;
}
public void write(StringBuilder sb) {
sb.append(" getComponentColor(c, \"").
append(propertyName).append("\", ").
append(defaultColorVariableName).append(", ").
append(saturationOffset).append("f, ").
append(brightnessOffset).append("f, ").
append(alphaOffset);
}
}
class GradientStop {
@XmlAttribute private float position;
public float getPosition() { return position; }
@XmlAttribute private float midpoint;
public float getMidpoint() { return midpoint; }
@XmlElement private Matte matte;
public Matte getColor() { return matte; }
}
class AbstractGradient extends Paint {
public static enum CycleMethod {
NO_CYCLE, REFLECT, REPEAT
}
@XmlElement(name="stop") private ArrayList<GradientStop> stops;
public List<GradientStop> getStops() { return stops; }
}
class Gradient extends AbstractGradient {
}
class RadialGradient extends AbstractGradient {
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
class Path extends Shape {
@XmlElement(name="point")
@XmlElementWrapper(name="points")
private List<Point> controlPoints = new ArrayList<Point>();
public List<Point> getControlPoints() { return controlPoints; }
}

View File

@ -0,0 +1,56 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
class Point {
@XmlAttribute private double x;
public double getX() { return x; }
@XmlAttribute private double y;
public double getY() { return y; }
@XmlAttribute(name="cp1x") private double cp1x;
public double getCp1X() { return cp1x; }
@XmlAttribute(name="cp1y") private double cp1y;
public double getCp1Y() { return cp1y; }
@XmlAttribute(name="cp2x") private double cp2x;
public double getCp2X() { return cp2x; }
@XmlAttribute(name="cp2y") private double cp2y;
public double getCp2Y() { return cp2y; }
public boolean isP1Sharp() {
return cp1x == x && cp1y == y;
}
public boolean isP2Sharp() {
return cp2x == x && cp2y == y;
}
}

View File

@ -0,0 +1,29 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
class RadialGradient extends AbstractGradient {
}

View File

@ -0,0 +1,61 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
class Rectangle extends Shape {
@XmlAttribute private double x1;
public double getX1() { return x1; }
@XmlAttribute private double x2;
public double getX2() { return x2; }
@XmlAttribute private double y1;
public double getY1() { return y1; }
@XmlAttribute private double y2;
public double getY2() { return y2; }
@XmlAttribute
public double getRounding() {
double rounding = Math.abs(roundingX - x1) * 2;
return rounding > 2 ? rounding : 0;
}
public void setRounding(double rounding) {
if (rounding > 0 && rounding < 2) {
rounding = 0;
}
roundingX = rounding / 2d + x1;
}
private double roundingX;
public boolean isRounded() {
return getRounding() > 0;
}
}

View File

@ -25,11 +25,8 @@
package build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
@ -56,85 +53,3 @@ public abstract class Shape {
@XmlAttribute double y2;
}
}
class Point {
@XmlAttribute private double x;
public double getX() { return x; }
@XmlAttribute private double y;
public double getY() { return y; }
@XmlAttribute(name="cp1x") private double cp1x;
public double getCp1X() { return cp1x; }
@XmlAttribute(name="cp1y") private double cp1y;
public double getCp1Y() { return cp1y; }
@XmlAttribute(name="cp2x") private double cp2x;
public double getCp2X() { return cp2x; }
@XmlAttribute(name="cp2y") private double cp2y;
public double getCp2Y() { return cp2y; }
public boolean isP1Sharp() {
return cp1x == x && cp1y == y;
}
public boolean isP2Sharp() {
return cp2x == x && cp2y == y;
}
}
class Path extends Shape {
@XmlElement(name="point")
@XmlElementWrapper(name="points")
private List<Point> controlPoints = new ArrayList<Point>();
public List<Point> getControlPoints() { return controlPoints; }
}
class Rectangle extends Shape {
@XmlAttribute private double x1;
public double getX1() { return x1; }
@XmlAttribute private double x2;
public double getX2() { return x2; }
@XmlAttribute private double y1;
public double getY1() { return y1; }
@XmlAttribute private double y2;
public double getY2() { return y2; }
@XmlAttribute
public double getRounding() {
double rounding = Math.abs(roundingX - x1) * 2;
return rounding > 2 ? rounding : 0;
}
public void setRounding(double rounding) {
if (rounding > 0 && rounding < 2) {
rounding = 0;
}
roundingX = rounding / 2d + x1;
}
private double roundingX;
public boolean isRounded() {
return getRounding() > 0;
}
}
class Ellipse extends Shape {
@XmlAttribute private double x1;
public double getX1() { return x1; }
@XmlAttribute private double x2;
public double getX2() { return x2; }
@XmlAttribute private double y1;
public double getY1() { return y1; }
@XmlAttribute private double y2;
public double getY2() { return y2; }
}

View File

@ -25,9 +25,7 @@
package build.tools.generatenimbus;
import java.awt.Font;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.*;
@ -78,139 +76,3 @@ public class SynthModel {
}
}
}
class Typeface {
public enum DeriveStyle {
Default, Off, On;
@Override public String toString() {
switch (this) {
default: return "null";
case On: return "true";
case Off: return "false";
}
}
}
@XmlAttribute private String uiDefaultParentName;
@XmlAttribute(name="family") private String name;
@XmlAttribute private int size;
@XmlAttribute private DeriveStyle bold = DeriveStyle.Default;
@XmlAttribute private DeriveStyle italic = DeriveStyle.Default;
@XmlAttribute private float sizeOffset = 1f;
public boolean isAbsolute() {
return uiDefaultParentName == null;
}
public String write() {
if (isAbsolute()) {
int style = Font.PLAIN;
if (bold == DeriveStyle.On) {
style = style | Font.BOLD;
}
if (italic == DeriveStyle.On) {
style = style | Font.ITALIC;
}
return String.format(
"new javax.swing.plaf.FontUIResource(\"%s\", %d, %d)",
name, style, size);
} else {
return String.format(
"new DerivedFont(\"%s\", %sf, %s, %s)",
uiDefaultParentName, String.valueOf(sizeOffset), bold, italic);
}
}
}
class Border {
enum BorderType {
@XmlEnumValue("empty") EMPTY,
@XmlEnumValue("painter") PAINTER
}
@XmlAttribute private BorderType type;
@XmlAttribute private String painter;
@XmlAttribute private int top;
@XmlAttribute private int left;
@XmlAttribute private int bottom;
@XmlAttribute private int right;
public String write() {
switch (type) {
case PAINTER:
return String.format("new PainterBorder(\"%s\", new Insets(%d, %d, %d, %d))",
painter, top, left, bottom, right);
case EMPTY:
return String.format("BorderFactory.createEmptyBorder(%d, %d, %d, %d)",
top, left, bottom, right);
default:
return "### Look, here's an unknown border! $$$";
}
}
}
class Insets {
@XmlAttribute int top;
@XmlAttribute int left;
@XmlAttribute int bottom;
@XmlAttribute int right;
public Insets() {
this(0, 0, 0, 0);
}
public Insets(int top, int left, int bottom, int right) {
this.top = top;
this.left = left;
this.bottom = bottom;
this.right = right;
}
public String write(boolean uiResource) {
String uiSuffix = (uiResource ? "UIResource" : "");
return String.format("new Insets%s(%d, %d, %d, %d)",
uiSuffix, top, left, bottom, right);
}
}
class Dimension {
@XmlAttribute int width;
@XmlAttribute int height;
public String write(boolean uiResource) {
String uiSuffix = (uiResource ? "UIResource" : "");
return String.format("new Dimension%s(%d, %d)", uiSuffix, width, height);
}
}
class Canvas {
@XmlElement private Dimension size;
public Dimension getSize() { return size; }
@XmlElement(name="layer") private List<Layer> layers;
public List<Layer> getLayers() { return layers; }
@XmlElement private Insets stretchingInsets = null;
public Insets getStretchingInsets() { return stretchingInsets; }
public boolean isBlank() {
return layers.size() == 0 || (layers.size() == 1 && layers.get(0).isEmpty());
}
}
class Layer {
/** List of shapes in this layer, first shape is painted on top */
@XmlElements({
@XmlElement(name = "ellipse", type = Ellipse.class),
@XmlElement(name = "path", type = Path.class),
@XmlElement(name = "rectangle", type = Rectangle.class)
})
@XmlElementWrapper(name="shapes")
private List<Shape> shapes = new ArrayList<Shape>();
public List<Shape> getShapes() { return shapes; }
public boolean isEmpty() {
return shapes.isEmpty();
}
}

View File

@ -0,0 +1,75 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.awt.Font;
import javax.xml.bind.annotation.XmlAttribute;
class Typeface {
public enum DeriveStyle {
Default, Off, On;
@Override public String toString() {
switch (this) {
default: return "null";
case On: return "true";
case Off: return "false";
}
}
}
@XmlAttribute private String uiDefaultParentName;
@XmlAttribute(name="family") private String name;
@XmlAttribute private int size;
@XmlAttribute private DeriveStyle bold = DeriveStyle.Default;
@XmlAttribute private DeriveStyle italic = DeriveStyle.Default;
@XmlAttribute private float sizeOffset = 1f;
public boolean isAbsolute() {
return uiDefaultParentName == null;
}
public String write() {
if (isAbsolute()) {
int style = Font.PLAIN;
if (bold == DeriveStyle.On) {
style = style | Font.BOLD;
}
if (italic == DeriveStyle.On) {
style = style | Font.ITALIC;
}
return String.format(
"new javax.swing.plaf.FontUIResource(\"%s\", %d, %d)",
name, style, size);
} else {
return String.format(
"new DerivedFont(\"%s\", %sf, %s, %s)",
uiDefaultParentName, String.valueOf(sizeOffset), bold, italic);
}
}
}

View File

@ -0,0 +1,41 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlElement;
class UIColor extends UIDefault<Matte> {
@XmlElement
public void setMatte(Matte m) {
setValue(m);
}
public String write() {
return String.format(" addColor(d, \"%s\", %s);\n",
getName(), getValue().write());
}
}

View File

@ -0,0 +1,54 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
class UIComponent extends UIRegion {
@XmlAttribute private String componentName;
@XmlElement(name="stateType")
@XmlElementWrapper(name="stateTypes")
private List<UIStateType> stateTypes = new ArrayList<UIStateType>();
public List<UIStateType> getStateTypes() { return stateTypes; }
@Override public String getKey() {
if (key == null || "".equals(key)) {
if (componentName == null || "".equals(componentName)) {
return name;
} else {
return "\"" + componentName + "\"";
}
} else {
return key;
}
}
}

View File

@ -26,7 +26,6 @@
package build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
public class UIDefault<T> {
@XmlAttribute private String name;
@ -44,83 +43,3 @@ public class UIDefault<T> {
this.value = value;
}
}
class UIColor extends UIDefault<Matte> {
@XmlElement
public void setMatte(Matte m) {
setValue(m);
}
public String write() {
return String.format(" addColor(d, \"%s\", %s);\n",
getName(), getValue().write());
}
}
class UIFont extends UIDefault<Typeface> {
@XmlElement
public void setTypeface(Typeface t) {
setValue(t);
}
public String write() {
return String.format(" d.put(\"%s\", %s);\n",
getName(), getValue().write());
}
}
class UIProperty extends UIDefault<String> {
public static enum PropertyType {
BOOLEAN, INT, FLOAT, DOUBLE, STRING, FONT, COLOR, INSETS, DIMENSION, BORDER
}
@XmlAttribute private PropertyType type;
@XmlElement private Border border;
@XmlElement private Dimension dimension;
@XmlElement private Insets insets;
@XmlElement private Matte matte;
@XmlElement private Typeface typeface;
@XmlAttribute
@Override public void setValue(String value) {
super.setValue(value);
}
public String write(String prefix) {
switch (type) {
case BOOLEAN:
return String.format(" d.put(\"%s%s\", Boolean.%s);\n",
prefix, getName(), getValue().toUpperCase()); ///autobox
case STRING:
return String.format(" d.put(\"%s%s\", \"%s\");\n",
prefix, getName(), getValue());
case INT:
return String.format(" d.put(\"%s%s\", new Integer(%s));\n",
prefix, getName(), getValue());
case FLOAT:
return String.format(" d.put(\"%s%s\", new Float(%sf));\n",
prefix, getName(), getValue());
case DOUBLE:
return String.format(" d.put(\"%s%s\", new Double(%s));\n",
prefix, getName(), getValue());
case COLOR:
return String.format(" addColor(d, \"%s%s\", %s);\n",
prefix, getName(), matte.write());
case FONT:
return String.format(" d.put(\"%s%s\", %s);\n",
prefix, getName(), typeface.write());
case INSETS:
return String.format(" d.put(\"%s%s\", %s);\n",
prefix, getName(), insets.write(true));
case DIMENSION:
return String.format(" d.put(\"%s%s\", new DimensionUIResource(%d, %d));\n",
prefix, getName(), dimension.width, dimension.height);
case BORDER:
return String.format(" d.put(\"%s%s\", new BorderUIResource(%s));\n",
prefix, getName(), border.write());
default:
return "### Look, something's wrong with UIProperty.write() $$$";
}
}
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlElement;
class UIFont extends UIDefault<Typeface> {
@XmlElement
public void setTypeface(Typeface t) {
setValue(t);
}
public String write() {
return String.format(" d.put(\"%s\", %s);\n",
getName(), getValue().write());
}
}

View File

@ -0,0 +1,53 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
class UIIconRegion extends UIRegion {
@XmlAttribute private String basicKey;
@Override public void write(StringBuilder sb, StringBuilder styleBuffer, UIComponent comp, String prefix, String pkg) {
Dimension size = null;
String fileNamePrefix = Utils.normalize(prefix) + "Painter";
// write states ui defaults
for (UIState state : backgroundStates) {
Canvas canvas = state.getCanvas();
if (!canvas.isBlank()) {
state.write(sb, prefix, pkg, fileNamePrefix, getKey());
size = canvas.getSize();
}
}
if (size != null) {
// Put SynthIconImpl wrapper in UiDefaults
String k = (basicKey == null ? prefix + "." + getKey() : basicKey);
sb.append(String.format(
" d.put(\"%s\", new NimbusIcon(\"%s\", \"%sPainter\", %d, %d));\n",
k, prefix, getKey(), size.width, size.height));
}
}
}

View File

@ -0,0 +1,84 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
class UIProperty extends UIDefault<String> {
public static enum PropertyType {
BOOLEAN, INT, FLOAT, DOUBLE, STRING, FONT, COLOR, INSETS, DIMENSION, BORDER
}
@XmlAttribute private PropertyType type;
@XmlElement private Border border;
@XmlElement private Dimension dimension;
@XmlElement private Insets insets;
@XmlElement private Matte matte;
@XmlElement private Typeface typeface;
@XmlAttribute
@Override public void setValue(String value) {
super.setValue(value);
}
public String write(String prefix) {
switch (type) {
case BOOLEAN:
return String.format(" d.put(\"%s%s\", Boolean.%s);\n",
prefix, getName(), getValue().toUpperCase()); ///autobox
case STRING:
return String.format(" d.put(\"%s%s\", \"%s\");\n",
prefix, getName(), getValue());
case INT:
return String.format(" d.put(\"%s%s\", new Integer(%s));\n",
prefix, getName(), getValue());
case FLOAT:
return String.format(" d.put(\"%s%s\", new Float(%sf));\n",
prefix, getName(), getValue());
case DOUBLE:
return String.format(" d.put(\"%s%s\", new Double(%s));\n",
prefix, getName(), getValue());
case COLOR:
return String.format(" addColor(d, \"%s%s\", %s);\n",
prefix, getName(), matte.write());
case FONT:
return String.format(" d.put(\"%s%s\", %s);\n",
prefix, getName(), typeface.write());
case INSETS:
return String.format(" d.put(\"%s%s\", %s);\n",
prefix, getName(), insets.write(true));
case DIMENSION:
return String.format(" d.put(\"%s%s\", new DimensionUIResource(%d, %d));\n",
prefix, getName(), dimension.width, dimension.height);
case BORDER:
return String.format(" d.put(\"%s%s\", new BorderUIResource(%s));\n",
prefix, getName(), border.write());
default:
return "### Look, something's wrong with UIProperty.write() $$$";
}
}
}

View File

@ -0,0 +1,200 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
class UIRegion {
@XmlAttribute protected String name;
@XmlAttribute protected String key;
@XmlAttribute private boolean opaque = false;
@XmlElement private Insets contentMargins = new Insets(0, 0, 0, 0);
@XmlElement(name="state")
@XmlElementWrapper(name="backgroundStates")
protected List<UIState> backgroundStates = new ArrayList<UIState>();
public List<UIState> getBackgroundStates() { return backgroundStates; }
@XmlElement(name="state")
@XmlElementWrapper(name="foregroundStates")
protected List<UIState> foregroundStates = new ArrayList<UIState>();
public List<UIState> getForegroundStates() { return foregroundStates; }
@XmlElement(name="state")
@XmlElementWrapper(name="borderStates")
protected List<UIState> borderStates = new ArrayList<UIState>();
public List<UIState> getBorderStates() { return borderStates; }
@XmlElement private UIStyle style = new UIStyle();
@XmlElements({
@XmlElement(name = "region", type = UIRegion.class),
@XmlElement(name = "uiComponent", type = UIComponent.class),
@XmlElement(name = "uiIconRegion", type = UIIconRegion.class)
})
@XmlElementWrapper(name="regions")
private List<UIRegion> subRegions = new ArrayList<UIRegion>();
public List<UIRegion> getSubRegions() { return subRegions; }
protected void initStyles(UIStyle parentStyle) {
style.setParentStyle(parentStyle);
for (UIState state: backgroundStates) {
state.getStyle().setParentStyle(this.style);
}
for (UIState state: foregroundStates) {
state.getStyle().setParentStyle(this.style);
}
for (UIState state: borderStates) {
state.getStyle().setParentStyle(this.style);
}
for (UIRegion region: subRegions) {
region.initStyles(this.style);
}
}
public String getKey() {
return key == null || "".equals(key) ? name : key;
}
private boolean hasCanvas() {
for (UIState s : backgroundStates) {
if (s.hasCanvas()) return true;
}
for (UIState s : borderStates) {
if (s.hasCanvas()) return true;
}
for (UIState s : foregroundStates) {
if (s.hasCanvas()) return true;
}
for (UIRegion r: subRegions) {
if (r.hasCanvas()) return true;
}
return false;
}
public void write(StringBuilder sb, StringBuilder styleBuffer,
UIComponent comp, String prefix, String pkg) {
// write content margins
sb.append(String.format(" d.put(\"%s.contentMargins\", %s);\n",
prefix, contentMargins.write(true)));
// write opaque if true
if (opaque) {
sb.append(String.format(" d.put(\"%s.opaque\", Boolean.TRUE);\n", prefix));
}
// register component with LAF
String regionCode = "Region." + Utils.regionNameToCaps(name);
styleBuffer.append(String.format(" register(%s, \"%s\");\n",
regionCode, prefix));
//write the State, if necessary
StringBuffer regString = new StringBuffer();
List<UIStateType> types = comp.getStateTypes();
if (types != null && types.size() > 0) {
for (UIStateType type : types) {
regString.append(type.getKey());
regString.append(",");
}
//remove the last ","
regString.deleteCharAt(regString.length() - 1);
}
if (! regString.equals("Enabled,MouseOver,Pressed,Disabled,Focused,Selected,Default") && types.size() > 0) {
//there were either custom states, or the normal states were in a custom order
//so go ahead and write out prefix.State
sb.append(String.format(" d.put(\"%s.States\", \"%s\");\n",
prefix, regString));
}
// write out any custom states, if necessary
for (UIStateType type : types) {
String synthState = type.getKey();
if (! "Enabled".equals(synthState) &&
! "MouseOver".equals(synthState) &&
! "Pressed".equals(synthState) &&
! "Disabled".equals(synthState) &&
! "Focused".equals(synthState) &&
! "Selected".equals(synthState) &&
! "Default".equals(synthState)) {
//what we have here, gentlemen, is a bona-fide custom state.
//if the type is not one of the standard types, then construct a name for
//the new type, and write out a new subclass of State.
String className = Utils.normalize(prefix) + synthState + "State";
sb.append(String.format(" d.put(\"%s.%s\", new %s());\n",
prefix, synthState, className));
String body = type.getCodeSnippet();
Map<String, String> variables = Generator.getVariables();
variables.put("STATE_NAME", className);
variables.put("STATE_KEY", synthState);
variables.put("BODY", body);
Generator.writeSrcFile("StateImpl", variables, className);
}
}
// write style
sb.append(style.write(prefix + '.'));
String fileName = Utils.normalize(prefix) + "Painter";
boolean hasCanvas = hasCanvas();
if (hasCanvas) {
PainterGenerator.writePainter(this, fileName);
}
// write states ui defaults
for (UIState state : backgroundStates) {
state.write(sb, prefix, pkg, fileName, "background");
}
for (UIState state : foregroundStates) {
state.write(sb, prefix, pkg, fileName, "foreground");
}
for (UIState state : borderStates) {
state.write(sb, prefix, pkg, fileName, "border");
}
// handle sub regions
for (UIRegion subreg : subRegions) {
String p = prefix;
if (! (subreg instanceof UIIconRegion)) {
p = prefix + ":" + Utils.escape(subreg.getKey());
}
UIComponent c = comp;
if (subreg instanceof UIComponent) {
c = (UIComponent) subreg;
}
subreg.write(sb, styleBuffer, c, p, pkg);
}
}
}

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
class UIState {
@XmlAttribute private String stateKeys;
public String getStateKeys() { return stateKeys; }
/** Indicates whether to invert the meaning of the 9-square stretching insets */
@XmlAttribute private boolean inverted;
/** A cached string representing the list of stateKeys deliminated with "+" */
private String cachedName = null;
@XmlElement private Canvas canvas;
public Canvas getCanvas() { return canvas; }
@XmlElement private UIStyle style;
public UIStyle getStyle() { return style; }
public boolean hasCanvas() {
return ! canvas.isBlank();
}
public static List<String> stringToKeys(String keysString) {
return Arrays.asList(keysString.split("\\+"));
}
public String getName() {
if (cachedName == null) {
StringBuilder buf = new StringBuilder();
List<String> keys = stringToKeys(stateKeys);
Collections.sort(keys);
for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
buf.append(iter.next());
if (iter.hasNext()) {
buf.append('+');
}
}
cachedName = buf.toString();
}
return cachedName;
}
public void write(StringBuilder sb, String prefix, String pkg, String fileNamePrefix, String painterPrefix) {
String statePrefix = prefix + "[" + getName() + "]";
// write state style
sb.append(style.write(statePrefix + '.'));
// write painter
if (hasCanvas()) {
writeLazyPainter(sb, statePrefix, pkg, fileNamePrefix, painterPrefix);
}
}
private void writeLazyPainter(StringBuilder sb, String statePrefix, String packageNamePrefix, String fileNamePrefix, String painterPrefix) {
String cacheModeString = "AbstractRegionPainter.PaintContext.CacheMode." + style.getCacheMode();
String stateConstant = Utils.statesToConstantName(painterPrefix + "_" + stateKeys);
sb.append(String.format(
" d.put(\"%s.%sPainter\", new LazyPainter(\"%s.%s\", %s.%s, %s, %s, %b, %s, %s, %s));\n",
statePrefix, painterPrefix, packageNamePrefix, fileNamePrefix,
fileNamePrefix, stateConstant, canvas.getStretchingInsets().write(false),
canvas.getSize().write(false), inverted, cacheModeString,
Utils.formatDouble(style.getMaxHozCachedImgScaling()),
Utils.formatDouble(style.getMaxVertCachedImgScaling())));
}
}

View File

@ -0,0 +1,37 @@
/*
* Copyright (c) 2002, 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 build.tools.generatenimbus;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
class UIStateType {
@XmlAttribute private String key;
public String getKey() { return key; }
@XmlElement private String codeSnippet;
public String getCodeSnippet() { return codeSnippet; }
}

View File

@ -26,15 +26,9 @@
package build.tools.generatenimbus;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlElementWrapper;
import javax.xml.bind.annotation.XmlElements;
class UIStyle {
@ -115,285 +109,3 @@ class UIStyle {
return sb.toString();
}
}
class UIRegion {
@XmlAttribute protected String name;
@XmlAttribute protected String key;
@XmlAttribute private boolean opaque = false;
@XmlElement private Insets contentMargins = new Insets(0, 0, 0, 0);
@XmlElement(name="state")
@XmlElementWrapper(name="backgroundStates")
protected List<UIState> backgroundStates = new ArrayList<UIState>();
public List<UIState> getBackgroundStates() { return backgroundStates; }
@XmlElement(name="state")
@XmlElementWrapper(name="foregroundStates")
protected List<UIState> foregroundStates = new ArrayList<UIState>();
public List<UIState> getForegroundStates() { return foregroundStates; }
@XmlElement(name="state")
@XmlElementWrapper(name="borderStates")
protected List<UIState> borderStates = new ArrayList<UIState>();
public List<UIState> getBorderStates() { return borderStates; }
@XmlElement private UIStyle style = new UIStyle();
@XmlElements({
@XmlElement(name = "region", type = UIRegion.class),
@XmlElement(name = "uiComponent", type = UIComponent.class),
@XmlElement(name = "uiIconRegion", type = UIIconRegion.class)
})
@XmlElementWrapper(name="regions")
private List<UIRegion> subRegions = new ArrayList<UIRegion>();
public List<UIRegion> getSubRegions() { return subRegions; }
protected void initStyles(UIStyle parentStyle) {
style.setParentStyle(parentStyle);
for (UIState state: backgroundStates) {
state.getStyle().setParentStyle(this.style);
}
for (UIState state: foregroundStates) {
state.getStyle().setParentStyle(this.style);
}
for (UIState state: borderStates) {
state.getStyle().setParentStyle(this.style);
}
for (UIRegion region: subRegions) {
region.initStyles(this.style);
}
}
public String getKey() {
return key == null || "".equals(key) ? name : key;
}
private boolean hasCanvas() {
for (UIState s : backgroundStates) {
if (s.hasCanvas()) return true;
}
for (UIState s : borderStates) {
if (s.hasCanvas()) return true;
}
for (UIState s : foregroundStates) {
if (s.hasCanvas()) return true;
}
for (UIRegion r: subRegions) {
if (r.hasCanvas()) return true;
}
return false;
}
public void write(StringBuilder sb, StringBuilder styleBuffer,
UIComponent comp, String prefix, String pkg) {
// write content margins
sb.append(String.format(" d.put(\"%s.contentMargins\", %s);\n",
prefix, contentMargins.write(true)));
// write opaque if true
if (opaque) {
sb.append(String.format(" d.put(\"%s.opaque\", Boolean.TRUE);\n", prefix));
}
// register component with LAF
String regionCode = "Region." + Utils.regionNameToCaps(name);
styleBuffer.append(String.format(" register(%s, \"%s\");\n",
regionCode, prefix));
//write the State, if necessary
StringBuffer regString = new StringBuffer();
List<UIStateType> types = comp.getStateTypes();
if (types != null && types.size() > 0) {
for (UIStateType type : types) {
regString.append(type.getKey());
regString.append(",");
}
//remove the last ","
regString.deleteCharAt(regString.length() - 1);
}
if (! regString.equals("Enabled,MouseOver,Pressed,Disabled,Focused,Selected,Default") && types.size() > 0) {
//there were either custom states, or the normal states were in a custom order
//so go ahead and write out prefix.State
sb.append(String.format(" d.put(\"%s.States\", \"%s\");\n",
prefix, regString));
}
// write out any custom states, if necessary
for (UIStateType type : types) {
String synthState = type.getKey();
if (! "Enabled".equals(synthState) &&
! "MouseOver".equals(synthState) &&
! "Pressed".equals(synthState) &&
! "Disabled".equals(synthState) &&
! "Focused".equals(synthState) &&
! "Selected".equals(synthState) &&
! "Default".equals(synthState)) {
//what we have here, gentlemen, is a bona-fide custom state.
//if the type is not one of the standard types, then construct a name for
//the new type, and write out a new subclass of State.
String className = Utils.normalize(prefix) + synthState + "State";
sb.append(String.format(" d.put(\"%s.%s\", new %s());\n",
prefix, synthState, className));
String body = type.getCodeSnippet();
Map<String, String> variables = Generator.getVariables();
variables.put("STATE_NAME", className);
variables.put("STATE_KEY", synthState);
variables.put("BODY", body);
Generator.writeSrcFile("StateImpl", variables, className);
}
}
// write style
sb.append(style.write(prefix + '.'));
String fileName = Utils.normalize(prefix) + "Painter";
boolean hasCanvas = hasCanvas();
if (hasCanvas) {
PainterGenerator.writePainter(this, fileName);
}
// write states ui defaults
for (UIState state : backgroundStates) {
state.write(sb, prefix, pkg, fileName, "background");
}
for (UIState state : foregroundStates) {
state.write(sb, prefix, pkg, fileName, "foreground");
}
for (UIState state : borderStates) {
state.write(sb, prefix, pkg, fileName, "border");
}
// handle sub regions
for (UIRegion subreg : subRegions) {
String p = prefix;
if (! (subreg instanceof UIIconRegion)) {
p = prefix + ":" + Utils.escape(subreg.getKey());
}
UIComponent c = comp;
if (subreg instanceof UIComponent) {
c = (UIComponent) subreg;
}
subreg.write(sb, styleBuffer, c, p, pkg);
}
}
}
class UIIconRegion extends UIRegion {
@XmlAttribute private String basicKey;
@Override public void write(StringBuilder sb, StringBuilder styleBuffer, UIComponent comp, String prefix, String pkg) {
Dimension size = null;
String fileNamePrefix = Utils.normalize(prefix) + "Painter";
// write states ui defaults
for (UIState state : backgroundStates) {
Canvas canvas = state.getCanvas();
if (!canvas.isBlank()) {
state.write(sb, prefix, pkg, fileNamePrefix, getKey());
size = canvas.getSize();
}
}
if (size != null) {
// Put SynthIconImpl wrapper in UiDefaults
String k = (basicKey == null ? prefix + "." + getKey() : basicKey);
sb.append(String.format(
" d.put(\"%s\", new NimbusIcon(\"%s\", \"%sPainter\", %d, %d));\n",
k, prefix, getKey(), size.width, size.height));
}
}
}
class UIComponent extends UIRegion {
@XmlAttribute private String componentName;
@XmlElement(name="stateType")
@XmlElementWrapper(name="stateTypes")
private List<UIStateType> stateTypes = new ArrayList<UIStateType>();
public List<UIStateType> getStateTypes() { return stateTypes; }
@Override public String getKey() {
if (key == null || "".equals(key)) {
if (componentName == null || "".equals(componentName)) {
return name;
} else {
return "\"" + componentName + "\"";
}
} else {
return key;
}
}
}
class UIState {
@XmlAttribute private String stateKeys;
public String getStateKeys() { return stateKeys; }
/** Indicates whether to invert the meaning of the 9-square stretching insets */
@XmlAttribute private boolean inverted;
/** A cached string representing the list of stateKeys deliminated with "+" */
private String cachedName = null;
@XmlElement private Canvas canvas;
public Canvas getCanvas() { return canvas; }
@XmlElement private UIStyle style;
public UIStyle getStyle() { return style; }
public boolean hasCanvas() {
return ! canvas.isBlank();
}
public static List<String> stringToKeys(String keysString) {
return Arrays.asList(keysString.split("\\+"));
}
public String getName() {
if (cachedName == null) {
StringBuilder buf = new StringBuilder();
List<String> keys = stringToKeys(stateKeys);
Collections.sort(keys);
for (Iterator<String> iter = keys.iterator(); iter.hasNext();) {
buf.append(iter.next());
if (iter.hasNext()) {
buf.append('+');
}
}
cachedName = buf.toString();
}
return cachedName;
}
public void write(StringBuilder sb, String prefix, String pkg, String fileNamePrefix, String painterPrefix) {
String statePrefix = prefix + "[" + getName() + "]";
// write state style
sb.append(style.write(statePrefix + '.'));
// write painter
if (hasCanvas()) {
writeLazyPainter(sb, statePrefix, pkg, fileNamePrefix, painterPrefix);
}
}
private void writeLazyPainter(StringBuilder sb, String statePrefix, String packageNamePrefix, String fileNamePrefix, String painterPrefix) {
String cacheModeString = "AbstractRegionPainter.PaintContext.CacheMode." + style.getCacheMode();
String stateConstant = Utils.statesToConstantName(painterPrefix + "_" + stateKeys);
sb.append(String.format(
" d.put(\"%s.%sPainter\", new LazyPainter(\"%s.%s\", %s.%s, %s, %s, %b, %s, %s, %s));\n",
statePrefix, painterPrefix, packageNamePrefix, fileNamePrefix,
fileNamePrefix, stateConstant, canvas.getStretchingInsets().write(false),
canvas.getSize().write(false), inverted, cacheModeString,
Utils.formatDouble(style.getMaxHozCachedImgScaling()),
Utils.formatDouble(style.getMaxVertCachedImgScaling())));
}
}
class UIStateType {
@XmlAttribute private String key;
public String getKey() { return key; }
@XmlElement private String codeSnippet;
public String getCodeSnippet() { return codeSnippet; }
}

View File

@ -1240,54 +1240,3 @@ public class Timer extends NotificationBroadcasterSupport
"sendNotification", "timer notification sent");
}
}
/**
* TimerAlarmClock inner class:
* This class provides a simple implementation of an alarm clock MBean.
* The aim of this MBean is to set up an alarm which wakes up the timer every timeout (fixed-delay)
* or at the specified date (fixed-rate).
*/
class TimerAlarmClock extends java.util.TimerTask {
Timer listener = null;
long timeout = 10000;
Date next = null;
/*
* ------------------------------------------
* CONSTRUCTORS
* ------------------------------------------
*/
public TimerAlarmClock(Timer listener, long timeout) {
this.listener = listener;
this.timeout = Math.max(0L, timeout);
}
public TimerAlarmClock(Timer listener, Date next) {
this.listener = listener;
this.next = next;
}
/*
* ------------------------------------------
* PUBLIC METHODS
* ------------------------------------------
*/
/**
* This method is called by the timer when it is started.
*/
public void run() {
try {
//this.sleep(timeout);
TimerAlarmClockNotification notif = new TimerAlarmClockNotification(this);
listener.notifyAlarmClock(notif);
} catch (Exception e) {
TIMER_LOGGER.logp(Level.FINEST, Timer.class.getName(), "run",
"Got unexpected exception when sending a notification", e);
}
}
}

View File

@ -0,0 +1,80 @@
/*
* Copyright (c) 1999, 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 javax.management.timer;
import java.util.Date;
import java.util.logging.Level;
import static com.sun.jmx.defaults.JmxProperties.TIMER_LOGGER;
/**
* This class provides a simple implementation of an alarm clock MBean.
* The aim of this MBean is to set up an alarm which wakes up the timer every timeout (fixed-delay)
* or at the specified date (fixed-rate).
*/
class TimerAlarmClock extends java.util.TimerTask {
Timer listener = null;
long timeout = 10000;
Date next = null;
/*
* ------------------------------------------
* CONSTRUCTORS
* ------------------------------------------
*/
public TimerAlarmClock(Timer listener, long timeout) {
this.listener = listener;
this.timeout = Math.max(0L, timeout);
}
public TimerAlarmClock(Timer listener, Date next) {
this.listener = listener;
this.next = next;
}
/*
* ------------------------------------------
* PUBLIC METHODS
* ------------------------------------------
*/
/**
* This method is called by the timer when it is started.
*/
public void run() {
try {
//this.sleep(timeout);
TimerAlarmClockNotification notif = new TimerAlarmClockNotification(this);
listener.notifyAlarmClock(notif);
} catch (Exception e) {
TIMER_LOGGER.logp(Level.FINEST, Timer.class.getName(), "run",
"Got unexpected exception when sending a notification", e);
}
}
}

View File

@ -0,0 +1,632 @@
/*
* Copyright (c) 1998, 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.awt.im;
import java.awt.AWTException;
import java.awt.CheckboxMenuItem;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.PopupMenu;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.Toolkit;
import sun.awt.AppContext;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InvocationEvent;
import java.awt.im.spi.InputMethodDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.ServiceLoader;
import java.util.Vector;
import java.util.Set;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import sun.awt.InputMethodSupport;
import sun.awt.SunToolkit;
/**
* <code>ExecutableInputMethodManager</code> is the implementation of the
* <code>InputMethodManager</code> class. It is runnable as a separate
* thread in the AWT environment.&nbsp;
* <code>InputMethodManager.getInstance()</code> creates an instance of
* <code>ExecutableInputMethodManager</code> and executes it as a deamon
* thread.
*
* @see InputMethodManager
*/
class ExecutableInputMethodManager extends InputMethodManager
implements Runnable
{
// the input context that's informed about selections from the user interface
private InputContext currentInputContext;
// Menu item string for the trigger menu.
private String triggerMenuString;
// popup menu for selecting an input method
private InputMethodPopupMenu selectionMenu;
private static String selectInputMethodMenuTitle;
// locator and name of host adapter
private InputMethodLocator hostAdapterLocator;
// locators for Java input methods
private int javaInputMethodCount; // number of Java input methods found
private Vector<InputMethodLocator> javaInputMethodLocatorList;
// component that is requesting input method switch
// must be Frame or Dialog
private Component requestComponent;
// input context that is requesting input method switch
private InputContext requestInputContext;
// IM preference stuff
private static final String preferredIMNode = "/sun/awt/im/preferredInputMethod";
private static final String descriptorKey = "descriptor";
private Hashtable<String, InputMethodLocator> preferredLocatorCache = new Hashtable<>();
private Preferences userRoot;
ExecutableInputMethodManager() {
// set up host adapter locator
Toolkit toolkit = Toolkit.getDefaultToolkit();
try {
if (toolkit instanceof InputMethodSupport) {
InputMethodDescriptor hostAdapterDescriptor =
((InputMethodSupport)toolkit)
.getInputMethodAdapterDescriptor();
if (hostAdapterDescriptor != null) {
hostAdapterLocator = new InputMethodLocator(hostAdapterDescriptor, null, null);
}
}
} catch (AWTException e) {
// if we can't get a descriptor, we'll just have to do without native input methods
}
javaInputMethodLocatorList = new Vector<InputMethodLocator>();
initializeInputMethodLocatorList();
}
synchronized void initialize() {
selectInputMethodMenuTitle = Toolkit.getProperty("AWT.InputMethodSelectionMenu", "Select Input Method");
triggerMenuString = selectInputMethodMenuTitle;
}
public void run() {
// If there are no multiple input methods to choose from, wait forever
while (!hasMultipleInputMethods()) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
}
}
// Loop for processing input method change requests
while (true) {
waitForChangeRequest();
initializeInputMethodLocatorList();
try {
if (requestComponent != null) {
showInputMethodMenuOnRequesterEDT(requestComponent);
} else {
// show the popup menu within the event thread
EventQueue.invokeAndWait(new Runnable() {
public void run() {
showInputMethodMenu();
}
});
}
} catch (InterruptedException ie) {
} catch (InvocationTargetException ite) {
// should we do anything under these exceptions?
}
}
}
// Shows Input Method Menu on the EDT of requester component
// to avoid side effects. See 6544309.
private void showInputMethodMenuOnRequesterEDT(Component requester)
throws InterruptedException, InvocationTargetException {
if (requester == null){
return;
}
class AWTInvocationLock {}
Object lock = new AWTInvocationLock();
InvocationEvent event =
new InvocationEvent(requester,
new Runnable() {
public void run() {
showInputMethodMenu();
}
},
lock,
true);
AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
synchronized (lock) {
SunToolkit.postEvent(requesterAppContext, event);
while (!event.isDispatched()) {
lock.wait();
}
}
Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null) {
throw new InvocationTargetException(eventThrowable);
}
}
void setInputContext(InputContext inputContext) {
if (currentInputContext != null && inputContext != null) {
// don't throw this exception until 4237852 is fixed
// throw new IllegalStateException("Can't have two active InputContext at the same time");
}
currentInputContext = inputContext;
}
public synchronized void notifyChangeRequest(Component comp) {
if (!(comp instanceof Frame || comp instanceof Dialog))
return;
// if busy with the current request, ignore this request.
if (requestComponent != null)
return;
requestComponent = comp;
notify();
}
public synchronized void notifyChangeRequestByHotKey(Component comp) {
while (!(comp instanceof Frame || comp instanceof Dialog)) {
if (comp == null) {
// no Frame or Dialog found in containment hierarchy.
return;
}
comp = comp.getParent();
}
notifyChangeRequest(comp);
}
public String getTriggerMenuString() {
return triggerMenuString;
}
/*
* Returns true if the environment indicates there are multiple input methods
*/
boolean hasMultipleInputMethods() {
return ((hostAdapterLocator != null) && (javaInputMethodCount > 0)
|| (javaInputMethodCount > 1));
}
private synchronized void waitForChangeRequest() {
try {
while (requestComponent == null) {
wait();
}
} catch (InterruptedException e) {
}
}
/*
* initializes the input method locator list for all
* installed input method descriptors.
*/
private void initializeInputMethodLocatorList() {
synchronized (javaInputMethodLocatorList) {
javaInputMethodLocatorList.clear();
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() {
for (InputMethodDescriptor descriptor :
ServiceLoader.loadInstalled(InputMethodDescriptor.class)) {
ClassLoader cl = descriptor.getClass().getClassLoader();
javaInputMethodLocatorList.add(new InputMethodLocator(descriptor, cl, null));
}
return null;
}
});
} catch (PrivilegedActionException e) {
e.printStackTrace();
}
javaInputMethodCount = javaInputMethodLocatorList.size();
}
if (hasMultipleInputMethods()) {
// initialize preferences
if (userRoot == null) {
userRoot = getUserRoot();
}
} else {
// indicate to clients not to offer the menu
triggerMenuString = null;
}
}
private void showInputMethodMenu() {
if (!hasMultipleInputMethods()) {
requestComponent = null;
return;
}
// initialize pop-up menu
selectionMenu = InputMethodPopupMenu.getInstance(requestComponent, selectInputMethodMenuTitle);
// we have to rebuild the menu each time because
// some input methods (such as IIIMP) may change
// their list of supported locales dynamically
selectionMenu.removeAll();
// get information about the currently selected input method
// ??? if there's no current input context, what's the point
// of showing the menu?
String currentSelection = getCurrentSelection();
// Add menu item for host adapter
if (hostAdapterLocator != null) {
selectionMenu.addOneInputMethodToMenu(hostAdapterLocator, currentSelection);
selectionMenu.addSeparator();
}
// Add menu items for other input methods
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
selectionMenu.addOneInputMethodToMenu(locator, currentSelection);
}
synchronized (this) {
selectionMenu.addToComponent(requestComponent);
requestInputContext = currentInputContext;
selectionMenu.show(requestComponent, 60, 80); // TODO: get proper x, y...
requestComponent = null;
}
}
private String getCurrentSelection() {
InputContext inputContext = currentInputContext;
if (inputContext != null) {
InputMethodLocator locator = inputContext.getInputMethodLocator();
if (locator != null) {
return locator.getActionCommandString();
}
}
return null;
}
synchronized void changeInputMethod(String choice) {
InputMethodLocator locator = null;
String inputMethodName = choice;
String localeString = null;
int index = choice.indexOf('\n');
if (index != -1) {
localeString = choice.substring(index + 1);
inputMethodName = choice.substring(0, index);
}
if (hostAdapterLocator.getActionCommandString().equals(inputMethodName)) {
locator = hostAdapterLocator;
} else {
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
String name = candidate.getActionCommandString();
if (name.equals(inputMethodName)) {
locator = candidate;
break;
}
}
}
if (locator != null && localeString != null) {
String language = "", country = "", variant = "";
int postIndex = localeString.indexOf('_');
if (postIndex == -1) {
language = localeString;
} else {
language = localeString.substring(0, postIndex);
int preIndex = postIndex + 1;
postIndex = localeString.indexOf('_', preIndex);
if (postIndex == -1) {
country = localeString.substring(preIndex);
} else {
country = localeString.substring(preIndex, postIndex);
variant = localeString.substring(postIndex + 1);
}
}
Locale locale = new Locale(language, country, variant);
locator = locator.deriveLocator(locale);
}
if (locator == null)
return;
// tell the input context about the change
if (requestInputContext != null) {
requestInputContext.changeInputMethod(locator);
requestInputContext = null;
// remember the selection
putPreferredInputMethod(locator);
}
}
InputMethodLocator findInputMethod(Locale locale) {
// look for preferred input method first
InputMethodLocator locator = getPreferredInputMethod(locale);
if (locator != null) {
return locator;
}
if (hostAdapterLocator != null && hostAdapterLocator.isLocaleAvailable(locale)) {
return hostAdapterLocator.deriveLocator(locale);
}
// Update the locator list
initializeInputMethodLocatorList();
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
if (candidate.isLocaleAvailable(locale)) {
return candidate.deriveLocator(locale);
}
}
return null;
}
Locale getDefaultKeyboardLocale() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
if (toolkit instanceof InputMethodSupport) {
return ((InputMethodSupport)toolkit).getDefaultKeyboardLocale();
} else {
return Locale.getDefault();
}
}
/**
* Returns a InputMethodLocator object that the
* user prefers for the given locale.
*
* @param locale Locale for which the user prefers the input method.
*/
private synchronized InputMethodLocator getPreferredInputMethod(Locale locale) {
InputMethodLocator preferredLocator = null;
if (!hasMultipleInputMethods()) {
// No need to look for a preferred Java input method
return null;
}
// look for the cached preference first.
preferredLocator = preferredLocatorCache.get(locale.toString().intern());
if (preferredLocator != null) {
return preferredLocator;
}
// look for the preference in the user preference tree
String nodePath = findPreferredInputMethodNode(locale);
String descriptorName = readPreferredInputMethod(nodePath);
Locale advertised;
// get the locator object
if (descriptorName != null) {
// check for the host adapter first
if (hostAdapterLocator != null &&
hostAdapterLocator.getDescriptor().getClass().getName().equals(descriptorName)) {
advertised = getAdvertisedLocale(hostAdapterLocator, locale);
if (advertised != null) {
preferredLocator = hostAdapterLocator.deriveLocator(advertised);
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
}
return preferredLocator;
}
// look for Java input methods
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
InputMethodDescriptor descriptor = locator.getDescriptor();
if (descriptor.getClass().getName().equals(descriptorName)) {
advertised = getAdvertisedLocale(locator, locale);
if (advertised != null) {
preferredLocator = locator.deriveLocator(advertised);
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
}
return preferredLocator;
}
}
// maybe preferred input method information is bogus.
writePreferredInputMethod(nodePath, null);
}
return null;
}
private String findPreferredInputMethodNode(Locale locale) {
if (userRoot == null) {
return null;
}
// create locale node relative path
String nodePath = preferredIMNode + "/" + createLocalePath(locale);
// look for the descriptor
while (!nodePath.equals(preferredIMNode)) {
try {
if (userRoot.nodeExists(nodePath)) {
if (readPreferredInputMethod(nodePath) != null) {
return nodePath;
}
}
} catch (BackingStoreException bse) {
}
// search at parent's node
nodePath = nodePath.substring(0, nodePath.lastIndexOf('/'));
}
return null;
}
private String readPreferredInputMethod(String nodePath) {
if ((userRoot == null) || (nodePath == null)) {
return null;
}
return userRoot.node(nodePath).get(descriptorKey, null);
}
/**
* Writes the preferred input method descriptor class name into
* the user's Preferences tree in accordance with the given locale.
*
* @param inputMethodLocator input method locator to remember.
*/
private synchronized void putPreferredInputMethod(InputMethodLocator locator) {
InputMethodDescriptor descriptor = locator.getDescriptor();
Locale preferredLocale = locator.getLocale();
if (preferredLocale == null) {
// check available locales of the input method
try {
Locale[] availableLocales = descriptor.getAvailableLocales();
if (availableLocales.length == 1) {
preferredLocale = availableLocales[0];
} else {
// there is no way to know which locale is the preferred one, so do nothing.
return;
}
} catch (AWTException ae) {
// do nothing here, either.
return;
}
}
// for regions that have only one language, we need to regard
// "xx_YY" as "xx" when putting the preference into tree
if (preferredLocale.equals(Locale.JAPAN)) {
preferredLocale = Locale.JAPANESE;
}
if (preferredLocale.equals(Locale.KOREA)) {
preferredLocale = Locale.KOREAN;
}
if (preferredLocale.equals(new Locale("th", "TH"))) {
preferredLocale = new Locale("th");
}
// obtain node
String path = preferredIMNode + "/" + createLocalePath(preferredLocale);
// write in the preference tree
writePreferredInputMethod(path, descriptor.getClass().getName());
preferredLocatorCache.put(preferredLocale.toString().intern(),
locator.deriveLocator(preferredLocale));
return;
}
private String createLocalePath(Locale locale) {
String language = locale.getLanguage();
String country = locale.getCountry();
String variant = locale.getVariant();
String localePath = null;
if (!variant.equals("")) {
localePath = "_" + language + "/_" + country + "/_" + variant;
} else if (!country.equals("")) {
localePath = "_" + language + "/_" + country;
} else {
localePath = "_" + language;
}
return localePath;
}
private void writePreferredInputMethod(String path, String descriptorName) {
if (userRoot != null) {
Preferences node = userRoot.node(path);
// record it
if (descriptorName != null) {
node.put(descriptorKey, descriptorName);
} else {
node.remove(descriptorKey);
}
}
}
private Preferences getUserRoot() {
return AccessController.doPrivileged(new PrivilegedAction<Preferences>() {
public Preferences run() {
return Preferences.userRoot();
}
});
}
private Locale getAdvertisedLocale(InputMethodLocator locator, Locale locale) {
Locale advertised = null;
if (locator.isLocaleAvailable(locale)) {
advertised = locale;
} else if (locale.getLanguage().equals("ja")) {
// for Japanese, Korean, and Thai, check whether the input method supports
// language or language_COUNTRY.
if (locator.isLocaleAvailable(Locale.JAPAN)) {
advertised = Locale.JAPAN;
} else if (locator.isLocaleAvailable(Locale.JAPANESE)) {
advertised = Locale.JAPANESE;
}
} else if (locale.getLanguage().equals("ko")) {
if (locator.isLocaleAvailable(Locale.KOREA)) {
advertised = Locale.KOREA;
} else if (locator.isLocaleAvailable(Locale.KOREAN)) {
advertised = Locale.KOREAN;
}
} else if (locale.getLanguage().equals("th")) {
if (locator.isLocaleAvailable(new Locale("th", "TH"))) {
advertised = new Locale("th", "TH");
} else if (locator.isLocaleAvailable(new Locale("th"))) {
advertised = new Locale("th");
}
}
return advertised;
}
}

View File

@ -229,578 +229,3 @@ public abstract class InputMethodManager {
abstract boolean hasMultipleInputMethods();
}
/**
* <code>ExecutableInputMethodManager</code> is the implementation of the
* <code>InputMethodManager</code> class. It is runnable as a separate
* thread in the AWT environment.&nbsp;
* <code>InputMethodManager.getInstance()</code> creates an instance of
* <code>ExecutableInputMethodManager</code> and executes it as a deamon
* thread.
*
* @see InputMethodManager
*/
class ExecutableInputMethodManager extends InputMethodManager
implements Runnable
{
// the input context that's informed about selections from the user interface
private InputContext currentInputContext;
// Menu item string for the trigger menu.
private String triggerMenuString;
// popup menu for selecting an input method
private InputMethodPopupMenu selectionMenu;
private static String selectInputMethodMenuTitle;
// locator and name of host adapter
private InputMethodLocator hostAdapterLocator;
// locators for Java input methods
private int javaInputMethodCount; // number of Java input methods found
private Vector<InputMethodLocator> javaInputMethodLocatorList;
// component that is requesting input method switch
// must be Frame or Dialog
private Component requestComponent;
// input context that is requesting input method switch
private InputContext requestInputContext;
// IM preference stuff
private static final String preferredIMNode = "/sun/awt/im/preferredInputMethod";
private static final String descriptorKey = "descriptor";
private Hashtable<String, InputMethodLocator> preferredLocatorCache = new Hashtable<>();
private Preferences userRoot;
ExecutableInputMethodManager() {
// set up host adapter locator
Toolkit toolkit = Toolkit.getDefaultToolkit();
try {
if (toolkit instanceof InputMethodSupport) {
InputMethodDescriptor hostAdapterDescriptor =
((InputMethodSupport)toolkit)
.getInputMethodAdapterDescriptor();
if (hostAdapterDescriptor != null) {
hostAdapterLocator = new InputMethodLocator(hostAdapterDescriptor, null, null);
}
}
} catch (AWTException e) {
// if we can't get a descriptor, we'll just have to do without native input methods
}
javaInputMethodLocatorList = new Vector<InputMethodLocator>();
initializeInputMethodLocatorList();
}
synchronized void initialize() {
selectInputMethodMenuTitle = Toolkit.getProperty("AWT.InputMethodSelectionMenu", "Select Input Method");
triggerMenuString = selectInputMethodMenuTitle;
}
public void run() {
// If there are no multiple input methods to choose from, wait forever
while (!hasMultipleInputMethods()) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
}
}
// Loop for processing input method change requests
while (true) {
waitForChangeRequest();
initializeInputMethodLocatorList();
try {
if (requestComponent != null) {
showInputMethodMenuOnRequesterEDT(requestComponent);
} else {
// show the popup menu within the event thread
EventQueue.invokeAndWait(new Runnable() {
public void run() {
showInputMethodMenu();
}
});
}
} catch (InterruptedException ie) {
} catch (InvocationTargetException ite) {
// should we do anything under these exceptions?
}
}
}
// Shows Input Method Menu on the EDT of requester component
// to avoid side effects. See 6544309.
private void showInputMethodMenuOnRequesterEDT(Component requester)
throws InterruptedException, InvocationTargetException {
if (requester == null){
return;
}
class AWTInvocationLock {}
Object lock = new AWTInvocationLock();
InvocationEvent event =
new InvocationEvent(requester,
new Runnable() {
public void run() {
showInputMethodMenu();
}
},
lock,
true);
AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
synchronized (lock) {
SunToolkit.postEvent(requesterAppContext, event);
while (!event.isDispatched()) {
lock.wait();
}
}
Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null) {
throw new InvocationTargetException(eventThrowable);
}
}
void setInputContext(InputContext inputContext) {
if (currentInputContext != null && inputContext != null) {
// don't throw this exception until 4237852 is fixed
// throw new IllegalStateException("Can't have two active InputContext at the same time");
}
currentInputContext = inputContext;
}
public synchronized void notifyChangeRequest(Component comp) {
if (!(comp instanceof Frame || comp instanceof Dialog))
return;
// if busy with the current request, ignore this request.
if (requestComponent != null)
return;
requestComponent = comp;
notify();
}
public synchronized void notifyChangeRequestByHotKey(Component comp) {
while (!(comp instanceof Frame || comp instanceof Dialog)) {
if (comp == null) {
// no Frame or Dialog found in containment hierarchy.
return;
}
comp = comp.getParent();
}
notifyChangeRequest(comp);
}
public String getTriggerMenuString() {
return triggerMenuString;
}
/*
* Returns true if the environment indicates there are multiple input methods
*/
boolean hasMultipleInputMethods() {
return ((hostAdapterLocator != null) && (javaInputMethodCount > 0)
|| (javaInputMethodCount > 1));
}
private synchronized void waitForChangeRequest() {
try {
while (requestComponent == null) {
wait();
}
} catch (InterruptedException e) {
}
}
/*
* initializes the input method locator list for all
* installed input method descriptors.
*/
private void initializeInputMethodLocatorList() {
synchronized (javaInputMethodLocatorList) {
javaInputMethodLocatorList.clear();
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() {
for (InputMethodDescriptor descriptor :
ServiceLoader.loadInstalled(InputMethodDescriptor.class)) {
ClassLoader cl = descriptor.getClass().getClassLoader();
javaInputMethodLocatorList.add(new InputMethodLocator(descriptor, cl, null));
}
return null;
}
});
} catch (PrivilegedActionException e) {
e.printStackTrace();
}
javaInputMethodCount = javaInputMethodLocatorList.size();
}
if (hasMultipleInputMethods()) {
// initialize preferences
if (userRoot == null) {
userRoot = getUserRoot();
}
} else {
// indicate to clients not to offer the menu
triggerMenuString = null;
}
}
private void showInputMethodMenu() {
if (!hasMultipleInputMethods()) {
requestComponent = null;
return;
}
// initialize pop-up menu
selectionMenu = InputMethodPopupMenu.getInstance(requestComponent, selectInputMethodMenuTitle);
// we have to rebuild the menu each time because
// some input methods (such as IIIMP) may change
// their list of supported locales dynamically
selectionMenu.removeAll();
// get information about the currently selected input method
// ??? if there's no current input context, what's the point
// of showing the menu?
String currentSelection = getCurrentSelection();
// Add menu item for host adapter
if (hostAdapterLocator != null) {
selectionMenu.addOneInputMethodToMenu(hostAdapterLocator, currentSelection);
selectionMenu.addSeparator();
}
// Add menu items for other input methods
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
selectionMenu.addOneInputMethodToMenu(locator, currentSelection);
}
synchronized (this) {
selectionMenu.addToComponent(requestComponent);
requestInputContext = currentInputContext;
selectionMenu.show(requestComponent, 60, 80); // TODO: get proper x, y...
requestComponent = null;
}
}
private String getCurrentSelection() {
InputContext inputContext = currentInputContext;
if (inputContext != null) {
InputMethodLocator locator = inputContext.getInputMethodLocator();
if (locator != null) {
return locator.getActionCommandString();
}
}
return null;
}
synchronized void changeInputMethod(String choice) {
InputMethodLocator locator = null;
String inputMethodName = choice;
String localeString = null;
int index = choice.indexOf('\n');
if (index != -1) {
localeString = choice.substring(index + 1);
inputMethodName = choice.substring(0, index);
}
if (hostAdapterLocator.getActionCommandString().equals(inputMethodName)) {
locator = hostAdapterLocator;
} else {
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
String name = candidate.getActionCommandString();
if (name.equals(inputMethodName)) {
locator = candidate;
break;
}
}
}
if (locator != null && localeString != null) {
String language = "", country = "", variant = "";
int postIndex = localeString.indexOf('_');
if (postIndex == -1) {
language = localeString;
} else {
language = localeString.substring(0, postIndex);
int preIndex = postIndex + 1;
postIndex = localeString.indexOf('_', preIndex);
if (postIndex == -1) {
country = localeString.substring(preIndex);
} else {
country = localeString.substring(preIndex, postIndex);
variant = localeString.substring(postIndex + 1);
}
}
Locale locale = new Locale(language, country, variant);
locator = locator.deriveLocator(locale);
}
if (locator == null)
return;
// tell the input context about the change
if (requestInputContext != null) {
requestInputContext.changeInputMethod(locator);
requestInputContext = null;
// remember the selection
putPreferredInputMethod(locator);
}
}
InputMethodLocator findInputMethod(Locale locale) {
// look for preferred input method first
InputMethodLocator locator = getPreferredInputMethod(locale);
if (locator != null) {
return locator;
}
if (hostAdapterLocator != null && hostAdapterLocator.isLocaleAvailable(locale)) {
return hostAdapterLocator.deriveLocator(locale);
}
// Update the locator list
initializeInputMethodLocatorList();
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
if (candidate.isLocaleAvailable(locale)) {
return candidate.deriveLocator(locale);
}
}
return null;
}
Locale getDefaultKeyboardLocale() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
if (toolkit instanceof InputMethodSupport) {
return ((InputMethodSupport)toolkit).getDefaultKeyboardLocale();
} else {
return Locale.getDefault();
}
}
/**
* Returns a InputMethodLocator object that the
* user prefers for the given locale.
*
* @param locale Locale for which the user prefers the input method.
*/
private synchronized InputMethodLocator getPreferredInputMethod(Locale locale) {
InputMethodLocator preferredLocator = null;
if (!hasMultipleInputMethods()) {
// No need to look for a preferred Java input method
return null;
}
// look for the cached preference first.
preferredLocator = preferredLocatorCache.get(locale.toString().intern());
if (preferredLocator != null) {
return preferredLocator;
}
// look for the preference in the user preference tree
String nodePath = findPreferredInputMethodNode(locale);
String descriptorName = readPreferredInputMethod(nodePath);
Locale advertised;
// get the locator object
if (descriptorName != null) {
// check for the host adapter first
if (hostAdapterLocator != null &&
hostAdapterLocator.getDescriptor().getClass().getName().equals(descriptorName)) {
advertised = getAdvertisedLocale(hostAdapterLocator, locale);
if (advertised != null) {
preferredLocator = hostAdapterLocator.deriveLocator(advertised);
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
}
return preferredLocator;
}
// look for Java input methods
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
InputMethodDescriptor descriptor = locator.getDescriptor();
if (descriptor.getClass().getName().equals(descriptorName)) {
advertised = getAdvertisedLocale(locator, locale);
if (advertised != null) {
preferredLocator = locator.deriveLocator(advertised);
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
}
return preferredLocator;
}
}
// maybe preferred input method information is bogus.
writePreferredInputMethod(nodePath, null);
}
return null;
}
private String findPreferredInputMethodNode(Locale locale) {
if (userRoot == null) {
return null;
}
// create locale node relative path
String nodePath = preferredIMNode + "/" + createLocalePath(locale);
// look for the descriptor
while (!nodePath.equals(preferredIMNode)) {
try {
if (userRoot.nodeExists(nodePath)) {
if (readPreferredInputMethod(nodePath) != null) {
return nodePath;
}
}
} catch (BackingStoreException bse) {
}
// search at parent's node
nodePath = nodePath.substring(0, nodePath.lastIndexOf('/'));
}
return null;
}
private String readPreferredInputMethod(String nodePath) {
if ((userRoot == null) || (nodePath == null)) {
return null;
}
return userRoot.node(nodePath).get(descriptorKey, null);
}
/**
* Writes the preferred input method descriptor class name into
* the user's Preferences tree in accordance with the given locale.
*
* @param inputMethodLocator input method locator to remember.
*/
private synchronized void putPreferredInputMethod(InputMethodLocator locator) {
InputMethodDescriptor descriptor = locator.getDescriptor();
Locale preferredLocale = locator.getLocale();
if (preferredLocale == null) {
// check available locales of the input method
try {
Locale[] availableLocales = descriptor.getAvailableLocales();
if (availableLocales.length == 1) {
preferredLocale = availableLocales[0];
} else {
// there is no way to know which locale is the preferred one, so do nothing.
return;
}
} catch (AWTException ae) {
// do nothing here, either.
return;
}
}
// for regions that have only one language, we need to regard
// "xx_YY" as "xx" when putting the preference into tree
if (preferredLocale.equals(Locale.JAPAN)) {
preferredLocale = Locale.JAPANESE;
}
if (preferredLocale.equals(Locale.KOREA)) {
preferredLocale = Locale.KOREAN;
}
if (preferredLocale.equals(new Locale("th", "TH"))) {
preferredLocale = new Locale("th");
}
// obtain node
String path = preferredIMNode + "/" + createLocalePath(preferredLocale);
// write in the preference tree
writePreferredInputMethod(path, descriptor.getClass().getName());
preferredLocatorCache.put(preferredLocale.toString().intern(),
locator.deriveLocator(preferredLocale));
return;
}
private String createLocalePath(Locale locale) {
String language = locale.getLanguage();
String country = locale.getCountry();
String variant = locale.getVariant();
String localePath = null;
if (!variant.equals("")) {
localePath = "_" + language + "/_" + country + "/_" + variant;
} else if (!country.equals("")) {
localePath = "_" + language + "/_" + country;
} else {
localePath = "_" + language;
}
return localePath;
}
private void writePreferredInputMethod(String path, String descriptorName) {
if (userRoot != null) {
Preferences node = userRoot.node(path);
// record it
if (descriptorName != null) {
node.put(descriptorKey, descriptorName);
} else {
node.remove(descriptorKey);
}
}
}
private Preferences getUserRoot() {
return AccessController.doPrivileged(new PrivilegedAction<Preferences>() {
public Preferences run() {
return Preferences.userRoot();
}
});
}
private Locale getAdvertisedLocale(InputMethodLocator locator, Locale locale) {
Locale advertised = null;
if (locator.isLocaleAvailable(locale)) {
advertised = locale;
} else if (locale.getLanguage().equals("ja")) {
// for Japanese, Korean, and Thai, check whether the input method supports
// language or language_COUNTRY.
if (locator.isLocaleAvailable(Locale.JAPAN)) {
advertised = Locale.JAPAN;
} else if (locator.isLocaleAvailable(Locale.JAPANESE)) {
advertised = Locale.JAPANESE;
}
} else if (locale.getLanguage().equals("ko")) {
if (locator.isLocaleAvailable(Locale.KOREA)) {
advertised = Locale.KOREA;
} else if (locator.isLocaleAvailable(Locale.KOREAN)) {
advertised = Locale.KOREAN;
}
} else if (locale.getLanguage().equals("th")) {
if (locator.isLocaleAvailable(new Locale("th", "TH"))) {
advertised = new Locale("th", "TH");
} else if (locator.isLocaleAvailable(new Locale("th"))) {
advertised = new Locale("th");
}
}
return advertised;
}
}

View File

@ -0,0 +1,493 @@
/*
* 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;
/*
* A really, really simple bigint package
* tailored to the needs of floating base conversion.
*/
class FDBigInt {
int nWords; // number of words used
int data[]; // value: data[0] is least significant
public FDBigInt( int v ){
nWords = 1;
data = new int[1];
data[0] = v;
}
public FDBigInt( long v ){
data = new int[2];
data[0] = (int)v;
data[1] = (int)(v>>>32);
nWords = (data[1]==0) ? 1 : 2;
}
public FDBigInt( FDBigInt other ){
data = new int[nWords = other.nWords];
System.arraycopy( other.data, 0, data, 0, nWords );
}
private FDBigInt( int [] d, int n ){
data = d;
nWords = n;
}
public FDBigInt( long seed, char digit[], int nd0, int nd ){
int n= (nd+8)/9; // estimate size needed.
if ( n < 2 ) n = 2;
data = new int[n]; // allocate enough space
data[0] = (int)seed; // starting value
data[1] = (int)(seed>>>32);
nWords = (data[1]==0) ? 1 : 2;
int i = nd0;
int limit = nd-5; // slurp digits 5 at a time.
int v;
while ( i < limit ){
int ilim = i+5;
v = (int)digit[i++]-(int)'0';
while( i <ilim ){
v = 10*v + (int)digit[i++]-(int)'0';
}
multaddMe( 100000, v); // ... where 100000 is 10^5.
}
int factor = 1;
v = 0;
while ( i < nd ){
v = 10*v + (int)digit[i++]-(int)'0';
factor *= 10;
}
if ( factor != 1 ){
multaddMe( factor, v );
}
}
/*
* Left shift by c bits.
* Shifts this in place.
*/
public void
lshiftMe( int c )throws IllegalArgumentException {
if ( c <= 0 ){
if ( c == 0 )
return; // silly.
else
throw new IllegalArgumentException("negative shift count");
}
int wordcount = c>>5;
int bitcount = c & 0x1f;
int anticount = 32-bitcount;
int t[] = data;
int s[] = data;
if ( nWords+wordcount+1 > t.length ){
// reallocate.
t = new int[ nWords+wordcount+1 ];
}
int target = nWords+wordcount;
int src = nWords-1;
if ( bitcount == 0 ){
// special hack, since an anticount of 32 won't go!
System.arraycopy( s, 0, t, wordcount, nWords );
target = wordcount-1;
} else {
t[target--] = s[src]>>>anticount;
while ( src >= 1 ){
t[target--] = (s[src]<<bitcount) | (s[--src]>>>anticount);
}
t[target--] = s[src]<<bitcount;
}
while( target >= 0 ){
t[target--] = 0;
}
data = t;
nWords += wordcount + 1;
// may have constructed high-order word of 0.
// if so, trim it
while ( nWords > 1 && data[nWords-1] == 0 )
nWords--;
}
/*
* normalize this number by shifting until
* the MSB of the number is at 0x08000000.
* This is in preparation for quoRemIteration, below.
* The idea is that, to make division easier, we want the
* divisor to be "normalized" -- usually this means shifting
* the MSB into the high words sign bit. But because we know that
* the quotient will be 0 < q < 10, we would like to arrange that
* the dividend not span up into another word of precision.
* (This needs to be explained more clearly!)
*/
public int
normalizeMe() throws IllegalArgumentException {
int src;
int wordcount = 0;
int bitcount = 0;
int v = 0;
for ( src= nWords-1 ; src >= 0 && (v=data[src]) == 0 ; src--){
wordcount += 1;
}
if ( src < 0 ){
// oops. Value is zero. Cannot normalize it!
throw new IllegalArgumentException("zero value");
}
/*
* In most cases, we assume that wordcount is zero. This only
* makes sense, as we try not to maintain any high-order
* words full of zeros. In fact, if there are zeros, we will
* simply SHORTEN our number at this point. Watch closely...
*/
nWords -= wordcount;
/*
* Compute how far left we have to shift v s.t. its highest-
* order bit is in the right place. Then call lshiftMe to
* do the work.
*/
if ( (v & 0xf0000000) != 0 ){
// will have to shift up into the next word.
// too bad.
for( bitcount = 32 ; (v & 0xf0000000) != 0 ; bitcount-- )
v >>>= 1;
} else {
while ( v <= 0x000fffff ){
// hack: byte-at-a-time shifting
v <<= 8;
bitcount += 8;
}
while ( v <= 0x07ffffff ){
v <<= 1;
bitcount += 1;
}
}
if ( bitcount != 0 )
lshiftMe( bitcount );
return bitcount;
}
/*
* Multiply a FDBigInt by an int.
* Result is a new FDBigInt.
*/
public FDBigInt
mult( int iv ) {
long v = iv;
int r[];
long p;
// guess adequate size of r.
r = new int[ ( v * ((long)data[nWords-1]&0xffffffffL) > 0xfffffffL ) ? nWords+1 : nWords ];
p = 0L;
for( int i=0; i < nWords; i++ ) {
p += v * ((long)data[i]&0xffffffffL);
r[i] = (int)p;
p >>>= 32;
}
if ( p == 0L){
return new FDBigInt( r, nWords );
} else {
r[nWords] = (int)p;
return new FDBigInt( r, nWords+1 );
}
}
/*
* Multiply a FDBigInt by an int and add another int.
* Result is computed in place.
* Hope it fits!
*/
public void
multaddMe( int iv, int addend ) {
long v = iv;
long p;
// unroll 0th iteration, doing addition.
p = v * ((long)data[0]&0xffffffffL) + ((long)addend&0xffffffffL);
data[0] = (int)p;
p >>>= 32;
for( int i=1; i < nWords; i++ ) {
p += v * ((long)data[i]&0xffffffffL);
data[i] = (int)p;
p >>>= 32;
}
if ( p != 0L){
data[nWords] = (int)p; // will fail noisily if illegal!
nWords++;
}
}
/*
* Multiply a FDBigInt by another FDBigInt.
* Result is a new FDBigInt.
*/
public FDBigInt
mult( FDBigInt other ){
// crudely guess adequate size for r
int r[] = new int[ nWords + other.nWords ];
int i;
// I think I am promised zeros...
for( i = 0; i < this.nWords; i++ ){
long v = (long)this.data[i] & 0xffffffffL; // UNSIGNED CONVERSION
long p = 0L;
int j;
for( j = 0; j < other.nWords; j++ ){
p += ((long)r[i+j]&0xffffffffL) + v*((long)other.data[j]&0xffffffffL); // UNSIGNED CONVERSIONS ALL 'ROUND.
r[i+j] = (int)p;
p >>>= 32;
}
r[i+j] = (int)p;
}
// compute how much of r we actually needed for all that.
for ( i = r.length-1; i> 0; i--)
if ( r[i] != 0 )
break;
return new FDBigInt( r, i+1 );
}
/*
* Add one FDBigInt to another. Return a FDBigInt
*/
public FDBigInt
add( FDBigInt other ){
int i;
int a[], b[];
int n, m;
long c = 0L;
// arrange such that a.nWords >= b.nWords;
// n = a.nWords, m = b.nWords
if ( this.nWords >= other.nWords ){
a = this.data;
n = this.nWords;
b = other.data;
m = other.nWords;
} else {
a = other.data;
n = other.nWords;
b = this.data;
m = this.nWords;
}
int r[] = new int[ n ];
for ( i = 0; i < n; i++ ){
c += (long)a[i] & 0xffffffffL;
if ( i < m ){
c += (long)b[i] & 0xffffffffL;
}
r[i] = (int) c;
c >>= 32; // signed shift.
}
if ( c != 0L ){
// oops -- carry out -- need longer result.
int s[] = new int[ r.length+1 ];
System.arraycopy( r, 0, s, 0, r.length );
s[i++] = (int)c;
return new FDBigInt( s, i );
}
return new FDBigInt( r, i );
}
/*
* Subtract one FDBigInt from another. Return a FDBigInt
* Assert that the result is positive.
*/
public FDBigInt
sub( FDBigInt other ){
int r[] = new int[ this.nWords ];
int i;
int n = this.nWords;
int m = other.nWords;
int nzeros = 0;
long c = 0L;
for ( i = 0; i < n; i++ ){
c += (long)this.data[i] & 0xffffffffL;
if ( i < m ){
c -= (long)other.data[i] & 0xffffffffL;
}
if ( ( r[i] = (int) c ) == 0 )
nzeros++;
else
nzeros = 0;
c >>= 32; // signed shift
}
assert c == 0L : c; // borrow out of subtract
assert dataInRangeIsZero(i, m, other); // negative result of subtract
return new FDBigInt( r, n-nzeros );
}
private static boolean dataInRangeIsZero(int i, int m, FDBigInt other) {
while ( i < m )
if (other.data[i++] != 0)
return false;
return true;
}
/*
* Compare FDBigInt with another FDBigInt. Return an integer
* >0: this > other
* 0: this == other
* <0: this < other
*/
public int
cmp( FDBigInt other ){
int i;
if ( this.nWords > other.nWords ){
// if any of my high-order words is non-zero,
// then the answer is evident
int j = other.nWords-1;
for ( i = this.nWords-1; i > j ; i-- )
if ( this.data[i] != 0 ) return 1;
}else if ( this.nWords < other.nWords ){
// if any of other's high-order words is non-zero,
// then the answer is evident
int j = this.nWords-1;
for ( i = other.nWords-1; i > j ; i-- )
if ( other.data[i] != 0 ) return -1;
} else{
i = this.nWords-1;
}
for ( ; i > 0 ; i-- )
if ( this.data[i] != other.data[i] )
break;
// careful! want unsigned compare!
// use brute force here.
int a = this.data[i];
int b = other.data[i];
if ( a < 0 ){
// a is really big, unsigned
if ( b < 0 ){
return a-b; // both big, negative
} else {
return 1; // b not big, answer is obvious;
}
} else {
// a is not really big
if ( b < 0 ) {
// but b is really big
return -1;
} else {
return a - b;
}
}
}
/*
* Compute
* 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 lshift'ed accordingly.
* Also assume, of course, that the result, q, can be expressed
* as an integer, 0 <= q < 10.
*/
public int
quoRemIteration( FDBigInt S )throws IllegalArgumentException {
// ensure that this and S have the same number of
// digits. If S is properly normalized and q < 10 then
// this must be so.
if ( nWords != S.nWords ){
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.
int n = nWords-1;
long q = ((long)data[n]&0xffffffffL) / (long)S.data[n];
long diff = 0L;
for ( int i = 0; i <= n ; i++ ){
diff += ((long)data[i]&0xffffffffL) - q*((long)S.data[i]&0xffffffffL);
data[i] = (int)diff;
diff >>= 32; // N.B. SIGNED shift.
}
if ( diff != 0L ) {
// damn, damn, damn. q is too big.
// add S back in until this turns +. This should
// not be very many times!
long sum = 0L;
while ( sum == 0L ){
sum = 0L;
for ( int i = 0; i <= n; i++ ){
sum += ((long)data[i]&0xffffffffL) + ((long)S.data[i]&0xffffffffL);
data[i] = (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!
long p = 0L;
for ( int i = 0; i <= n; i++ ){
p += 10*((long)data[i]&0xffffffffL);
data[i] = (int)p;
p >>= 32; // SIGNED shift.
}
assert p == 0L : p; // Carry out of *10
return (int)q;
}
public long
longValue(){
// if this can be represented as a long, return the value
assert this.nWords > 0 : this.nWords; // longValue confused
if (this.nWords == 1)
return ((long)data[0]&0xffffffffL);
assert dataInRangeIsZero(2, this.nWords, this); // value too big
assert data[1] >= 0; // value too big
return ((long)(data[1]) << 32) | ((long)data[0]&0xffffffffL);
}
public String
toString() {
StringBuffer r = new StringBuffer(30);
r.append('[');
int i = Math.min( nWords-1, data.length-1) ;
if ( nWords > data.length ){
r.append( "("+data.length+"<"+nWords+"!)" );
}
for( ; i> 0 ; i-- ){
r.append( Integer.toHexString( data[i] ) );
r.append(' ');
}
r.append( Integer.toHexString( data[0] ) );
r.append(']');
return new String( r );
}
}

View File

@ -2409,470 +2409,3 @@ public class FloatingDecimal{
}
/*
* A really, really simple bigint package
* tailored to the needs of floating base conversion.
*/
class FDBigInt {
int nWords; // number of words used
int data[]; // value: data[0] is least significant
public FDBigInt( int v ){
nWords = 1;
data = new int[1];
data[0] = v;
}
public FDBigInt( long v ){
data = new int[2];
data[0] = (int)v;
data[1] = (int)(v>>>32);
nWords = (data[1]==0) ? 1 : 2;
}
public FDBigInt( FDBigInt other ){
data = new int[nWords = other.nWords];
System.arraycopy( other.data, 0, data, 0, nWords );
}
private FDBigInt( int [] d, int n ){
data = d;
nWords = n;
}
public FDBigInt( long seed, char digit[], int nd0, int nd ){
int n= (nd+8)/9; // estimate size needed.
if ( n < 2 ) n = 2;
data = new int[n]; // allocate enough space
data[0] = (int)seed; // starting value
data[1] = (int)(seed>>>32);
nWords = (data[1]==0) ? 1 : 2;
int i = nd0;
int limit = nd-5; // slurp digits 5 at a time.
int v;
while ( i < limit ){
int ilim = i+5;
v = (int)digit[i++]-(int)'0';
while( i <ilim ){
v = 10*v + (int)digit[i++]-(int)'0';
}
multaddMe( 100000, v); // ... where 100000 is 10^5.
}
int factor = 1;
v = 0;
while ( i < nd ){
v = 10*v + (int)digit[i++]-(int)'0';
factor *= 10;
}
if ( factor != 1 ){
multaddMe( factor, v );
}
}
/*
* Left shift by c bits.
* Shifts this in place.
*/
public void
lshiftMe( int c )throws IllegalArgumentException {
if ( c <= 0 ){
if ( c == 0 )
return; // silly.
else
throw new IllegalArgumentException("negative shift count");
}
int wordcount = c>>5;
int bitcount = c & 0x1f;
int anticount = 32-bitcount;
int t[] = data;
int s[] = data;
if ( nWords+wordcount+1 > t.length ){
// reallocate.
t = new int[ nWords+wordcount+1 ];
}
int target = nWords+wordcount;
int src = nWords-1;
if ( bitcount == 0 ){
// special hack, since an anticount of 32 won't go!
System.arraycopy( s, 0, t, wordcount, nWords );
target = wordcount-1;
} else {
t[target--] = s[src]>>>anticount;
while ( src >= 1 ){
t[target--] = (s[src]<<bitcount) | (s[--src]>>>anticount);
}
t[target--] = s[src]<<bitcount;
}
while( target >= 0 ){
t[target--] = 0;
}
data = t;
nWords += wordcount + 1;
// may have constructed high-order word of 0.
// if so, trim it
while ( nWords > 1 && data[nWords-1] == 0 )
nWords--;
}
/*
* normalize this number by shifting until
* the MSB of the number is at 0x08000000.
* This is in preparation for quoRemIteration, below.
* The idea is that, to make division easier, we want the
* divisor to be "normalized" -- usually this means shifting
* the MSB into the high words sign bit. But because we know that
* the quotient will be 0 < q < 10, we would like to arrange that
* the dividend not span up into another word of precision.
* (This needs to be explained more clearly!)
*/
public int
normalizeMe() throws IllegalArgumentException {
int src;
int wordcount = 0;
int bitcount = 0;
int v = 0;
for ( src= nWords-1 ; src >= 0 && (v=data[src]) == 0 ; src--){
wordcount += 1;
}
if ( src < 0 ){
// oops. Value is zero. Cannot normalize it!
throw new IllegalArgumentException("zero value");
}
/*
* In most cases, we assume that wordcount is zero. This only
* makes sense, as we try not to maintain any high-order
* words full of zeros. In fact, if there are zeros, we will
* simply SHORTEN our number at this point. Watch closely...
*/
nWords -= wordcount;
/*
* Compute how far left we have to shift v s.t. its highest-
* order bit is in the right place. Then call lshiftMe to
* do the work.
*/
if ( (v & 0xf0000000) != 0 ){
// will have to shift up into the next word.
// too bad.
for( bitcount = 32 ; (v & 0xf0000000) != 0 ; bitcount-- )
v >>>= 1;
} else {
while ( v <= 0x000fffff ){
// hack: byte-at-a-time shifting
v <<= 8;
bitcount += 8;
}
while ( v <= 0x07ffffff ){
v <<= 1;
bitcount += 1;
}
}
if ( bitcount != 0 )
lshiftMe( bitcount );
return bitcount;
}
/*
* Multiply a FDBigInt by an int.
* Result is a new FDBigInt.
*/
public FDBigInt
mult( int iv ) {
long v = iv;
int r[];
long p;
// guess adequate size of r.
r = new int[ ( v * ((long)data[nWords-1]&0xffffffffL) > 0xfffffffL ) ? nWords+1 : nWords ];
p = 0L;
for( int i=0; i < nWords; i++ ) {
p += v * ((long)data[i]&0xffffffffL);
r[i] = (int)p;
p >>>= 32;
}
if ( p == 0L){
return new FDBigInt( r, nWords );
} else {
r[nWords] = (int)p;
return new FDBigInt( r, nWords+1 );
}
}
/*
* Multiply a FDBigInt by an int and add another int.
* Result is computed in place.
* Hope it fits!
*/
public void
multaddMe( int iv, int addend ) {
long v = iv;
long p;
// unroll 0th iteration, doing addition.
p = v * ((long)data[0]&0xffffffffL) + ((long)addend&0xffffffffL);
data[0] = (int)p;
p >>>= 32;
for( int i=1; i < nWords; i++ ) {
p += v * ((long)data[i]&0xffffffffL);
data[i] = (int)p;
p >>>= 32;
}
if ( p != 0L){
data[nWords] = (int)p; // will fail noisily if illegal!
nWords++;
}
}
/*
* Multiply a FDBigInt by another FDBigInt.
* Result is a new FDBigInt.
*/
public FDBigInt
mult( FDBigInt other ){
// crudely guess adequate size for r
int r[] = new int[ nWords + other.nWords ];
int i;
// I think I am promised zeros...
for( i = 0; i < this.nWords; i++ ){
long v = (long)this.data[i] & 0xffffffffL; // UNSIGNED CONVERSION
long p = 0L;
int j;
for( j = 0; j < other.nWords; j++ ){
p += ((long)r[i+j]&0xffffffffL) + v*((long)other.data[j]&0xffffffffL); // UNSIGNED CONVERSIONS ALL 'ROUND.
r[i+j] = (int)p;
p >>>= 32;
}
r[i+j] = (int)p;
}
// compute how much of r we actually needed for all that.
for ( i = r.length-1; i> 0; i--)
if ( r[i] != 0 )
break;
return new FDBigInt( r, i+1 );
}
/*
* Add one FDBigInt to another. Return a FDBigInt
*/
public FDBigInt
add( FDBigInt other ){
int i;
int a[], b[];
int n, m;
long c = 0L;
// arrange such that a.nWords >= b.nWords;
// n = a.nWords, m = b.nWords
if ( this.nWords >= other.nWords ){
a = this.data;
n = this.nWords;
b = other.data;
m = other.nWords;
} else {
a = other.data;
n = other.nWords;
b = this.data;
m = this.nWords;
}
int r[] = new int[ n ];
for ( i = 0; i < n; i++ ){
c += (long)a[i] & 0xffffffffL;
if ( i < m ){
c += (long)b[i] & 0xffffffffL;
}
r[i] = (int) c;
c >>= 32; // signed shift.
}
if ( c != 0L ){
// oops -- carry out -- need longer result.
int s[] = new int[ r.length+1 ];
System.arraycopy( r, 0, s, 0, r.length );
s[i++] = (int)c;
return new FDBigInt( s, i );
}
return new FDBigInt( r, i );
}
/*
* Subtract one FDBigInt from another. Return a FDBigInt
* Assert that the result is positive.
*/
public FDBigInt
sub( FDBigInt other ){
int r[] = new int[ this.nWords ];
int i;
int n = this.nWords;
int m = other.nWords;
int nzeros = 0;
long c = 0L;
for ( i = 0; i < n; i++ ){
c += (long)this.data[i] & 0xffffffffL;
if ( i < m ){
c -= (long)other.data[i] & 0xffffffffL;
}
if ( ( r[i] = (int) c ) == 0 )
nzeros++;
else
nzeros = 0;
c >>= 32; // signed shift
}
assert c == 0L : c; // borrow out of subtract
assert dataInRangeIsZero(i, m, other); // negative result of subtract
return new FDBigInt( r, n-nzeros );
}
private static boolean dataInRangeIsZero(int i, int m, FDBigInt other) {
while ( i < m )
if (other.data[i++] != 0)
return false;
return true;
}
/*
* Compare FDBigInt with another FDBigInt. Return an integer
* >0: this > other
* 0: this == other
* <0: this < other
*/
public int
cmp( FDBigInt other ){
int i;
if ( this.nWords > other.nWords ){
// if any of my high-order words is non-zero,
// then the answer is evident
int j = other.nWords-1;
for ( i = this.nWords-1; i > j ; i-- )
if ( this.data[i] != 0 ) return 1;
}else if ( this.nWords < other.nWords ){
// if any of other's high-order words is non-zero,
// then the answer is evident
int j = this.nWords-1;
for ( i = other.nWords-1; i > j ; i-- )
if ( other.data[i] != 0 ) return -1;
} else{
i = this.nWords-1;
}
for ( ; i > 0 ; i-- )
if ( this.data[i] != other.data[i] )
break;
// careful! want unsigned compare!
// use brute force here.
int a = this.data[i];
int b = other.data[i];
if ( a < 0 ){
// a is really big, unsigned
if ( b < 0 ){
return a-b; // both big, negative
} else {
return 1; // b not big, answer is obvious;
}
} else {
// a is not really big
if ( b < 0 ) {
// but b is really big
return -1;
} else {
return a - b;
}
}
}
/*
* Compute
* 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 lshift'ed accordingly.
* Also assume, of course, that the result, q, can be expressed
* as an integer, 0 <= q < 10.
*/
public int
quoRemIteration( FDBigInt S )throws IllegalArgumentException {
// ensure that this and S have the same number of
// digits. If S is properly normalized and q < 10 then
// this must be so.
if ( nWords != S.nWords ){
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.
int n = nWords-1;
long q = ((long)data[n]&0xffffffffL) / (long)S.data[n];
long diff = 0L;
for ( int i = 0; i <= n ; i++ ){
diff += ((long)data[i]&0xffffffffL) - q*((long)S.data[i]&0xffffffffL);
data[i] = (int)diff;
diff >>= 32; // N.B. SIGNED shift.
}
if ( diff != 0L ) {
// damn, damn, damn. q is too big.
// add S back in until this turns +. This should
// not be very many times!
long sum = 0L;
while ( sum == 0L ){
sum = 0L;
for ( int i = 0; i <= n; i++ ){
sum += ((long)data[i]&0xffffffffL) + ((long)S.data[i]&0xffffffffL);
data[i] = (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!
long p = 0L;
for ( int i = 0; i <= n; i++ ){
p += 10*((long)data[i]&0xffffffffL);
data[i] = (int)p;
p >>= 32; // SIGNED shift.
}
assert p == 0L : p; // Carry out of *10
return (int)q;
}
public long
longValue(){
// if this can be represented as a long, return the value
assert this.nWords > 0 : this.nWords; // longValue confused
if (this.nWords == 1)
return ((long)data[0]&0xffffffffL);
assert dataInRangeIsZero(2, this.nWords, this); // value too big
assert data[1] >= 0; // value too big
return ((long)(data[1]) << 32) | ((long)data[0]&0xffffffffL);
}
public String
toString() {
StringBuffer r = new StringBuffer(30);
r.append('[');
int i = Math.min( nWords-1, data.length-1) ;
if ( nWords > data.length ){
r.append( "("+data.length+"<"+nWords+"!)" );
}
for( ; i> 0 ; i-- ){
r.append( Integer.toHexString( data[i] ) );
r.append(' ');
}
r.append( Integer.toHexString( data[0] ) );
r.append(']');
return new String( r );
}
}

View File

@ -36,11 +36,3 @@ class Event {
this.exchange = t;
}
}
class WriteFinishedEvent extends Event {
WriteFinishedEvent (ExchangeImpl t) {
super (t);
assert !t.writefinished;
t.writefinished = true;
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2005, 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 sun.net.httpserver;
class WriteFinishedEvent extends Event {
WriteFinishedEvent (ExchangeImpl t) {
super (t);
assert !t.writefinished;
t.writefinished = true;
}
}

View File

@ -0,0 +1,56 @@
/*
* 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.net.www.http;
import java.io.*;
class KeepAliveCleanerEntry
{
KeepAliveStream kas;
HttpClient hc;
public KeepAliveCleanerEntry(KeepAliveStream kas, HttpClient hc) {
this.kas = kas;
this.hc = hc;
}
protected KeepAliveStream getKeepAliveStream() {
return kas;
}
protected HttpClient getHttpClient() {
return hc;
}
protected void setQueuedForCleanup() {
kas.queuedForCleanup = true;
}
protected boolean getQueuedForCleanup() {
return kas.queuedForCleanup;
}
}

View File

@ -206,32 +206,3 @@ class KeepAliveStream extends MeteredStream implements Hurryable {
closed = true;
}
}
class KeepAliveCleanerEntry
{
KeepAliveStream kas;
HttpClient hc;
public KeepAliveCleanerEntry(KeepAliveStream kas, HttpClient hc) {
this.kas = kas;
this.hc = hc;
}
protected KeepAliveStream getKeepAliveStream() {
return kas;
}
protected HttpClient getHttpClient() {
return hc;
}
protected void setQueuedForCleanup() {
kas.queuedForCleanup = true;
}
protected boolean getQueuedForCleanup() {
return kas.queuedForCleanup;
}
}

View File

@ -0,0 +1,101 @@
/*
* 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.security.ssl;
import java.util.ArrayList;
import java.util.List;
final class ExtensionType {
final int id;
final String name;
private ExtensionType(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return name;
}
static List<ExtensionType> knownExtensions = new ArrayList<ExtensionType>(9);
static ExtensionType get(int id) {
for (ExtensionType ext : knownExtensions) {
if (ext.id == id) {
return ext;
}
}
return new ExtensionType(id, "type_" + id);
}
private static ExtensionType e(int id, String name) {
ExtensionType ext = new ExtensionType(id, name);
knownExtensions.add(ext);
return ext;
}
// extensions defined in RFC 3546
final static ExtensionType EXT_SERVER_NAME =
e(0x0000, "server_name"); // IANA registry value: 0
final static ExtensionType EXT_MAX_FRAGMENT_LENGTH =
e(0x0001, "max_fragment_length"); // IANA registry value: 1
final static ExtensionType EXT_CLIENT_CERTIFICATE_URL =
e(0x0002, "client_certificate_url"); // IANA registry value: 2
final static ExtensionType EXT_TRUSTED_CA_KEYS =
e(0x0003, "trusted_ca_keys"); // IANA registry value: 3
final static ExtensionType EXT_TRUNCATED_HMAC =
e(0x0004, "truncated_hmac"); // IANA registry value: 4
final static ExtensionType EXT_STATUS_REQUEST =
e(0x0005, "status_request"); // IANA registry value: 5
// extensions defined in RFC 4681
final static ExtensionType EXT_USER_MAPPING =
e(0x0006, "user_mapping"); // IANA registry value: 6
// extensions defined in RFC 5081
final static ExtensionType EXT_CERT_TYPE =
e(0x0009, "cert_type"); // IANA registry value: 9
// extensions defined in RFC 4492 (ECC)
final static ExtensionType EXT_ELLIPTIC_CURVES =
e(0x000A, "elliptic_curves"); // IANA registry value: 10
final static ExtensionType EXT_EC_POINT_FORMATS =
e(0x000B, "ec_point_formats"); // IANA registry value: 11
// extensions defined in RFC 5054
final static ExtensionType EXT_SRP =
e(0x000C, "srp"); // IANA registry value: 12
// extensions defined in RFC 5246
final static ExtensionType EXT_SIGNATURE_ALGORITHMS =
e(0x000D, "signature_algorithms"); // IANA registry value: 13
// extensions defined in RFC 5746
final static ExtensionType EXT_RENEGOTIATION_INFO =
e(0xff01, "renegotiation_info"); // IANA registry value: 65281
}

View File

@ -0,0 +1,45 @@
/*
* 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.security.ssl;
import java.io.IOException;
abstract class HelloExtension {
final ExtensionType type;
HelloExtension(ExtensionType type) {
this.type = type;
}
// Length of the encoded extension, including the type and length fields
abstract int length();
abstract void send(HandshakeOutStream s) throws IOException;
public abstract String toString();
}

View File

@ -153,795 +153,3 @@ final class HelloExtensions {
}
}
}
final class ExtensionType {
final int id;
final String name;
private ExtensionType(int id, String name) {
this.id = id;
this.name = name;
}
public String toString() {
return name;
}
static List<ExtensionType> knownExtensions = new ArrayList<>(9);
static ExtensionType get(int id) {
for (ExtensionType ext : knownExtensions) {
if (ext.id == id) {
return ext;
}
}
return new ExtensionType(id, "type_" + id);
}
private static ExtensionType e(int id, String name) {
ExtensionType ext = new ExtensionType(id, name);
knownExtensions.add(ext);
return ext;
}
// extensions defined in RFC 3546
final static ExtensionType EXT_SERVER_NAME =
e(0x0000, "server_name"); // IANA registry value: 0
final static ExtensionType EXT_MAX_FRAGMENT_LENGTH =
e(0x0001, "max_fragment_length"); // IANA registry value: 1
final static ExtensionType EXT_CLIENT_CERTIFICATE_URL =
e(0x0002, "client_certificate_url"); // IANA registry value: 2
final static ExtensionType EXT_TRUSTED_CA_KEYS =
e(0x0003, "trusted_ca_keys"); // IANA registry value: 3
final static ExtensionType EXT_TRUNCATED_HMAC =
e(0x0004, "truncated_hmac"); // IANA registry value: 4
final static ExtensionType EXT_STATUS_REQUEST =
e(0x0005, "status_request"); // IANA registry value: 5
// extensions defined in RFC 4681
final static ExtensionType EXT_USER_MAPPING =
e(0x0006, "user_mapping"); // IANA registry value: 6
// extensions defined in RFC 5081
final static ExtensionType EXT_CERT_TYPE =
e(0x0009, "cert_type"); // IANA registry value: 9
// extensions defined in RFC 4492 (ECC)
final static ExtensionType EXT_ELLIPTIC_CURVES =
e(0x000A, "elliptic_curves"); // IANA registry value: 10
final static ExtensionType EXT_EC_POINT_FORMATS =
e(0x000B, "ec_point_formats"); // IANA registry value: 11
// extensions defined in RFC 5054
final static ExtensionType EXT_SRP =
e(0x000C, "srp"); // IANA registry value: 12
// extensions defined in RFC 5246
final static ExtensionType EXT_SIGNATURE_ALGORITHMS =
e(0x000D, "signature_algorithms"); // IANA registry value: 13
// extensions defined in RFC 5746
final static ExtensionType EXT_RENEGOTIATION_INFO =
e(0xff01, "renegotiation_info"); // IANA registry value: 65281
}
abstract class HelloExtension {
final ExtensionType type;
HelloExtension(ExtensionType type) {
this.type = type;
}
// Length of the encoded extension, including the type and length fields
abstract int length();
abstract void send(HandshakeOutStream s) throws IOException;
public abstract String toString();
}
final class UnknownExtension extends HelloExtension {
private final byte[] data;
UnknownExtension(HandshakeInStream s, int len, ExtensionType type)
throws IOException {
super(type);
data = new byte[len];
// s.read() does not handle 0-length arrays.
if (len != 0) {
s.read(data);
}
}
int length() {
return 4 + data.length;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putBytes16(data);
}
public String toString() {
return "Unsupported extension " + type + ", data: " +
Debug.toString(data);
}
}
/*
* [RFC 4366/6066] To facilitate secure connections to servers that host
* multiple 'virtual' servers at a single underlying network address, clients
* MAY include an extension of type "server_name" in the (extended) client
* hello. The "extension_data" field of this extension SHALL contain
* "ServerNameList" where:
*
* struct {
* NameType name_type;
* select (name_type) {
* case host_name: HostName;
* } name;
* } ServerName;
*
* enum {
* host_name(0), (255)
* } NameType;
*
* opaque HostName<1..2^16-1>;
*
* struct {
* ServerName server_name_list<1..2^16-1>
* } ServerNameList;
*/
final class ServerNameExtension extends HelloExtension {
// For backward compatibility, all future data structures associated with
// new NameTypes MUST begin with a 16-bit length field.
final static int NAME_HEADER_LENGTH = 3; // NameType: 1 byte
// Name length: 2 bytes
private Map<Integer, SNIServerName> sniMap;
private int listLength; // ServerNameList length
// constructor for ServerHello
ServerNameExtension() throws IOException {
super(ExtensionType.EXT_SERVER_NAME);
listLength = 0;
sniMap = Collections.<Integer, SNIServerName>emptyMap();
}
// constructor for ClientHello
ServerNameExtension(List<SNIServerName> serverNames)
throws IOException {
super(ExtensionType.EXT_SERVER_NAME);
listLength = 0;
sniMap = new LinkedHashMap<>();
for (SNIServerName serverName : serverNames) {
// check for duplicated server name type
if (sniMap.put(serverName.getType(), serverName) != null) {
// unlikely to happen, but in case ...
throw new RuntimeException(
"Duplicated server name of type " + serverName.getType());
}
listLength += serverName.getEncoded().length + NAME_HEADER_LENGTH;
}
// This constructor is used for ClientHello only. Empty list is
// not allowed in client mode.
if (listLength == 0) {
throw new RuntimeException("The ServerNameList cannot be empty");
}
}
// constructor for ServerHello for parsing SNI extension
ServerNameExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_SERVER_NAME);
int remains = len;
if (len >= 2) { // "server_name" extension in ClientHello
listLength = s.getInt16(); // ServerNameList length
if (listLength == 0 || listLength + 2 != len) {
throw new SSLProtocolException(
"Invalid " + type + " extension");
}
remains -= 2;
sniMap = new LinkedHashMap<>();
while (remains > 0) {
int code = s.getInt8(); // NameType
// HostName (length read in getBytes16);
byte[] encoded = s.getBytes16();
SNIServerName serverName;
switch (code) {
case StandardConstants.SNI_HOST_NAME:
if (encoded.length == 0) {
throw new SSLProtocolException(
"Empty HostName in server name indication");
}
try {
serverName = new SNIHostName(encoded);
} catch (IllegalArgumentException iae) {
SSLProtocolException spe = new SSLProtocolException(
"Illegal server name, type=host_name(" +
code + "), name=" +
(new String(encoded, StandardCharsets.UTF_8)) +
", value=" + Debug.toString(encoded));
spe.initCause(iae);
throw spe;
}
break;
default:
try {
serverName = new UnknownServerName(code, encoded);
} catch (IllegalArgumentException iae) {
SSLProtocolException spe = new SSLProtocolException(
"Illegal server name, type=(" + code +
"), value=" + Debug.toString(encoded));
spe.initCause(iae);
throw spe;
}
}
// check for duplicated server name type
if (sniMap.put(serverName.getType(), serverName) != null) {
throw new SSLProtocolException(
"Duplicated server name of type " +
serverName.getType());
}
remains -= encoded.length + NAME_HEADER_LENGTH;
}
} else if (len == 0) { // "server_name" extension in ServerHello
listLength = 0;
sniMap = Collections.<Integer, SNIServerName>emptyMap();
}
if (remains != 0) {
throw new SSLProtocolException("Invalid server_name extension");
}
}
List<SNIServerName> getServerNames() {
if (sniMap != null && !sniMap.isEmpty()) {
return Collections.<SNIServerName>unmodifiableList(
new ArrayList<>(sniMap.values()));
}
return Collections.<SNIServerName>emptyList();
}
/*
* Is the extension recognized by the corresponding matcher?
*
* This method is used to check whether the server name indication can
* be recognized by the server name matchers.
*
* Per RFC 6066, if the server understood the ClientHello extension but
* does not recognize the server name, the server SHOULD take one of two
* actions: either abort the handshake by sending a fatal-level
* unrecognized_name(112) alert or continue the handshake.
*
* If there is an instance of SNIMatcher defined for a particular name
* type, it must be used to perform match operations on the server name.
*/
boolean isMatched(Collection<SNIMatcher> matchers) {
if (sniMap != null && !sniMap.isEmpty()) {
for (SNIMatcher matcher : matchers) {
SNIServerName sniName = sniMap.get(matcher.getType());
if (sniName != null && (!matcher.matches(sniName))) {
return false;
}
}
}
return true;
}
/*
* Is the extension is identical to a server name list?
*
* This method is used to check the server name indication during session
* resumption.
*
* Per RFC 6066, when the server is deciding whether or not to accept a
* request to resume a session, the contents of a server_name extension
* MAY be used in the lookup of the session in the session cache. The
* client SHOULD include the same server_name extension in the session
* resumption request as it did in the full handshake that established
* the session. A server that implements this extension MUST NOT accept
* the request to resume the session if the server_name extension contains
* a different name. Instead, it proceeds with a full handshake to
* establish a new session. When resuming a session, the server MUST NOT
* include a server_name extension in the server hello.
*/
boolean isIdentical(List<SNIServerName> other) {
if (other.size() == sniMap.size()) {
for(SNIServerName sniInOther : other) {
SNIServerName sniName = sniMap.get(sniInOther.getType());
if (sniName == null || !sniInOther.equals(sniName)) {
return false;
}
}
return true;
}
return false;
}
int length() {
return listLength == 0 ? 4 : 6 + listLength;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
if (listLength == 0) {
s.putInt16(listLength); // in ServerHello, empty extension_data
} else {
s.putInt16(listLength + 2); // length of extension_data
s.putInt16(listLength); // length of ServerNameList
for (SNIServerName sniName : sniMap.values()) {
s.putInt8(sniName.getType()); // server name type
s.putBytes16(sniName.getEncoded()); // server name value
}
}
}
public String toString() {
StringBuffer buffer = new StringBuffer();
for (SNIServerName sniName : sniMap.values()) {
buffer.append("[" + sniName + "]");
}
return "Extension " + type + ", server_name: " + buffer;
}
private static class UnknownServerName extends SNIServerName {
UnknownServerName(int code, byte[] encoded) {
super(code, encoded);
}
}
}
final class SupportedEllipticCurvesExtension extends HelloExtension {
// the extension value to send in the ClientHello message
static final SupportedEllipticCurvesExtension DEFAULT;
private static final boolean fips;
static {
int[] ids;
fips = SunJSSE.isFIPS();
if (fips == false) {
ids = new int[] {
// NIST curves first
// prefer NIST P-256, rest in order of increasing key length
23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14,
// non-NIST curves
15, 16, 17, 2, 18, 4, 5, 20, 8, 22,
};
} else {
ids = new int[] {
// same as above, but allow only NIST curves in FIPS mode
23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14,
};
}
DEFAULT = new SupportedEllipticCurvesExtension(ids);
}
private final int[] curveIds;
private SupportedEllipticCurvesExtension(int[] curveIds) {
super(ExtensionType.EXT_ELLIPTIC_CURVES);
this.curveIds = curveIds;
}
SupportedEllipticCurvesExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_ELLIPTIC_CURVES);
int k = s.getInt16();
if (((len & 1) != 0) || (k + 2 != len)) {
throw new SSLProtocolException("Invalid " + type + " extension");
}
curveIds = new int[k >> 1];
for (int i = 0; i < curveIds.length; i++) {
curveIds[i] = s.getInt16();
}
}
boolean contains(int index) {
for (int curveId : curveIds) {
if (index == curveId) {
return true;
}
}
return false;
}
// Return a reference to the internal curveIds array.
// The caller must NOT modify the contents.
int[] curveIds() {
return curveIds;
}
int length() {
return 6 + (curveIds.length << 1);
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
int k = curveIds.length << 1;
s.putInt16(k + 2);
s.putInt16(k);
for (int curveId : curveIds) {
s.putInt16(curveId);
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Extension " + type + ", curve names: {");
boolean first = true;
for (int curveId : curveIds) {
if (first) {
first = false;
} else {
sb.append(", ");
}
// first check if it is a known named curve, then try other cases.
String oid = getCurveOid(curveId);
if (oid != null) {
ECParameterSpec spec = JsseJce.getECParameterSpec(oid);
// this toString() output will look nice for the current
// implementation of the ECParameterSpec class in the Sun
// provider, but may not look good for other implementations.
if (spec != null) {
sb.append(spec.toString().split(" ")[0]);
} else {
sb.append(oid);
}
} else if (curveId == ARBITRARY_PRIME) {
sb.append("arbitrary_explicit_prime_curves");
} else if (curveId == ARBITRARY_CHAR2) {
sb.append("arbitrary_explicit_char2_curves");
} else {
sb.append("unknown curve " + curveId);
}
}
sb.append("}");
return sb.toString();
}
// Test whether we support the curve with the given index.
static boolean isSupported(int index) {
if ((index <= 0) || (index >= NAMED_CURVE_OID_TABLE.length)) {
return false;
}
if (fips == false) {
// in non-FIPS mode, we support all valid indices
return true;
}
return DEFAULT.contains(index);
}
static int getCurveIndex(ECParameterSpec params) {
String oid = JsseJce.getNamedCurveOid(params);
if (oid == null) {
return -1;
}
Integer n = curveIndices.get(oid);
return (n == null) ? -1 : n;
}
static String getCurveOid(int index) {
if ((index > 0) && (index < NAMED_CURVE_OID_TABLE.length)) {
return NAMED_CURVE_OID_TABLE[index];
}
return null;
}
private final static int ARBITRARY_PRIME = 0xff01;
private final static int ARBITRARY_CHAR2 = 0xff02;
// See sun.security.ec.NamedCurve for the OIDs
private final static String[] NAMED_CURVE_OID_TABLE = new String[] {
null, // (0) unused
"1.3.132.0.1", // (1) sect163k1, NIST K-163
"1.3.132.0.2", // (2) sect163r1
"1.3.132.0.15", // (3) sect163r2, NIST B-163
"1.3.132.0.24", // (4) sect193r1
"1.3.132.0.25", // (5) sect193r2
"1.3.132.0.26", // (6) sect233k1, NIST K-233
"1.3.132.0.27", // (7) sect233r1, NIST B-233
"1.3.132.0.3", // (8) sect239k1
"1.3.132.0.16", // (9) sect283k1, NIST K-283
"1.3.132.0.17", // (10) sect283r1, NIST B-283
"1.3.132.0.36", // (11) sect409k1, NIST K-409
"1.3.132.0.37", // (12) sect409r1, NIST B-409
"1.3.132.0.38", // (13) sect571k1, NIST K-571
"1.3.132.0.39", // (14) sect571r1, NIST B-571
"1.3.132.0.9", // (15) secp160k1
"1.3.132.0.8", // (16) secp160r1
"1.3.132.0.30", // (17) secp160r2
"1.3.132.0.31", // (18) secp192k1
"1.2.840.10045.3.1.1", // (19) secp192r1, NIST P-192
"1.3.132.0.32", // (20) secp224k1
"1.3.132.0.33", // (21) secp224r1, NIST P-224
"1.3.132.0.10", // (22) secp256k1
"1.2.840.10045.3.1.7", // (23) secp256r1, NIST P-256
"1.3.132.0.34", // (24) secp384r1, NIST P-384
"1.3.132.0.35", // (25) secp521r1, NIST P-521
};
private final static Map<String,Integer> curveIndices;
static {
curveIndices = new HashMap<String,Integer>();
for (int i = 1; i < NAMED_CURVE_OID_TABLE.length; i++) {
curveIndices.put(NAMED_CURVE_OID_TABLE[i], i);
}
}
}
final class SupportedEllipticPointFormatsExtension extends HelloExtension {
final static int FMT_UNCOMPRESSED = 0;
final static int FMT_ANSIX962_COMPRESSED_PRIME = 1;
final static int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;
static final HelloExtension DEFAULT =
new SupportedEllipticPointFormatsExtension(
new byte[] {FMT_UNCOMPRESSED});
private final byte[] formats;
private SupportedEllipticPointFormatsExtension(byte[] formats) {
super(ExtensionType.EXT_EC_POINT_FORMATS);
this.formats = formats;
}
SupportedEllipticPointFormatsExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_EC_POINT_FORMATS);
formats = s.getBytes8();
// RFC 4492 says uncompressed points must always be supported.
// Check just to make sure.
boolean uncompressed = false;
for (int format : formats) {
if (format == FMT_UNCOMPRESSED) {
uncompressed = true;
break;
}
}
if (uncompressed == false) {
throw new SSLProtocolException
("Peer does not support uncompressed points");
}
}
int length() {
return 5 + formats.length;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putInt16(formats.length + 1);
s.putBytes8(formats);
}
private static String toString(byte format) {
int f = format & 0xff;
switch (f) {
case FMT_UNCOMPRESSED:
return "uncompressed";
case FMT_ANSIX962_COMPRESSED_PRIME:
return "ansiX962_compressed_prime";
case FMT_ANSIX962_COMPRESSED_CHAR2:
return "ansiX962_compressed_char2";
default:
return "unknown-" + f;
}
}
public String toString() {
List<String> list = new ArrayList<>();
for (byte format : formats) {
list.add(toString(format));
}
return "Extension " + type + ", formats: " + list;
}
}
/*
* For secure renegotiation, RFC5746 defines a new TLS extension,
* "renegotiation_info" (with extension type 0xff01), which contains a
* cryptographic binding to the enclosing TLS connection (if any) for
* which the renegotiation is being performed. The "extension data"
* field of this extension contains a "RenegotiationInfo" structure:
*
* struct {
* opaque renegotiated_connection<0..255>;
* } RenegotiationInfo;
*/
final class RenegotiationInfoExtension extends HelloExtension {
private final byte[] renegotiated_connection;
RenegotiationInfoExtension(byte[] clientVerifyData,
byte[] serverVerifyData) {
super(ExtensionType.EXT_RENEGOTIATION_INFO);
if (clientVerifyData.length != 0) {
renegotiated_connection =
new byte[clientVerifyData.length + serverVerifyData.length];
System.arraycopy(clientVerifyData, 0, renegotiated_connection,
0, clientVerifyData.length);
if (serverVerifyData.length != 0) {
System.arraycopy(serverVerifyData, 0, renegotiated_connection,
clientVerifyData.length, serverVerifyData.length);
}
} else {
// ignore both the client and server verify data.
renegotiated_connection = new byte[0];
}
}
RenegotiationInfoExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_RENEGOTIATION_INFO);
// check the extension length
if (len < 1) {
throw new SSLProtocolException("Invalid " + type + " extension");
}
int renegoInfoDataLen = s.getInt8();
if (renegoInfoDataLen + 1 != len) { // + 1 = the byte we just read
throw new SSLProtocolException("Invalid " + type + " extension");
}
renegotiated_connection = new byte[renegoInfoDataLen];
if (renegoInfoDataLen != 0) {
s.read(renegotiated_connection, 0, renegoInfoDataLen);
}
}
// Length of the encoded extension, including the type and length fields
int length() {
return 5 + renegotiated_connection.length;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putInt16(renegotiated_connection.length + 1);
s.putBytes8(renegotiated_connection);
}
boolean isEmpty() {
return renegotiated_connection.length == 0;
}
byte[] getRenegotiatedConnection() {
return renegotiated_connection;
}
public String toString() {
return "Extension " + type + ", renegotiated_connection: " +
(renegotiated_connection.length == 0 ? "<empty>" :
Debug.toString(renegotiated_connection));
}
}
/*
* [RFC5246] The client uses the "signature_algorithms" extension to
* indicate to the server which signature/hash algorithm pairs may be
* used in digital signatures. The "extension_data" field of this
* extension contains a "supported_signature_algorithms" value.
*
* enum {
* none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
* sha512(6), (255)
* } HashAlgorithm;
*
* enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
* SignatureAlgorithm;
*
* struct {
* HashAlgorithm hash;
* SignatureAlgorithm signature;
* } SignatureAndHashAlgorithm;
*
* SignatureAndHashAlgorithm
* supported_signature_algorithms<2..2^16-2>;
*/
final class SignatureAlgorithmsExtension extends HelloExtension {
private Collection<SignatureAndHashAlgorithm> algorithms;
private int algorithmsLen; // length of supported_signature_algorithms
SignatureAlgorithmsExtension(
Collection<SignatureAndHashAlgorithm> signAlgs) {
super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);
algorithmsLen =
SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();
}
SignatureAlgorithmsExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
algorithmsLen = s.getInt16();
if (algorithmsLen == 0 || algorithmsLen + 2 != len) {
throw new SSLProtocolException("Invalid " + type + " extension");
}
algorithms = new ArrayList<SignatureAndHashAlgorithm>();
int remains = algorithmsLen;
int sequence = 0;
while (remains > 1) { // needs at least two bytes
int hash = s.getInt8(); // hash algorithm
int signature = s.getInt8(); // signature algorithm
SignatureAndHashAlgorithm algorithm =
SignatureAndHashAlgorithm.valueOf(hash, signature, ++sequence);
algorithms.add(algorithm);
remains -= 2; // one byte for hash, one byte for signature
}
if (remains != 0) {
throw new SSLProtocolException("Invalid server_name extension");
}
}
Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
return algorithms;
}
@Override
int length() {
return 6 + algorithmsLen;
}
@Override
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putInt16(algorithmsLen + 2);
s.putInt16(algorithmsLen);
for (SignatureAndHashAlgorithm algorithm : algorithms) {
s.putInt8(algorithm.getHashValue()); // HashAlgorithm
s.putInt8(algorithm.getSignatureValue()); // SignatureAlgorithm
}
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
boolean opened = false;
for (SignatureAndHashAlgorithm signAlg : algorithms) {
if (opened) {
buffer.append(", " + signAlg.getAlgorithmName());
} else {
buffer.append(signAlg.getAlgorithmName());
opened = true;
}
}
return "Extension " + type + ", signature_algorithms: " + buffer;
}
}

View File

@ -0,0 +1,112 @@
/*
* 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.security.ssl;
import java.io.IOException;
import javax.net.ssl.SSLProtocolException;
/*
* For secure renegotiation, RFC5746 defines a new TLS extension,
* "renegotiation_info" (with extension type 0xff01), which contains a
* cryptographic binding to the enclosing TLS connection (if any) for
* which the renegotiation is being performed. The "extension data"
* field of this extension contains a "RenegotiationInfo" structure:
*
* struct {
* opaque renegotiated_connection<0..255>;
* } RenegotiationInfo;
*/
final class RenegotiationInfoExtension extends HelloExtension {
private final byte[] renegotiated_connection;
RenegotiationInfoExtension(byte[] clientVerifyData,
byte[] serverVerifyData) {
super(ExtensionType.EXT_RENEGOTIATION_INFO);
if (clientVerifyData.length != 0) {
renegotiated_connection =
new byte[clientVerifyData.length + serverVerifyData.length];
System.arraycopy(clientVerifyData, 0, renegotiated_connection,
0, clientVerifyData.length);
if (serverVerifyData.length != 0) {
System.arraycopy(serverVerifyData, 0, renegotiated_connection,
clientVerifyData.length, serverVerifyData.length);
}
} else {
// ignore both the client and server verify data.
renegotiated_connection = new byte[0];
}
}
RenegotiationInfoExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_RENEGOTIATION_INFO);
// check the extension length
if (len < 1) {
throw new SSLProtocolException("Invalid " + type + " extension");
}
int renegoInfoDataLen = s.getInt8();
if (renegoInfoDataLen + 1 != len) { // + 1 = the byte we just read
throw new SSLProtocolException("Invalid " + type + " extension");
}
renegotiated_connection = new byte[renegoInfoDataLen];
if (renegoInfoDataLen != 0) {
s.read(renegotiated_connection, 0, renegoInfoDataLen);
}
}
// Length of the encoded extension, including the type and length fields
int length() {
return 5 + renegotiated_connection.length;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putInt16(renegotiated_connection.length + 1);
s.putBytes8(renegotiated_connection);
}
boolean isEmpty() {
return renegotiated_connection.length == 0;
}
byte[] getRenegotiatedConnection() {
return renegotiated_connection;
}
public String toString() {
return "Extension " + type + ", renegotiated_connection: " +
(renegotiated_connection.length == 0 ? "<empty>" :
Debug.toString(renegotiated_connection));
}
}

View File

@ -0,0 +1,280 @@
/*
* 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.security.ssl;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.LinkedHashMap;
import java.util.Map;
import javax.net.ssl.SNIHostName;
import javax.net.ssl.SNIMatcher;
import javax.net.ssl.SNIServerName;
import javax.net.ssl.SSLProtocolException;
import javax.net.ssl.StandardConstants;
/*
* [RFC 4366/6066] To facilitate secure connections to servers that host
* multiple 'virtual' servers at a single underlying network address, clients
* MAY include an extension of type "server_name" in the (extended) client
* hello. The "extension_data" field of this extension SHALL contain
* "ServerNameList" where:
*
* struct {
* NameType name_type;
* select (name_type) {
* case host_name: HostName;
* } name;
* } ServerName;
*
* enum {
* host_name(0), (255)
* } NameType;
*
* opaque HostName<1..2^16-1>;
*
* struct {
* ServerName server_name_list<1..2^16-1>
* } ServerNameList;
*/
final class ServerNameExtension extends HelloExtension {
// For backward compatibility, all future data structures associated with
// new NameTypes MUST begin with a 16-bit length field.
final static int NAME_HEADER_LENGTH = 3; // NameType: 1 byte
// Name length: 2 bytes
private Map<Integer, SNIServerName> sniMap;
private int listLength; // ServerNameList length
// constructor for ServerHello
ServerNameExtension() throws IOException {
super(ExtensionType.EXT_SERVER_NAME);
listLength = 0;
sniMap = Collections.<Integer, SNIServerName>emptyMap();
}
// constructor for ClientHello
ServerNameExtension(List<SNIServerName> serverNames)
throws IOException {
super(ExtensionType.EXT_SERVER_NAME);
listLength = 0;
sniMap = new LinkedHashMap<>();
for (SNIServerName serverName : serverNames) {
// check for duplicated server name type
if (sniMap.put(serverName.getType(), serverName) != null) {
// unlikely to happen, but in case ...
throw new RuntimeException(
"Duplicated server name of type " + serverName.getType());
}
listLength += serverName.getEncoded().length + NAME_HEADER_LENGTH;
}
// This constructor is used for ClientHello only. Empty list is
// not allowed in client mode.
if (listLength == 0) {
throw new RuntimeException("The ServerNameList cannot be empty");
}
}
// constructor for ServerHello for parsing SNI extension
ServerNameExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_SERVER_NAME);
int remains = len;
if (len >= 2) { // "server_name" extension in ClientHello
listLength = s.getInt16(); // ServerNameList length
if (listLength == 0 || listLength + 2 != len) {
throw new SSLProtocolException(
"Invalid " + type + " extension");
}
remains -= 2;
sniMap = new LinkedHashMap<>();
while (remains > 0) {
int code = s.getInt8(); // NameType
// HostName (length read in getBytes16);
byte[] encoded = s.getBytes16();
SNIServerName serverName;
switch (code) {
case StandardConstants.SNI_HOST_NAME:
if (encoded.length == 0) {
throw new SSLProtocolException(
"Empty HostName in server name indication");
}
try {
serverName = new SNIHostName(encoded);
} catch (IllegalArgumentException iae) {
SSLProtocolException spe = new SSLProtocolException(
"Illegal server name, type=host_name(" +
code + "), name=" +
(new String(encoded, StandardCharsets.UTF_8)) +
", value=" + Debug.toString(encoded));
spe.initCause(iae);
throw spe;
}
break;
default:
try {
serverName = new UnknownServerName(code, encoded);
} catch (IllegalArgumentException iae) {
SSLProtocolException spe = new SSLProtocolException(
"Illegal server name, type=(" + code +
"), value=" + Debug.toString(encoded));
spe.initCause(iae);
throw spe;
}
}
// check for duplicated server name type
if (sniMap.put(serverName.getType(), serverName) != null) {
throw new SSLProtocolException(
"Duplicated server name of type " +
serverName.getType());
}
remains -= encoded.length + NAME_HEADER_LENGTH;
}
} else if (len == 0) { // "server_name" extension in ServerHello
listLength = 0;
sniMap = Collections.<Integer, SNIServerName>emptyMap();
}
if (remains != 0) {
throw new SSLProtocolException("Invalid server_name extension");
}
}
List<SNIServerName> getServerNames() {
if (sniMap != null && !sniMap.isEmpty()) {
return Collections.<SNIServerName>unmodifiableList(
new ArrayList<>(sniMap.values()));
}
return Collections.<SNIServerName>emptyList();
}
/*
* Is the extension recognized by the corresponding matcher?
*
* This method is used to check whether the server name indication can
* be recognized by the server name matchers.
*
* Per RFC 6066, if the server understood the ClientHello extension but
* does not recognize the server name, the server SHOULD take one of two
* actions: either abort the handshake by sending a fatal-level
* unrecognized_name(112) alert or continue the handshake.
*
* If there is an instance of SNIMatcher defined for a particular name
* type, it must be used to perform match operations on the server name.
*/
boolean isMatched(Collection<SNIMatcher> matchers) {
if (sniMap != null && !sniMap.isEmpty()) {
for (SNIMatcher matcher : matchers) {
SNIServerName sniName = sniMap.get(matcher.getType());
if (sniName != null && (!matcher.matches(sniName))) {
return false;
}
}
}
return true;
}
/*
* Is the extension is identical to a server name list?
*
* This method is used to check the server name indication during session
* resumption.
*
* Per RFC 6066, when the server is deciding whether or not to accept a
* request to resume a session, the contents of a server_name extension
* MAY be used in the lookup of the session in the session cache. The
* client SHOULD include the same server_name extension in the session
* resumption request as it did in the full handshake that established
* the session. A server that implements this extension MUST NOT accept
* the request to resume the session if the server_name extension contains
* a different name. Instead, it proceeds with a full handshake to
* establish a new session. When resuming a session, the server MUST NOT
* include a server_name extension in the server hello.
*/
boolean isIdentical(List<SNIServerName> other) {
if (other.size() == sniMap.size()) {
for(SNIServerName sniInOther : other) {
SNIServerName sniName = sniMap.get(sniInOther.getType());
if (sniName == null || !sniInOther.equals(sniName)) {
return false;
}
}
return true;
}
return false;
}
int length() {
return listLength == 0 ? 4 : 6 + listLength;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
if (listLength == 0) {
s.putInt16(listLength); // in ServerHello, empty extension_data
} else {
s.putInt16(listLength + 2); // length of extension_data
s.putInt16(listLength); // length of ServerNameList
for (SNIServerName sniName : sniMap.values()) {
s.putInt8(sniName.getType()); // server name type
s.putBytes16(sniName.getEncoded()); // server name value
}
}
}
public String toString() {
StringBuffer buffer = new StringBuffer();
for (SNIServerName sniName : sniMap.values()) {
buffer.append("[" + sniName + "]");
}
return "Extension " + type + ", server_name: " + buffer;
}
private static class UnknownServerName extends SNIServerName {
UnknownServerName(int code, byte[] encoded) {
super(code, encoded);
}
}
}

View File

@ -0,0 +1,135 @@
/*
* 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.security.ssl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import javax.net.ssl.SSLProtocolException;
/*
* [RFC5246] The client uses the "signature_algorithms" extension to
* indicate to the server which signature/hash algorithm pairs may be
* used in digital signatures. The "extension_data" field of this
* extension contains a "supported_signature_algorithms" value.
*
* enum {
* none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
* sha512(6), (255)
* } HashAlgorithm;
*
* enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
* SignatureAlgorithm;
*
* struct {
* HashAlgorithm hash;
* SignatureAlgorithm signature;
* } SignatureAndHashAlgorithm;
*
* SignatureAndHashAlgorithm
* supported_signature_algorithms<2..2^16-2>;
*/
final class SignatureAlgorithmsExtension extends HelloExtension {
private Collection<SignatureAndHashAlgorithm> algorithms;
private int algorithmsLen; // length of supported_signature_algorithms
SignatureAlgorithmsExtension(
Collection<SignatureAndHashAlgorithm> signAlgs) {
super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
algorithms = new ArrayList<SignatureAndHashAlgorithm>(signAlgs);
algorithmsLen =
SignatureAndHashAlgorithm.sizeInRecord() * algorithms.size();
}
SignatureAlgorithmsExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_SIGNATURE_ALGORITHMS);
algorithmsLen = s.getInt16();
if (algorithmsLen == 0 || algorithmsLen + 2 != len) {
throw new SSLProtocolException("Invalid " + type + " extension");
}
algorithms = new ArrayList<SignatureAndHashAlgorithm>();
int remains = algorithmsLen;
int sequence = 0;
while (remains > 1) { // needs at least two bytes
int hash = s.getInt8(); // hash algorithm
int signature = s.getInt8(); // signature algorithm
SignatureAndHashAlgorithm algorithm =
SignatureAndHashAlgorithm.valueOf(hash, signature, ++sequence);
algorithms.add(algorithm);
remains -= 2; // one byte for hash, one byte for signature
}
if (remains != 0) {
throw new SSLProtocolException("Invalid server_name extension");
}
}
Collection<SignatureAndHashAlgorithm> getSignAlgorithms() {
return algorithms;
}
@Override
int length() {
return 6 + algorithmsLen;
}
@Override
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putInt16(algorithmsLen + 2);
s.putInt16(algorithmsLen);
for (SignatureAndHashAlgorithm algorithm : algorithms) {
s.putInt8(algorithm.getHashValue()); // HashAlgorithm
s.putInt8(algorithm.getSignatureValue()); // SignatureAlgorithm
}
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
boolean opened = false;
for (SignatureAndHashAlgorithm signAlg : algorithms) {
if (opened) {
buffer.append(", " + signAlg.getAlgorithmName());
} else {
buffer.append(signAlg.getAlgorithmName());
opened = true;
}
}
return "Extension " + type + ", signature_algorithms: " + buffer;
}
}

View File

@ -0,0 +1,215 @@
/*
* 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.security.ssl;
import java.io.IOException;
import java.security.spec.ECParameterSpec;
import java.util.HashMap;
import java.util.Map;
import javax.net.ssl.SSLProtocolException;
final class SupportedEllipticCurvesExtension extends HelloExtension {
// the extension value to send in the ClientHello message
static final SupportedEllipticCurvesExtension DEFAULT;
private static final boolean fips;
static {
int[] ids;
fips = SunJSSE.isFIPS();
if (fips == false) {
ids = new int[] {
// NIST curves first
// prefer NIST P-256, rest in order of increasing key length
23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14,
// non-NIST curves
15, 16, 17, 2, 18, 4, 5, 20, 8, 22,
};
} else {
ids = new int[] {
// same as above, but allow only NIST curves in FIPS mode
23, 1, 3, 19, 21, 6, 7, 9, 10, 24, 11, 12, 25, 13, 14,
};
}
DEFAULT = new SupportedEllipticCurvesExtension(ids);
}
private final int[] curveIds;
private SupportedEllipticCurvesExtension(int[] curveIds) {
super(ExtensionType.EXT_ELLIPTIC_CURVES);
this.curveIds = curveIds;
}
SupportedEllipticCurvesExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_ELLIPTIC_CURVES);
int k = s.getInt16();
if (((len & 1) != 0) || (k + 2 != len)) {
throw new SSLProtocolException("Invalid " + type + " extension");
}
curveIds = new int[k >> 1];
for (int i = 0; i < curveIds.length; i++) {
curveIds[i] = s.getInt16();
}
}
boolean contains(int index) {
for (int curveId : curveIds) {
if (index == curveId) {
return true;
}
}
return false;
}
// Return a reference to the internal curveIds array.
// The caller must NOT modify the contents.
int[] curveIds() {
return curveIds;
}
int length() {
return 6 + (curveIds.length << 1);
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
int k = curveIds.length << 1;
s.putInt16(k + 2);
s.putInt16(k);
for (int curveId : curveIds) {
s.putInt16(curveId);
}
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("Extension " + type + ", curve names: {");
boolean first = true;
for (int curveId : curveIds) {
if (first) {
first = false;
} else {
sb.append(", ");
}
// first check if it is a known named curve, then try other cases.
String oid = getCurveOid(curveId);
if (oid != null) {
ECParameterSpec spec = JsseJce.getECParameterSpec(oid);
// this toString() output will look nice for the current
// implementation of the ECParameterSpec class in the Sun
// provider, but may not look good for other implementations.
if (spec != null) {
sb.append(spec.toString().split(" ")[0]);
} else {
sb.append(oid);
}
} else if (curveId == ARBITRARY_PRIME) {
sb.append("arbitrary_explicit_prime_curves");
} else if (curveId == ARBITRARY_CHAR2) {
sb.append("arbitrary_explicit_char2_curves");
} else {
sb.append("unknown curve " + curveId);
}
}
sb.append("}");
return sb.toString();
}
// Test whether we support the curve with the given index.
static boolean isSupported(int index) {
if ((index <= 0) || (index >= NAMED_CURVE_OID_TABLE.length)) {
return false;
}
if (fips == false) {
// in non-FIPS mode, we support all valid indices
return true;
}
return DEFAULT.contains(index);
}
static int getCurveIndex(ECParameterSpec params) {
String oid = JsseJce.getNamedCurveOid(params);
if (oid == null) {
return -1;
}
Integer n = curveIndices.get(oid);
return (n == null) ? -1 : n;
}
static String getCurveOid(int index) {
if ((index > 0) && (index < NAMED_CURVE_OID_TABLE.length)) {
return NAMED_CURVE_OID_TABLE[index];
}
return null;
}
private final static int ARBITRARY_PRIME = 0xff01;
private final static int ARBITRARY_CHAR2 = 0xff02;
// See sun.security.ec.NamedCurve for the OIDs
private final static String[] NAMED_CURVE_OID_TABLE = new String[] {
null, // (0) unused
"1.3.132.0.1", // (1) sect163k1, NIST K-163
"1.3.132.0.2", // (2) sect163r1
"1.3.132.0.15", // (3) sect163r2, NIST B-163
"1.3.132.0.24", // (4) sect193r1
"1.3.132.0.25", // (5) sect193r2
"1.3.132.0.26", // (6) sect233k1, NIST K-233
"1.3.132.0.27", // (7) sect233r1, NIST B-233
"1.3.132.0.3", // (8) sect239k1
"1.3.132.0.16", // (9) sect283k1, NIST K-283
"1.3.132.0.17", // (10) sect283r1, NIST B-283
"1.3.132.0.36", // (11) sect409k1, NIST K-409
"1.3.132.0.37", // (12) sect409r1, NIST B-409
"1.3.132.0.38", // (13) sect571k1, NIST K-571
"1.3.132.0.39", // (14) sect571r1, NIST B-571
"1.3.132.0.9", // (15) secp160k1
"1.3.132.0.8", // (16) secp160r1
"1.3.132.0.30", // (17) secp160r2
"1.3.132.0.31", // (18) secp192k1
"1.2.840.10045.3.1.1", // (19) secp192r1, NIST P-192
"1.3.132.0.32", // (20) secp224k1
"1.3.132.0.33", // (21) secp224r1, NIST P-224
"1.3.132.0.10", // (22) secp256k1
"1.2.840.10045.3.1.7", // (23) secp256r1, NIST P-256
"1.3.132.0.34", // (24) secp384r1, NIST P-384
"1.3.132.0.35", // (25) secp521r1, NIST P-521
};
private final static Map<String,Integer> curveIndices;
static {
curveIndices = new HashMap<String,Integer>();
for (int i = 1; i < NAMED_CURVE_OID_TABLE.length; i++) {
curveIndices.put(NAMED_CURVE_OID_TABLE[i], i);
}
}
}

View File

@ -0,0 +1,101 @@
/*
* 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.security.ssl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.SSLProtocolException;
final class SupportedEllipticPointFormatsExtension extends HelloExtension {
final static int FMT_UNCOMPRESSED = 0;
final static int FMT_ANSIX962_COMPRESSED_PRIME = 1;
final static int FMT_ANSIX962_COMPRESSED_CHAR2 = 2;
static final HelloExtension DEFAULT =
new SupportedEllipticPointFormatsExtension(
new byte[] {FMT_UNCOMPRESSED});
private final byte[] formats;
private SupportedEllipticPointFormatsExtension(byte[] formats) {
super(ExtensionType.EXT_EC_POINT_FORMATS);
this.formats = formats;
}
SupportedEllipticPointFormatsExtension(HandshakeInStream s, int len)
throws IOException {
super(ExtensionType.EXT_EC_POINT_FORMATS);
formats = s.getBytes8();
// RFC 4492 says uncompressed points must always be supported.
// Check just to make sure.
boolean uncompressed = false;
for (int format : formats) {
if (format == FMT_UNCOMPRESSED) {
uncompressed = true;
break;
}
}
if (uncompressed == false) {
throw new SSLProtocolException
("Peer does not support uncompressed points");
}
}
int length() {
return 5 + formats.length;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putInt16(formats.length + 1);
s.putBytes8(formats);
}
private static String toString(byte format) {
int f = format & 0xff;
switch (f) {
case FMT_UNCOMPRESSED:
return "uncompressed";
case FMT_ANSIX962_COMPRESSED_PRIME:
return "ansiX962_compressed_prime";
case FMT_ANSIX962_COMPRESSED_CHAR2:
return "ansiX962_compressed_char2";
default:
return "unknown-" + f;
}
}
public String toString() {
List<String> list = new ArrayList<String>();
for (byte format : formats) {
list.add(toString(format));
}
return "Extension " + type + ", formats: " + list;
}
}

View File

@ -0,0 +1,57 @@
/*
* 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.security.ssl;
import java.io.IOException;
final class UnknownExtension extends HelloExtension {
private final byte[] data;
UnknownExtension(HandshakeInStream s, int len, ExtensionType type)
throws IOException {
super(type);
data = new byte[len];
// s.read() does not handle 0-length arrays.
if (len != 0) {
s.read(data);
}
}
int length() {
return 4 + data.length;
}
void send(HandshakeOutStream s) throws IOException {
s.putInt16(type.id);
s.putBytes16(data);
}
public String toString() {
return "Unsupported extension " + type + ", data: " +
Debug.toString(data);
}
}

View File

@ -1108,17 +1108,3 @@ public class XChoicePeer extends XComponentPeer implements ChoicePeer, ToplevelS
return true;
}
}
/*
* The listener interface for receiving "interesting" for XFileDialogPeer
* choice events (opening, closing).
* The listener added by means of the method addXChoicePeerListener
* A opening choice event is generated when the invoking unfurledChoice.toFront()
* A closing choice event is generated at the time of the processing the mouse releasing
* and the Enter pressing.
* see 6240074 for more information
*/
interface XChoicePeerListener{
public void unfurledChoiceOpening(ListHelper choiceHelper);
public void unfurledChoiceClosing();
}

View File

@ -0,0 +1,40 @@
/*
* Copyright (c) 2003, 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.awt.X11;
/*
* The listener interface for receiving "interesting" for XFileDialogPeer
* choice events (opening, closing).
* The listener added by means of the method addXChoicePeerListener
* A opening choice event is generated when the invoking unfurledChoice.toFront()
* A closing choice event is generated at the time of the processing the mouse releasing
* and the Enter pressing.
* see 6240074 for more information
*/
interface XChoicePeerListener{
public void unfurledChoiceOpening(ListHelper choiceHelper);
public void unfurledChoiceClosing();
}

View File

@ -0,0 +1,114 @@
/*
* Copyright (c) 2003, 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.font;
import java.awt.geom.GeneralPath;
import java.awt.geom.Point2D;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
/* Returned instead of a NativeStrike.
* It can intercept any request it wants, but mostly
* passes them on to its delegate strike. It is important that
* it override all the inherited FontStrike methods to delegate them
* appropriately.
*/
class DelegateStrike extends NativeStrike {
private FontStrike delegateStrike;
DelegateStrike(NativeFont nativeFont, FontStrikeDesc desc,
FontStrike delegate) {
super(nativeFont, desc);
this.delegateStrike = delegate;
}
/* We want the native font to be responsible for reporting the
* font metrics, even if it often delegates to another font.
* The code here isn't yet implementing exactly that. If the glyph
* transform was something native couldn't handle, there's no native
* context from which to obtain metrics. Need to revise this to obtain
* the metrics and transform them. But currently in such a case it
* gets the metrics from a different font - its glyph delegate font.
*/
StrikeMetrics getFontMetrics() {
if (strikeMetrics == null) {
if (pScalerContext != 0) {
strikeMetrics = super.getFontMetrics();
}
if (strikeMetrics == null) {
strikeMetrics = delegateStrike.getFontMetrics();
}
}
return strikeMetrics;
}
void getGlyphImagePtrs(int[] glyphCodes, long[] images,int len) {
delegateStrike.getGlyphImagePtrs(glyphCodes, images, len);
}
long getGlyphImagePtr(int glyphCode) {
return delegateStrike.getGlyphImagePtr(glyphCode);
}
void getGlyphImageBounds(int glyphCode,
Point2D.Float pt, Rectangle result) {
delegateStrike.getGlyphImageBounds(glyphCode, pt, result);
}
Point2D.Float getGlyphMetrics(int glyphCode) {
return delegateStrike.getGlyphMetrics(glyphCode);
}
float getGlyphAdvance(int glyphCode) {
return delegateStrike.getGlyphAdvance(glyphCode);
}
Point2D.Float getCharMetrics(char ch) {
return delegateStrike.getCharMetrics(ch);
}
float getCodePointAdvance(int cp) {
if (cp < 0 || cp >= 0x10000) {
cp = 0xffff;
}
return delegateStrike.getGlyphAdvance(cp);
}
Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) {
return delegateStrike.getGlyphOutlineBounds(glyphCode);
}
GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
return delegateStrike.getGlyphOutline(glyphCode, x, y);
}
GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
return delegateStrike.getGlyphVectorOutline(glyphs, x, y);
}
}

View File

@ -32,7 +32,7 @@ import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.geom.NoninvertibleTransformException;
class NativeStrike extends PhysicalStrike {
class NativeStrike extends PhysicalStrike {
NativeFont nativeFont;
int numGlyphs;
@ -294,86 +294,3 @@ import java.awt.geom.NoninvertibleTransformException;
}
}
/* Returned instead of a NativeStrike.
* It can intercept any request it wants, but mostly
* passes them on to its delegate strike. It is important that
* it override all the inherited FontStrike methods to delegate them
* appropriately.
*/
class DelegateStrike extends NativeStrike {
private FontStrike delegateStrike;
DelegateStrike(NativeFont nativeFont, FontStrikeDesc desc,
FontStrike delegate) {
super(nativeFont, desc);
this.delegateStrike = delegate;
}
/* We want the native font to be responsible for reporting the
* font metrics, even if it often delegates to another font.
* The code here isn't yet implementing exactly that. If the glyph
* transform was something native couldn't handle, there's no native
* context from which to obtain metrics. Need to revise this to obtain
* the metrics and transform them. But currently in such a case it
* gets the metrics from a different font - its glyph delegate font.
*/
StrikeMetrics getFontMetrics() {
if (strikeMetrics == null) {
if (pScalerContext != 0) {
strikeMetrics = super.getFontMetrics();
}
if (strikeMetrics == null) {
strikeMetrics = delegateStrike.getFontMetrics();
}
}
return strikeMetrics;
}
void getGlyphImagePtrs(int[] glyphCodes, long[] images,int len) {
delegateStrike.getGlyphImagePtrs(glyphCodes, images, len);
}
long getGlyphImagePtr(int glyphCode) {
return delegateStrike.getGlyphImagePtr(glyphCode);
}
void getGlyphImageBounds(int glyphCode,
Point2D.Float pt, Rectangle result) {
delegateStrike.getGlyphImageBounds(glyphCode, pt, result);
}
Point2D.Float getGlyphMetrics(int glyphCode) {
return delegateStrike.getGlyphMetrics(glyphCode);
}
float getGlyphAdvance(int glyphCode) {
return delegateStrike.getGlyphAdvance(glyphCode);
}
Point2D.Float getCharMetrics(char ch) {
return delegateStrike.getCharMetrics(ch);
}
float getCodePointAdvance(int cp) {
if (cp < 0 || cp >= 0x10000) {
cp = 0xffff;
}
return delegateStrike.getGlyphAdvance(cp);
}
Rectangle2D.Float getGlyphOutlineBounds(int glyphCode) {
return delegateStrike.getGlyphOutlineBounds(glyphCode);
}
GeneralPath getGlyphOutline(int glyphCode, float x, float y) {
return delegateStrike.getGlyphOutline(glyphCode, x, y);
}
GeneralPath getGlyphVectorOutline(int[] glyphs, float x, float y) {
return delegateStrike.getGlyphVectorOutline(glyphs, x, y);
}
}

View File

@ -326,24 +326,3 @@ public class JulesAATileGenerator implements AATileGenerator {
return tiledTrapArray[index];
}
}
class TileTrapContainer {
int tileAlpha;
GrowableIntArray traps;
public TileTrapContainer(GrowableIntArray traps) {
this.traps = traps;
}
public void setTileAlpha(int tileAlpha) {
this.tileAlpha = tileAlpha;
}
public int getTileAlpha() {
return tileAlpha;
}
public GrowableIntArray getTraps() {
return traps;
}
}

View File

@ -0,0 +1,49 @@
/*
* 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 sun.java2d.jules;
import sun.java2d.xr.GrowableIntArray;
class TileTrapContainer {
int tileAlpha;
GrowableIntArray traps;
public TileTrapContainer(GrowableIntArray traps) {
this.traps = traps;
}
public void setTileAlpha(int tileAlpha) {
this.tileAlpha = tileAlpha;
}
public int getTileAlpha() {
return tileAlpha;
}
public GrowableIntArray getTraps() {
return traps;
}
}