1 /*
2  * Copyright (c) 1998, 2003, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 package sun.java2d.loops;
27 
28 /**
29  *   GraphicsPrimitiveProxy
30  *
31  * Acts as a proxy for instances of GraphicsPrimitive, enabling lazy
32  * classloading of these primitives.  This leads to a substantial
33  * savings in start-up time and footprint.  In the typical case,
34  * it has been found that a small number of GraphicsPrimitive instance
35  * actually end up getting instantiated.
36  * <p>
37  * Note that the makePrimitive method should never be invoked on
38  * a GraphicsPrimitiveProxy object since they are instantiated as
39  * soon as they are found in the primitive list and never returned
40  * to the caller.
41  */
42 public class GraphicsPrimitiveProxy extends GraphicsPrimitive {
43 
44     private Class<?> owner;
45     private String relativeClassName;
46 
47     /**
48      * Create a GraphicsPrimitiveProxy for a primitive with a no-argument
49      * constructor.
50      *
51      * @param owner The owner class for this primitive.  The primitive
52      *          must be in the same package as this owner.
53      * @param relativeClassName  The name of the class this is a proxy for.
54      *          This should not include the package.
55      */
GraphicsPrimitiveProxy(Class<?> owner, String relativeClassName, String methodSignature, int primID, SurfaceType srctype, CompositeType comptype, SurfaceType dsttype)56     public GraphicsPrimitiveProxy(Class<?> owner, String relativeClassName,
57                                   String methodSignature,
58                                   int primID,
59                                   SurfaceType srctype,
60                                   CompositeType comptype,
61                                   SurfaceType dsttype)
62     {
63         super(methodSignature, primID, srctype, comptype, dsttype);
64         this.owner = owner;
65         this.relativeClassName = relativeClassName;
66     }
67 
makePrimitive(SurfaceType srctype, CompositeType comptype, SurfaceType dsttype)68     public GraphicsPrimitive makePrimitive(SurfaceType srctype,
69                                            CompositeType comptype,
70                                            SurfaceType dsttype) {
71         // This should never happen.
72         throw new InternalError("makePrimitive called on a Proxy!");
73     }
74 
75     //
76     // Come up with the real instance.  Called from
77     // GraphicsPrimitiveMgr.locate()
78     //
instantiate()79     GraphicsPrimitive instantiate() {
80         String name = getPackageName(owner.getName()) + "."
81                         + relativeClassName;
82         try {
83             Class<?> clazz = Class.forName(name);
84             GraphicsPrimitive p =
85                 (GraphicsPrimitive) clazz.getDeclaredConstructor().newInstance();
86             if (!satisfiesSameAs(p)) {
87                 throw new RuntimeException("Primitive " + p
88                                            + " incompatible with proxy for "
89                                            + name);
90             }
91             return p;
92         } catch (ReflectiveOperationException ex) {
93             throw new RuntimeException(ex.toString());
94         }
95         // A RuntimeException should never happen in a deployed JDK, because
96         // the regression test GraphicsPrimitiveProxyTest will catch any
97         // of these errors.
98     }
99 
getPackageName(String className)100     private static String getPackageName(String className) {
101         int lastDotIdx = className.lastIndexOf('.');
102         if (lastDotIdx < 0) {
103             return className;
104         }
105         return className.substring(0, lastDotIdx);
106     }
107 
traceWrap()108     public GraphicsPrimitive traceWrap() {
109         return instantiate().traceWrap();
110     }
111 }
112