Survey
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the work of artificial intelligence, which forms the content of this project
Java in SAS®
JavaObj, a DATA Step
Component Object
Richard A. DeVenezia
Independent Consultant
SAS is a registered trademark or trademark of SAS Institute Inc. in the USA and other countries. ® indicates USA registration.
Other brand and product names are registered trademarks or Trademarks of their respective companies.
Slide imagery Copyright © 2005, SAS Institute Inc. All rights reserved.
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Overview
Component Object
Component Interface
• Syntax
• Design
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Component Interface
DECLARE Statement
_NEW_ Operator
Object References
Object Methods
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
DECLARE Statement
DECLARE ComponentObject variable;
Places variable in PDV
Variable is an object reference
Cannot be output to a data set
DECLARE ComponentObject variable
( constructor arguments );
Instantiates an object at declaration
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
_NEW_ Operator
DECLARE ComponentObject variable;
variable = _NEW_ (constructor arguments);
Instantiates an object
Pattern of argument types
• signature
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Object References
Object variables refer to an underlying component
Assignable
myObj1
myObj1 == myObj2;
myObj2;
• original myObj1 reference lost!
Terminate objects no longer needed
myObj1.delete();
myObj1.delete();
No documented garbage collection
• some automatic termination
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Object Methods
Object Dot Syntax
myObj . method ( arguments );
Each object has a set of documented methods
• Allows DATA Step to interact with component
Pattern of argument types
• signature
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
JavaObj Component Object
One of three production objects
• Others are Hash, HIter
Constructor signature
( Char, {other args} );
Char - name of Java class
{ other args } - signature of class constructor
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
JVM - Java Virtual Machine
Execution environment for Java classes
Initialized when first JavaObj instantiated
• Persists until SAS session ends
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Java classes
Loaded from CLASSPATH
Must be compatible with active JVM
-JREOPTIONS(-Dsas.jre.home=...)
Class names - hierarchy and nesting
Java code
SAS Code
x.y.z.MyClass
'x/y/z/MyClass'
x.y.MyClass.Foo
'x/y/z/MyClass$Foo'
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
CLASSPATH
Environment Variable
location-1;location-2;...;location-N
Folders or Jar files
Set via
• command line
• configuration file
• invoking process
• user profile
• system profile
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Java fields
Type
• Primitive or Class
Value
• Primitive or Object reference
JavaObj can interact, if
• field is primitive type or String
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Java methods
Have arguments
• signature - pattern of types
Return nothing, a primitive type, or an object
JavaObj can interact
• signature is void
• signature contains doubles, Strings and classes that
JavaObj can instantiate.
-Important!
• if return is not an object (String excluded)
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
JavaObj accessor methods
Allow interaction between DATA Step and
underlying Java object
Fields
javaobj.get[Static]TypeField(field,out-variable)
javaobj.set[Static]TypeField(field,in-expression)
Method
javaobj.call[Static]TypeMethod
(method, in-args, out-variable)
• in-args signature must match method signature
j.getDoubleField (‘score’, score);
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
JavaObj accessor methods
Java: public Type Method (args…) {… return * }
SAS:
javaobj.callTypeMethod ( ‘Method’, args…, return );
SAS:
javaobj.getTypeField ( ‘Field’, out-variable );
Java: public Type Field = value;
SAS:
javaobj.setTypeField ( ‘Field’, in-expression );
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
First Program
data _null_;
declare JavaObj j ('java/lang/String'
,'My first JavaObj');
length s $200;
j.callStringMethod ('toString', s);
put s=;
run;
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Second Program - Java
public class Greetings
{
private String[3] phrases = { 'Hello', 'Hi There', '' };
public void setGreeting (String phrase, double index)
{ phrases [ (int) index ] = phrase; }
public String getGreeting ()
{ return phrases [ 0 ]; }
public String getGreeting (double index)
{ return phrases [ (int) index ]; }
}
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Second Program - SAS
data _null_;
declare JavaObj j ('Greetings');
length s1-s3 $200;
j.callStringMethod
j.callStringMethod
j.callVoidMethod
j.callStringMethod
put (s1-s3) (=/);
run;
------ log -----s1=Hello
s2=Hi There
s3=Wassup
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
('getGreeting',
('getGreeting',
('setGreeting',
('getGreeting',
s1);
1, s2);
2, 'Wassup');
2, s3);
JavaObj support methods
Interact with Java exceptions
exceptionDescribe (in-debug-logging)
• use 1 to log exception stack traces on SAS session stderr
exceptionCheck (out-status)
• returns 1 if an exception occurred
exceptionClear ()
• resets status (internal to JavaObj system)
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Third Program - Uh, oh
data _null_;
length s $200;
declare JavaObj j ('Greetings');
j.exceptionDescribe (1);
j.callStringMethod ('getGreeting', 9, s);
j.exceptionCheck (e); put e= s=;
if (e) then do;
put 'An exception occurred.';
j.exceptionClear ();
end;
run;
------ log -----e=1 s=
An exception occurred.
------ stderr -----java.lang.ArrayIndexOutOfBoundsException: 9
at Greetings.getGreeting(Greetings.java:11)
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Java2D
Object oriented approach to Graphics
More colors than SAS/Graph
Anti-aliased drawing
Alpha blending
Affine Transformations
JPG and PNG
• Other formats via plug-in classes
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Fourth Program - Display an Image
Runtime library has many useful classes
Program uses a few
import java.io.File;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JOptionPane;
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Fourth Program - SUGI30.Graphics
package SUGI30;
...import statements...
public Graphics {
private String
readSource;
private BufferedImage readBuffer;
void readImage (String source) throws Exception {
readSource = null;
readBuffer = ImageIO.read (new File(source));
readSource = source;
}
void showReadBuffer () {
show ( readBuffer, readSource );
}
void show (BufferedImage img, String title) {
JOptionPane.showMessageDialog(null,null,title,
JOptionPane.PLAIN_MESSAGE, new ImageIcon(img));
}
}
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Fourth Program - SAS
Short and sweet
• Real work occurs ‘over in Java’
data _null_;
declare JavaObj j ('SUGI30/Graphics');
j.exceptionDescribe(1);
j.callVoidMethod ('readImage', 'sugi30_logo.png');
j.callVoidMethod ('showReadBuffer');
j.delete();
run;
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Recompiling Java
Occurs often during rapid development
• Corrections or changes made to java source
If done while SAS active
• New version of an already loaded class
will not get loaded !
Solution - use Batch SAS
• Compile Java, then run SAS
• Non-trivial Java systems
-build tool, Ant
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Development Configuration
batch file - example1.bat
• compiles java
• runs SAS program
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Batch for Development
clear log
set program=GraphicsTester
echo . > %program%.log
compile java if not exist class\ mkdir class\
javac -d class\ java\*.java
if errorlevel 1 goto done
sas program
set CLASSPATH=class;%CLASSPATH% 2>stderr.log >stdout.log
sas -sysin sas\%program%.sas
review logs
notepad %program%.log
notepad stderr.log
notepad stdout.log
:done
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
SUGI30.Graphics - An Adapter
private BufferedImage buffer;
private Graphics2D g;
private double antiAlias;
// drawing buffer
// graphics context
// state variable
void createBuffer (double width, double height) {
buffer = new BufferedImage ((int)width,(int)height
,BufferedImage.TYPE_INT_RGB);
g = buffer.createGraphics();
setAntiAlias (1d); // 1 as double
}
void setAntiAlias (double smooth) {
if (smooth != 0d) {
g.setRenderingHint
( RenderingHints.KEY_ANTIALIASING
, RenderingHints.KEY_ANTIALIASING_ON
);
} else { ... }
}
}
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Adapter
Also known as Wrapper
“Convert the interface of a class into another
interface clients expect. Adapter lets classes
work together that couldn’t otherwise because
of incompatible interfaces”
[ Design Patterns - Gang of Four ]
Incompability
• JavaObj passes primitives, Strings and JavaObj
-cannot receive object reference in return
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Drawing (Adapters)
void setColor (double r, double g, double b) {
this.g.setColor (new Color ((int)r,(int)g,(int)b));
}
void drawLine (double x1, double y1, double x2, double y2) {
g.drawLine ( (int) x1, (int) y1, (int) x2, (int) y2);
}
void fillRect (double x, double y, double width, double height) {
g.fillRect ( (int) x, (int) y, (int) width, (int) height);
}
void drawOval (double x, double y, double width, double height) {
g.drawOval ( (int) x, (int) y, (int) width, (int) height);
}
void fillOval (double x, double y, double width, double height) {
g.fillOval ( (int) x, (int) y, (int) width, (int) height);
}
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Saving Graphics
String saveAs ( String type, String name )
{
String savedAs = "";
try {
File file = new File(name);
savedAs = file.getCanonicalPath();
ImageIO.write (buffer, type, new File(savedAs));
}
catch (Exception e) {
savedAs = "";
}
return savedAs;
}
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
GraphicsTester
Notice the j.* pattern
data _null_;
length fname $200;
declare JavaObj j ('SUGI30/Graphics');
j.exceptionDescribe(1);
j.callVoidMethod (’createBuffer', 200,200);
j.callVoidMethod (‘setColor’, 255,255,255);
j.callVoidMethod (‘fillRect’, 0,0,200,200);
j.callVoidMethod (‘setColor’, 255,0,0);
j.callVoidMethod (‘drawOval’, 1,1,198,198);
j.callVoidMethod (‘fillOVal’, 80,80,40,40);
j.callVoidMethod ('saveAs’, ‘png’,‘sqare.png’, fname);
j.callVoidMethod (‘show’, fname, ‘Drawing buffer’);
j.delete();
run;
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Emulate DSGI
An adaper surfaces a set of methods
State variables
• Maintain properties of context
Extensible
• Add new methods and states to Graphics.java
Downside
• Not GRSEG compatible
Upside
• Other graphics formats via ImageIO plugins
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Patterns in SAS Code ==> Macro
%macro createBuffer (width, height);
&jdsgi..callVoidMethod ('createBuffer', &width, &height)
%mend;
%macro
setColor ( r , g, b);
&jdsgi..callVoidMethod ('setColor', &r, &g, &b)
%mend;
%macro
fillRect ( x, y, width, height);
&jdsgi..callVoidMethod ('fillRect', &x,&y,&width,&height)
%mend;
and so on...
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Patterns in SAS Code ==> Macro
%macro canvas_create (javaobj, width, height, color);
%global jdsgi;
%let jdsgi = &javaobj;
declare javaobj &jdsgi (‘SUGI30/Graphics’);
&jdsgi..exceptionDescribe(1);
%createBuffer (&width, &height);
%setColor (&color);
%fillRect (0,0,&width,&height);
%setColor (0,0,0);
%mend;
%canvas_delete ();
&jdsgi..delete();
%symdel &jdsgi;
%mend;
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
GraphicsTester
Simplifies adapter use
data _null_;
length fname $200;
%canvas_create (_g, 200,200, 255,255,255);
%setColor (255,0,0);
%drawOval (1,1,198,198);
%fillOval (80,80,40,40);
%saveAs (‘png’, ‘target2.png’, fname);
%showTM (savedAs, cat(‘Drawing buffer’,’0a’x,
’Drawn with Macros.’);
%canvas_delete();
run;
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
Conclusion
Component Object technology introduces the concept
of Object to DATA Step
JavaObj is one doorway into the vast domain of Java
based tools and solutions
Extensive jDSGI samples at
www.devenezia.com/downloads/sas/samples/#jdsgi
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.
About the Speaker
Speaker Richard A. DeVenezia
Independent Consultant
Location 9949 East Steuben Road
Remsen, NY 13438
Telephone (315) 831-8802
E-Mail [email protected]
Copyright © 2005 , Richard A. DeVenezia. All rights reserved.