8000970: break out auxiliary classes that will prevent multi-core compilation of the JDK
Reviewed-by: alanb, wetmore
This commit is contained in:
parent
dc9bf2de74
commit
f5e72e432e
@ -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; }
|
||||
}
|
55
jdk/make/tools/src/build/tools/generatenimbus/Border.java
Normal file
55
jdk/make/tools/src/build/tools/generatenimbus/Border.java
Normal 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! $$$";
|
||||
}
|
||||
}
|
||||
}
|
45
jdk/make/tools/src/build/tools/generatenimbus/Canvas.java
Normal file
45
jdk/make/tools/src/build/tools/generatenimbus/Canvas.java
Normal 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());
|
||||
}
|
||||
}
|
@ -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);
|
||||
}
|
||||
}
|
38
jdk/make/tools/src/build/tools/generatenimbus/Dimension.java
Normal file
38
jdk/make/tools/src/build/tools/generatenimbus/Dimension.java
Normal 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);
|
||||
}
|
||||
}
|
42
jdk/make/tools/src/build/tools/generatenimbus/Ellipse.java
Normal file
42
jdk/make/tools/src/build/tools/generatenimbus/Ellipse.java
Normal 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; }
|
||||
}
|
29
jdk/make/tools/src/build/tools/generatenimbus/Gradient.java
Normal file
29
jdk/make/tools/src/build/tools/generatenimbus/Gradient.java
Normal 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 {
|
||||
}
|
@ -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; }
|
||||
}
|
52
jdk/make/tools/src/build/tools/generatenimbus/Insets.java
Normal file
52
jdk/make/tools/src/build/tools/generatenimbus/Insets.java
Normal 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);
|
||||
}
|
||||
}
|
49
jdk/make/tools/src/build/tools/generatenimbus/Layer.java
Normal file
49
jdk/make/tools/src/build/tools/generatenimbus/Layer.java
Normal 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();
|
||||
}
|
||||
}
|
82
jdk/make/tools/src/build/tools/generatenimbus/Matte.java
Normal file
82
jdk/make/tools/src/build/tools/generatenimbus/Matte.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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 {
|
||||
}
|
||||
|
39
jdk/make/tools/src/build/tools/generatenimbus/Path.java
Normal file
39
jdk/make/tools/src/build/tools/generatenimbus/Path.java
Normal 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; }
|
||||
}
|
56
jdk/make/tools/src/build/tools/generatenimbus/Point.java
Normal file
56
jdk/make/tools/src/build/tools/generatenimbus/Point.java
Normal 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;
|
||||
}
|
||||
}
|
@ -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 {
|
||||
}
|
61
jdk/make/tools/src/build/tools/generatenimbus/Rectangle.java
Normal file
61
jdk/make/tools/src/build/tools/generatenimbus/Rectangle.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@ -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; }
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
75
jdk/make/tools/src/build/tools/generatenimbus/Typeface.java
Normal file
75
jdk/make/tools/src/build/tools/generatenimbus/Typeface.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
41
jdk/make/tools/src/build/tools/generatenimbus/UIColor.java
Normal file
41
jdk/make/tools/src/build/tools/generatenimbus/UIColor.java
Normal 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());
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
@ -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() $$$";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
40
jdk/make/tools/src/build/tools/generatenimbus/UIFont.java
Normal file
40
jdk/make/tools/src/build/tools/generatenimbus/UIFont.java
Normal 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());
|
||||
}
|
||||
}
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
@ -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() $$$";
|
||||
}
|
||||
}
|
||||
}
|
200
jdk/make/tools/src/build/tools/generatenimbus/UIRegion.java
Normal file
200
jdk/make/tools/src/build/tools/generatenimbus/UIRegion.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
97
jdk/make/tools/src/build/tools/generatenimbus/UIState.java
Normal file
97
jdk/make/tools/src/build/tools/generatenimbus/UIState.java
Normal 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())));
|
||||
}
|
||||
}
|
@ -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; }
|
||||
}
|
@ -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; }
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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.
|
||||
* <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;
|
||||
}
|
||||
}
|
@ -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.
|
||||
* <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;
|
||||
}
|
||||
}
|
||||
|
493
jdk/src/share/classes/sun/misc/FDBigInt.java
Normal file
493
jdk/src/share/classes/sun/misc/FDBigInt.java
Normal 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 );
|
||||
}
|
||||
}
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
@ -36,11 +36,3 @@ class Event {
|
||||
this.exchange = t;
|
||||
}
|
||||
}
|
||||
|
||||
class WriteFinishedEvent extends Event {
|
||||
WriteFinishedEvent (ExchangeImpl t) {
|
||||
super (t);
|
||||
assert !t.writefinished;
|
||||
t.writefinished = true;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
101
jdk/src/share/classes/sun/security/ssl/ExtensionType.java
Normal file
101
jdk/src/share/classes/sun/security/ssl/ExtensionType.java
Normal 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
|
||||
}
|
45
jdk/src/share/classes/sun/security/ssl/HelloExtension.java
Normal file
45
jdk/src/share/classes/sun/security/ssl/HelloExtension.java
Normal 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();
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
280
jdk/src/share/classes/sun/security/ssl/ServerNameExtension.java
Normal file
280
jdk/src/share/classes/sun/security/ssl/ServerNameExtension.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
57
jdk/src/share/classes/sun/security/ssl/UnknownExtension.java
Normal file
57
jdk/src/share/classes/sun/security/ssl/UnknownExtension.java
Normal 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);
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
|
40
jdk/src/solaris/classes/sun/awt/X11/XChoicePeerListener.java
Normal file
40
jdk/src/solaris/classes/sun/awt/X11/XChoicePeerListener.java
Normal 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();
|
||||
}
|
114
jdk/src/solaris/classes/sun/font/DelegateStrike.java
Normal file
114
jdk/src/solaris/classes/sun/font/DelegateStrike.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user