mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 12:09:14 +00:00
7150322: Stop using drop source bundles in jaxws
Reviewed-by: darcy, ohrstrom
This commit is contained in:
parent
abf322bf84
commit
bc113af571
@ -17,9 +17,3 @@ Simple Build Instructions:
|
||||
"dist" directory.
|
||||
Help information is available by running "ant -projecthelp" or "make help".
|
||||
|
||||
Drop Repository:
|
||||
This repository builds sources from a created "drop" source directory.
|
||||
These files will normally be copied from a shared directory area or
|
||||
downloaded from a public website.
|
||||
See the ant build script (build.xml) for more details.
|
||||
|
||||
|
||||
@ -1,150 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (c) 2009, 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.
|
||||
-->
|
||||
|
||||
<project name="jaxws_defs" default="all" basedir=".">
|
||||
|
||||
<!-- Specific build properties. -->
|
||||
<property file="jaxws.properties"/>
|
||||
|
||||
<!-- Where generated xml files will stay. -->
|
||||
<property name="xml.gen.dir" value="${build.dir}/xml_generated"/>
|
||||
<property name="xml.template" value="build-drop-template.xml"/>
|
||||
|
||||
<!-- ############### -->
|
||||
<!-- Begin Macrodefs -->
|
||||
|
||||
<!-- Copies template file, replaces @DROP@ pattern, and imports it. -->
|
||||
<macrodef name="drop-import">
|
||||
<attribute name="name"/>
|
||||
<sequential>
|
||||
<property name="xml.gen.@{name}" value="${xml.gen.dir}/build-drop-@{name}.xml"/>
|
||||
<mkdir dir="${xml.gen.dir}"/>
|
||||
<copy file="${xml.template}" tofile="${xml.gen.@{name}}"/>
|
||||
<replace file="${xml.gen.@{name}}" token="@DROP@" value="@{name}"/>
|
||||
<import file="${xml.gen.@{name}}"/>
|
||||
</sequential>
|
||||
</macrodef>
|
||||
|
||||
<!-- End of Macrodefs -->
|
||||
<!-- ############### -->
|
||||
|
||||
<!-- Create xml file and import it for these drops. -->
|
||||
<drop-import name="jaxws_src"/>
|
||||
<drop-import name="jaf_src"/>
|
||||
<!-- <drop-import name="jaxws_tests"/> -->
|
||||
|
||||
<!-- Fail and print helpful messages if source does not exist. -->
|
||||
<target name="-src-help">
|
||||
<fail message="${failed.url.src.message}">
|
||||
<condition>
|
||||
<and>
|
||||
<not>
|
||||
<and>
|
||||
<available file="${jaxws_src.src.dir}" type="dir"/>
|
||||
<available file="${jaf_src.src.dir}" type="dir"/>
|
||||
</and>
|
||||
</not>
|
||||
<istrue value="${allow.downloads}"/>
|
||||
</and>
|
||||
</condition>
|
||||
</fail>
|
||||
<fail message="${failed.nourl.src.message}">
|
||||
<condition>
|
||||
<not>
|
||||
<and>
|
||||
<available file="${jaxws_src.src.dir}" type="dir"/>
|
||||
<available file="${jaf_src.src.dir}" type="dir"/>
|
||||
</and>
|
||||
</not>
|
||||
</condition>
|
||||
</fail>
|
||||
</target>
|
||||
|
||||
<!-- Special build area setup. -->
|
||||
<target name="-drop-build-setup" depends="init, -init-src-dirs">
|
||||
<mkdir dir="${build.classes.dir}"/>
|
||||
<copy todir="${build.classes.dir}">
|
||||
<fileset dir="${primary.src.dir}"
|
||||
includes="**/*.xsd, **/*.default, **/*.properties"
|
||||
excludes="**/*.java, **/*.package.html"/>
|
||||
</copy>
|
||||
<replaceregexp match="#(.*)$" replace="#" flags="gm">
|
||||
<fileset dir="${build.classes.dir}" includes="**/*.properties"/>
|
||||
</replaceregexp>
|
||||
|
||||
<mkdir dir="${build.classes.dir}/META-INF/services"/>
|
||||
<copy todir="${build.classes.dir}/META-INF"
|
||||
file="${secondary.src.dir}/META-INF/mailcap.default"/>
|
||||
<copy todir="${build.classes.dir}/META-INF"
|
||||
file="${secondary.src.dir}/META-INF/mimetypes.default"/>
|
||||
<copy todir="${build.classes.dir}/META-INF/services"
|
||||
file="${primary.src.dir}/com/sun/tools/etc/META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin"/>
|
||||
<copy todir="${build.classes.dir}/META-INF/services"
|
||||
file="${primary.src.dir}/com/sun/tools/etc/META-INF/services/com.sun.tools.internal.xjc.Plugin"/>
|
||||
<mkdir dir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime"/>
|
||||
<copy todir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime">
|
||||
<fileset dir="${primary.src.dir}/com/sun/tools/internal/xjc/runtime"
|
||||
includes="**/*.java"
|
||||
excludes="**/*.package.html"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<!-- Try to get drop sources. -->
|
||||
<target name="-set-props"
|
||||
depends="init,
|
||||
jaxws_src-update,
|
||||
jaf_src-update">
|
||||
</target>
|
||||
|
||||
<!-- Set up source to use drop.dir. -->
|
||||
<target name="-use-drop" depends="-set-props">
|
||||
<property name="primary.src.dir" value="${jaxws_src.src.dir}"/>
|
||||
<property name="secondary.src.dir" value="${jaf_src.src.dir}"/>
|
||||
<path id="src.dir.id">
|
||||
<pathelement path="${primary.src.dir}"/>
|
||||
<pathelement path="${jaf_src.src.dir}"/>
|
||||
</path>
|
||||
</target>
|
||||
|
||||
<!-- Source directory selection. -->
|
||||
<target name="-init-src-dirs"
|
||||
depends="init, -use-drop,-src-help">
|
||||
<echo message="Using primary.src.dir=${primary.src.dir}"/>
|
||||
<pathconvert property="src.list.id" refid="src.dir.id"/>
|
||||
<echo message="Using src.dir.id=${src.list.id}"/>
|
||||
</target>
|
||||
|
||||
<!-- Create drop src.zip. -->
|
||||
<target name="-drop-src-zip" depends="init, -set-props">
|
||||
<zip file="${dist.src.zip}" basedir="${primary.src.dir}"/>
|
||||
<zip file="${dist.src.zip}" basedir="${jaf_src.src.dir}" update="true"/>
|
||||
</target>
|
||||
|
||||
<!-- Create src.zip. -->
|
||||
<target name="-dist-src-zip" depends="init, -drop-src-zip">
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@ -1,144 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
Copyright (c) 2009, 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.
|
||||
-->
|
||||
|
||||
<project name="@DROP@-drop" default="all" basedir=".">
|
||||
|
||||
<!-- Locations of master drop bundles. -->
|
||||
<property name="@DROP@.master.bundle.copy"
|
||||
value="${@DROP@.master.bundle.dir}/${@DROP@.bundle.name}"/>
|
||||
<property name="@DROP@.master.bundle.url"
|
||||
value="${@DROP@.master.bundle.url.base}/${@DROP@.bundle.name}"/>
|
||||
|
||||
<!-- Location where the copied bundle lands. -->
|
||||
<property name="@DROP@.bundle.copy"
|
||||
value="${drop.expanded.dir}/bundles/${@DROP@.bundle.name}"/>
|
||||
|
||||
<!-- Root of exploded area. -->
|
||||
<property name="@DROP@.root.dir" value="${drop.dir}/@DROP@"/>
|
||||
<property name="@DROP@.src.dir" value="${@DROP@.root.dir}/src"/>
|
||||
|
||||
<!-- To see if the drop areas are ready. (ignoring bundles) -->
|
||||
<target name="-@DROP@-ready">
|
||||
<condition property="@DROP@.ready">
|
||||
<or>
|
||||
<available file="${drop.included.dir}" type="dir"/>
|
||||
<and>
|
||||
<available file="${@DROP@.root.dir}" type="dir"/>
|
||||
<available file="${@DROP@.root.dir}/PATCHED" type="file"/>
|
||||
</and>
|
||||
</or>
|
||||
</condition>
|
||||
</target>
|
||||
|
||||
<!-- Copy over bundles from some shared master area. -->
|
||||
<condition property="@DROP@.master.bundle.copy.exists">
|
||||
<available file="${@DROP@.master.bundle.copy}" type="file"/>
|
||||
</condition>
|
||||
<target name="-@DROP@-copy-bundle"
|
||||
depends="init, -@DROP@-ready"
|
||||
if="@DROP@.master.bundle.copy.exists"
|
||||
unless="@DROP@.ready">
|
||||
<echo message="Copying from ${@DROP@.master.bundle.copy}"/>
|
||||
<dirname property="@DROP@.bundle.dirname" file="${@DROP@.bundle.copy}"/>
|
||||
<mkdir dir="${@DROP@.bundle.dirname}"/>
|
||||
<delete file="${@DROP@.bundle.copy}.temp"/>
|
||||
<delete file="${@DROP@.bundle.copy}"/>
|
||||
<copy file="${@DROP@.master.bundle.copy}" tofile="${@DROP@.bundle.copy}.temp"/>
|
||||
<move file="${@DROP@.bundle.copy}.temp" tofile="${@DROP@.bundle.copy}"/>
|
||||
<property name="@DROP@.master.bundle.found" value="true"/>
|
||||
</target>
|
||||
|
||||
<!-- Determine if the master url download should be used. -->
|
||||
<target name="-@DROP@-url-should-be-used" unless="@DROP@.url.should.be.used">
|
||||
<condition property="@DROP@.url.should.be.used">
|
||||
<and>
|
||||
<istrue value="${allow.downloads}"/>
|
||||
<not>
|
||||
<isset property="@DROP@.master.bundle.copy.exists"/>
|
||||
</not>
|
||||
</and>
|
||||
</condition>
|
||||
</target>
|
||||
|
||||
<!-- Download bundles from a url. -->
|
||||
<target name="-@DROP@-url-bundle"
|
||||
depends="init, -@DROP@-ready, -@DROP@-url-should-be-used"
|
||||
if="@DROP@.url.should.be.used"
|
||||
unless="@DROP@.ready">
|
||||
<echo message="Downloading from ${@DROP@.master.bundle.url}"/>
|
||||
<dirname property="@DROP@.bundle.dirname" file="${@DROP@.bundle.copy}"/>
|
||||
<mkdir dir="${@DROP@.bundle.dirname}"/>
|
||||
<delete file="${@DROP@.bundle.copy}.temp"/>
|
||||
<delete file="${@DROP@.bundle.copy}"/>
|
||||
<get src="${@DROP@.master.bundle.url}" dest="${@DROP@.bundle.copy}.temp"/>
|
||||
<move file="${@DROP@.bundle.copy}.temp" tofile="${@DROP@.bundle.copy}"/>
|
||||
<property name="@DROP@.master.bundle.found" value="true"/>
|
||||
</target>
|
||||
|
||||
<!-- Fill in the drop zones, but just when needed. -->
|
||||
<target name="@DROP@-update"
|
||||
depends="init,
|
||||
-@DROP@-copy-bundle,
|
||||
-@DROP@-url-bundle,
|
||||
-@DROP@-ready"
|
||||
if="@DROP@.master.bundle.found"
|
||||
unless="@DROP@.ready">
|
||||
<delete dir="${@DROP@.root.dir}"/>
|
||||
<delete dir="${@DROP@.root.dir}-temp"/>
|
||||
<mkdir dir="${@DROP@.root.dir}-temp"/>
|
||||
<checksum file="${@DROP@.bundle.copy}"
|
||||
property="@DROP@.bundle.md5.checksum.is"/>
|
||||
<condition property="@DROP@.bundle.md5.checksum.good">
|
||||
<equals arg1="${@DROP@.bundle.md5.checksum}"
|
||||
arg2="${@DROP@.bundle.md5.checksum.is}"/>
|
||||
</condition>
|
||||
<fail unless="@DROP@.bundle.md5.checksum.good">
|
||||
Checksum on file ${@DROP@.bundle.copy} is
|
||||
${@DROP@.bundle.md5.checksum.is}, not ${@DROP@.bundle.md5.checksum}
|
||||
</fail>
|
||||
<unzip src="${@DROP@.bundle.copy}" dest="${@DROP@.root.dir}-temp"/>
|
||||
<move file="${@DROP@.root.dir}-temp" tofile="${@DROP@.root.dir}"/>
|
||||
<touch>
|
||||
<fileset dir="${@DROP@.root.dir}"/>
|
||||
</touch>
|
||||
<condition property="patch.utility" value="gpatch" else="patch">
|
||||
<os name="SunOS"/>
|
||||
</condition>
|
||||
<apply executable="${patch.utility}"
|
||||
dir="${@DROP@.root.dir}"
|
||||
parallel="false"
|
||||
failonerror="true"
|
||||
verbose="true">
|
||||
<arg value="-l"/>
|
||||
<arg value="-p0"/>
|
||||
<arg value="-i"/>
|
||||
<filelist dir="${patches.dir}/@DROP@" files="${@DROP@.patch.list}"/>
|
||||
</apply>
|
||||
<echo file="${@DROP@.root.dir}/PATCHED"
|
||||
message="Patches have been applied."/>
|
||||
</target>
|
||||
|
||||
</project>
|
||||
@ -23,10 +23,6 @@
|
||||
# questions.
|
||||
#
|
||||
|
||||
# Base locations where bundles are located
|
||||
slashjava=/java
|
||||
drops.dir=${slashjava}/devtools/share/jdk8-drops
|
||||
|
||||
# This is the JDK used to build and run the bootstrap version of javac.
|
||||
# The bootstrap javac is used to compile both boostrap versions of the
|
||||
# other tools, and product versions of all the tools.
|
||||
@ -68,15 +64,6 @@ dist.lib.dir=${dist.dir}/lib
|
||||
dist.classes.jar=${dist.lib.dir}/classes.jar
|
||||
dist.src.zip=${dist.lib.dir}/src.zip
|
||||
|
||||
# Where all drop sources get placed when downloaded and unzipped
|
||||
drop.expanded.dir=${output.dir}/drop
|
||||
|
||||
# Location if the sources were included already
|
||||
drop.included.dir=./drop_included
|
||||
|
||||
# Where patches to drop bundle sources live
|
||||
patches.dir=patches
|
||||
|
||||
# Sanity information
|
||||
sanity.info= Sanity Settings:${line.separator}\
|
||||
ant.home=${ant.home}${line.separator}\
|
||||
@ -100,28 +87,6 @@ sanity.info= Sanity Settings:${line.separator}\
|
||||
output.dir=${output.dir}${line.separator}\
|
||||
build.dir=${build.dir}${line.separator}\
|
||||
dist.dir=${dist.dir}${line.separator}\
|
||||
drop.dir=${drop.dir}${line.separator}\
|
||||
drops.dir=${drops.dir}${line.separator}\
|
||||
${line.separator}
|
||||
|
||||
# Failure messages when source cannot be found on the file system
|
||||
failed.nourl.src.message=\
|
||||
ERROR: Cannot find source for project ${ant.project.name}.\
|
||||
${line.separator}${line.separator}\
|
||||
HINT: Try setting drops.dir to indicate where the bundles can be found, \
|
||||
or try setting the ant property allow.downloads=true to download the bundle from the URL.\
|
||||
${line.separator}\
|
||||
e.g. ant -Dallow.downloads=true -OR- ant -Ddrops.dir=some_directory \
|
||||
${line.separator}
|
||||
|
||||
# Failure message when source cannot be downloaded
|
||||
failed.url.src.message=\
|
||||
ERROR: Cannot find source for project ${ant.project.name}.\
|
||||
${line.separator}${line.separator}\
|
||||
HINT: Try setting drops.dir to indicate where the bundles can be found, \
|
||||
or try checking the URL with your browser.\
|
||||
${line.separator}\
|
||||
e.g. ant -Ddrops.dir=some_directory \
|
||||
${line.separator}
|
||||
|
||||
#------------------------------------------------------------
|
||||
|
||||
@ -36,9 +36,6 @@
|
||||
javac.debug - true or false for debug classfiles
|
||||
javac.target - classfile version target
|
||||
javac.source - source version
|
||||
drops.dir - directory that holds source drop bundles
|
||||
allow.download - permit downloads from public url (default is false)
|
||||
(used if bundles not found in drops.dir)
|
||||
|
||||
Run 'make help' for help using the Makefile.
|
||||
</description>
|
||||
@ -46,15 +43,12 @@
|
||||
<!-- Project build properties. -->
|
||||
<property file="build.properties"/>
|
||||
|
||||
<!-- See if drop sources were included. -->
|
||||
<condition property="drop.dir"
|
||||
value="${drop.included.dir}"
|
||||
else="${drop.expanded.dir}">
|
||||
<available file="${drop.included.dir}" type="dir"/>
|
||||
</condition>
|
||||
|
||||
<!-- Get shared targets. -->
|
||||
<import file="build-defs.xml"/>
|
||||
<property name="jaxws.src.dir" value="src/share/jaxws_classes"/>
|
||||
<property name="jaf.src.dir" value="src/share/jaf_classes"/>
|
||||
<path id="src.dir.id">
|
||||
<pathelement path="${jaxws.src.dir}"/>
|
||||
<pathelement path="${jaf.src.dir}"/>
|
||||
</path>
|
||||
|
||||
<!-- Initialization of directories needed for build. -->
|
||||
<target name="init">
|
||||
@ -79,14 +73,20 @@
|
||||
unless="javac.jar.exists">
|
||||
<echo message="WARNING: Cannot find ${javac.jar}"/>
|
||||
</target>
|
||||
|
||||
<!-- Create src.zip. -->
|
||||
<target name="-dist-src-zip" depends="init">
|
||||
<zip file="${dist.src.zip}" basedir="${jaxws.src.dir}"/>
|
||||
<zip file="${dist.src.zip}" basedir="${jaf.src.dir}" update="true"/>
|
||||
</target>
|
||||
|
||||
<!-- Creation of distribution files to jdk build process. -->
|
||||
<target name="dist"
|
||||
depends="init, -init-src-dirs, build, -dist-classes-jar, -dist-src-zip"
|
||||
depends="init, build, -dist-classes-jar, -dist-src-zip"
|
||||
description="Create all built distribution files.">
|
||||
</target>
|
||||
<target name="-dist-classes-jar-uptodate"
|
||||
depends="init, -init-src-dirs">
|
||||
depends="init">
|
||||
<condition property="dist.classes.jar.uptodate">
|
||||
<and>
|
||||
<available file="${dist.classes.jar}" type="file"/>
|
||||
@ -97,14 +97,39 @@
|
||||
</condition>
|
||||
</target>
|
||||
<target name="-dist-classes-jar"
|
||||
depends="init, -init-src-dirs, -dist-classes-jar-uptodate"
|
||||
depends="init, -dist-classes-jar-uptodate"
|
||||
unless="dist.classes.jar.uptodate">
|
||||
<delete file="${dist.classes.jar}"/>
|
||||
<jar file="${dist.classes.jar}" basedir="${build.classes.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="-build-setup"
|
||||
depends="init, -init-src-dirs, -drop-build-setup">
|
||||
<!-- Special build area setup. -->
|
||||
<target name="-build-setup" depends="init">
|
||||
<mkdir dir="${build.classes.dir}"/>
|
||||
<copy todir="${build.classes.dir}">
|
||||
<fileset dir="${jaxws.src.dir}"
|
||||
includes="**/*.xsd, **/*.default, **/*.properties"
|
||||
excludes="**/*.java, **/*.package.html"/>
|
||||
</copy>
|
||||
<replaceregexp match="#(.*)$" replace="#" flags="gm">
|
||||
<fileset dir="${build.classes.dir}" includes="**/*.properties"/>
|
||||
</replaceregexp>
|
||||
|
||||
<mkdir dir="${build.classes.dir}/META-INF/services"/>
|
||||
<copy todir="${build.classes.dir}/META-INF"
|
||||
file="${jaf.src.dir}/META-INF/mailcap.default"/>
|
||||
<copy todir="${build.classes.dir}/META-INF"
|
||||
file="${jaf.src.dir}/META-INF/mimetypes.default"/>
|
||||
<copy todir="${build.classes.dir}/META-INF/services"
|
||||
file="${jaxws.src.dir}/com/sun/tools/etc/META-INF/services/com.sun.tools.internal.ws.wscompile.Plugin"/>
|
||||
<copy todir="${build.classes.dir}/META-INF/services"
|
||||
file="${jaxws.src.dir}/com/sun/tools/etc/META-INF/services/com.sun.tools.internal.xjc.Plugin"/>
|
||||
<mkdir dir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime"/>
|
||||
<copy todir="${build.classes.dir}/com/sun/tools/internal/xjc/runtime">
|
||||
<fileset dir="${jaxws.src.dir}/com/sun/tools/internal/xjc/runtime"
|
||||
includes="**/*.java"
|
||||
excludes="**/*.package.html"/>
|
||||
</copy>
|
||||
</target>
|
||||
|
||||
<!-- Build (compilation) of sources to class files. -->
|
||||
@ -112,7 +137,7 @@
|
||||
depends="compile, -build-setup">
|
||||
</target>
|
||||
<target name="compile"
|
||||
depends="init, -init-src-dirs">
|
||||
depends="init">
|
||||
<mkdir dir="${build.classes.dir}"/>
|
||||
<javac
|
||||
includeAntRuntime="false"
|
||||
@ -132,26 +157,16 @@
|
||||
|
||||
<!-- Test. (FIXME: Need to know how to run tests.) -->
|
||||
<target name="test"
|
||||
depends="init, -init-src-dirs, dist">
|
||||
depends="init, dist">
|
||||
<echo message="FIXME: How do you run the tests"/>
|
||||
</target>
|
||||
|
||||
<!-- Populate source area if needed. -->
|
||||
<target name="source"
|
||||
depends="init, -init-src-dirs"
|
||||
depends="init"
|
||||
description="Populate all source file directories">
|
||||
</target>
|
||||
|
||||
<!-- Populate drop_included area. -->
|
||||
<target name="drop_included"
|
||||
depends="clobber"
|
||||
description="Populate all source file directories">
|
||||
<delete dir="${drop.included.dir}"/>
|
||||
<antcall target="source"/>
|
||||
<move file="${drop.expanded.dir}" tofile="${drop.included.dir}"/>
|
||||
<delete dir="${drop.included.dir}/bundles"/>
|
||||
</target>
|
||||
|
||||
<!-- Clean up compiled files. -->
|
||||
<target name="clean"
|
||||
description="Delete all generated files">
|
||||
@ -163,7 +178,6 @@
|
||||
<target name="clobber"
|
||||
depends="clean"
|
||||
description="Delete all generated files, including imported sources">
|
||||
<delete dir="${drop.expanded.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="-banner">
|
||||
|
||||
@ -91,23 +91,6 @@ else
|
||||
endif
|
||||
endif
|
||||
|
||||
# Do we have the drops already downloaded?
|
||||
# Check ALT_DROPS_DIR for a full path first,
|
||||
# before trying to use the devtools path,
|
||||
# either via ALT_JDK_DEVTOOLS_DIR or /java/devtools.
|
||||
ifdef ALT_DROPS_DIR
|
||||
DROPS_DIR = $(ALT_DROPS_DIR)
|
||||
else
|
||||
ifdef ALT_JDK_DEVTOOLS_DIR
|
||||
DROPS_DIR = $(ALT_JDK_DEVTOOLS_DIR)/share/jdk8-drops
|
||||
else
|
||||
DROPS_DIR = $(_SLASHJAVA)/devtools/share/jdk8-drops
|
||||
endif
|
||||
endif
|
||||
|
||||
# Add in path to drops already downloaded
|
||||
ANT_OPTIONS += -Ddrops.dir=$(DROPS_DIR)
|
||||
|
||||
ifdef ALT_OUTPUTDIR
|
||||
OUTPUTDIR = $(ALT_OUTPUTDIR)
|
||||
ANT_OPTIONS += -Doutput.dir=$(ALT_OUTPUTDIR)
|
||||
@ -144,13 +127,17 @@ endif
|
||||
default: all
|
||||
|
||||
# All ant targets of interest
|
||||
ANT_TARGETS = all source drop_included build dist clobber clean sanity
|
||||
ANT_TARGETS = all build dist clobber clean sanity
|
||||
|
||||
# Create a make target for each
|
||||
$(ANT_TARGETS):
|
||||
cd .. && $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) -version
|
||||
cd .. && $(ANT_JAVA_HOME) $(ANT) $(ANT_OPTIONS) $@
|
||||
|
||||
# Just for compat reasons, delete in future.
|
||||
drop_included:
|
||||
source:
|
||||
|
||||
# Help target
|
||||
define helpenvline
|
||||
@echo " $1";echo " $2"
|
||||
@ -164,8 +151,6 @@ help:
|
||||
@echo " $(ANT_TARGETS)"
|
||||
@echo " "
|
||||
@echo " Environment or command line variables (all optional):"
|
||||
$(call helpenvline, ALT_DROPS_DIR,\
|
||||
"Directory that contains the drop source bundles i.e. drops.dir")
|
||||
$(call helpenvline, ALT_BOOTDIR,\
|
||||
"JAVA_HOME to use when running ant")
|
||||
$(call helpenvline, ALT_LANGTOOLS_DIST,\
|
||||
|
||||
90
jaxws/make/scripts/update_src.sh
Normal file
90
jaxws/make/scripts/update_src.sh
Normal file
@ -0,0 +1,90 @@
|
||||
#
|
||||
# Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
|
||||
# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
#
|
||||
# This code is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License version 2 only, as
|
||||
# published by the Free Software Foundation. Oracle designates this
|
||||
# particular file as subject to the "Classpath" exception as provided
|
||||
# by Oracle in the LICENSE file that accompanied this code.
|
||||
#
|
||||
# This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
# version 2 for more details (a copy is included in the LICENSE file that
|
||||
# accompanied this code).
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License version
|
||||
# 2 along with this work; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
# or visit www.oracle.com if you need additional information or have any
|
||||
# questions.
|
||||
#
|
||||
|
||||
# This script was used to copy the former drop source bundle source into
|
||||
# the repository. Exists as a form of documentation.
|
||||
|
||||
curdir="`(cd . && pwd)`"
|
||||
|
||||
# Whitespace normalizer script is in the top repository.
|
||||
normalizer="perl ${curdir}/../make/scripts/normalizer.pl"
|
||||
|
||||
# Locations for bundle and root of source tree
|
||||
tmp=/tmp
|
||||
srcroot=${curdir}/src
|
||||
mkdir -p ${srcroot}
|
||||
|
||||
# Bundle information
|
||||
drops_dir="/java/devtools/share/jdk8-drops"
|
||||
url1="http://download.java.net/glassfish/components/jax-ws/openjdk/jdk8"
|
||||
bundle1="jdk8-jaxws-2_2-SNAPSHOT-2012_01_11-patched.zip"
|
||||
srcdir1="${srcroot}/share/jaxws_classes"
|
||||
url2="http://download.java.net/glassfish/components/jax-ws/openjdk/jdk8"
|
||||
bundle2="jdk8-jaf-2011_07_22.zip"
|
||||
srcdir2="${srcroot}/share/jaf_classes"
|
||||
|
||||
# Function to get a bundle and explode it and normalize the source files.
|
||||
getBundle() # drops_dir url bundlename bundledestdir srcrootdir
|
||||
{
|
||||
# Get the bundle from drops_dir or downloaded
|
||||
mkdir -p $4
|
||||
rm -f $4/$3
|
||||
if [ -f $1/$3 ] ; then
|
||||
echo "Copy over bundle: $1/$3"
|
||||
cp $1/$3 $4
|
||||
else
|
||||
echo "Downloading bundle: $2/$3"
|
||||
(cd $4 && wget $2/$3)
|
||||
fi
|
||||
# Fail if it does not exist
|
||||
if [ ! -f $4/$3 ] ; then
|
||||
echo "ERROR: Could not get $3"
|
||||
exit 1
|
||||
fi
|
||||
# Wipe it out completely
|
||||
echo "Cleaning up $5"
|
||||
rm -f -r $5
|
||||
mkdir -p $5
|
||||
echo "Unzipping $4/$3"
|
||||
( cd $5 && unzip -q $4/$3 && mv src/* . && rmdir src && rm LICENSE )
|
||||
# Run whitespace normalizer
|
||||
echo "Normalizing the sources in $5"
|
||||
( cd $5 && ${normalizer} . )
|
||||
# Delete the bundle and leftover files
|
||||
rm -f $4/$3 $5/filelist
|
||||
}
|
||||
|
||||
# Process the bundles.
|
||||
getBundle "${drops_dir}" "${url1}" "${bundle1}" ${tmp} ${srcdir1}
|
||||
getBundle "${drops_dir}" "${url2}" "${bundle2}" ${tmp} ${srcdir2}
|
||||
echo "Completed bundle extraction."
|
||||
echo " "
|
||||
|
||||
# Appropriate Mercurial commands needed to run:
|
||||
echo "Run: hg addremove src"
|
||||
echo "Run: ksh ../make/scripts/webrev.ksh -N -o ${HOME}/webrev"
|
||||
echo "Get reviewer, get CR, then..."
|
||||
echo "Run: hg commit"
|
||||
|
||||
@ -1,5 +0,0 @@
|
||||
|
||||
This directory will hold any patches that need to be applied to the drop files.
|
||||
|
||||
The patch order is defined in the ant build script properties.
|
||||
|
||||
7
jaxws/src/share/jaf_classes/META-INF/mailcap.default
Normal file
7
jaxws/src/share/jaf_classes/META-INF/mailcap.default
Normal file
@ -0,0 +1,7 @@
|
||||
#
|
||||
# This is a very simple 'mailcap' file
|
||||
#
|
||||
image/gif;; x-java-view=com.sun.activation.viewers.ImageViewer
|
||||
image/jpeg;; x-java-view=com.sun.activation.viewers.ImageViewer
|
||||
text/*;; x-java-view=com.sun.activation.viewers.TextViewer
|
||||
text/*;; x-java-edit=com.sun.activation.viewers.TextEditor
|
||||
24
jaxws/src/share/jaf_classes/META-INF/mimetypes.default
Normal file
24
jaxws/src/share/jaf_classes/META-INF/mimetypes.default
Normal file
@ -0,0 +1,24 @@
|
||||
#
|
||||
# A simple, old format, mime.types file
|
||||
#
|
||||
text/html html htm HTML HTM
|
||||
text/plain txt text TXT TEXT
|
||||
image/gif gif GIF
|
||||
image/ief ief
|
||||
image/jpeg jpeg jpg jpe JPG
|
||||
image/tiff tiff tif
|
||||
image/x-xwindowdump xwd
|
||||
application/postscript ai eps ps
|
||||
application/rtf rtf
|
||||
application/x-tex tex
|
||||
application/x-texinfo texinfo texi
|
||||
application/x-troff t tr roff
|
||||
audio/basic au
|
||||
audio/midi midi mid
|
||||
audio/x-aifc aifc
|
||||
audio/x-aiff aif aiff
|
||||
audio/x-mpeg mpeg mpg
|
||||
audio/x-wav wav
|
||||
video/mpeg mpeg mpg mpe
|
||||
video/quicktime qt mov
|
||||
video/x-msvideo avi
|
||||
@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2003, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.activation.registries;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.logging.*;
|
||||
|
||||
/**
|
||||
* Logging related methods.
|
||||
*/
|
||||
public class LogSupport {
|
||||
private static boolean debug = false;
|
||||
private static Logger logger;
|
||||
private static final Level level = Level.FINE;
|
||||
|
||||
static {
|
||||
try {
|
||||
debug = Boolean.getBoolean("javax.activation.debug");
|
||||
} catch (Throwable t) {
|
||||
// ignore any errors
|
||||
}
|
||||
logger = Logger.getLogger("javax.activation");
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
private LogSupport() {
|
||||
// private constructor, can't create instances
|
||||
}
|
||||
|
||||
public static void log(String msg) {
|
||||
if (debug)
|
||||
System.out.println(msg);
|
||||
logger.log(level, msg);
|
||||
}
|
||||
|
||||
public static void log(String msg, Throwable t) {
|
||||
if (debug)
|
||||
System.out.println(msg + "; Exception: " + t);
|
||||
logger.log(level, msg, t);
|
||||
}
|
||||
|
||||
public static boolean isLoggable() {
|
||||
return debug || logger.isLoggable(level);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,563 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.activation.registries;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MailcapFile {
|
||||
|
||||
/**
|
||||
* A Map indexed by MIME type (string) that references
|
||||
* a Map of commands for each type. The comand Map
|
||||
* is indexed by the command name and references a List of
|
||||
* class names (strings) for each command.
|
||||
*/
|
||||
private Map type_hash = new HashMap();
|
||||
|
||||
/**
|
||||
* Another Map like above, but for fallback entries.
|
||||
*/
|
||||
private Map fallback_hash = new HashMap();
|
||||
|
||||
/**
|
||||
* A Map indexed by MIME type (string) that references
|
||||
* a List of native commands (string) corresponding to the type.
|
||||
*/
|
||||
private Map native_commands = new HashMap();
|
||||
|
||||
private static boolean addReverse = false;
|
||||
|
||||
static {
|
||||
try {
|
||||
addReverse = Boolean.getBoolean("javax.activation.addreverse");
|
||||
} catch (Throwable t) {
|
||||
// ignore any errors
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor that takes a filename as an argument.
|
||||
*
|
||||
* @param new_fname The file name of the mailcap file.
|
||||
*/
|
||||
public MailcapFile(String new_fname) throws IOException {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("new MailcapFile: file " + new_fname);
|
||||
FileReader reader = null;
|
||||
try {
|
||||
reader = new FileReader(new_fname);
|
||||
parse(new BufferedReader(reader));
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException ex) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The constructor that takes an input stream as an argument.
|
||||
*
|
||||
* @param is the input stream
|
||||
*/
|
||||
public MailcapFile(InputStream is) throws IOException {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("new MailcapFile: InputStream");
|
||||
parse(new BufferedReader(new InputStreamReader(is, "iso-8859-1")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Mailcap file default constructor.
|
||||
*/
|
||||
public MailcapFile() {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("new MailcapFile: default");
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Map of MailcapEntries based on the MIME type.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Semantics:</strong> First check for the literal mime type,
|
||||
* if that fails looks for wildcard <type>/\* and return that. Return the
|
||||
* list of all that hit.
|
||||
*/
|
||||
public Map getMailcapList(String mime_type) {
|
||||
Map search_result = null;
|
||||
Map wildcard_result = null;
|
||||
|
||||
// first try the literal
|
||||
search_result = (Map)type_hash.get(mime_type);
|
||||
|
||||
// ok, now try the wildcard
|
||||
int separator = mime_type.indexOf('/');
|
||||
String subtype = mime_type.substring(separator + 1);
|
||||
if (!subtype.equals("*")) {
|
||||
String type = mime_type.substring(0, separator + 1) + "*";
|
||||
wildcard_result = (Map)type_hash.get(type);
|
||||
|
||||
if (wildcard_result != null) { // damn, we have to merge!!!
|
||||
if (search_result != null)
|
||||
search_result =
|
||||
mergeResults(search_result, wildcard_result);
|
||||
else
|
||||
search_result = wildcard_result;
|
||||
}
|
||||
}
|
||||
return search_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Map of fallback MailcapEntries based on the MIME type.
|
||||
*
|
||||
* <p>
|
||||
* <strong>Semantics:</strong> First check for the literal mime type,
|
||||
* if that fails looks for wildcard <type>/\* and return that. Return the
|
||||
* list of all that hit.
|
||||
*/
|
||||
public Map getMailcapFallbackList(String mime_type) {
|
||||
Map search_result = null;
|
||||
Map wildcard_result = null;
|
||||
|
||||
// first try the literal
|
||||
search_result = (Map)fallback_hash.get(mime_type);
|
||||
|
||||
// ok, now try the wildcard
|
||||
int separator = mime_type.indexOf('/');
|
||||
String subtype = mime_type.substring(separator + 1);
|
||||
if (!subtype.equals("*")) {
|
||||
String type = mime_type.substring(0, separator + 1) + "*";
|
||||
wildcard_result = (Map)fallback_hash.get(type);
|
||||
|
||||
if (wildcard_result != null) { // damn, we have to merge!!!
|
||||
if (search_result != null)
|
||||
search_result =
|
||||
mergeResults(search_result, wildcard_result);
|
||||
else
|
||||
search_result = wildcard_result;
|
||||
}
|
||||
}
|
||||
return search_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the MIME types known to this mailcap file.
|
||||
*/
|
||||
public String[] getMimeTypes() {
|
||||
Set types = new HashSet(type_hash.keySet());
|
||||
types.addAll(fallback_hash.keySet());
|
||||
types.addAll(native_commands.keySet());
|
||||
String[] mts = new String[types.size()];
|
||||
mts = (String[])types.toArray(mts);
|
||||
return mts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the native comands for the given MIME type.
|
||||
*/
|
||||
public String[] getNativeCommands(String mime_type) {
|
||||
String[] cmds = null;
|
||||
List v =
|
||||
(List)native_commands.get(mime_type.toLowerCase(Locale.ENGLISH));
|
||||
if (v != null) {
|
||||
cmds = new String[v.size()];
|
||||
cmds = (String[])v.toArray(cmds);
|
||||
}
|
||||
return cmds;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the first hash into the second.
|
||||
* This merge will only effect the hashtable that is
|
||||
* returned, we don't want to touch the one passed in since
|
||||
* its integrity must be maintained.
|
||||
*/
|
||||
private Map mergeResults(Map first, Map second) {
|
||||
Iterator verb_enum = second.keySet().iterator();
|
||||
Map clonedHash = new HashMap(first);
|
||||
|
||||
// iterate through the verbs in the second map
|
||||
while (verb_enum.hasNext()) {
|
||||
String verb = (String)verb_enum.next();
|
||||
List cmdVector = (List)clonedHash.get(verb);
|
||||
if (cmdVector == null) {
|
||||
clonedHash.put(verb, second.get(verb));
|
||||
} else {
|
||||
// merge the two
|
||||
List oldV = (List)second.get(verb);
|
||||
cmdVector = new ArrayList(cmdVector);
|
||||
cmdVector.addAll(oldV);
|
||||
clonedHash.put(verb, cmdVector);
|
||||
}
|
||||
}
|
||||
return clonedHash;
|
||||
}
|
||||
|
||||
/**
|
||||
* appendToMailcap: Append to this Mailcap DB, use the mailcap
|
||||
* format:
|
||||
* Comment == "# <i>comment string</i>
|
||||
* Entry == "mimetype; javabeanclass<nl>
|
||||
*
|
||||
* Example:
|
||||
* # this is a comment
|
||||
* image/gif jaf.viewers.ImageViewer
|
||||
*/
|
||||
public void appendToMailcap(String mail_cap) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("appendToMailcap: " + mail_cap);
|
||||
try {
|
||||
parse(new StringReader(mail_cap));
|
||||
} catch (IOException ex) {
|
||||
// can't happen
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* parse file into a hash table of MC Type Entry Obj
|
||||
*/
|
||||
private void parse(Reader reader) throws IOException {
|
||||
BufferedReader buf_reader = new BufferedReader(reader);
|
||||
String line = null;
|
||||
String continued = null;
|
||||
|
||||
while ((line = buf_reader.readLine()) != null) {
|
||||
// LogSupport.log("parsing line: " + line);
|
||||
|
||||
line = line.trim();
|
||||
|
||||
try {
|
||||
if (line.charAt(0) == '#')
|
||||
continue;
|
||||
if (line.charAt(line.length() - 1) == '\\') {
|
||||
if (continued != null)
|
||||
continued += line.substring(0, line.length() - 1);
|
||||
else
|
||||
continued = line.substring(0, line.length() - 1);
|
||||
} else if (continued != null) {
|
||||
// handle the two strings
|
||||
continued = continued + line;
|
||||
// LogSupport.log("parse: " + continued);
|
||||
try {
|
||||
parseLine(continued);
|
||||
} catch (MailcapParseException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
continued = null;
|
||||
}
|
||||
else {
|
||||
// LogSupport.log("parse: " + line);
|
||||
try {
|
||||
parseLine(line);
|
||||
// LogSupport.log("hash.size = " + type_hash.size());
|
||||
} catch (MailcapParseException e) {
|
||||
//e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} catch (StringIndexOutOfBoundsException e) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A routine to parse individual entries in a Mailcap file.
|
||||
*
|
||||
* Note that this routine does not handle line continuations.
|
||||
* They should have been handled prior to calling this routine.
|
||||
*/
|
||||
protected void parseLine(String mailcapEntry)
|
||||
throws MailcapParseException, IOException {
|
||||
MailcapTokenizer tokenizer = new MailcapTokenizer(mailcapEntry);
|
||||
tokenizer.setIsAutoquoting(false);
|
||||
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("parse: " + mailcapEntry);
|
||||
// parse the primary type
|
||||
int currentToken = tokenizer.nextToken();
|
||||
if (currentToken != MailcapTokenizer.STRING_TOKEN) {
|
||||
reportParseError(MailcapTokenizer.STRING_TOKEN, currentToken,
|
||||
tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
String primaryType =
|
||||
tokenizer.getCurrentTokenValue().toLowerCase(Locale.ENGLISH);
|
||||
String subType = "*";
|
||||
|
||||
// parse the '/' between primary and sub
|
||||
// if it's not present that's ok, we just don't have a subtype
|
||||
currentToken = tokenizer.nextToken();
|
||||
if ((currentToken != MailcapTokenizer.SLASH_TOKEN) &&
|
||||
(currentToken != MailcapTokenizer.SEMICOLON_TOKEN)) {
|
||||
reportParseError(MailcapTokenizer.SLASH_TOKEN,
|
||||
MailcapTokenizer.SEMICOLON_TOKEN, currentToken,
|
||||
tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
|
||||
// only need to look for a sub type if we got a '/'
|
||||
if (currentToken == MailcapTokenizer.SLASH_TOKEN) {
|
||||
// parse the sub type
|
||||
currentToken = tokenizer.nextToken();
|
||||
if (currentToken != MailcapTokenizer.STRING_TOKEN) {
|
||||
reportParseError(MailcapTokenizer.STRING_TOKEN,
|
||||
currentToken, tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
subType =
|
||||
tokenizer.getCurrentTokenValue().toLowerCase(Locale.ENGLISH);
|
||||
|
||||
// get the next token to simplify the next step
|
||||
currentToken = tokenizer.nextToken();
|
||||
}
|
||||
|
||||
String mimeType = primaryType + "/" + subType;
|
||||
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log(" Type: " + mimeType);
|
||||
|
||||
// now setup the commands hashtable
|
||||
Map commands = new LinkedHashMap(); // keep commands in order found
|
||||
|
||||
// parse the ';' that separates the type from the parameters
|
||||
if (currentToken != MailcapTokenizer.SEMICOLON_TOKEN) {
|
||||
reportParseError(MailcapTokenizer.SEMICOLON_TOKEN,
|
||||
currentToken, tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
// eat it
|
||||
|
||||
// parse the required view command
|
||||
tokenizer.setIsAutoquoting(true);
|
||||
currentToken = tokenizer.nextToken();
|
||||
tokenizer.setIsAutoquoting(false);
|
||||
if ((currentToken != MailcapTokenizer.STRING_TOKEN) &&
|
||||
(currentToken != MailcapTokenizer.SEMICOLON_TOKEN)) {
|
||||
reportParseError(MailcapTokenizer.STRING_TOKEN,
|
||||
MailcapTokenizer.SEMICOLON_TOKEN, currentToken,
|
||||
tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
|
||||
if (currentToken == MailcapTokenizer.STRING_TOKEN) {
|
||||
// have a native comand, save the entire mailcap entry
|
||||
//String nativeCommand = tokenizer.getCurrentTokenValue();
|
||||
List v = (List)native_commands.get(mimeType);
|
||||
if (v == null) {
|
||||
v = new ArrayList();
|
||||
v.add(mailcapEntry);
|
||||
native_commands.put(mimeType, v);
|
||||
} else {
|
||||
// XXX - check for duplicates?
|
||||
v.add(mailcapEntry);
|
||||
}
|
||||
}
|
||||
|
||||
// only have to get the next token if the current one isn't a ';'
|
||||
if (currentToken != MailcapTokenizer.SEMICOLON_TOKEN) {
|
||||
currentToken = tokenizer.nextToken();
|
||||
}
|
||||
|
||||
// look for a ';' which will indicate whether
|
||||
// a parameter list is present or not
|
||||
if (currentToken == MailcapTokenizer.SEMICOLON_TOKEN) {
|
||||
boolean isFallback = false;
|
||||
do {
|
||||
// eat the ';'
|
||||
|
||||
// parse the parameter name
|
||||
currentToken = tokenizer.nextToken();
|
||||
if (currentToken != MailcapTokenizer.STRING_TOKEN) {
|
||||
reportParseError(MailcapTokenizer.STRING_TOKEN,
|
||||
currentToken, tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
String paramName = tokenizer.getCurrentTokenValue().
|
||||
toLowerCase(Locale.ENGLISH);
|
||||
|
||||
// parse the '=' which separates the name from the value
|
||||
currentToken = tokenizer.nextToken();
|
||||
if ((currentToken != MailcapTokenizer.EQUALS_TOKEN) &&
|
||||
(currentToken != MailcapTokenizer.SEMICOLON_TOKEN) &&
|
||||
(currentToken != MailcapTokenizer.EOI_TOKEN)) {
|
||||
reportParseError(MailcapTokenizer.EQUALS_TOKEN,
|
||||
MailcapTokenizer.SEMICOLON_TOKEN,
|
||||
MailcapTokenizer.EOI_TOKEN,
|
||||
currentToken, tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
|
||||
// we only have a useful command if it is named
|
||||
if (currentToken == MailcapTokenizer.EQUALS_TOKEN) {
|
||||
// eat it
|
||||
|
||||
// parse the parameter value (which is autoquoted)
|
||||
tokenizer.setIsAutoquoting(true);
|
||||
currentToken = tokenizer.nextToken();
|
||||
tokenizer.setIsAutoquoting(false);
|
||||
if (currentToken != MailcapTokenizer.STRING_TOKEN) {
|
||||
reportParseError(MailcapTokenizer.STRING_TOKEN,
|
||||
currentToken, tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
String paramValue =
|
||||
tokenizer.getCurrentTokenValue();
|
||||
|
||||
// add the class to the list iff it is one we care about
|
||||
if (paramName.startsWith("x-java-")) {
|
||||
String commandName = paramName.substring(7);
|
||||
// 7 == "x-java-".length
|
||||
|
||||
if (commandName.equals("fallback-entry") &&
|
||||
paramValue.equalsIgnoreCase("true")) {
|
||||
isFallback = true;
|
||||
} else {
|
||||
|
||||
// setup the class entry list
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log(" Command: " + commandName +
|
||||
", Class: " + paramValue);
|
||||
List classes = (List)commands.get(commandName);
|
||||
if (classes == null) {
|
||||
classes = new ArrayList();
|
||||
commands.put(commandName, classes);
|
||||
}
|
||||
if (addReverse)
|
||||
classes.add(0, paramValue);
|
||||
else
|
||||
classes.add(paramValue);
|
||||
}
|
||||
}
|
||||
|
||||
// set up the next iteration
|
||||
currentToken = tokenizer.nextToken();
|
||||
}
|
||||
} while (currentToken == MailcapTokenizer.SEMICOLON_TOKEN);
|
||||
|
||||
Map masterHash = isFallback ? fallback_hash : type_hash;
|
||||
Map curcommands =
|
||||
(Map)masterHash.get(mimeType);
|
||||
if (curcommands == null) {
|
||||
masterHash.put(mimeType, commands);
|
||||
} else {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("Merging commands for type " + mimeType);
|
||||
// have to merge current and new commands
|
||||
// first, merge list of classes for commands already known
|
||||
Iterator cn = curcommands.keySet().iterator();
|
||||
while (cn.hasNext()) {
|
||||
String cmdName = (String)cn.next();
|
||||
List ccv = (List)curcommands.get(cmdName);
|
||||
List cv = (List)commands.get(cmdName);
|
||||
if (cv == null)
|
||||
continue;
|
||||
// add everything in cv to ccv, if it's not already there
|
||||
Iterator cvn = cv.iterator();
|
||||
while (cvn.hasNext()) {
|
||||
String clazz = (String)cvn.next();
|
||||
if (!ccv.contains(clazz))
|
||||
if (addReverse)
|
||||
ccv.add(0, clazz);
|
||||
else
|
||||
ccv.add(clazz);
|
||||
}
|
||||
}
|
||||
// now, add commands not previously known
|
||||
cn = commands.keySet().iterator();
|
||||
while (cn.hasNext()) {
|
||||
String cmdName = (String)cn.next();
|
||||
if (curcommands.containsKey(cmdName))
|
||||
continue;
|
||||
List cv = (List)commands.get(cmdName);
|
||||
curcommands.put(cmdName, cv);
|
||||
}
|
||||
}
|
||||
} else if (currentToken != MailcapTokenizer.EOI_TOKEN) {
|
||||
reportParseError(MailcapTokenizer.EOI_TOKEN,
|
||||
MailcapTokenizer.SEMICOLON_TOKEN,
|
||||
currentToken, tokenizer.getCurrentTokenValue());
|
||||
}
|
||||
}
|
||||
|
||||
protected static void reportParseError(int expectedToken, int actualToken,
|
||||
String actualTokenValue) throws MailcapParseException {
|
||||
throw new MailcapParseException("Encountered a " +
|
||||
MailcapTokenizer.nameForToken(actualToken) + " token (" +
|
||||
actualTokenValue + ") while expecting a " +
|
||||
MailcapTokenizer.nameForToken(expectedToken) + " token.");
|
||||
}
|
||||
|
||||
protected static void reportParseError(int expectedToken,
|
||||
int otherExpectedToken, int actualToken, String actualTokenValue)
|
||||
throws MailcapParseException {
|
||||
throw new MailcapParseException("Encountered a " +
|
||||
MailcapTokenizer.nameForToken(actualToken) + " token (" +
|
||||
actualTokenValue + ") while expecting a " +
|
||||
MailcapTokenizer.nameForToken(expectedToken) + " or a " +
|
||||
MailcapTokenizer.nameForToken(otherExpectedToken) + " token.");
|
||||
}
|
||||
|
||||
protected static void reportParseError(int expectedToken,
|
||||
int otherExpectedToken, int anotherExpectedToken, int actualToken,
|
||||
String actualTokenValue) throws MailcapParseException {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("PARSE ERROR: " + "Encountered a " +
|
||||
MailcapTokenizer.nameForToken(actualToken) + " token (" +
|
||||
actualTokenValue + ") while expecting a " +
|
||||
MailcapTokenizer.nameForToken(expectedToken) + ", a " +
|
||||
MailcapTokenizer.nameForToken(otherExpectedToken) + ", or a " +
|
||||
MailcapTokenizer.nameForToken(anotherExpectedToken) + " token.");
|
||||
throw new MailcapParseException("Encountered a " +
|
||||
MailcapTokenizer.nameForToken(actualToken) + " token (" +
|
||||
actualTokenValue + ") while expecting a " +
|
||||
MailcapTokenizer.nameForToken(expectedToken) + ", a " +
|
||||
MailcapTokenizer.nameForToken(otherExpectedToken) + ", or a " +
|
||||
MailcapTokenizer.nameForToken(anotherExpectedToken) + " token.");
|
||||
}
|
||||
|
||||
/** for debugging
|
||||
public static void main(String[] args) throws Exception {
|
||||
Map masterHash = new HashMap();
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
System.out.println("Entry " + i + ": " + args[i]);
|
||||
parseLine(args[i], masterHash);
|
||||
}
|
||||
|
||||
Enumeration types = masterHash.keys();
|
||||
while (types.hasMoreElements()) {
|
||||
String key = (String)types.nextElement();
|
||||
System.out.println("MIME Type: " + key);
|
||||
|
||||
Map commandHash = (Map)masterHash.get(key);
|
||||
Enumeration commands = commandHash.keys();
|
||||
while (commands.hasMoreElements()) {
|
||||
String command = (String)commands.nextElement();
|
||||
System.out.println(" Command: " + command);
|
||||
|
||||
Vector classes = (Vector)commandHash.get(command);
|
||||
for (int i = 0; i < classes.size(); ++i) {
|
||||
System.out.println(" Class: " +
|
||||
(String)classes.elementAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 1997, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.activation.registries;
|
||||
|
||||
/**
|
||||
* A class to encapsulate Mailcap parsing related exceptions
|
||||
*/
|
||||
public class MailcapParseException extends Exception {
|
||||
|
||||
public MailcapParseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public MailcapParseException(String inInfo) {
|
||||
super(inInfo);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.activation.registries;
|
||||
|
||||
/**
|
||||
* A tokenizer for strings in the form of "foo/bar; prop1=val1; ... ".
|
||||
* Useful for parsing MIME content types.
|
||||
*/
|
||||
public class MailcapTokenizer {
|
||||
|
||||
public static final int UNKNOWN_TOKEN = 0;
|
||||
public static final int START_TOKEN = 1;
|
||||
public static final int STRING_TOKEN = 2;
|
||||
public static final int EOI_TOKEN = 5;
|
||||
public static final int SLASH_TOKEN = '/';
|
||||
public static final int SEMICOLON_TOKEN = ';';
|
||||
public static final int EQUALS_TOKEN = '=';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @parameter inputString the string to tokenize
|
||||
*/
|
||||
public MailcapTokenizer(String inputString) {
|
||||
data = inputString;
|
||||
dataIndex = 0;
|
||||
dataLength = inputString.length();
|
||||
|
||||
currentToken = START_TOKEN;
|
||||
currentTokenValue = "";
|
||||
|
||||
isAutoquoting = false;
|
||||
autoquoteChar = ';';
|
||||
}
|
||||
|
||||
/**
|
||||
* Set whether auto-quoting is on or off.
|
||||
*
|
||||
* Auto-quoting means that all characters after the first
|
||||
* non-whitespace, non-control character up to the auto-quote
|
||||
* terminator character or EOI (minus any whitespace immediatley
|
||||
* preceeding it) is considered a token.
|
||||
*
|
||||
* This is required for handling command strings in a mailcap entry.
|
||||
*/
|
||||
public void setIsAutoquoting(boolean value) {
|
||||
isAutoquoting = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve current token.
|
||||
*
|
||||
* @returns The current token value
|
||||
*/
|
||||
public int getCurrentToken() {
|
||||
return currentToken;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a String that describes the given token.
|
||||
*/
|
||||
public static String nameForToken(int token) {
|
||||
String name = "really unknown";
|
||||
|
||||
switch(token) {
|
||||
case UNKNOWN_TOKEN:
|
||||
name = "unknown";
|
||||
break;
|
||||
case START_TOKEN:
|
||||
name = "start";
|
||||
break;
|
||||
case STRING_TOKEN:
|
||||
name = "string";
|
||||
break;
|
||||
case EOI_TOKEN:
|
||||
name = "EOI";
|
||||
break;
|
||||
case SLASH_TOKEN:
|
||||
name = "'/'";
|
||||
break;
|
||||
case SEMICOLON_TOKEN:
|
||||
name = "';'";
|
||||
break;
|
||||
case EQUALS_TOKEN:
|
||||
name = "'='";
|
||||
break;
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
|
||||
/*
|
||||
* Retrieve current token value.
|
||||
*
|
||||
* @returns A String containing the current token value
|
||||
*/
|
||||
public String getCurrentTokenValue() {
|
||||
return currentTokenValue;
|
||||
}
|
||||
/*
|
||||
* Process the next token.
|
||||
*
|
||||
* @returns the next token
|
||||
*/
|
||||
public int nextToken() {
|
||||
if (dataIndex < dataLength) {
|
||||
// skip white space
|
||||
while ((dataIndex < dataLength) &&
|
||||
(isWhiteSpaceChar(data.charAt(dataIndex)))) {
|
||||
++dataIndex;
|
||||
}
|
||||
|
||||
if (dataIndex < dataLength) {
|
||||
// examine the current character and see what kind of token we have
|
||||
char c = data.charAt(dataIndex);
|
||||
if (isAutoquoting) {
|
||||
if (c == ';' || c == '=') {
|
||||
currentToken = c;
|
||||
currentTokenValue = new Character(c).toString();
|
||||
++dataIndex;
|
||||
} else {
|
||||
processAutoquoteToken();
|
||||
}
|
||||
} else {
|
||||
if (isStringTokenChar(c)) {
|
||||
processStringToken();
|
||||
} else if ((c == '/') || (c == ';') || (c == '=')) {
|
||||
currentToken = c;
|
||||
currentTokenValue = new Character(c).toString();
|
||||
++dataIndex;
|
||||
} else {
|
||||
currentToken = UNKNOWN_TOKEN;
|
||||
currentTokenValue = new Character(c).toString();
|
||||
++dataIndex;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
currentToken = EOI_TOKEN;
|
||||
currentTokenValue = null;
|
||||
}
|
||||
} else {
|
||||
currentToken = EOI_TOKEN;
|
||||
currentTokenValue = null;
|
||||
}
|
||||
|
||||
return currentToken;
|
||||
}
|
||||
|
||||
private void processStringToken() {
|
||||
// capture the initial index
|
||||
int initialIndex = dataIndex;
|
||||
|
||||
// skip to 1st non string token character
|
||||
while ((dataIndex < dataLength) &&
|
||||
isStringTokenChar(data.charAt(dataIndex))) {
|
||||
++dataIndex;
|
||||
}
|
||||
|
||||
currentToken = STRING_TOKEN;
|
||||
currentTokenValue = data.substring(initialIndex, dataIndex);
|
||||
}
|
||||
|
||||
private void processAutoquoteToken() {
|
||||
// capture the initial index
|
||||
int initialIndex = dataIndex;
|
||||
|
||||
// now skip to the 1st non-escaped autoquote termination character
|
||||
// XXX - doesn't actually consider escaping
|
||||
boolean foundTerminator = false;
|
||||
while ((dataIndex < dataLength) && !foundTerminator) {
|
||||
char c = data.charAt(dataIndex);
|
||||
if (c != autoquoteChar) {
|
||||
++dataIndex;
|
||||
} else {
|
||||
foundTerminator = true;
|
||||
}
|
||||
}
|
||||
|
||||
currentToken = STRING_TOKEN;
|
||||
currentTokenValue =
|
||||
fixEscapeSequences(data.substring(initialIndex, dataIndex));
|
||||
}
|
||||
|
||||
private static boolean isSpecialChar(char c) {
|
||||
boolean lAnswer = false;
|
||||
|
||||
switch(c) {
|
||||
case '(':
|
||||
case ')':
|
||||
case '<':
|
||||
case '>':
|
||||
case '@':
|
||||
case ',':
|
||||
case ';':
|
||||
case ':':
|
||||
case '\\':
|
||||
case '"':
|
||||
case '/':
|
||||
case '[':
|
||||
case ']':
|
||||
case '?':
|
||||
case '=':
|
||||
lAnswer = true;
|
||||
break;
|
||||
}
|
||||
|
||||
return lAnswer;
|
||||
}
|
||||
|
||||
private static boolean isControlChar(char c) {
|
||||
return Character.isISOControl(c);
|
||||
}
|
||||
|
||||
private static boolean isWhiteSpaceChar(char c) {
|
||||
return Character.isWhitespace(c);
|
||||
}
|
||||
|
||||
private static boolean isStringTokenChar(char c) {
|
||||
return !isSpecialChar(c) && !isControlChar(c) && !isWhiteSpaceChar(c);
|
||||
}
|
||||
|
||||
private static String fixEscapeSequences(String inputString) {
|
||||
int inputLength = inputString.length();
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.ensureCapacity(inputLength);
|
||||
|
||||
for (int i = 0; i < inputLength; ++i) {
|
||||
char currentChar = inputString.charAt(i);
|
||||
if (currentChar != '\\') {
|
||||
buffer.append(currentChar);
|
||||
} else {
|
||||
if (i < inputLength - 1) {
|
||||
char nextChar = inputString.charAt(i + 1);
|
||||
buffer.append(nextChar);
|
||||
|
||||
// force a skip over the next character too
|
||||
++i;
|
||||
} else {
|
||||
buffer.append(currentChar);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
private String data;
|
||||
private int dataIndex;
|
||||
private int dataLength;
|
||||
private int currentToken;
|
||||
private String currentTokenValue;
|
||||
private boolean isAutoquoting;
|
||||
private char autoquoteChar;
|
||||
|
||||
/*
|
||||
public static void main(String[] args) {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
MailcapTokenizer tokenizer = new MailcapTokenizer(args[i]);
|
||||
|
||||
System.out.println("Original: |" + args[i] + "|");
|
||||
|
||||
int currentToken = tokenizer.nextToken();
|
||||
while (currentToken != EOI_TOKEN) {
|
||||
switch(currentToken) {
|
||||
case UNKNOWN_TOKEN:
|
||||
System.out.println(" Unknown Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
case START_TOKEN:
|
||||
System.out.println(" Start Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
case STRING_TOKEN:
|
||||
System.out.println(" String Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
case EOI_TOKEN:
|
||||
System.out.println(" EOI Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
case SLASH_TOKEN:
|
||||
System.out.println(" Slash Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
case SEMICOLON_TOKEN:
|
||||
System.out.println(" Semicolon Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
case EQUALS_TOKEN:
|
||||
System.out.println(" Equals Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
default:
|
||||
System.out.println(" Really Unknown Token: |" + tokenizer.getCurrentTokenValue() + "|");
|
||||
break;
|
||||
}
|
||||
|
||||
currentToken = tokenizer.nextToken();
|
||||
}
|
||||
|
||||
System.out.println("");
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1998, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.activation.registries;
|
||||
|
||||
import java.lang.*;
|
||||
|
||||
public class MimeTypeEntry {
|
||||
private String type;
|
||||
private String extension;
|
||||
|
||||
public MimeTypeEntry(String mime_type, String file_ext) {
|
||||
type = mime_type;
|
||||
extension = file_ext;
|
||||
}
|
||||
|
||||
public String getMIMEType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public String getFileExtension() {
|
||||
return extension;
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return "MIMETypeEntry: " + type + ", " + extension;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,317 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package com.sun.activation.registries;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
public class MimeTypeFile {
|
||||
private String fname = null;
|
||||
private Hashtable type_hash = new Hashtable();
|
||||
|
||||
/**
|
||||
* The construtor that takes a filename as an argument.
|
||||
*
|
||||
* @param new_fname The file name of the mime types file.
|
||||
*/
|
||||
public MimeTypeFile(String new_fname) throws IOException {
|
||||
File mime_file = null;
|
||||
FileReader fr = null;
|
||||
|
||||
fname = new_fname; // remember the file name
|
||||
|
||||
mime_file = new File(fname); // get a file object
|
||||
|
||||
fr = new FileReader(mime_file);
|
||||
|
||||
try {
|
||||
parse(new BufferedReader(fr));
|
||||
} finally {
|
||||
try {
|
||||
fr.close(); // close it
|
||||
} catch (IOException e) {
|
||||
// ignore it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public MimeTypeFile(InputStream is) throws IOException {
|
||||
parse(new BufferedReader(new InputStreamReader(is, "iso-8859-1")));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an empty DB.
|
||||
*/
|
||||
public MimeTypeFile() {
|
||||
}
|
||||
|
||||
/**
|
||||
* get the MimeTypeEntry based on the file extension
|
||||
*/
|
||||
public MimeTypeEntry getMimeTypeEntry(String file_ext) {
|
||||
return (MimeTypeEntry)type_hash.get((Object)file_ext);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the MIME type string corresponding to the file extension.
|
||||
*/
|
||||
public String getMIMETypeString(String file_ext) {
|
||||
MimeTypeEntry entry = this.getMimeTypeEntry(file_ext);
|
||||
|
||||
if (entry != null)
|
||||
return entry.getMIMEType();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends string of entries to the types registry, must be valid
|
||||
* .mime.types format.
|
||||
* A mime.types entry is one of two forms:
|
||||
*
|
||||
* type/subtype ext1 ext2 ...
|
||||
* or
|
||||
* type=type/subtype desc="description of type" exts=ext1,ext2,...
|
||||
*
|
||||
* Example:
|
||||
* # this is a test
|
||||
* audio/basic au
|
||||
* text/plain txt text
|
||||
* type=application/postscript exts=ps,eps
|
||||
*/
|
||||
public void appendToRegistry(String mime_types) {
|
||||
try {
|
||||
parse(new BufferedReader(new StringReader(mime_types)));
|
||||
} catch (IOException ex) {
|
||||
// can't happen
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse a stream of mime.types entries.
|
||||
*/
|
||||
private void parse(BufferedReader buf_reader) throws IOException {
|
||||
String line = null, prev = null;
|
||||
|
||||
while ((line = buf_reader.readLine()) != null) {
|
||||
if (prev == null)
|
||||
prev = line;
|
||||
else
|
||||
prev += line;
|
||||
int end = prev.length();
|
||||
if (prev.length() > 0 && prev.charAt(end - 1) == '\\') {
|
||||
prev = prev.substring(0, end - 1);
|
||||
continue;
|
||||
}
|
||||
this.parseEntry(prev);
|
||||
prev = null;
|
||||
}
|
||||
if (prev != null)
|
||||
this.parseEntry(prev);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parse single mime.types entry.
|
||||
*/
|
||||
private void parseEntry(String line) {
|
||||
String mime_type = null;
|
||||
String file_ext = null;
|
||||
line = line.trim();
|
||||
|
||||
if (line.length() == 0) // empty line...
|
||||
return; // BAIL!
|
||||
|
||||
// check to see if this is a comment line?
|
||||
if (line.charAt(0) == '#')
|
||||
return; // then we are done!
|
||||
|
||||
// is it a new format line or old format?
|
||||
if (line.indexOf('=') > 0) {
|
||||
// new format
|
||||
LineTokenizer lt = new LineTokenizer(line);
|
||||
while (lt.hasMoreTokens()) {
|
||||
String name = lt.nextToken();
|
||||
String value = null;
|
||||
if (lt.hasMoreTokens() && lt.nextToken().equals("=") &&
|
||||
lt.hasMoreTokens())
|
||||
value = lt.nextToken();
|
||||
if (value == null) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("Bad .mime.types entry: " + line);
|
||||
return;
|
||||
}
|
||||
if (name.equals("type"))
|
||||
mime_type = value;
|
||||
else if (name.equals("exts")) {
|
||||
StringTokenizer st = new StringTokenizer(value, ",");
|
||||
while (st.hasMoreTokens()) {
|
||||
file_ext = st.nextToken();
|
||||
MimeTypeEntry entry =
|
||||
new MimeTypeEntry(mime_type, file_ext);
|
||||
type_hash.put(file_ext, entry);
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("Added: " + entry.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// old format
|
||||
// count the tokens
|
||||
StringTokenizer strtok = new StringTokenizer(line);
|
||||
int num_tok = strtok.countTokens();
|
||||
|
||||
if (num_tok == 0) // empty line
|
||||
return;
|
||||
|
||||
mime_type = strtok.nextToken(); // get the MIME type
|
||||
|
||||
while (strtok.hasMoreTokens()) {
|
||||
MimeTypeEntry entry = null;
|
||||
|
||||
file_ext = strtok.nextToken();
|
||||
entry = new MimeTypeEntry(mime_type, file_ext);
|
||||
type_hash.put(file_ext, entry);
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("Added: " + entry.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// for debugging
|
||||
/*
|
||||
public static void main(String[] argv) throws Exception {
|
||||
MimeTypeFile mf = new MimeTypeFile(argv[0]);
|
||||
System.out.println("ext " + argv[1] + " type " +
|
||||
mf.getMIMETypeString(argv[1]));
|
||||
System.exit(0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
class LineTokenizer {
|
||||
private int currentPosition;
|
||||
private int maxPosition;
|
||||
private String str;
|
||||
private Vector stack = new Vector();
|
||||
private static final String singles = "="; // single character tokens
|
||||
|
||||
/**
|
||||
* Constructs a tokenizer for the specified string.
|
||||
* <p>
|
||||
*
|
||||
* @param str a string to be parsed.
|
||||
*/
|
||||
public LineTokenizer(String str) {
|
||||
currentPosition = 0;
|
||||
this.str = str;
|
||||
maxPosition = str.length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips white space.
|
||||
*/
|
||||
private void skipWhiteSpace() {
|
||||
while ((currentPosition < maxPosition) &&
|
||||
Character.isWhitespace(str.charAt(currentPosition))) {
|
||||
currentPosition++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests if there are more tokens available from this tokenizer's string.
|
||||
*
|
||||
* @return <code>true</code> if there are more tokens available from this
|
||||
* tokenizer's string; <code>false</code> otherwise.
|
||||
*/
|
||||
public boolean hasMoreTokens() {
|
||||
if (stack.size() > 0)
|
||||
return true;
|
||||
skipWhiteSpace();
|
||||
return (currentPosition < maxPosition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the next token from this tokenizer.
|
||||
*
|
||||
* @return the next token from this tokenizer.
|
||||
* @exception NoSuchElementException if there are no more tokens in this
|
||||
* tokenizer's string.
|
||||
*/
|
||||
public String nextToken() {
|
||||
int size = stack.size();
|
||||
if (size > 0) {
|
||||
String t = (String)stack.elementAt(size - 1);
|
||||
stack.removeElementAt(size - 1);
|
||||
return t;
|
||||
}
|
||||
skipWhiteSpace();
|
||||
|
||||
if (currentPosition >= maxPosition) {
|
||||
throw new NoSuchElementException();
|
||||
}
|
||||
|
||||
int start = currentPosition;
|
||||
char c = str.charAt(start);
|
||||
if (c == '"') {
|
||||
currentPosition++;
|
||||
boolean filter = false;
|
||||
while (currentPosition < maxPosition) {
|
||||
c = str.charAt(currentPosition++);
|
||||
if (c == '\\') {
|
||||
currentPosition++;
|
||||
filter = true;
|
||||
} else if (c == '"') {
|
||||
String s;
|
||||
|
||||
if (filter) {
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int i = start + 1; i < currentPosition - 1; i++) {
|
||||
c = str.charAt(i);
|
||||
if (c != '\\')
|
||||
sb.append(c);
|
||||
}
|
||||
s = sb.toString();
|
||||
} else
|
||||
s = str.substring(start + 1, currentPosition - 1);
|
||||
return s;
|
||||
}
|
||||
}
|
||||
} else if (singles.indexOf(c) >= 0) {
|
||||
currentPosition++;
|
||||
} else {
|
||||
while ((currentPosition < maxPosition) &&
|
||||
singles.indexOf(str.charAt(currentPosition)) < 0 &&
|
||||
!Character.isWhitespace(str.charAt(currentPosition))) {
|
||||
currentPosition++;
|
||||
}
|
||||
}
|
||||
return str.substring(start, currentPosition);
|
||||
}
|
||||
|
||||
public void pushToken(String token) {
|
||||
stack.addElement(token);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,250 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.io.IOException;
|
||||
import javax.activation.MimeType;
|
||||
|
||||
/**
|
||||
* The ActivationDataFlavor class is a special subclass of
|
||||
* <code>java.awt.datatransfer.DataFlavor</code>. It allows the JAF to
|
||||
* set all three values stored by the DataFlavor class via a new
|
||||
* constructor. It also contains improved MIME parsing in the <code>equals
|
||||
* </code> method. Except for the improved parsing, its semantics are
|
||||
* identical to that of the JDK's DataFlavor class.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public class ActivationDataFlavor extends DataFlavor {
|
||||
|
||||
/*
|
||||
* Raison d'etre:
|
||||
*
|
||||
* The DataFlavor class included in JDK 1.1 has several limitations
|
||||
* including piss poor MIME type parsing, and the limitation of
|
||||
* only supporting serialized objects and InputStreams as
|
||||
* representation objects. This class 'fixes' that.
|
||||
*/
|
||||
|
||||
// I think for now I'll keep copies of all the variables and
|
||||
// then later I may choose try to better coexist with the base
|
||||
// class *sigh*
|
||||
private String mimeType = null;
|
||||
private MimeType mimeObject = null;
|
||||
private String humanPresentableName = null;
|
||||
private Class representationClass = null;
|
||||
|
||||
/**
|
||||
* Construct a DataFlavor that represents an arbitrary
|
||||
* Java object. This constructor is an extension of the
|
||||
* JDK's DataFlavor in that it allows the explicit setting
|
||||
* of all three DataFlavor attributes.
|
||||
* <p>
|
||||
* The returned DataFlavor will have the following characteristics:
|
||||
* <p>
|
||||
* representationClass = representationClass<br>
|
||||
* mimeType = mimeType<br>
|
||||
* humanName = humanName
|
||||
* <p>
|
||||
*
|
||||
* @param representationClass the class used in this DataFlavor
|
||||
* @param mimeType the MIME type of the data represented by this class
|
||||
* @param humanPresentableName the human presentable name of the flavor
|
||||
*/
|
||||
public ActivationDataFlavor(Class representationClass,
|
||||
String mimeType, String humanPresentableName) {
|
||||
super(mimeType, humanPresentableName); // need to call super
|
||||
|
||||
// init private variables:
|
||||
this.mimeType = mimeType;
|
||||
this.humanPresentableName = humanPresentableName;
|
||||
this.representationClass = representationClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a DataFlavor that represents a MimeType.
|
||||
* <p>
|
||||
* The returned DataFlavor will have the following characteristics:
|
||||
* <p>
|
||||
* If the mimeType is "application/x-java-serialized-object;
|
||||
* class=", the result is the same as calling new
|
||||
* DataFlavor(Class.forName()) as above.
|
||||
* <p>
|
||||
* otherwise:
|
||||
* <p>
|
||||
* representationClass = InputStream<p>
|
||||
* mimeType = mimeType<p>
|
||||
*
|
||||
* @param representationClass the class used in this DataFlavor
|
||||
* @param humanPresentableName the human presentable name of the flavor
|
||||
*/
|
||||
public ActivationDataFlavor(Class representationClass,
|
||||
String humanPresentableName) {
|
||||
super(representationClass, humanPresentableName);
|
||||
this.mimeType = super.getMimeType();
|
||||
this.representationClass = representationClass;
|
||||
this.humanPresentableName = humanPresentableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a DataFlavor that represents a MimeType.
|
||||
* <p>
|
||||
* The returned DataFlavor will have the following characteristics:
|
||||
* <p>
|
||||
* If the mimeType is "application/x-java-serialized-object; class=",
|
||||
* the result is the same as calling new DataFlavor(Class.forName()) as
|
||||
* above, otherwise:
|
||||
* <p>
|
||||
* representationClass = InputStream<p>
|
||||
* mimeType = mimeType
|
||||
*
|
||||
* @param mimeType the MIME type of the data represented by this class
|
||||
* @param humanPresentableName the human presentable name of the flavor
|
||||
*/
|
||||
public ActivationDataFlavor(String mimeType, String humanPresentableName) {
|
||||
super(mimeType, humanPresentableName);
|
||||
this.mimeType = mimeType;
|
||||
try {
|
||||
this.representationClass = Class.forName("java.io.InputStream");
|
||||
} catch (ClassNotFoundException ex) {
|
||||
// XXX - should never happen, ignore it
|
||||
}
|
||||
this.humanPresentableName = humanPresentableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MIME type for this DataFlavor.
|
||||
*
|
||||
* @return the MIME type
|
||||
*/
|
||||
public String getMimeType() {
|
||||
return mimeType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the representation class.
|
||||
*
|
||||
* @return the representation class
|
||||
*/
|
||||
public Class getRepresentationClass() {
|
||||
return representationClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Human Presentable name.
|
||||
*
|
||||
* @return the human presentable name
|
||||
*/
|
||||
public String getHumanPresentableName() {
|
||||
return humanPresentableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the human presentable name.
|
||||
*
|
||||
* @param humanPresentableName the name to set
|
||||
*/
|
||||
public void setHumanPresentableName(String humanPresentableName) {
|
||||
this.humanPresentableName = humanPresentableName;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares the DataFlavor passed in with this DataFlavor; calls
|
||||
* the <code>isMimeTypeEqual</code> method.
|
||||
*
|
||||
* @param dataFlavor the DataFlavor to compare with
|
||||
* @return true if the MIME type and representation class
|
||||
* are the same
|
||||
*/
|
||||
public boolean equals(DataFlavor dataFlavor) {
|
||||
return (isMimeTypeEqual(dataFlavor) &&
|
||||
dataFlavor.getRepresentationClass() == representationClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Is the string representation of the MIME type passed in equivalent
|
||||
* to the MIME type of this DataFlavor. <p>
|
||||
*
|
||||
* ActivationDataFlavor delegates the comparison of MIME types to
|
||||
* the MimeType class included as part of the JavaBeans Activation
|
||||
* Framework. This provides a more robust comparison than is normally
|
||||
* available in the DataFlavor class.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return true if the same MIME type
|
||||
*/
|
||||
public boolean isMimeTypeEqual(String mimeType) {
|
||||
MimeType mt = null;
|
||||
try {
|
||||
if (mimeObject == null)
|
||||
mimeObject = new MimeType(this.mimeType);
|
||||
mt = new MimeType(mimeType);
|
||||
} catch (MimeTypeParseException e) {
|
||||
// something didn't parse, do a crude comparison
|
||||
return this.mimeType.equalsIgnoreCase(mimeType);
|
||||
}
|
||||
|
||||
return mimeObject.match(mt);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called on DataFlavor for every MIME Type parameter to allow DataFlavor
|
||||
* subclasses to handle special parameters like the text/plain charset
|
||||
* parameters, whose values are case insensitive. (MIME type parameter
|
||||
* values are supposed to be case sensitive).
|
||||
* <p>
|
||||
* This method is called for each parameter name/value pair and should
|
||||
* return the normalized representation of the parameterValue.
|
||||
* This method is never invoked by this implementation.
|
||||
*
|
||||
* @param parameterName the parameter name
|
||||
* @param parameterValue the parameter value
|
||||
* @return the normalized parameter value
|
||||
* @deprecated
|
||||
*/
|
||||
protected String normalizeMimeTypeParameter(String parameterName,
|
||||
String parameterValue) {
|
||||
return parameterValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Called for each MIME type string to give DataFlavor subtypes the
|
||||
* opportunity to change how the normalization of MIME types is
|
||||
* accomplished.
|
||||
* One possible use would be to add default parameter/value pairs in cases
|
||||
* where none are present in the MIME type string passed in.
|
||||
* This method is never invoked by this implementation.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return the normalized MIME type
|
||||
* @deprecated
|
||||
*/
|
||||
protected String normalizeMimeType(String mimeType) {
|
||||
return mimeType;
|
||||
}
|
||||
}
|
||||
138
jaxws/src/share/jaf_classes/javax/activation/CommandInfo.java
Normal file
138
jaxws/src/share/jaf_classes/javax/activation/CommandInfo.java
Normal file
@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 1999, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.*;
|
||||
import java.beans.Beans;
|
||||
|
||||
/**
|
||||
* The CommandInfo class is used by CommandMap implementations to
|
||||
* describe the results of command requests. It provides the requestor
|
||||
* with both the verb requested, as well as an instance of the
|
||||
* bean. There is also a method that will return the name of the
|
||||
* class that implements the command but <i>it is not guaranteed to
|
||||
* return a valid value</i>. The reason for this is to allow CommandMap
|
||||
* implmentations that subclass CommandInfo to provide special
|
||||
* behavior. For example a CommandMap could dynamically generate
|
||||
* JavaBeans. In this case, it might not be possible to create an
|
||||
* object with all the correct state information solely from the class
|
||||
* name.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public class CommandInfo {
|
||||
private String verb;
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* The Constructor for CommandInfo.
|
||||
* @param verb The command verb this CommandInfo decribes.
|
||||
* @param className The command's fully qualified class name.
|
||||
*/
|
||||
public CommandInfo(String verb, String className) {
|
||||
this.verb = verb;
|
||||
this.className = className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the command verb.
|
||||
*
|
||||
* @return the command verb.
|
||||
*/
|
||||
public String getCommandName() {
|
||||
return verb;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the command's class name. <i>This method MAY return null in
|
||||
* cases where a CommandMap subclassed CommandInfo for its
|
||||
* own purposes.</i> In other words, it might not be possible to
|
||||
* create the correct state in the command by merely knowing
|
||||
* its class name. <b>DO NOT DEPEND ON THIS METHOD RETURNING
|
||||
* A VALID VALUE!</b>
|
||||
*
|
||||
* @return The class name of the command, or <i>null</i>
|
||||
*/
|
||||
public String getCommandClass() {
|
||||
return className;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the instantiated JavaBean component.
|
||||
* <p>
|
||||
* Begin by instantiating the component with
|
||||
* <code>Beans.instantiate()</code>.
|
||||
* <p>
|
||||
* If the bean implements the <code>javax.activation.CommandObject</code>
|
||||
* interface, call its <code>setCommandContext</code> method.
|
||||
* <p>
|
||||
* If the DataHandler parameter is null, then the bean is
|
||||
* instantiated with no data. NOTE: this may be useful
|
||||
* if for some reason the DataHandler that is passed in
|
||||
* throws IOExceptions when this method attempts to
|
||||
* access its InputStream. It will allow the caller to
|
||||
* retrieve a reference to the bean if it can be
|
||||
* instantiated.
|
||||
* <p>
|
||||
* If the bean does NOT implement the CommandObject interface,
|
||||
* this method will check if it implements the
|
||||
* java.io.Externalizable interface. If it does, the bean's
|
||||
* readExternal method will be called if an InputStream
|
||||
* can be acquired from the DataHandler.<p>
|
||||
*
|
||||
* @param dh The DataHandler that describes the data to be
|
||||
* passed to the command.
|
||||
* @param loader The ClassLoader to be used to instantiate the bean.
|
||||
* @return The bean
|
||||
* @see java.beans.Beans#instantiate
|
||||
* @see javax.activation.CommandObject
|
||||
*/
|
||||
public Object getCommandObject(DataHandler dh, ClassLoader loader)
|
||||
throws IOException, ClassNotFoundException {
|
||||
Object new_bean = null;
|
||||
|
||||
// try to instantiate the bean
|
||||
new_bean = java.beans.Beans.instantiate(loader, className);
|
||||
|
||||
// if we got one and it is a CommandObject
|
||||
if (new_bean != null) {
|
||||
if (new_bean instanceof CommandObject) {
|
||||
((CommandObject)new_bean).setCommandContext(verb, dh);
|
||||
} else if (new_bean instanceof Externalizable) {
|
||||
if (dh != null) {
|
||||
InputStream is = dh.getInputStream();
|
||||
if (is != null) {
|
||||
((Externalizable)new_bean).readExternal(
|
||||
new ObjectInputStream(is));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new_bean;
|
||||
}
|
||||
}
|
||||
220
jaxws/src/share/jaf_classes/javax/activation/CommandMap.java
Normal file
220
jaxws/src/share/jaf_classes/javax/activation/CommandMap.java
Normal file
@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
|
||||
/**
|
||||
* The CommandMap class provides an interface to a registry of
|
||||
* command objects available in the system.
|
||||
* Developers are expected to either use the CommandMap
|
||||
* implementation included with this package (MailcapCommandMap) or
|
||||
* develop their own. Note that some of the methods in this class are
|
||||
* abstract.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public abstract class CommandMap {
|
||||
private static CommandMap defaultCommandMap = null;
|
||||
|
||||
/**
|
||||
* Get the default CommandMap.
|
||||
* <p>
|
||||
*
|
||||
* <ul>
|
||||
* <li> In cases where a CommandMap instance has been previously set
|
||||
* to some value (via <i>setDefaultCommandMap</i>)
|
||||
* return the CommandMap.
|
||||
* <li>
|
||||
* In cases where no CommandMap has been set, the CommandMap
|
||||
* creates an instance of <code>MailcapCommandMap</code> and
|
||||
* set that to the default, returning its value.
|
||||
*
|
||||
* </ul>
|
||||
*
|
||||
* @return the CommandMap
|
||||
*/
|
||||
public static CommandMap getDefaultCommandMap() {
|
||||
if (defaultCommandMap == null)
|
||||
defaultCommandMap = new MailcapCommandMap();
|
||||
|
||||
return defaultCommandMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the default CommandMap. Reset the CommandMap to the default by
|
||||
* calling this method with <code>null</code>.
|
||||
*
|
||||
* @param commandMap The new default CommandMap.
|
||||
* @exception SecurityException if the caller doesn't have permission
|
||||
* to change the default
|
||||
*/
|
||||
public static void setDefaultCommandMap(CommandMap commandMap) {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
try {
|
||||
// if it's ok with the SecurityManager, it's ok with me...
|
||||
security.checkSetFactory();
|
||||
} catch (SecurityException ex) {
|
||||
// otherwise, we also allow it if this code and the
|
||||
// factory come from the same class loader (e.g.,
|
||||
// the JAF classes were loaded with the applet classes).
|
||||
if (CommandMap.class.getClassLoader() !=
|
||||
commandMap.getClass().getClassLoader())
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
defaultCommandMap = commandMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred command list from a MIME Type. The actual semantics
|
||||
* are determined by the implementation of the CommandMap.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return the CommandInfo classes that represent the command Beans.
|
||||
*/
|
||||
abstract public CommandInfo[] getPreferredCommands(String mimeType);
|
||||
|
||||
/**
|
||||
* Get the preferred command list from a MIME Type. The actual semantics
|
||||
* are determined by the implementation of the CommandMap. <p>
|
||||
*
|
||||
* The <code>DataSource</code> provides extra information, such as
|
||||
* the file name, that a CommandMap implementation may use to further
|
||||
* refine the list of commands that are returned. The implementation
|
||||
* in this class simply calls the <code>getPreferredCommands</code>
|
||||
* method that ignores this argument.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @param ds a DataSource for the data
|
||||
* @return the CommandInfo classes that represent the command Beans.
|
||||
* @since JAF 1.1
|
||||
*/
|
||||
public CommandInfo[] getPreferredCommands(String mimeType, DataSource ds) {
|
||||
return getPreferredCommands(mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the available commands for this type. This method
|
||||
* should return all the possible commands for this MIME type.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return the CommandInfo objects representing all the commands.
|
||||
*/
|
||||
abstract public CommandInfo[] getAllCommands(String mimeType);
|
||||
|
||||
/**
|
||||
* Get all the available commands for this type. This method
|
||||
* should return all the possible commands for this MIME type. <p>
|
||||
*
|
||||
* The <code>DataSource</code> provides extra information, such as
|
||||
* the file name, that a CommandMap implementation may use to further
|
||||
* refine the list of commands that are returned. The implementation
|
||||
* in this class simply calls the <code>getAllCommands</code>
|
||||
* method that ignores this argument.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @param ds a DataSource for the data
|
||||
* @return the CommandInfo objects representing all the commands.
|
||||
* @since JAF 1.1
|
||||
*/
|
||||
public CommandInfo[] getAllCommands(String mimeType, DataSource ds) {
|
||||
return getAllCommands(mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the default command corresponding to the MIME type.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @param cmdName the command name
|
||||
* @return the CommandInfo corresponding to the command.
|
||||
*/
|
||||
abstract public CommandInfo getCommand(String mimeType, String cmdName);
|
||||
|
||||
/**
|
||||
* Get the default command corresponding to the MIME type. <p>
|
||||
*
|
||||
* The <code>DataSource</code> provides extra information, such as
|
||||
* the file name, that a CommandMap implementation may use to further
|
||||
* refine the command that is chosen. The implementation
|
||||
* in this class simply calls the <code>getCommand</code>
|
||||
* method that ignores this argument.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @param cmdName the command name
|
||||
* @param ds a DataSource for the data
|
||||
* @return the CommandInfo corresponding to the command.
|
||||
* @since JAF 1.1
|
||||
*/
|
||||
public CommandInfo getCommand(String mimeType, String cmdName,
|
||||
DataSource ds) {
|
||||
return getCommand(mimeType, cmdName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a DataContentHandler that corresponds to the MIME type.
|
||||
* The mechanism and semantics for determining this are determined
|
||||
* by the implementation of the particular CommandMap.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return the DataContentHandler for the MIME type
|
||||
*/
|
||||
abstract public DataContentHandler createDataContentHandler(String
|
||||
mimeType);
|
||||
|
||||
/**
|
||||
* Locate a DataContentHandler that corresponds to the MIME type.
|
||||
* The mechanism and semantics for determining this are determined
|
||||
* by the implementation of the particular CommandMap. <p>
|
||||
*
|
||||
* The <code>DataSource</code> provides extra information, such as
|
||||
* the file name, that a CommandMap implementation may use to further
|
||||
* refine the choice of DataContentHandler. The implementation
|
||||
* in this class simply calls the <code>createDataContentHandler</code>
|
||||
* method that ignores this argument.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @param ds a DataSource for the data
|
||||
* @return the DataContentHandler for the MIME type
|
||||
* @since JAF 1.1
|
||||
*/
|
||||
public DataContentHandler createDataContentHandler(String mimeType,
|
||||
DataSource ds) {
|
||||
return createDataContentHandler(mimeType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the MIME types known to this command map.
|
||||
* If the command map doesn't support this operation,
|
||||
* null is returned.
|
||||
*
|
||||
* @return array of MIME types as strings, or null if not supported
|
||||
* @since JAF 1.1
|
||||
*/
|
||||
public String[] getMimeTypes() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* JavaBeans components that are Activation Framework aware implement
|
||||
* this interface to find out which command verb they're being asked
|
||||
* to perform, and to obtain the DataHandler representing the
|
||||
* data they should operate on. JavaBeans that don't implement
|
||||
* this interface may be used as well. Such commands may obtain
|
||||
* the data using the Externalizable interface, or using an
|
||||
* application-specific method.<p>
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public interface CommandObject {
|
||||
|
||||
/**
|
||||
* Initialize the Command with the verb it is requested to handle
|
||||
* and the DataHandler that describes the data it will
|
||||
* operate on. <b>NOTE:</b> it is acceptable for the caller
|
||||
* to pass <i>null</i> as the value for <code>DataHandler</code>.
|
||||
*
|
||||
* @param verb The Command Verb this object refers to.
|
||||
* @param dh The DataHandler.
|
||||
*/
|
||||
public void setCommandContext(String verb, DataHandler dh)
|
||||
throws IOException;
|
||||
}
|
||||
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import javax.activation.DataSource;
|
||||
|
||||
/**
|
||||
* The DataContentHandler interface is implemented by objects that can
|
||||
* be used to extend the capabilities of the DataHandler's implementation
|
||||
* of the Transferable interface. Through <code>DataContentHandlers</code>
|
||||
* the framework can be extended to convert streams in to objects, and
|
||||
* to write objects to streams. <p>
|
||||
*
|
||||
* Applications don't generally call the methods in DataContentHandlers
|
||||
* directly. Instead, an application calls the equivalent methods in
|
||||
* DataHandler. The DataHandler will attempt to find an appropriate
|
||||
* DataContentHandler that corresponds to its MIME type using the
|
||||
* current DataContentHandlerFactory. The DataHandler then calls
|
||||
* through to the methods in the DataContentHandler.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public interface DataContentHandler {
|
||||
/**
|
||||
* Returns an array of DataFlavor objects indicating the flavors the
|
||||
* data can be provided in. The array should be ordered according to
|
||||
* preference for providing the data (from most richly descriptive to
|
||||
* least descriptive).
|
||||
*
|
||||
* @return The DataFlavors.
|
||||
*/
|
||||
public DataFlavor[] getTransferDataFlavors();
|
||||
|
||||
/**
|
||||
* Returns an object which represents the data to be transferred.
|
||||
* The class of the object returned is defined by the representation class
|
||||
* of the flavor.
|
||||
*
|
||||
* @param df The DataFlavor representing the requested type.
|
||||
* @param ds The DataSource representing the data to be converted.
|
||||
* @return The constructed Object.
|
||||
* @exception UnsupportedFlavorException if the handler doesn't
|
||||
* support the requested flavor
|
||||
* @exception IOException if the data can't be accessed
|
||||
*/
|
||||
public Object getTransferData(DataFlavor df, DataSource ds)
|
||||
throws UnsupportedFlavorException, IOException;
|
||||
|
||||
/**
|
||||
* Return an object representing the data in its most preferred form.
|
||||
* Generally this will be the form described by the first DataFlavor
|
||||
* returned by the <code>getTransferDataFlavors</code> method.
|
||||
*
|
||||
* @param ds The DataSource representing the data to be converted.
|
||||
* @return The constructed Object.
|
||||
* @exception IOException if the data can't be accessed
|
||||
*/
|
||||
public Object getContent(DataSource ds) throws IOException;
|
||||
|
||||
/**
|
||||
* Convert the object to a byte stream of the specified MIME type
|
||||
* and write it to the output stream.
|
||||
*
|
||||
* @param obj The object to be converted.
|
||||
* @param mimeType The requested MIME type of the resulting byte stream.
|
||||
* @param os The output stream into which to write the converted
|
||||
* byte stream.
|
||||
* @exception IOException errors writing to the stream
|
||||
*/
|
||||
public void writeTo(Object obj, String mimeType, OutputStream os)
|
||||
throws IOException;
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
/**
|
||||
* This interface defines a factory for <code>DataContentHandlers</code>. An
|
||||
* implementation of this interface should map a MIME type into an
|
||||
* instance of DataContentHandler. The design pattern for classes implementing
|
||||
* this interface is the same as for the ContentHandler mechanism used in
|
||||
* <code>java.net.URL</code>.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public interface DataContentHandlerFactory {
|
||||
|
||||
/**
|
||||
* Creates a new DataContentHandler object for the MIME type.
|
||||
*
|
||||
* @param mimeType the MIME type to create the DataContentHandler for.
|
||||
* @return The new <code>DataContentHandler</code>, or <i>null</i>
|
||||
* if none are found.
|
||||
*/
|
||||
public DataContentHandler createDataContentHandler(String mimeType);
|
||||
}
|
||||
894
jaxws/src/share/jaf_classes/javax/activation/DataHandler.java
Normal file
894
jaxws/src/share/jaf_classes/javax/activation/DataHandler.java
Normal file
@ -0,0 +1,894 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2006, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PipedInputStream;
|
||||
import java.io.PipedOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.URL;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.awt.datatransfer.DataFlavor;
|
||||
import java.awt.datatransfer.UnsupportedFlavorException;
|
||||
|
||||
/**
|
||||
* The DataHandler class provides a consistent interface to data
|
||||
* available in many different sources and formats.
|
||||
* It manages simple stream to string conversions and related operations
|
||||
* using DataContentHandlers.
|
||||
* It provides access to commands that can operate on the data.
|
||||
* The commands are found using a CommandMap. <p>
|
||||
*
|
||||
* <b>DataHandler and the Transferable Interface</b><p>
|
||||
* DataHandler implements the Transferable interface so that data can
|
||||
* be used in AWT data transfer operations, such as cut and paste and
|
||||
* drag and drop. The implementation of the Transferable interface
|
||||
* relies on the availability of an installed DataContentHandler
|
||||
* object corresponding to the MIME type of the data represented in
|
||||
* the specific instance of the DataHandler.<p>
|
||||
*
|
||||
* <b>DataHandler and CommandMaps</b><p>
|
||||
* The DataHandler keeps track of the current CommandMap that it uses to
|
||||
* service requests for commands (<code>getCommand</code>,
|
||||
* <code>getAllCommands</code>, <code>getPreferredCommands</code>).
|
||||
* Each instance of a DataHandler may have a CommandMap associated with
|
||||
* it using the <code>setCommandMap</code> method. If a CommandMap was
|
||||
* not set, DataHandler calls the <code>getDefaultCommandMap</code>
|
||||
* method in CommandMap and uses the value it returns. See
|
||||
* <i>CommandMap</i> for more information. <p>
|
||||
*
|
||||
* <b>DataHandler and URLs</b><p>
|
||||
* The current DataHandler implementation creates a private
|
||||
* instance of URLDataSource when it is constructed with a URL.
|
||||
*
|
||||
* @see javax.activation.CommandMap
|
||||
* @see javax.activation.DataContentHandler
|
||||
* @see javax.activation.DataSource
|
||||
* @see javax.activation.URLDataSource
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public class DataHandler implements Transferable {
|
||||
|
||||
// Use the datasource to indicate whether we were started via the
|
||||
// DataSource constructor or the object constructor.
|
||||
private DataSource dataSource = null;
|
||||
private DataSource objDataSource = null;
|
||||
|
||||
// The Object and mimetype from the constructor (if passed in).
|
||||
// object remains null if it was instantiated with a
|
||||
// DataSource.
|
||||
private Object object = null;
|
||||
private String objectMimeType = null;
|
||||
|
||||
// Keep track of the CommandMap
|
||||
private CommandMap currentCommandMap = null;
|
||||
|
||||
// our transfer flavors
|
||||
private static final DataFlavor emptyFlavors[] = new DataFlavor[0];
|
||||
private DataFlavor transferFlavors[] = emptyFlavors;
|
||||
|
||||
// our DataContentHandler
|
||||
private DataContentHandler dataContentHandler = null;
|
||||
private DataContentHandler factoryDCH = null;
|
||||
|
||||
// our DataContentHandlerFactory
|
||||
private static DataContentHandlerFactory factory = null;
|
||||
private DataContentHandlerFactory oldFactory = null;
|
||||
// the short representation of the ContentType (sans params)
|
||||
private String shortType = null;
|
||||
|
||||
/**
|
||||
* Create a <code>DataHandler</code> instance referencing the
|
||||
* specified DataSource. The data exists in a byte stream form.
|
||||
* The DataSource will provide an InputStream to access the data.
|
||||
*
|
||||
* @param ds the DataSource
|
||||
*/
|
||||
public DataHandler(DataSource ds) {
|
||||
// save a reference to the incoming DS
|
||||
dataSource = ds;
|
||||
oldFactory = factory; // keep track of the factory
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a <code>DataHandler</code> instance representing an object
|
||||
* of this MIME type. This constructor is
|
||||
* used when the application already has an in-memory representation
|
||||
* of the data in the form of a Java Object.
|
||||
*
|
||||
* @param obj the Java Object
|
||||
* @param mimeType the MIME type of the object
|
||||
*/
|
||||
public DataHandler(Object obj, String mimeType) {
|
||||
object = obj;
|
||||
objectMimeType = mimeType;
|
||||
oldFactory = factory; // keep track of the factory
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a <code>DataHandler</code> instance referencing a URL.
|
||||
* The DataHandler internally creates a <code>URLDataSource</code>
|
||||
* instance to represent the URL.
|
||||
*
|
||||
* @param url a URL object
|
||||
*/
|
||||
public DataHandler(URL url) {
|
||||
dataSource = new URLDataSource(url);
|
||||
oldFactory = factory; // keep track of the factory
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the CommandMap for this instance of DataHandler.
|
||||
*/
|
||||
private synchronized CommandMap getCommandMap() {
|
||||
if (currentCommandMap != null)
|
||||
return currentCommandMap;
|
||||
else
|
||||
return CommandMap.getDefaultCommandMap();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataSource associated with this instance
|
||||
* of DataHandler.
|
||||
* <p>
|
||||
* For DataHandlers that have been instantiated with a DataSource,
|
||||
* this method returns the DataSource that was used to create the
|
||||
* DataHandler object. In other cases the DataHandler
|
||||
* constructs a DataSource from the data used to construct
|
||||
* the DataHandler. DataSources created for DataHandlers <b>not</b>
|
||||
* instantiated with a DataSource are cached for performance
|
||||
* reasons.
|
||||
*
|
||||
* @return a valid DataSource object for this DataHandler
|
||||
*/
|
||||
public DataSource getDataSource() {
|
||||
if (dataSource == null) {
|
||||
// create one on the fly
|
||||
if (objDataSource == null)
|
||||
objDataSource = new DataHandlerDataSource(this);
|
||||
return objDataSource;
|
||||
}
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the name of the data object. If this DataHandler
|
||||
* was created with a DataSource, this method calls through
|
||||
* to the <code>DataSource.getName</code> method, otherwise it
|
||||
* returns <i>null</i>.
|
||||
*
|
||||
* @return the name of the object
|
||||
*/
|
||||
public String getName() {
|
||||
if (dataSource != null)
|
||||
return dataSource.getName();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MIME type of this object as retrieved from
|
||||
* the source object. Note that this is the <i>full</i>
|
||||
* type with parameters.
|
||||
*
|
||||
* @return the MIME type
|
||||
*/
|
||||
public String getContentType() {
|
||||
if (dataSource != null) // data source case
|
||||
return dataSource.getContentType();
|
||||
else
|
||||
return objectMimeType; // obj/type case
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the InputStream for this object. <p>
|
||||
*
|
||||
* For DataHandlers instantiated with a DataSource, the DataHandler
|
||||
* calls the <code>DataSource.getInputStream</code> method and
|
||||
* returns the result to the caller.
|
||||
* <p>
|
||||
* For DataHandlers instantiated with an Object, the DataHandler
|
||||
* first attempts to find a DataContentHandler for the Object. If
|
||||
* the DataHandler can not find a DataContentHandler for this MIME
|
||||
* type, it throws an UnsupportedDataTypeException. If it is
|
||||
* successful, it creates a pipe and a thread. The thread uses the
|
||||
* DataContentHandler's <code>writeTo</code> method to write the
|
||||
* stream data into one end of the pipe. The other end of the pipe
|
||||
* is returned to the caller. Because a thread is created to copy
|
||||
* the data, IOExceptions that may occur during the copy can not be
|
||||
* propagated back to the caller. The result is an empty stream.<p>
|
||||
*
|
||||
* @return the InputStream representing this data
|
||||
* @exception IOException if an I/O error occurs
|
||||
*
|
||||
* @see javax.activation.DataContentHandler#writeTo
|
||||
* @see javax.activation.UnsupportedDataTypeException
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException {
|
||||
InputStream ins = null;
|
||||
|
||||
if (dataSource != null) {
|
||||
ins = dataSource.getInputStream();
|
||||
} else {
|
||||
DataContentHandler dch = getDataContentHandler();
|
||||
// we won't even try if we can't get a dch
|
||||
if (dch == null)
|
||||
throw new UnsupportedDataTypeException(
|
||||
"no DCH for MIME type " + getBaseType());
|
||||
|
||||
if (dch instanceof ObjectDataContentHandler) {
|
||||
if (((ObjectDataContentHandler)dch).getDCH() == null)
|
||||
throw new UnsupportedDataTypeException(
|
||||
"no object DCH for MIME type " + getBaseType());
|
||||
}
|
||||
// there is none but the default^^^^^^^^^^^^^^^^
|
||||
final DataContentHandler fdch = dch;
|
||||
|
||||
// from bill s.
|
||||
// ce n'est pas une pipe!
|
||||
//
|
||||
// NOTE: This block of code needs to throw exceptions, but
|
||||
// can't because it is in another thread!!! ARG!
|
||||
//
|
||||
final PipedOutputStream pos = new PipedOutputStream();
|
||||
PipedInputStream pin = new PipedInputStream(pos);
|
||||
new Thread(
|
||||
new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
fdch.writeTo(object, objectMimeType, pos);
|
||||
} catch (IOException e) {
|
||||
|
||||
} finally {
|
||||
try {
|
||||
pos.close();
|
||||
} catch (IOException ie) { }
|
||||
}
|
||||
}
|
||||
},
|
||||
"DataHandler.getInputStream").start();
|
||||
ins = pin;
|
||||
}
|
||||
|
||||
return ins;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the data to an <code>OutputStream</code>.<p>
|
||||
*
|
||||
* If the DataHandler was created with a DataSource, writeTo
|
||||
* retrieves the InputStream and copies the bytes from the
|
||||
* InputStream to the OutputStream passed in.
|
||||
* <p>
|
||||
* If the DataHandler was created with an object, writeTo
|
||||
* retrieves the DataContentHandler for the object's type.
|
||||
* If the DataContentHandler was found, it calls the
|
||||
* <code>writeTo</code> method on the <code>DataContentHandler</code>.
|
||||
*
|
||||
* @param os the OutputStream to write to
|
||||
* @exception IOException if an I/O error occurs
|
||||
*/
|
||||
public void writeTo(OutputStream os) throws IOException {
|
||||
// for the DataSource case
|
||||
if (dataSource != null) {
|
||||
InputStream is = null;
|
||||
byte data[] = new byte[8*1024];
|
||||
int bytes_read;
|
||||
|
||||
is = dataSource.getInputStream();
|
||||
|
||||
try {
|
||||
while ((bytes_read = is.read(data)) > 0) {
|
||||
os.write(data, 0, bytes_read);
|
||||
}
|
||||
} finally {
|
||||
is.close();
|
||||
is = null;
|
||||
}
|
||||
} else { // for the Object case
|
||||
DataContentHandler dch = getDataContentHandler();
|
||||
dch.writeTo(object, objectMimeType, os);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an OutputStream for this DataHandler to allow overwriting
|
||||
* the underlying data.
|
||||
* If the DataHandler was created with a DataSource, the
|
||||
* DataSource's <code>getOutputStream</code> method is called.
|
||||
* Otherwise, <code>null</code> is returned.
|
||||
*
|
||||
* @return the OutputStream
|
||||
*
|
||||
* @see javax.activation.DataSource#getOutputStream
|
||||
* @see javax.activation.URLDataSource
|
||||
*/
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
if (dataSource != null)
|
||||
return dataSource.getOutputStream();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataFlavors in which this data is available. <p>
|
||||
*
|
||||
* Returns an array of DataFlavor objects indicating the flavors
|
||||
* the data can be provided in. The array is usually ordered
|
||||
* according to preference for providing the data, from most
|
||||
* richly descriptive to least richly descriptive.<p>
|
||||
*
|
||||
* The DataHandler attempts to find a DataContentHandler that
|
||||
* corresponds to the MIME type of the data. If one is located,
|
||||
* the DataHandler calls the DataContentHandler's
|
||||
* <code>getTransferDataFlavors</code> method. <p>
|
||||
*
|
||||
* If a DataContentHandler can <i>not</i> be located, and if the
|
||||
* DataHandler was created with a DataSource (or URL), one
|
||||
* DataFlavor is returned that represents this object's MIME type
|
||||
* and the <code>java.io.InputStream</code> class. If the
|
||||
* DataHandler was created with an object and a MIME type,
|
||||
* getTransferDataFlavors returns one DataFlavor that represents
|
||||
* this object's MIME type and the object's class.
|
||||
*
|
||||
* @return an array of data flavors in which this data can be transferred
|
||||
* @see javax.activation.DataContentHandler#getTransferDataFlavors
|
||||
*/
|
||||
public synchronized DataFlavor[] getTransferDataFlavors() {
|
||||
if (factory != oldFactory) // if the factory has changed, clear cache
|
||||
transferFlavors = emptyFlavors;
|
||||
|
||||
// if it's not set, set it...
|
||||
if (transferFlavors == emptyFlavors)
|
||||
transferFlavors = getDataContentHandler().getTransferDataFlavors();
|
||||
return transferFlavors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the specified data flavor is supported
|
||||
* for this object.<p>
|
||||
*
|
||||
* This method iterates through the DataFlavors returned from
|
||||
* <code>getTransferDataFlavors</code>, comparing each with
|
||||
* the specified flavor.
|
||||
*
|
||||
* @param flavor the requested flavor for the data
|
||||
* @return true if the data flavor is supported
|
||||
* @see javax.activation.DataHandler#getTransferDataFlavors
|
||||
*/
|
||||
public boolean isDataFlavorSupported(DataFlavor flavor) {
|
||||
DataFlavor[] lFlavors = getTransferDataFlavors();
|
||||
|
||||
for (int i = 0; i < lFlavors.length; i++) {
|
||||
if (lFlavors[i].equals(flavor))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an object that represents the data to be
|
||||
* transferred. The class of the object returned is defined by the
|
||||
* representation class of the data flavor.<p>
|
||||
*
|
||||
* <b>For DataHandler's created with DataSources or URLs:</b><p>
|
||||
*
|
||||
* The DataHandler attempts to locate a DataContentHandler
|
||||
* for this MIME type. If one is found, the passed in DataFlavor
|
||||
* and the type of the data are passed to its <code>getTransferData</code>
|
||||
* method. If the DataHandler fails to locate a DataContentHandler
|
||||
* and the flavor specifies this object's MIME type and the
|
||||
* <code>java.io.InputStream</code> class, this object's InputStream
|
||||
* is returned.
|
||||
* Otherwise it throws an UnsupportedFlavorException. <p>
|
||||
*
|
||||
* <b>For DataHandler's created with Objects:</b><p>
|
||||
*
|
||||
* The DataHandler attempts to locate a DataContentHandler
|
||||
* for this MIME type. If one is found, the passed in DataFlavor
|
||||
* and the type of the data are passed to its getTransferData
|
||||
* method. If the DataHandler fails to locate a DataContentHandler
|
||||
* and the flavor specifies this object's MIME type and its class,
|
||||
* this DataHandler's referenced object is returned.
|
||||
* Otherwise it throws an UnsupportedFlavorException.
|
||||
*
|
||||
* @param flavor the requested flavor for the data
|
||||
* @return the object
|
||||
* @exception UnsupportedFlavorException if the data could not be
|
||||
* converted to the requested flavor
|
||||
* @exception IOException if an I/O error occurs
|
||||
* @see javax.activation.ActivationDataFlavor
|
||||
*/
|
||||
public Object getTransferData(DataFlavor flavor)
|
||||
throws UnsupportedFlavorException, IOException {
|
||||
return getDataContentHandler().getTransferData(flavor, dataSource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the CommandMap for use by this DataHandler.
|
||||
* Setting it to <code>null</code> causes the CommandMap to revert
|
||||
* to the CommandMap returned by the
|
||||
* <code>CommandMap.getDefaultCommandMap</code> method.
|
||||
* Changing the CommandMap, or setting it to <code>null</code>,
|
||||
* clears out any data cached from the previous CommandMap.
|
||||
*
|
||||
* @param commandMap the CommandMap to use in this DataHandler
|
||||
*
|
||||
* @see javax.activation.CommandMap#setDefaultCommandMap
|
||||
*/
|
||||
public synchronized void setCommandMap(CommandMap commandMap) {
|
||||
if (commandMap != currentCommandMap || commandMap == null) {
|
||||
// clear cached values...
|
||||
transferFlavors = emptyFlavors;
|
||||
dataContentHandler = null;
|
||||
|
||||
currentCommandMap = commandMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the <i>preferred</i> commands for this type of data.
|
||||
* This method calls the <code>getPreferredCommands</code> method
|
||||
* in the CommandMap associated with this instance of DataHandler.
|
||||
* This method returns an array that represents a subset of
|
||||
* available commands. In cases where multiple commands for the
|
||||
* MIME type represented by this DataHandler are present, the
|
||||
* installed CommandMap chooses the appropriate commands.
|
||||
*
|
||||
* @return the CommandInfo objects representing the preferred commands
|
||||
*
|
||||
* @see javax.activation.CommandMap#getPreferredCommands
|
||||
*/
|
||||
public CommandInfo[] getPreferredCommands() {
|
||||
if (dataSource != null)
|
||||
return getCommandMap().getPreferredCommands(getBaseType(),
|
||||
dataSource);
|
||||
else
|
||||
return getCommandMap().getPreferredCommands(getBaseType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all the commands for this type of data.
|
||||
* This method returns an array containing all commands
|
||||
* for the type of data represented by this DataHandler. The
|
||||
* MIME type for the underlying data represented by this DataHandler
|
||||
* is used to call through to the <code>getAllCommands</code> method
|
||||
* of the CommandMap associated with this DataHandler.
|
||||
*
|
||||
* @return the CommandInfo objects representing all the commands
|
||||
*
|
||||
* @see javax.activation.CommandMap#getAllCommands
|
||||
*/
|
||||
public CommandInfo[] getAllCommands() {
|
||||
if (dataSource != null)
|
||||
return getCommandMap().getAllCommands(getBaseType(), dataSource);
|
||||
else
|
||||
return getCommandMap().getAllCommands(getBaseType());
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command <i>cmdName</i>. Use the search semantics as
|
||||
* defined by the CommandMap installed in this DataHandler. The
|
||||
* MIME type for the underlying data represented by this DataHandler
|
||||
* is used to call through to the <code>getCommand</code> method
|
||||
* of the CommandMap associated with this DataHandler.
|
||||
*
|
||||
* @param cmdName the command name
|
||||
* @return the CommandInfo corresponding to the command
|
||||
*
|
||||
* @see javax.activation.CommandMap#getCommand
|
||||
*/
|
||||
public CommandInfo getCommand(String cmdName) {
|
||||
if (dataSource != null)
|
||||
return getCommandMap().getCommand(getBaseType(), cmdName,
|
||||
dataSource);
|
||||
else
|
||||
return getCommandMap().getCommand(getBaseType(), cmdName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the data in its preferred Object form. <p>
|
||||
*
|
||||
* If the DataHandler was instantiated with an object, return
|
||||
* the object. <p>
|
||||
*
|
||||
* If the DataHandler was instantiated with a DataSource,
|
||||
* this method uses a DataContentHandler to return the content
|
||||
* object for the data represented by this DataHandler. If no
|
||||
* <code>DataContentHandler</code> can be found for the
|
||||
* the type of this data, the DataHandler returns an
|
||||
* InputStream for the data.
|
||||
*
|
||||
* @return the content.
|
||||
* @exception IOException if an IOException occurs during
|
||||
* this operation.
|
||||
*/
|
||||
public Object getContent() throws IOException {
|
||||
if (object != null)
|
||||
return object;
|
||||
else
|
||||
return getDataContentHandler().getContent(getDataSource());
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method that takes a CommandInfo object
|
||||
* and instantiates the corresponding command, usually
|
||||
* a JavaBean component.
|
||||
* <p>
|
||||
* This method calls the CommandInfo's <code>getCommandObject</code>
|
||||
* method with the <code>ClassLoader</code> used to load
|
||||
* the <code>javax.activation.DataHandler</code> class itself.
|
||||
*
|
||||
* @param cmdinfo the CommandInfo corresponding to a command
|
||||
* @return the instantiated command object
|
||||
*/
|
||||
public Object getBean(CommandInfo cmdinfo) {
|
||||
Object bean = null;
|
||||
|
||||
try {
|
||||
// make the bean
|
||||
ClassLoader cld = null;
|
||||
// First try the "application's" class loader.
|
||||
cld = SecuritySupport.getContextClassLoader();
|
||||
if (cld == null)
|
||||
cld = this.getClass().getClassLoader();
|
||||
bean = cmdinfo.getCommandObject(this, cld);
|
||||
} catch (IOException e) {
|
||||
} catch (ClassNotFoundException e) { }
|
||||
|
||||
return bean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the DataContentHandler for this DataHandler: <p>
|
||||
*
|
||||
* If a DataContentHandlerFactory is set, use it.
|
||||
* Otherwise look for an object to serve DCH in the
|
||||
* following order: <p>
|
||||
*
|
||||
* 1) if a factory is set, use it <p>
|
||||
* 2) if a CommandMap is set, use it <p>
|
||||
* 3) use the default CommandMap <p>
|
||||
*
|
||||
* In any case, wrap the real DataContentHandler with one of our own
|
||||
* to handle any missing cases, fill in defaults, and to ensure that
|
||||
* we always have a non-null DataContentHandler.
|
||||
*
|
||||
* @return the requested DataContentHandler
|
||||
*/
|
||||
private synchronized DataContentHandler getDataContentHandler() {
|
||||
|
||||
// make sure the factory didn't change
|
||||
if (factory != oldFactory) {
|
||||
oldFactory = factory;
|
||||
factoryDCH = null;
|
||||
dataContentHandler = null;
|
||||
transferFlavors = emptyFlavors;
|
||||
}
|
||||
|
||||
if (dataContentHandler != null)
|
||||
return dataContentHandler;
|
||||
|
||||
String simpleMT = getBaseType();
|
||||
|
||||
if (factoryDCH == null && factory != null)
|
||||
factoryDCH = factory.createDataContentHandler(simpleMT);
|
||||
|
||||
if (factoryDCH != null)
|
||||
dataContentHandler = factoryDCH;
|
||||
|
||||
if (dataContentHandler == null) {
|
||||
if (dataSource != null)
|
||||
dataContentHandler = getCommandMap().
|
||||
createDataContentHandler(simpleMT, dataSource);
|
||||
else
|
||||
dataContentHandler = getCommandMap().
|
||||
createDataContentHandler(simpleMT);
|
||||
}
|
||||
|
||||
// getDataContentHandler always uses these 'wrapper' handlers
|
||||
// to make sure it returns SOMETHING meaningful...
|
||||
if (dataSource != null)
|
||||
dataContentHandler = new DataSourceDataContentHandler(
|
||||
dataContentHandler,
|
||||
dataSource);
|
||||
else
|
||||
dataContentHandler = new ObjectDataContentHandler(
|
||||
dataContentHandler,
|
||||
object,
|
||||
objectMimeType);
|
||||
return dataContentHandler;
|
||||
}
|
||||
|
||||
/**
|
||||
* Use the MimeType class to extract the MIME type/subtype,
|
||||
* ignoring the parameters. The type is cached.
|
||||
*/
|
||||
private synchronized String getBaseType() {
|
||||
if (shortType == null) {
|
||||
String ct = getContentType();
|
||||
try {
|
||||
MimeType mt = new MimeType(ct);
|
||||
shortType = mt.getBaseType();
|
||||
} catch (MimeTypeParseException e) {
|
||||
shortType = ct;
|
||||
}
|
||||
}
|
||||
return shortType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the DataContentHandlerFactory. The DataContentHandlerFactory
|
||||
* is called first to find DataContentHandlers.
|
||||
* The DataContentHandlerFactory can only be set once.
|
||||
* <p>
|
||||
* If the DataContentHandlerFactory has already been set,
|
||||
* this method throws an Error.
|
||||
*
|
||||
* @param newFactory the DataContentHandlerFactory
|
||||
* @exception Error if the factory has already been defined.
|
||||
*
|
||||
* @see javax.activation.DataContentHandlerFactory
|
||||
*/
|
||||
public static synchronized void setDataContentHandlerFactory(
|
||||
DataContentHandlerFactory newFactory) {
|
||||
if (factory != null)
|
||||
throw new Error("DataContentHandlerFactory already defined");
|
||||
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
try {
|
||||
// if it's ok with the SecurityManager, it's ok with me...
|
||||
security.checkSetFactory();
|
||||
} catch (SecurityException ex) {
|
||||
// otherwise, we also allow it if this code and the
|
||||
// factory come from the same class loader (e.g.,
|
||||
// the JAF classes were loaded with the applet classes).
|
||||
if (DataHandler.class.getClassLoader() !=
|
||||
newFactory.getClass().getClassLoader())
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
factory = newFactory;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The DataHanderDataSource class implements the
|
||||
* DataSource interface when the DataHandler is constructed
|
||||
* with an Object and a mimeType string.
|
||||
*/
|
||||
class DataHandlerDataSource implements DataSource {
|
||||
DataHandler dataHandler = null;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public DataHandlerDataSource(DataHandler dh) {
|
||||
this.dataHandler = dh;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an <code>InputStream</code> representing this object.
|
||||
* @return the <code>InputStream</code>
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return dataHandler.getInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the <code>OutputStream</code> for this object.
|
||||
* @return the <code>OutputStream</code>
|
||||
*/
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return dataHandler.getOutputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the MIME type of the data represented by this object.
|
||||
* @return the MIME type
|
||||
*/
|
||||
public String getContentType() {
|
||||
return dataHandler.getContentType();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this object.
|
||||
* @return the name of this object
|
||||
*/
|
||||
public String getName() {
|
||||
return dataHandler.getName(); // what else would it be?
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* DataSourceDataContentHandler
|
||||
*
|
||||
* This is a <i>private</i> DataContentHandler that wraps the real
|
||||
* DataContentHandler in the case where the DataHandler was instantiated
|
||||
* with a DataSource.
|
||||
*/
|
||||
class DataSourceDataContentHandler implements DataContentHandler {
|
||||
private DataSource ds = null;
|
||||
private DataFlavor transferFlavors[] = null;
|
||||
private DataContentHandler dch = null;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public DataSourceDataContentHandler(DataContentHandler dch, DataSource ds) {
|
||||
this.ds = ds;
|
||||
this.dch = dch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataFlavors for this <code>DataContentHandler</code>.
|
||||
* @return the DataFlavors
|
||||
*/
|
||||
public DataFlavor[] getTransferDataFlavors() {
|
||||
|
||||
if (transferFlavors == null) {
|
||||
if (dch != null) { // is there a dch?
|
||||
transferFlavors = dch.getTransferDataFlavors();
|
||||
} else {
|
||||
transferFlavors = new DataFlavor[1];
|
||||
transferFlavors[0] =
|
||||
new ActivationDataFlavor(ds.getContentType(),
|
||||
ds.getContentType());
|
||||
}
|
||||
}
|
||||
return transferFlavors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Transfer Data of type DataFlavor from InputStream.
|
||||
* @param df the DataFlavor
|
||||
* @param ds the DataSource
|
||||
* @return the constructed Object
|
||||
*/
|
||||
public Object getTransferData(DataFlavor df, DataSource ds) throws
|
||||
UnsupportedFlavorException, IOException {
|
||||
|
||||
if (dch != null)
|
||||
return dch.getTransferData(df, ds);
|
||||
else if (df.equals(getTransferDataFlavors()[0])) // only have one now
|
||||
return ds.getInputStream();
|
||||
else
|
||||
throw new UnsupportedFlavorException(df);
|
||||
}
|
||||
|
||||
public Object getContent(DataSource ds) throws IOException {
|
||||
|
||||
if (dch != null)
|
||||
return dch.getContent(ds);
|
||||
else
|
||||
return ds.getInputStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the object to the output stream.
|
||||
*/
|
||||
public void writeTo(Object obj, String mimeType, OutputStream os)
|
||||
throws IOException {
|
||||
if (dch != null)
|
||||
dch.writeTo(obj, mimeType, os);
|
||||
else
|
||||
throw new UnsupportedDataTypeException(
|
||||
"no DCH for content type " + ds.getContentType());
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* ObjectDataContentHandler
|
||||
*
|
||||
* This is a <i>private</i> DataContentHandler that wraps the real
|
||||
* DataContentHandler in the case where the DataHandler was instantiated
|
||||
* with an object.
|
||||
*/
|
||||
class ObjectDataContentHandler implements DataContentHandler {
|
||||
private DataFlavor transferFlavors[] = null;
|
||||
private Object obj;
|
||||
private String mimeType;
|
||||
private DataContentHandler dch = null;
|
||||
|
||||
/**
|
||||
* The constructor.
|
||||
*/
|
||||
public ObjectDataContentHandler(DataContentHandler dch,
|
||||
Object obj, String mimeType) {
|
||||
this.obj = obj;
|
||||
this.mimeType = mimeType;
|
||||
this.dch = dch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataContentHandler for this object.
|
||||
* Used only by the DataHandler class.
|
||||
*/
|
||||
public DataContentHandler getDCH() {
|
||||
return dch;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataFlavors for this <code>DataContentHandler</code>.
|
||||
* @return the DataFlavors
|
||||
*/
|
||||
public synchronized DataFlavor[] getTransferDataFlavors() {
|
||||
if (transferFlavors == null) {
|
||||
if (dch != null) {
|
||||
transferFlavors = dch.getTransferDataFlavors();
|
||||
} else {
|
||||
transferFlavors = new DataFlavor[1];
|
||||
transferFlavors[0] = new ActivationDataFlavor(obj.getClass(),
|
||||
mimeType, mimeType);
|
||||
}
|
||||
}
|
||||
return transferFlavors;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the Transfer Data of type DataFlavor from InputStream.
|
||||
* @param df the DataFlavor
|
||||
* @param ds the DataSource
|
||||
* @return the constructed Object
|
||||
*/
|
||||
public Object getTransferData(DataFlavor df, DataSource ds)
|
||||
throws UnsupportedFlavorException, IOException {
|
||||
|
||||
if (dch != null)
|
||||
return dch.getTransferData(df, ds);
|
||||
else if (df.equals(getTransferDataFlavors()[0])) // only have one now
|
||||
return obj;
|
||||
else
|
||||
throw new UnsupportedFlavorException(df);
|
||||
|
||||
}
|
||||
|
||||
public Object getContent(DataSource ds) {
|
||||
return obj;
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the object to the output stream.
|
||||
*/
|
||||
public void writeTo(Object obj, String mimeType, OutputStream os)
|
||||
throws IOException {
|
||||
if (dch != null)
|
||||
dch.writeTo(obj, mimeType, os);
|
||||
else if (obj instanceof byte[])
|
||||
os.write((byte[])obj);
|
||||
else if (obj instanceof String) {
|
||||
OutputStreamWriter osw = new OutputStreamWriter(os);
|
||||
osw.write((String)obj);
|
||||
osw.flush();
|
||||
} else throw new UnsupportedDataTypeException(
|
||||
"no object DCH for MIME type " + this.mimeType);
|
||||
}
|
||||
}
|
||||
86
jaxws/src/share/jaf_classes/javax/activation/DataSource.java
Normal file
86
jaxws/src/share/jaf_classes/javax/activation/DataSource.java
Normal file
@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The DataSource interface provides the JavaBeans Activation Framework
|
||||
* with an abstraction of an arbitrary collection of data. It
|
||||
* provides a type for that data as well as access
|
||||
* to it in the form of <code>InputStreams</code> and
|
||||
* <code>OutputStreams</code> where appropriate.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public interface DataSource {
|
||||
|
||||
/**
|
||||
* This method returns an <code>InputStream</code> representing
|
||||
* the data and throws the appropriate exception if it can
|
||||
* not do so. Note that a new <code>InputStream</code> object must be
|
||||
* returned each time this method is called, and the stream must be
|
||||
* positioned at the beginning of the data.
|
||||
*
|
||||
* @return an InputStream
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException;
|
||||
|
||||
/**
|
||||
* This method returns an <code>OutputStream</code> where the
|
||||
* data can be written and throws the appropriate exception if it can
|
||||
* not do so. Note that a new <code>OutputStream</code> object must
|
||||
* be returned each time this method is called, and the stream must
|
||||
* be positioned at the location the data is to be written.
|
||||
*
|
||||
* @return an OutputStream
|
||||
*/
|
||||
public OutputStream getOutputStream() throws IOException;
|
||||
|
||||
/**
|
||||
* This method returns the MIME type of the data in the form of a
|
||||
* string. It should always return a valid type. It is suggested
|
||||
* that getContentType return "application/octet-stream" if the
|
||||
* DataSource implementation can not determine the data type.
|
||||
*
|
||||
* @return the MIME Type
|
||||
*/
|
||||
public String getContentType();
|
||||
|
||||
/**
|
||||
* Return the <i>name</i> of this object where the name of the object
|
||||
* is dependant on the nature of the underlying objects. DataSources
|
||||
* encapsulating files may choose to return the filename of the object.
|
||||
* (Typically this would be the last component of the filename, not an
|
||||
* entire pathname.)
|
||||
*
|
||||
* @return the name of the object.
|
||||
*/
|
||||
public String getName();
|
||||
}
|
||||
158
jaxws/src/share/jaf_classes/javax/activation/FileDataSource.java
Normal file
158
jaxws/src/share/jaf_classes/javax/activation/FileDataSource.java
Normal file
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileDescriptor;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import com.sun.activation.registries.MimeTypeFile;
|
||||
|
||||
/**
|
||||
* The FileDataSource class implements a simple DataSource object
|
||||
* that encapsulates a file. It provides data typing services via
|
||||
* a FileTypeMap object. <p>
|
||||
*
|
||||
* <b>FileDataSource Typing Semantics</b><p>
|
||||
*
|
||||
* The FileDataSource class delegates data typing of files
|
||||
* to an object subclassed from the FileTypeMap class.
|
||||
* The <code>setFileTypeMap</code> method can be used to explicitly
|
||||
* set the FileTypeMap for an instance of FileDataSource. If no
|
||||
* FileTypeMap is set, the FileDataSource will call the FileTypeMap's
|
||||
* getDefaultFileTypeMap method to get the System's default FileTypeMap.
|
||||
*
|
||||
* @see javax.activation.DataSource
|
||||
* @see javax.activation.FileTypeMap
|
||||
* @see javax.activation.MimetypesFileTypeMap
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class FileDataSource implements DataSource {
|
||||
|
||||
// keep track of original 'ref' passed in, non-null
|
||||
// one indicated which was passed in:
|
||||
private File _file = null;
|
||||
private FileTypeMap typeMap = null;
|
||||
|
||||
/**
|
||||
* Creates a FileDataSource from a File object. <i>Note:
|
||||
* The file will not actually be opened until a method is
|
||||
* called that requires the file to be opened.</i>
|
||||
*
|
||||
* @param file the file
|
||||
*/
|
||||
public FileDataSource(File file) {
|
||||
_file = file; // save the file Object...
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a FileDataSource from
|
||||
* the specified path name. <i>Note:
|
||||
* The file will not actually be opened until a method is
|
||||
* called that requires the file to be opened.</i>
|
||||
*
|
||||
* @param name the system-dependent file name.
|
||||
*/
|
||||
public FileDataSource(String name) {
|
||||
this(new File(name)); // use the file constructor
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return an InputStream representing the
|
||||
* the data and will throw an IOException if it can
|
||||
* not do so. This method will return a new
|
||||
* instance of InputStream with each invocation.
|
||||
*
|
||||
* @return an InputStream
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return new FileInputStream(_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return an OutputStream representing the
|
||||
* the data and will throw an IOException if it can
|
||||
* not do so. This method will return a new instance of
|
||||
* OutputStream with each invocation.
|
||||
*
|
||||
* @return an OutputStream
|
||||
*/
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
return new FileOutputStream(_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the MIME type of the data in the form of a
|
||||
* string. This method uses the currently installed FileTypeMap. If
|
||||
* there is no FileTypeMap explictly set, the FileDataSource will
|
||||
* call the <code>getDefaultFileTypeMap</code> method on
|
||||
* FileTypeMap to acquire a default FileTypeMap. <i>Note: By
|
||||
* default, the FileTypeMap used will be a MimetypesFileTypeMap.</i>
|
||||
*
|
||||
* @return the MIME Type
|
||||
* @see javax.activation.FileTypeMap#getDefaultFileTypeMap
|
||||
*/
|
||||
public String getContentType() {
|
||||
// check to see if the type map is null?
|
||||
if (typeMap == null)
|
||||
return FileTypeMap.getDefaultFileTypeMap().getContentType(_file);
|
||||
else
|
||||
return typeMap.getContentType(_file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the <i>name</i> of this object. The FileDataSource
|
||||
* will return the file name of the object.
|
||||
*
|
||||
* @return the name of the object.
|
||||
* @see javax.activation.DataSource
|
||||
*/
|
||||
public String getName() {
|
||||
return _file.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the File object that corresponds to this FileDataSource.
|
||||
* @return the File object for the file represented by this object.
|
||||
*/
|
||||
public File getFile() {
|
||||
return _file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the FileTypeMap to use with this FileDataSource
|
||||
*
|
||||
* @param map The FileTypeMap for this object.
|
||||
*/
|
||||
public void setFileTypeMap(FileTypeMap map) {
|
||||
typeMap = map;
|
||||
}
|
||||
}
|
||||
118
jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java
Normal file
118
jaxws/src/share/jaf_classes/javax/activation/FileTypeMap.java
Normal file
@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* The FileTypeMap is an abstract class that provides a data typing
|
||||
* interface for files. Implementations of this class will
|
||||
* implement the getContentType methods which will derive a content
|
||||
* type from a file name or a File object. FileTypeMaps could use any
|
||||
* scheme to determine the data type, from examining the file extension
|
||||
* of a file (like the MimetypesFileTypeMap) to opening the file and
|
||||
* trying to derive its type from the contents of the file. The
|
||||
* FileDataSource class uses the default FileTypeMap (a MimetypesFileTypeMap
|
||||
* unless changed) to determine the content type of files.
|
||||
*
|
||||
* @see javax.activation.FileTypeMap
|
||||
* @see javax.activation.FileDataSource
|
||||
* @see javax.activation.MimetypesFileTypeMap
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public abstract class FileTypeMap {
|
||||
|
||||
private static FileTypeMap defaultMap = null;
|
||||
|
||||
/**
|
||||
* The default constructor.
|
||||
*/
|
||||
public FileTypeMap() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the file object. This method should
|
||||
* always return a valid MIME type.
|
||||
*
|
||||
* @param file A file to be typed.
|
||||
* @return The content type.
|
||||
*/
|
||||
abstract public String getContentType(File file);
|
||||
|
||||
/**
|
||||
* Return the type of the file passed in. This method should
|
||||
* always return a valid MIME type.
|
||||
*
|
||||
* @param filename the pathname of the file.
|
||||
* @return The content type.
|
||||
*/
|
||||
abstract public String getContentType(String filename);
|
||||
|
||||
/**
|
||||
* Sets the default FileTypeMap for the system. This instance
|
||||
* will be returned to callers of getDefaultFileTypeMap.
|
||||
*
|
||||
* @param map The FileTypeMap.
|
||||
* @exception SecurityException if the caller doesn't have permission
|
||||
* to change the default
|
||||
*/
|
||||
public static void setDefaultFileTypeMap(FileTypeMap map) {
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null) {
|
||||
try {
|
||||
// if it's ok with the SecurityManager, it's ok with me...
|
||||
security.checkSetFactory();
|
||||
} catch (SecurityException ex) {
|
||||
// otherwise, we also allow it if this code and the
|
||||
// factory come from the same class loader (e.g.,
|
||||
// the JAF classes were loaded with the applet classes).
|
||||
if (FileTypeMap.class.getClassLoader() !=
|
||||
map.getClass().getClassLoader())
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
defaultMap = map;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the default FileTypeMap for the system.
|
||||
* If setDefaultFileTypeMap was called, return
|
||||
* that instance, otherwise return an instance of
|
||||
* <code>MimetypesFileTypeMap</code>.
|
||||
*
|
||||
* @return The default FileTypeMap
|
||||
* @see javax.activation.FileTypeMap#setDefaultFileTypeMap
|
||||
*/
|
||||
public static FileTypeMap getDefaultFileTypeMap() {
|
||||
// XXX - probably should be synchronized
|
||||
if (defaultMap == null)
|
||||
defaultMap = new MimetypesFileTypeMap();
|
||||
return defaultMap;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,701 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import com.sun.activation.registries.MailcapFile;
|
||||
import com.sun.activation.registries.LogSupport;
|
||||
|
||||
/**
|
||||
* MailcapCommandMap extends the CommandMap
|
||||
* abstract class. It implements a CommandMap whose configuration
|
||||
* is based on mailcap files
|
||||
* (<A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A>).
|
||||
* The MailcapCommandMap can be configured both programmatically
|
||||
* and via configuration files.
|
||||
* <p>
|
||||
* <b>Mailcap file search order:</b><p>
|
||||
* The MailcapCommandMap looks in various places in the user's
|
||||
* system for mailcap file entries. When requests are made
|
||||
* to search for commands in the MailcapCommandMap, it searches
|
||||
* mailcap files in the following order:
|
||||
* <p>
|
||||
* <ol>
|
||||
* <li> Programatically added entries to the MailcapCommandMap instance.
|
||||
* <li> The file <code>.mailcap</code> in the user's home directory.
|
||||
* <li> The file <<i>java.home</i>><code>/lib/mailcap</code>.
|
||||
* <li> The file or resources named <code>META-INF/mailcap</code>.
|
||||
* <li> The file or resource named <code>META-INF/mailcap.default</code>
|
||||
* (usually found only in the <code>activation.jar</code> file).
|
||||
* </ol>
|
||||
* <p>
|
||||
* <b>Mailcap file format:</b><p>
|
||||
*
|
||||
* Mailcap files must conform to the mailcap
|
||||
* file specification (RFC 1524, <i>A User Agent Configuration Mechanism
|
||||
* For Multimedia Mail Format Information</i>).
|
||||
* The file format consists of entries corresponding to
|
||||
* particular MIME types. In general, the specification
|
||||
* specifies <i>applications</i> for clients to use when they
|
||||
* themselves cannot operate on the specified MIME type. The
|
||||
* MailcapCommandMap extends this specification by using a parameter mechanism
|
||||
* in mailcap files that allows JavaBeans(tm) components to be specified as
|
||||
* corresponding to particular commands for a MIME type.<p>
|
||||
*
|
||||
* When a mailcap file is
|
||||
* parsed, the MailcapCommandMap recognizes certain parameter signatures,
|
||||
* specifically those parameter names that begin with <code>x-java-</code>.
|
||||
* The MailcapCommandMap uses this signature to find
|
||||
* command entries for inclusion into its registries.
|
||||
* Parameter names with the form <code>x-java-<name></code>
|
||||
* are read by the MailcapCommandMap as identifying a command
|
||||
* with the name <i>name</i>. When the <i>name</i> is <code>
|
||||
* content-handler</code> the MailcapCommandMap recognizes the class
|
||||
* signified by this parameter as a <i>DataContentHandler</i>.
|
||||
* All other commands are handled generically regardless of command
|
||||
* name. The command implementation is specified by a fully qualified
|
||||
* class name of a JavaBean(tm) component. For example; a command for viewing
|
||||
* some data can be specified as: <code>x-java-view=com.foo.ViewBean</code>.<p>
|
||||
*
|
||||
* When the command name is <code>fallback-entry</code>, the value of
|
||||
* the command may be <code>true</code> or <code>false</code>. An
|
||||
* entry for a MIME type that includes a parameter of
|
||||
* <code>x-java-fallback-entry=true</code> defines fallback commands
|
||||
* for that MIME type that will only be used if no non-fallback entry
|
||||
* can be found. For example, an entry of the form <code>text/*; ;
|
||||
* x-java-fallback-entry=true; x-java-view=com.sun.TextViewer</code>
|
||||
* specifies a view command to be used for any text MIME type. This
|
||||
* view command would only be used if a non-fallback view command for
|
||||
* the MIME type could not be found.<p>
|
||||
*
|
||||
* MailcapCommandMap aware mailcap files have the
|
||||
* following general form:<p>
|
||||
* <code>
|
||||
* # Comments begin with a '#' and continue to the end of the line.<br>
|
||||
* <mime type>; ; <parameter list><br>
|
||||
* # Where a parameter list consists of one or more parameters,<br>
|
||||
* # where parameters look like: x-java-view=com.sun.TextViewer<br>
|
||||
* # and a parameter list looks like: <br>
|
||||
* text/plain; ; x-java-view=com.sun.TextViewer; x-java-edit=com.sun.TextEdit
|
||||
* <br>
|
||||
* # Note that mailcap entries that do not contain 'x-java' parameters<br>
|
||||
* # and comply to RFC 1524 are simply ignored:<br>
|
||||
* image/gif; /usr/dt/bin/sdtimage %s<br>
|
||||
*
|
||||
* </code>
|
||||
* <p>
|
||||
*
|
||||
* @author Bart Calder
|
||||
* @author Bill Shannon
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public class MailcapCommandMap extends CommandMap {
|
||||
/*
|
||||
* We manage a collection of databases, searched in order.
|
||||
* The default database is shared between all instances
|
||||
* of this class.
|
||||
* XXX - Can we safely share more databases between instances?
|
||||
*/
|
||||
private static MailcapFile defDB = null;
|
||||
private MailcapFile[] DB;
|
||||
private static final int PROG = 0; // programmatically added entries
|
||||
|
||||
/**
|
||||
* The default Constructor.
|
||||
*/
|
||||
public MailcapCommandMap() {
|
||||
super();
|
||||
List dbv = new ArrayList(5); // usually 5 or less databases
|
||||
MailcapFile mf = null;
|
||||
dbv.add(null); // place holder for PROG entry
|
||||
|
||||
LogSupport.log("MailcapCommandMap: load HOME");
|
||||
try {
|
||||
String user_home = System.getProperty("user.home");
|
||||
|
||||
if (user_home != null) {
|
||||
String path = user_home + File.separator + ".mailcap";
|
||||
mf = loadFile(path);
|
||||
if (mf != null)
|
||||
dbv.add(mf);
|
||||
}
|
||||
} catch (SecurityException ex) {}
|
||||
|
||||
LogSupport.log("MailcapCommandMap: load SYS");
|
||||
try {
|
||||
// check system's home
|
||||
String system_mailcap = System.getProperty("java.home") +
|
||||
File.separator + "lib" + File.separator + "mailcap";
|
||||
mf = loadFile(system_mailcap);
|
||||
if (mf != null)
|
||||
dbv.add(mf);
|
||||
} catch (SecurityException ex) {}
|
||||
|
||||
LogSupport.log("MailcapCommandMap: load JAR");
|
||||
// load from the app's jar file
|
||||
loadAllResources(dbv, "META-INF/mailcap");
|
||||
|
||||
LogSupport.log("MailcapCommandMap: load DEF");
|
||||
synchronized (MailcapCommandMap.class) {
|
||||
// see if another instance has created this yet.
|
||||
if (defDB == null)
|
||||
defDB = loadResource("/META-INF/mailcap.default");
|
||||
}
|
||||
|
||||
if (defDB != null)
|
||||
dbv.add(defDB);
|
||||
|
||||
DB = new MailcapFile[dbv.size()];
|
||||
DB = (MailcapFile[])dbv.toArray(DB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load from the named resource.
|
||||
*/
|
||||
private MailcapFile loadResource(String name) {
|
||||
InputStream clis = null;
|
||||
try {
|
||||
clis = SecuritySupport.getResourceAsStream(this.getClass(), name);
|
||||
if (clis != null) {
|
||||
MailcapFile mf = new MailcapFile(clis);
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: successfully loaded " +
|
||||
"mailcap file: " + name);
|
||||
return mf;
|
||||
} else {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: not loading " +
|
||||
"mailcap file: " + name);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: can't load " + name, e);
|
||||
} catch (SecurityException sex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: can't load " + name, sex);
|
||||
} finally {
|
||||
try {
|
||||
if (clis != null)
|
||||
clis.close();
|
||||
} catch (IOException ex) { } // ignore it
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all of the named resource.
|
||||
*/
|
||||
private void loadAllResources(List v, String name) {
|
||||
boolean anyLoaded = false;
|
||||
try {
|
||||
URL[] urls;
|
||||
ClassLoader cld = null;
|
||||
// First try the "application's" class loader.
|
||||
cld = SecuritySupport.getContextClassLoader();
|
||||
if (cld == null)
|
||||
cld = this.getClass().getClassLoader();
|
||||
if (cld != null)
|
||||
urls = SecuritySupport.getResources(cld, name);
|
||||
else
|
||||
urls = SecuritySupport.getSystemResources(name);
|
||||
if (urls != null) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: getResources");
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
URL url = urls[i];
|
||||
InputStream clis = null;
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: URL " + url);
|
||||
try {
|
||||
clis = SecuritySupport.openStream(url);
|
||||
if (clis != null) {
|
||||
v.add(new MailcapFile(clis));
|
||||
anyLoaded = true;
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: " +
|
||||
"successfully loaded " +
|
||||
"mailcap file from URL: " +
|
||||
url);
|
||||
} else {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: " +
|
||||
"not loading mailcap " +
|
||||
"file from URL: " + url);
|
||||
}
|
||||
} catch (IOException ioex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: can't load " +
|
||||
url, ioex);
|
||||
} catch (SecurityException sex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: can't load " +
|
||||
url, sex);
|
||||
} finally {
|
||||
try {
|
||||
if (clis != null)
|
||||
clis.close();
|
||||
} catch (IOException cex) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: can't load " + name, ex);
|
||||
}
|
||||
|
||||
// if failed to load anything, fall back to old technique, just in case
|
||||
if (!anyLoaded) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: !anyLoaded");
|
||||
MailcapFile mf = loadResource("/" + name);
|
||||
if (mf != null)
|
||||
v.add(mf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load from the named file.
|
||||
*/
|
||||
private MailcapFile loadFile(String name) {
|
||||
MailcapFile mtf = null;
|
||||
|
||||
try {
|
||||
mtf = new MailcapFile(name);
|
||||
} catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return mtf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that allows the caller to specify the path
|
||||
* of a <i>mailcap</i> file.
|
||||
*
|
||||
* @param fileName The name of the <i>mailcap</i> file to open
|
||||
* @exception IOException if the file can't be accessed
|
||||
*/
|
||||
public MailcapCommandMap(String fileName) throws IOException {
|
||||
this();
|
||||
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MailcapCommandMap: load PROG from " + fileName);
|
||||
if (DB[PROG] == null) {
|
||||
DB[PROG] = new MailcapFile(fileName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Constructor that allows the caller to specify an <i>InputStream</i>
|
||||
* containing a mailcap file.
|
||||
*
|
||||
* @param is InputStream of the <i>mailcap</i> file to open
|
||||
*/
|
||||
public MailcapCommandMap(InputStream is) {
|
||||
this();
|
||||
|
||||
LogSupport.log("MailcapCommandMap: load PROG");
|
||||
if (DB[PROG] == null) {
|
||||
try {
|
||||
DB[PROG] = new MailcapFile(is);
|
||||
} catch (IOException ex) {
|
||||
// XXX - should throw it
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the preferred command list for a MIME Type. The MailcapCommandMap
|
||||
* searches the mailcap files as described above under
|
||||
* <i>Mailcap file search order</i>.<p>
|
||||
*
|
||||
* The result of the search is a proper subset of available
|
||||
* commands in all mailcap files known to this instance of
|
||||
* MailcapCommandMap. The first entry for a particular command
|
||||
* is considered the preferred command.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return the CommandInfo objects representing the preferred commands.
|
||||
*/
|
||||
public synchronized CommandInfo[] getPreferredCommands(String mimeType) {
|
||||
List cmdList = new ArrayList();
|
||||
if (mimeType != null)
|
||||
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
Map cmdMap = DB[i].getMailcapList(mimeType);
|
||||
if (cmdMap != null)
|
||||
appendPrefCmdsToList(cmdMap, cmdList);
|
||||
}
|
||||
|
||||
// now add the fallback commands
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
|
||||
if (cmdMap != null)
|
||||
appendPrefCmdsToList(cmdMap, cmdList);
|
||||
}
|
||||
|
||||
CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
|
||||
cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
|
||||
|
||||
return cmdInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the commands that are in the hash table, into the list.
|
||||
*/
|
||||
private void appendPrefCmdsToList(Map cmdHash, List cmdList) {
|
||||
Iterator verb_enum = cmdHash.keySet().iterator();
|
||||
|
||||
while (verb_enum.hasNext()) {
|
||||
String verb = (String)verb_enum.next();
|
||||
if (!checkForVerb(cmdList, verb)) {
|
||||
List cmdList2 = (List)cmdHash.get(verb); // get the list
|
||||
String className = (String)cmdList2.get(0);
|
||||
cmdList.add(new CommandInfo(verb, className));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the cmdList to see if this command exists, return
|
||||
* true if the verb is there.
|
||||
*/
|
||||
private boolean checkForVerb(List cmdList, String verb) {
|
||||
Iterator ee = cmdList.iterator();
|
||||
while (ee.hasNext()) {
|
||||
String enum_verb =
|
||||
(String)((CommandInfo)ee.next()).getCommandName();
|
||||
if (enum_verb.equals(verb))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the available commands in all mailcap files known to
|
||||
* this instance of MailcapCommandMap for this MIME type.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return the CommandInfo objects representing all the commands.
|
||||
*/
|
||||
public synchronized CommandInfo[] getAllCommands(String mimeType) {
|
||||
List cmdList = new ArrayList();
|
||||
if (mimeType != null)
|
||||
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
Map cmdMap = DB[i].getMailcapList(mimeType);
|
||||
if (cmdMap != null)
|
||||
appendCmdsToList(cmdMap, cmdList);
|
||||
}
|
||||
|
||||
// now add the fallback commands
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
|
||||
if (cmdMap != null)
|
||||
appendCmdsToList(cmdMap, cmdList);
|
||||
}
|
||||
|
||||
CommandInfo[] cmdInfos = new CommandInfo[cmdList.size()];
|
||||
cmdInfos = (CommandInfo[])cmdList.toArray(cmdInfos);
|
||||
|
||||
return cmdInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Put the commands that are in the hash table, into the list.
|
||||
*/
|
||||
private void appendCmdsToList(Map typeHash, List cmdList) {
|
||||
Iterator verb_enum = typeHash.keySet().iterator();
|
||||
|
||||
while (verb_enum.hasNext()) {
|
||||
String verb = (String)verb_enum.next();
|
||||
List cmdList2 = (List)typeHash.get(verb);
|
||||
Iterator cmd_enum = ((List)cmdList2).iterator();
|
||||
|
||||
while (cmd_enum.hasNext()) {
|
||||
String cmd = (String)cmd_enum.next();
|
||||
cmdList.add(new CommandInfo(verb, cmd));
|
||||
// cmdList.add(0, new CommandInfo(verb, cmd));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the command corresponding to <code>cmdName</code> for the MIME type.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @param cmdName the command name
|
||||
* @return the CommandInfo object corresponding to the command.
|
||||
*/
|
||||
public synchronized CommandInfo getCommand(String mimeType,
|
||||
String cmdName) {
|
||||
if (mimeType != null)
|
||||
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
Map cmdMap = DB[i].getMailcapList(mimeType);
|
||||
if (cmdMap != null) {
|
||||
// get the cmd list for the cmd
|
||||
List v = (List)cmdMap.get(cmdName);
|
||||
if (v != null) {
|
||||
String cmdClassName = (String)v.get(0);
|
||||
|
||||
if (cmdClassName != null)
|
||||
return new CommandInfo(cmdName, cmdClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now try the fallback list
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
|
||||
if (cmdMap != null) {
|
||||
// get the cmd list for the cmd
|
||||
List v = (List)cmdMap.get(cmdName);
|
||||
if (v != null) {
|
||||
String cmdClassName = (String)v.get(0);
|
||||
|
||||
if (cmdClassName != null)
|
||||
return new CommandInfo(cmdName, cmdClassName);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add entries to the registry. Programmatically
|
||||
* added entries are searched before other entries.<p>
|
||||
*
|
||||
* The string that is passed in should be in mailcap
|
||||
* format.
|
||||
*
|
||||
* @param mail_cap a correctly formatted mailcap string
|
||||
*/
|
||||
public synchronized void addMailcap(String mail_cap) {
|
||||
// check to see if one exists
|
||||
LogSupport.log("MailcapCommandMap: add to PROG");
|
||||
if (DB[PROG] == null)
|
||||
DB[PROG] = new MailcapFile();
|
||||
|
||||
DB[PROG].appendToMailcap(mail_cap);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the DataContentHandler for the specified MIME type.
|
||||
*
|
||||
* @param mimeType the MIME type
|
||||
* @return the DataContentHandler
|
||||
*/
|
||||
public synchronized DataContentHandler createDataContentHandler(
|
||||
String mimeType) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log(
|
||||
"MailcapCommandMap: createDataContentHandler for " + mimeType);
|
||||
if (mimeType != null)
|
||||
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log(" search DB #" + i);
|
||||
Map cmdMap = DB[i].getMailcapList(mimeType);
|
||||
if (cmdMap != null) {
|
||||
List v = (List)cmdMap.get("content-handler");
|
||||
if (v != null) {
|
||||
String name = (String)v.get(0);
|
||||
DataContentHandler dch = getDataContentHandler(name);
|
||||
if (dch != null)
|
||||
return dch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// now try the fallback entries
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log(" search fallback DB #" + i);
|
||||
Map cmdMap = DB[i].getMailcapFallbackList(mimeType);
|
||||
if (cmdMap != null) {
|
||||
List v = (List)cmdMap.get("content-handler");
|
||||
if (v != null) {
|
||||
String name = (String)v.get(0);
|
||||
DataContentHandler dch = getDataContentHandler(name);
|
||||
if (dch != null)
|
||||
return dch;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private DataContentHandler getDataContentHandler(String name) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log(" got content-handler");
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log(" class " + name);
|
||||
try {
|
||||
ClassLoader cld = null;
|
||||
// First try the "application's" class loader.
|
||||
cld = SecuritySupport.getContextClassLoader();
|
||||
if (cld == null)
|
||||
cld = this.getClass().getClassLoader();
|
||||
Class cl = null;
|
||||
try {
|
||||
cl = cld.loadClass(name);
|
||||
} catch (Exception ex) {
|
||||
// if anything goes wrong, do it the old way
|
||||
cl = Class.forName(name);
|
||||
}
|
||||
if (cl != null) // XXX - always true?
|
||||
return (DataContentHandler)cl.newInstance();
|
||||
} catch (IllegalAccessException e) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("Can't load DCH " + name, e);
|
||||
} catch (ClassNotFoundException e) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("Can't load DCH " + name, e);
|
||||
} catch (InstantiationException e) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("Can't load DCH " + name, e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all the MIME types known to this command map.
|
||||
*
|
||||
* @return array of MIME types as strings
|
||||
* @since JAF 1.1
|
||||
*/
|
||||
public synchronized String[] getMimeTypes() {
|
||||
List mtList = new ArrayList();
|
||||
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
String[] ts = DB[i].getMimeTypes();
|
||||
if (ts != null) {
|
||||
for (int j = 0; j < ts.length; j++) {
|
||||
// eliminate duplicates
|
||||
if (!mtList.contains(ts[j]))
|
||||
mtList.add(ts[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String[] mts = new String[mtList.size()];
|
||||
mts = (String[])mtList.toArray(mts);
|
||||
|
||||
return mts;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the native commands for the given MIME type.
|
||||
* Returns an array of strings where each string is
|
||||
* an entire mailcap file entry. The application
|
||||
* will need to parse the entry to extract the actual
|
||||
* command as well as any attributes it needs. See
|
||||
* <A HREF="http://www.ietf.org/rfc/rfc1524.txt">RFC 1524</A>
|
||||
* for details of the mailcap entry syntax. Only mailcap
|
||||
* entries that specify a view command for the specified
|
||||
* MIME type are returned.
|
||||
*
|
||||
* @return array of native command entries
|
||||
* @since JAF 1.1
|
||||
*/
|
||||
public synchronized String[] getNativeCommands(String mimeType) {
|
||||
List cmdList = new ArrayList();
|
||||
if (mimeType != null)
|
||||
mimeType = mimeType.toLowerCase(Locale.ENGLISH);
|
||||
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
String[] cmds = DB[i].getNativeCommands(mimeType);
|
||||
if (cmds != null) {
|
||||
for (int j = 0; j < cmds.length; j++) {
|
||||
// eliminate duplicates
|
||||
if (!cmdList.contains(cmds[j]))
|
||||
cmdList.add(cmds[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String[] cmds = new String[cmdList.size()];
|
||||
cmds = (String[])cmdList.toArray(cmds);
|
||||
|
||||
return cmds;
|
||||
}
|
||||
|
||||
/**
|
||||
* for debugging...
|
||||
*
|
||||
public static void main(String[] argv) throws Exception {
|
||||
MailcapCommandMap map = new MailcapCommandMap();
|
||||
CommandInfo[] cmdInfo;
|
||||
|
||||
cmdInfo = map.getPreferredCommands(argv[0]);
|
||||
System.out.println("Preferred Commands:");
|
||||
for (int i = 0; i < cmdInfo.length; i++)
|
||||
System.out.println("Command " + cmdInfo[i].getCommandName() + " [" +
|
||||
cmdInfo[i].getCommandClass() + "]");
|
||||
cmdInfo = map.getAllCommands(argv[0]);
|
||||
System.out.println();
|
||||
System.out.println("All Commands:");
|
||||
for (int i = 0; i < cmdInfo.length; i++)
|
||||
System.out.println("Command " + cmdInfo[i].getCommandName() + " [" +
|
||||
cmdInfo[i].getCommandClass() + "]");
|
||||
DataContentHandler dch = map.createDataContentHandler(argv[0]);
|
||||
if (dch != null)
|
||||
System.out.println("DataContentHandler " +
|
||||
dch.getClass().toString());
|
||||
System.exit(0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
344
jaxws/src/share/jaf_classes/javax/activation/MimeType.java
Normal file
344
jaxws/src/share/jaf_classes/javax/activation/MimeType.java
Normal file
@ -0,0 +1,344 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A Multipurpose Internet Mail Extension (MIME) type, as defined
|
||||
* in RFC 2045 and 2046.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class MimeType implements Externalizable {
|
||||
|
||||
private String primaryType;
|
||||
private String subType;
|
||||
private MimeTypeParameterList parameters;
|
||||
|
||||
/**
|
||||
* A string that holds all the special chars.
|
||||
*/
|
||||
private static final String TSPECIALS = "()<>@,;:/[]?=\\\"";
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public MimeType() {
|
||||
primaryType = "application";
|
||||
subType = "*";
|
||||
parameters = new MimeTypeParameterList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that builds a MimeType from a String.
|
||||
*
|
||||
* @param rawdata the MIME type string
|
||||
*/
|
||||
public MimeType(String rawdata) throws MimeTypeParseException {
|
||||
parse(rawdata);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor that builds a MimeType with the given primary and sub type
|
||||
* but has an empty parameter list.
|
||||
*
|
||||
* @param primary the primary MIME type
|
||||
* @param sub the MIME sub-type
|
||||
* @exception MimeTypeParseException if the primary type or subtype
|
||||
* is not a valid token
|
||||
*/
|
||||
public MimeType(String primary, String sub) throws MimeTypeParseException {
|
||||
// check to see if primary is valid
|
||||
if (isValidToken(primary)) {
|
||||
primaryType = primary.toLowerCase(Locale.ENGLISH);
|
||||
} else {
|
||||
throw new MimeTypeParseException("Primary type is invalid.");
|
||||
}
|
||||
|
||||
// check to see if sub is valid
|
||||
if (isValidToken(sub)) {
|
||||
subType = sub.toLowerCase(Locale.ENGLISH);
|
||||
} else {
|
||||
throw new MimeTypeParseException("Sub type is invalid.");
|
||||
}
|
||||
|
||||
parameters = new MimeTypeParameterList();
|
||||
}
|
||||
|
||||
/**
|
||||
* A routine for parsing the MIME type out of a String.
|
||||
*/
|
||||
private void parse(String rawdata) throws MimeTypeParseException {
|
||||
int slashIndex = rawdata.indexOf('/');
|
||||
int semIndex = rawdata.indexOf(';');
|
||||
if ((slashIndex < 0) && (semIndex < 0)) {
|
||||
// neither character is present, so treat it
|
||||
// as an error
|
||||
throw new MimeTypeParseException("Unable to find a sub type.");
|
||||
} else if ((slashIndex < 0) && (semIndex >= 0)) {
|
||||
// we have a ';' (and therefore a parameter list),
|
||||
// but no '/' indicating a sub type is present
|
||||
throw new MimeTypeParseException("Unable to find a sub type.");
|
||||
} else if ((slashIndex >= 0) && (semIndex < 0)) {
|
||||
// we have a primary and sub type but no parameter list
|
||||
primaryType = rawdata.substring(0, slashIndex).trim().
|
||||
toLowerCase(Locale.ENGLISH);
|
||||
subType = rawdata.substring(slashIndex + 1).trim().
|
||||
toLowerCase(Locale.ENGLISH);
|
||||
parameters = new MimeTypeParameterList();
|
||||
} else if (slashIndex < semIndex) {
|
||||
// we have all three items in the proper sequence
|
||||
primaryType = rawdata.substring(0, slashIndex).trim().
|
||||
toLowerCase(Locale.ENGLISH);
|
||||
subType = rawdata.substring(slashIndex + 1, semIndex).trim().
|
||||
toLowerCase(Locale.ENGLISH);
|
||||
parameters = new MimeTypeParameterList(rawdata.substring(semIndex));
|
||||
} else {
|
||||
// we have a ';' lexically before a '/' which means we
|
||||
// have a primary type and a parameter list but no sub type
|
||||
throw new MimeTypeParseException("Unable to find a sub type.");
|
||||
}
|
||||
|
||||
// now validate the primary and sub types
|
||||
|
||||
// check to see if primary is valid
|
||||
if (!isValidToken(primaryType))
|
||||
throw new MimeTypeParseException("Primary type is invalid.");
|
||||
|
||||
// check to see if sub is valid
|
||||
if (!isValidToken(subType))
|
||||
throw new MimeTypeParseException("Sub type is invalid.");
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the primary type of this object.
|
||||
*
|
||||
* @return the primary MIME type
|
||||
*/
|
||||
public String getPrimaryType() {
|
||||
return primaryType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the primary type for this object to the given String.
|
||||
*
|
||||
* @param primary the primary MIME type
|
||||
* @exception MimeTypeParseException if the primary type
|
||||
* is not a valid token
|
||||
*/
|
||||
public void setPrimaryType(String primary) throws MimeTypeParseException {
|
||||
// check to see if primary is valid
|
||||
if (!isValidToken(primaryType))
|
||||
throw new MimeTypeParseException("Primary type is invalid.");
|
||||
primaryType = primary.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the subtype of this object.
|
||||
*
|
||||
* @return the MIME subtype
|
||||
*/
|
||||
public String getSubType() {
|
||||
return subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the subtype for this object to the given String.
|
||||
*
|
||||
* @param sub the MIME subtype
|
||||
* @exception MimeTypeParseException if the subtype
|
||||
* is not a valid token
|
||||
*/
|
||||
public void setSubType(String sub) throws MimeTypeParseException {
|
||||
// check to see if sub is valid
|
||||
if (!isValidToken(subType))
|
||||
throw new MimeTypeParseException("Sub type is invalid.");
|
||||
subType = sub.toLowerCase(Locale.ENGLISH);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve this object's parameter list.
|
||||
*
|
||||
* @return a MimeTypeParameterList object representing the parameters
|
||||
*/
|
||||
public MimeTypeParameterList getParameters() {
|
||||
return parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value associated with the given name, or null if there
|
||||
* is no current association.
|
||||
*
|
||||
* @param name the parameter name
|
||||
* @return the paramter's value
|
||||
*/
|
||||
public String getParameter(String name) {
|
||||
return parameters.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value to be associated with the given name, replacing
|
||||
* any previous association.
|
||||
*
|
||||
* @param name the parameter name
|
||||
* @param value the paramter's value
|
||||
*/
|
||||
public void setParameter(String name, String value) {
|
||||
parameters.set(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any value associated with the given name.
|
||||
*
|
||||
* @param name the parameter name
|
||||
*/
|
||||
public void removeParameter(String name) {
|
||||
parameters.remove(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the String representation of this object.
|
||||
*/
|
||||
public String toString() {
|
||||
return getBaseType() + parameters.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a String representation of this object
|
||||
* without the parameter list.
|
||||
*
|
||||
* @return the MIME type and sub-type
|
||||
*/
|
||||
public String getBaseType() {
|
||||
return primaryType + "/" + subType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the primary and sub type of this object is
|
||||
* the same as what is in the given type.
|
||||
*
|
||||
* @param type the MimeType object to compare with
|
||||
* @return true if they match
|
||||
*/
|
||||
public boolean match(MimeType type) {
|
||||
return primaryType.equals(type.getPrimaryType())
|
||||
&& (subType.equals("*")
|
||||
|| type.getSubType().equals("*")
|
||||
|| (subType.equals(type.getSubType())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if the primary and sub type of this object is
|
||||
* the same as the content type described in rawdata.
|
||||
*
|
||||
* @param rawdata the MIME type string to compare with
|
||||
* @return true if they match
|
||||
*/
|
||||
public boolean match(String rawdata) throws MimeTypeParseException {
|
||||
return match(new MimeType(rawdata));
|
||||
}
|
||||
|
||||
/**
|
||||
* The object implements the writeExternal method to save its contents
|
||||
* by calling the methods of DataOutput for its primitive values or
|
||||
* calling the writeObject method of ObjectOutput for objects, strings
|
||||
* and arrays.
|
||||
*
|
||||
* @param out the ObjectOutput object to write to
|
||||
* @exception IOException Includes any I/O exceptions that may occur
|
||||
*/
|
||||
public void writeExternal(ObjectOutput out) throws IOException {
|
||||
out.writeUTF(toString());
|
||||
out.flush();
|
||||
}
|
||||
|
||||
/**
|
||||
* The object implements the readExternal method to restore its
|
||||
* contents by calling the methods of DataInput for primitive
|
||||
* types and readObject for objects, strings and arrays. The
|
||||
* readExternal method must read the values in the same sequence
|
||||
* and with the same types as were written by writeExternal.
|
||||
*
|
||||
* @param in the ObjectInput object to read from
|
||||
* @exception ClassNotFoundException If the class for an object being
|
||||
* restored cannot be found.
|
||||
*/
|
||||
public void readExternal(ObjectInput in)
|
||||
throws IOException, ClassNotFoundException {
|
||||
try {
|
||||
parse(in.readUTF());
|
||||
} catch (MimeTypeParseException e) {
|
||||
throw new IOException(e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
// below here be scary parsing related things
|
||||
|
||||
/**
|
||||
* Determine whether or not a given character belongs to a legal token.
|
||||
*/
|
||||
private static boolean isTokenChar(char c) {
|
||||
return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not a given string is a legal token.
|
||||
*/
|
||||
private boolean isValidToken(String s) {
|
||||
int len = s.length();
|
||||
if (len > 0) {
|
||||
for (int i = 0; i < len; ++i) {
|
||||
char c = s.charAt(i);
|
||||
if (!isTokenChar(c)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A simple parser test,
|
||||
* for debugging...
|
||||
*
|
||||
public static void main(String[] args)
|
||||
throws MimeTypeParseException, IOException {
|
||||
for (int i = 0; i < args.length; ++i) {
|
||||
System.out.println("Original: " + args[i]);
|
||||
|
||||
MimeType type = new MimeType(args[i]);
|
||||
|
||||
System.out.println("Short: " + type.getBaseType());
|
||||
System.out.println("Parsed: " + type.toString());
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -0,0 +1,339 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.Enumeration;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A parameter list of a MimeType
|
||||
* as defined in RFC 2045 and 2046. The Primary type of the
|
||||
* object must already be stripped off.
|
||||
*
|
||||
* @see javax.activation.MimeType
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class MimeTypeParameterList {
|
||||
private Hashtable parameters;
|
||||
|
||||
/**
|
||||
* A string that holds all the special chars.
|
||||
*/
|
||||
private static final String TSPECIALS = "()<>@,;:/[]?=\\\"";
|
||||
|
||||
|
||||
/**
|
||||
* Default constructor.
|
||||
*/
|
||||
public MimeTypeParameterList() {
|
||||
parameters = new Hashtable();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new MimeTypeParameterList with the passed in data.
|
||||
*
|
||||
* @param parameterList an RFC 2045, 2046 compliant parameter list.
|
||||
*/
|
||||
public MimeTypeParameterList(String parameterList)
|
||||
throws MimeTypeParseException {
|
||||
parameters = new Hashtable();
|
||||
|
||||
// now parse rawdata
|
||||
parse(parameterList);
|
||||
}
|
||||
|
||||
/**
|
||||
* A routine for parsing the parameter list out of a String.
|
||||
*
|
||||
* @param parameterList an RFC 2045, 2046 compliant parameter list.
|
||||
*/
|
||||
protected void parse(String parameterList) throws MimeTypeParseException {
|
||||
if (parameterList == null)
|
||||
return;
|
||||
|
||||
int length = parameterList.length();
|
||||
if (length <= 0)
|
||||
return;
|
||||
|
||||
int i;
|
||||
char c;
|
||||
for (i = skipWhiteSpace(parameterList, 0);
|
||||
i < length && (c = parameterList.charAt(i)) == ';';
|
||||
i = skipWhiteSpace(parameterList, i)) {
|
||||
int lastIndex;
|
||||
String name;
|
||||
String value;
|
||||
|
||||
// eat the ';'
|
||||
i++;
|
||||
|
||||
// now parse the parameter name
|
||||
|
||||
// skip whitespace
|
||||
i = skipWhiteSpace(parameterList, i);
|
||||
|
||||
// tolerate trailing semicolon, even though it violates the spec
|
||||
if (i >= length)
|
||||
return;
|
||||
|
||||
// find the end of the token char run
|
||||
lastIndex = i;
|
||||
while ((i < length) && isTokenChar(parameterList.charAt(i)))
|
||||
i++;
|
||||
|
||||
name = parameterList.substring(lastIndex, i).
|
||||
toLowerCase(Locale.ENGLISH);
|
||||
|
||||
// now parse the '=' that separates the name from the value
|
||||
i = skipWhiteSpace(parameterList, i);
|
||||
|
||||
if (i >= length || parameterList.charAt(i) != '=')
|
||||
throw new MimeTypeParseException(
|
||||
"Couldn't find the '=' that separates a " +
|
||||
"parameter name from its value.");
|
||||
|
||||
// eat it and parse the parameter value
|
||||
i++;
|
||||
i = skipWhiteSpace(parameterList, i);
|
||||
|
||||
if (i >= length)
|
||||
throw new MimeTypeParseException(
|
||||
"Couldn't find a value for parameter named " + name);
|
||||
|
||||
// now find out whether or not we have a quoted value
|
||||
c = parameterList.charAt(i);
|
||||
if (c == '"') {
|
||||
// yup it's quoted so eat it and capture the quoted string
|
||||
i++;
|
||||
if (i >= length)
|
||||
throw new MimeTypeParseException(
|
||||
"Encountered unterminated quoted parameter value.");
|
||||
|
||||
lastIndex = i;
|
||||
|
||||
// find the next unescaped quote
|
||||
while (i < length) {
|
||||
c = parameterList.charAt(i);
|
||||
if (c == '"')
|
||||
break;
|
||||
if (c == '\\') {
|
||||
// found an escape sequence
|
||||
// so skip this and the
|
||||
// next character
|
||||
i++;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (c != '"')
|
||||
throw new MimeTypeParseException(
|
||||
"Encountered unterminated quoted parameter value.");
|
||||
|
||||
value = unquote(parameterList.substring(lastIndex, i));
|
||||
// eat the quote
|
||||
i++;
|
||||
} else if (isTokenChar(c)) {
|
||||
// nope it's an ordinary token so it
|
||||
// ends with a non-token char
|
||||
lastIndex = i;
|
||||
while (i < length && isTokenChar(parameterList.charAt(i)))
|
||||
i++;
|
||||
value = parameterList.substring(lastIndex, i);
|
||||
} else {
|
||||
// it ain't a value
|
||||
throw new MimeTypeParseException(
|
||||
"Unexpected character encountered at index " + i);
|
||||
}
|
||||
|
||||
// now put the data into the hashtable
|
||||
parameters.put(name, value);
|
||||
}
|
||||
if (i < length) {
|
||||
throw new MimeTypeParseException(
|
||||
"More characters encountered in input than expected.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the number of name-value pairs in this list.
|
||||
*
|
||||
* @return the number of parameters
|
||||
*/
|
||||
public int size() {
|
||||
return parameters.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether or not this list is empty.
|
||||
*
|
||||
* @return true if there are no parameters
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return parameters.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the value associated with the given name, or null if there
|
||||
* is no current association.
|
||||
*
|
||||
* @param name the parameter name
|
||||
* @return the parameter's value
|
||||
*/
|
||||
public String get(String name) {
|
||||
return (String)parameters.get(name.trim().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the value to be associated with the given name, replacing
|
||||
* any previous association.
|
||||
*
|
||||
* @param name the parameter name
|
||||
* @param value the parameter's value
|
||||
*/
|
||||
public void set(String name, String value) {
|
||||
parameters.put(name.trim().toLowerCase(Locale.ENGLISH), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove any value associated with the given name.
|
||||
*
|
||||
* @param name the parameter name
|
||||
*/
|
||||
public void remove(String name) {
|
||||
parameters.remove(name.trim().toLowerCase(Locale.ENGLISH));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve an enumeration of all the names in this list.
|
||||
*
|
||||
* @return an enumeration of all parameter names
|
||||
*/
|
||||
public Enumeration getNames() {
|
||||
return parameters.keys();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of this object.
|
||||
*/
|
||||
public String toString() {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.ensureCapacity(parameters.size() * 16);
|
||||
// heuristic: 8 characters per field
|
||||
|
||||
Enumeration keys = parameters.keys();
|
||||
while (keys.hasMoreElements()) {
|
||||
String key = (String)keys.nextElement();
|
||||
buffer.append("; ");
|
||||
buffer.append(key);
|
||||
buffer.append('=');
|
||||
buffer.append(quote((String)parameters.get(key)));
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
|
||||
// below here be scary parsing related things
|
||||
|
||||
/**
|
||||
* Determine whether or not a given character belongs to a legal token.
|
||||
*/
|
||||
private static boolean isTokenChar(char c) {
|
||||
return ((c > 040) && (c < 0177)) && (TSPECIALS.indexOf(c) < 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* return the index of the first non white space character in
|
||||
* rawdata at or after index i.
|
||||
*/
|
||||
private static int skipWhiteSpace(String rawdata, int i) {
|
||||
int length = rawdata.length();
|
||||
while ((i < length) && Character.isWhitespace(rawdata.charAt(i)))
|
||||
i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* A routine that knows how and when to quote and escape the given value.
|
||||
*/
|
||||
private static String quote(String value) {
|
||||
boolean needsQuotes = false;
|
||||
|
||||
// check to see if we actually have to quote this thing
|
||||
int length = value.length();
|
||||
for (int i = 0; (i < length) && !needsQuotes; i++) {
|
||||
needsQuotes = !isTokenChar(value.charAt(i));
|
||||
}
|
||||
|
||||
if (needsQuotes) {
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.ensureCapacity((int)(length * 1.5));
|
||||
|
||||
// add the initial quote
|
||||
buffer.append('"');
|
||||
|
||||
// add the properly escaped text
|
||||
for (int i = 0; i < length; ++i) {
|
||||
char c = value.charAt(i);
|
||||
if ((c == '\\') || (c == '"'))
|
||||
buffer.append('\\');
|
||||
buffer.append(c);
|
||||
}
|
||||
|
||||
// add the closing quote
|
||||
buffer.append('"');
|
||||
|
||||
return buffer.toString();
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A routine that knows how to strip the quotes and
|
||||
* escape sequences from the given value.
|
||||
*/
|
||||
private static String unquote(String value) {
|
||||
int valueLength = value.length();
|
||||
StringBuffer buffer = new StringBuffer();
|
||||
buffer.ensureCapacity(valueLength);
|
||||
|
||||
boolean escaped = false;
|
||||
for (int i = 0; i < valueLength; ++i) {
|
||||
char currentChar = value.charAt(i);
|
||||
if (!escaped && (currentChar != '\\')) {
|
||||
buffer.append(currentChar);
|
||||
} else if (escaped) {
|
||||
buffer.append(currentChar);
|
||||
escaped = false;
|
||||
} else {
|
||||
escaped = true;
|
||||
}
|
||||
}
|
||||
|
||||
return buffer.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
/**
|
||||
* A class to encapsulate MimeType parsing related exceptions.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class MimeTypeParseException extends Exception {
|
||||
|
||||
/**
|
||||
* Constructs a MimeTypeParseException with no specified detail message.
|
||||
*/
|
||||
public MimeTypeParseException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a MimeTypeParseException with the specified detail message.
|
||||
*
|
||||
* @param s the detail message.
|
||||
*/
|
||||
public MimeTypeParseException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,336 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.*;
|
||||
import java.util.*;
|
||||
import com.sun.activation.registries.MimeTypeFile;
|
||||
import com.sun.activation.registries.LogSupport;
|
||||
|
||||
/**
|
||||
* This class extends FileTypeMap and provides data typing of files
|
||||
* via their file extension. It uses the <code>.mime.types</code> format. <p>
|
||||
*
|
||||
* <b>MIME types file search order:</b><p>
|
||||
* The MimetypesFileTypeMap looks in various places in the user's
|
||||
* system for MIME types file entries. When requests are made
|
||||
* to search for MIME types in the MimetypesFileTypeMap, it searches
|
||||
* MIME types files in the following order:
|
||||
* <p>
|
||||
* <ol>
|
||||
* <li> Programmatically added entries to the MimetypesFileTypeMap instance.
|
||||
* <li> The file <code>.mime.types</code> in the user's home directory.
|
||||
* <li> The file <<i>java.home</i>><code>/lib/mime.types</code>.
|
||||
* <li> The file or resources named <code>META-INF/mime.types</code>.
|
||||
* <li> The file or resource named <code>META-INF/mimetypes.default</code>
|
||||
* (usually found only in the <code>activation.jar</code> file).
|
||||
* </ol>
|
||||
* <p>
|
||||
* <b>MIME types file format:</b><p>
|
||||
*
|
||||
* <code>
|
||||
* # comments begin with a '#'<br>
|
||||
* # the format is <mime type> <space separated file extensions><br>
|
||||
* # for example:<br>
|
||||
* text/plain txt text TXT<br>
|
||||
* # this would map file.txt, file.text, and file.TXT to<br>
|
||||
* # the mime type "text/plain"<br>
|
||||
* </code>
|
||||
*
|
||||
* @author Bart Calder
|
||||
* @author Bill Shannon
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class MimetypesFileTypeMap extends FileTypeMap {
|
||||
/*
|
||||
* We manage a collection of databases, searched in order.
|
||||
* The default database is shared between all instances
|
||||
* of this class.
|
||||
* XXX - Can we safely share more databases between instances?
|
||||
*/
|
||||
private static MimeTypeFile defDB = null;
|
||||
private MimeTypeFile[] DB;
|
||||
private static final int PROG = 0; // programmatically added entries
|
||||
|
||||
private static String defaultType = "application/octet-stream";
|
||||
|
||||
/**
|
||||
* The default constructor.
|
||||
*/
|
||||
public MimetypesFileTypeMap() {
|
||||
Vector dbv = new Vector(5); // usually 5 or less databases
|
||||
MimeTypeFile mf = null;
|
||||
dbv.addElement(null); // place holder for PROG entry
|
||||
|
||||
LogSupport.log("MimetypesFileTypeMap: load HOME");
|
||||
try {
|
||||
String user_home = System.getProperty("user.home");
|
||||
|
||||
if (user_home != null) {
|
||||
String path = user_home + File.separator + ".mime.types";
|
||||
mf = loadFile(path);
|
||||
if (mf != null)
|
||||
dbv.addElement(mf);
|
||||
}
|
||||
} catch (SecurityException ex) {}
|
||||
|
||||
LogSupport.log("MimetypesFileTypeMap: load SYS");
|
||||
try {
|
||||
// check system's home
|
||||
String system_mimetypes = System.getProperty("java.home") +
|
||||
File.separator + "lib" + File.separator + "mime.types";
|
||||
mf = loadFile(system_mimetypes);
|
||||
if (mf != null)
|
||||
dbv.addElement(mf);
|
||||
} catch (SecurityException ex) {}
|
||||
|
||||
LogSupport.log("MimetypesFileTypeMap: load JAR");
|
||||
// load from the app's jar file
|
||||
loadAllResources(dbv, "META-INF/mime.types");
|
||||
|
||||
LogSupport.log("MimetypesFileTypeMap: load DEF");
|
||||
synchronized (MimetypesFileTypeMap.class) {
|
||||
// see if another instance has created this yet.
|
||||
if (defDB == null)
|
||||
defDB = loadResource("/META-INF/mimetypes.default");
|
||||
}
|
||||
|
||||
if (defDB != null)
|
||||
dbv.addElement(defDB);
|
||||
|
||||
DB = new MimeTypeFile[dbv.size()];
|
||||
dbv.copyInto(DB);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load from the named resource.
|
||||
*/
|
||||
private MimeTypeFile loadResource(String name) {
|
||||
InputStream clis = null;
|
||||
try {
|
||||
clis = SecuritySupport.getResourceAsStream(this.getClass(), name);
|
||||
if (clis != null) {
|
||||
MimeTypeFile mf = new MimeTypeFile(clis);
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: successfully " +
|
||||
"loaded mime types file: " + name);
|
||||
return mf;
|
||||
} else {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: not loading " +
|
||||
"mime types file: " + name);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: can't load " + name, e);
|
||||
} catch (SecurityException sex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: can't load " + name, sex);
|
||||
} finally {
|
||||
try {
|
||||
if (clis != null)
|
||||
clis.close();
|
||||
} catch (IOException ex) { } // ignore it
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load all of the named resource.
|
||||
*/
|
||||
private void loadAllResources(Vector v, String name) {
|
||||
boolean anyLoaded = false;
|
||||
try {
|
||||
URL[] urls;
|
||||
ClassLoader cld = null;
|
||||
// First try the "application's" class loader.
|
||||
cld = SecuritySupport.getContextClassLoader();
|
||||
if (cld == null)
|
||||
cld = this.getClass().getClassLoader();
|
||||
if (cld != null)
|
||||
urls = SecuritySupport.getResources(cld, name);
|
||||
else
|
||||
urls = SecuritySupport.getSystemResources(name);
|
||||
if (urls != null) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: getResources");
|
||||
for (int i = 0; i < urls.length; i++) {
|
||||
URL url = urls[i];
|
||||
InputStream clis = null;
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: URL " + url);
|
||||
try {
|
||||
clis = SecuritySupport.openStream(url);
|
||||
if (clis != null) {
|
||||
v.addElement(new MimeTypeFile(clis));
|
||||
anyLoaded = true;
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: " +
|
||||
"successfully loaded " +
|
||||
"mime types from URL: " + url);
|
||||
} else {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: " +
|
||||
"not loading " +
|
||||
"mime types from URL: " + url);
|
||||
}
|
||||
} catch (IOException ioex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: can't load " +
|
||||
url, ioex);
|
||||
} catch (SecurityException sex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: can't load " +
|
||||
url, sex);
|
||||
} finally {
|
||||
try {
|
||||
if (clis != null)
|
||||
clis.close();
|
||||
} catch (IOException cex) { }
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
if (LogSupport.isLoggable())
|
||||
LogSupport.log("MimetypesFileTypeMap: can't load " + name, ex);
|
||||
}
|
||||
|
||||
// if failed to load anything, fall back to old technique, just in case
|
||||
if (!anyLoaded) {
|
||||
LogSupport.log("MimetypesFileTypeMap: !anyLoaded");
|
||||
MimeTypeFile mf = loadResource("/" + name);
|
||||
if (mf != null)
|
||||
v.addElement(mf);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the named file.
|
||||
*/
|
||||
private MimeTypeFile loadFile(String name) {
|
||||
MimeTypeFile mtf = null;
|
||||
|
||||
try {
|
||||
mtf = new MimeTypeFile(name);
|
||||
} catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
}
|
||||
return mtf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a MimetypesFileTypeMap with programmatic entries
|
||||
* added from the named file.
|
||||
*
|
||||
* @param mimeTypeFileName the file name
|
||||
*/
|
||||
public MimetypesFileTypeMap(String mimeTypeFileName) throws IOException {
|
||||
this();
|
||||
DB[PROG] = new MimeTypeFile(mimeTypeFileName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a MimetypesFileTypeMap with programmatic entries
|
||||
* added from the InputStream.
|
||||
*
|
||||
* @param is the input stream to read from
|
||||
*/
|
||||
public MimetypesFileTypeMap(InputStream is) {
|
||||
this();
|
||||
try {
|
||||
DB[PROG] = new MimeTypeFile(is);
|
||||
} catch (IOException ex) {
|
||||
// XXX - really should throw it
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepend the MIME type values to the registry.
|
||||
*
|
||||
* @param mime_types A .mime.types formatted string of entries.
|
||||
*/
|
||||
public synchronized void addMimeTypes(String mime_types) {
|
||||
// check to see if we have created the registry
|
||||
if (DB[PROG] == null)
|
||||
DB[PROG] = new MimeTypeFile(); // make one
|
||||
|
||||
DB[PROG].appendToRegistry(mime_types);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MIME type of the file object.
|
||||
* The implementation in this class calls
|
||||
* <code>getContentType(f.getName())</code>.
|
||||
*
|
||||
* @param f the file
|
||||
* @return the file's MIME type
|
||||
*/
|
||||
public String getContentType(File f) {
|
||||
return this.getContentType(f.getName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the MIME type based on the specified file name.
|
||||
* The MIME type entries are searched as described above under
|
||||
* <i>MIME types file search order</i>.
|
||||
* If no entry is found, the type "application/octet-stream" is returned.
|
||||
*
|
||||
* @param filename the file name
|
||||
* @return the file's MIME type
|
||||
*/
|
||||
public synchronized String getContentType(String filename) {
|
||||
int dot_pos = filename.lastIndexOf("."); // period index
|
||||
|
||||
if (dot_pos < 0)
|
||||
return defaultType;
|
||||
|
||||
String file_ext = filename.substring(dot_pos + 1);
|
||||
if (file_ext.length() == 0)
|
||||
return defaultType;
|
||||
|
||||
for (int i = 0; i < DB.length; i++) {
|
||||
if (DB[i] == null)
|
||||
continue;
|
||||
String result = DB[i].getMIMETypeString(file_ext);
|
||||
if (result != null)
|
||||
return result;
|
||||
}
|
||||
return defaultType;
|
||||
}
|
||||
|
||||
/**
|
||||
* for debugging...
|
||||
*
|
||||
public static void main(String[] argv) throws Exception {
|
||||
MimetypesFileTypeMap map = new MimetypesFileTypeMap();
|
||||
System.out.println("File " + argv[0] + " has MIME type " +
|
||||
map.getContentType(argv[0]));
|
||||
System.exit(0);
|
||||
}
|
||||
*/
|
||||
}
|
||||
@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.security.*;
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Security related methods that only work on J2SE 1.2 and newer.
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
class SecuritySupport {
|
||||
|
||||
private SecuritySupport() {
|
||||
// private constructor, can't create an instance
|
||||
}
|
||||
|
||||
public static ClassLoader getContextClassLoader() {
|
||||
return (ClassLoader)
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
ClassLoader cl = null;
|
||||
try {
|
||||
cl = Thread.currentThread().getContextClassLoader();
|
||||
} catch (SecurityException ex) { }
|
||||
return cl;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static InputStream getResourceAsStream(final Class c,
|
||||
final String name) throws IOException {
|
||||
try {
|
||||
return (InputStream)
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() throws IOException {
|
||||
return c.getResourceAsStream(name);
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (IOException)e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
public static URL[] getResources(final ClassLoader cl, final String name) {
|
||||
return (URL[])
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
URL[] ret = null;
|
||||
try {
|
||||
List v = new ArrayList();
|
||||
Enumeration e = cl.getResources(name);
|
||||
while (e != null && e.hasMoreElements()) {
|
||||
URL url = (URL)e.nextElement();
|
||||
if (url != null)
|
||||
v.add(url);
|
||||
}
|
||||
if (v.size() > 0) {
|
||||
ret = new URL[v.size()];
|
||||
ret = (URL[])v.toArray(ret);
|
||||
}
|
||||
} catch (IOException ioex) {
|
||||
} catch (SecurityException ex) { }
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static URL[] getSystemResources(final String name) {
|
||||
return (URL[])
|
||||
AccessController.doPrivileged(new PrivilegedAction() {
|
||||
public Object run() {
|
||||
URL[] ret = null;
|
||||
try {
|
||||
List v = new ArrayList();
|
||||
Enumeration e = ClassLoader.getSystemResources(name);
|
||||
while (e != null && e.hasMoreElements()) {
|
||||
URL url = (URL)e.nextElement();
|
||||
if (url != null)
|
||||
v.add(url);
|
||||
}
|
||||
if (v.size() > 0) {
|
||||
ret = new URL[v.size()];
|
||||
ret = (URL[])v.toArray(ret);
|
||||
}
|
||||
} catch (IOException ioex) {
|
||||
} catch (SecurityException ex) { }
|
||||
return ret;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static InputStream openStream(final URL url) throws IOException {
|
||||
try {
|
||||
return (InputStream)
|
||||
AccessController.doPrivileged(new PrivilegedExceptionAction() {
|
||||
public Object run() throws IOException {
|
||||
return url.openStream();
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (IOException)e.getException();
|
||||
}
|
||||
}
|
||||
}
|
||||
137
jaxws/src/share/jaf_classes/javax/activation/URLDataSource.java
Normal file
137
jaxws/src/share/jaf_classes/javax/activation/URLDataSource.java
Normal file
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* The URLDataSource class provides an object that wraps a <code>URL</code>
|
||||
* object in a DataSource interface. URLDataSource simplifies the handling
|
||||
* of data described by URLs within the JavaBeans Activation Framework
|
||||
* because this class can be used to create new DataHandlers. <i>NOTE: The
|
||||
* DataHandler object creates a URLDataSource internally,
|
||||
* when it is constructed with a URL.</i>
|
||||
*
|
||||
* @see javax.activation.DataSource
|
||||
* @see javax.activation.DataHandler
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
public class URLDataSource implements DataSource {
|
||||
private URL url = null;
|
||||
private URLConnection url_conn = null;
|
||||
|
||||
/**
|
||||
* URLDataSource constructor. The URLDataSource class will
|
||||
* not open a connection to the URL until a method requiring it
|
||||
* to do so is called.
|
||||
*
|
||||
* @param url The URL to be encapsulated in this object.
|
||||
*/
|
||||
public URLDataSource(URL url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value of the URL content-type header field.
|
||||
* It calls the URL's <code>URLConnection.getContentType</code> method
|
||||
* after retrieving a URLConnection object.
|
||||
* <i>Note: this method attempts to call the <code>openConnection</code>
|
||||
* method on the URL. If this method fails, or if a content type is not
|
||||
* returned from the URLConnection, getContentType returns
|
||||
* "application/octet-stream" as the content type.</i>
|
||||
*
|
||||
* @return the content type.
|
||||
*/
|
||||
public String getContentType() {
|
||||
String type = null;
|
||||
|
||||
try {
|
||||
if (url_conn == null)
|
||||
url_conn = url.openConnection();
|
||||
} catch (IOException e) { }
|
||||
|
||||
if (url_conn != null)
|
||||
type = url_conn.getContentType();
|
||||
|
||||
if (type == null)
|
||||
type = "application/octet-stream";
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls the <code>getFile</code> method on the URL used to
|
||||
* instantiate the object.
|
||||
*
|
||||
* @return the result of calling the URL's getFile method.
|
||||
*/
|
||||
public String getName() {
|
||||
return url.getFile();
|
||||
}
|
||||
|
||||
/**
|
||||
* The getInputStream method from the URL. Calls the
|
||||
* <code>openStream</code> method on the URL.
|
||||
*
|
||||
* @return the InputStream.
|
||||
*/
|
||||
public InputStream getInputStream() throws IOException {
|
||||
return url.openStream();
|
||||
}
|
||||
|
||||
/**
|
||||
* The getOutputStream method from the URL. First an attempt is
|
||||
* made to get the URLConnection object for the URL. If that
|
||||
* succeeds, the getOutputStream method on the URLConnection
|
||||
* is returned.
|
||||
*
|
||||
* @return the OutputStream.
|
||||
*/
|
||||
public OutputStream getOutputStream() throws IOException {
|
||||
// get the url connection if it is available
|
||||
url_conn = url.openConnection();
|
||||
|
||||
if (url_conn != null) {
|
||||
url_conn.setDoOutput(true);
|
||||
return url_conn.getOutputStream();
|
||||
} else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the URL used to create this DataSource.
|
||||
*
|
||||
* @return The URL.
|
||||
*/
|
||||
public URL getURL() {
|
||||
return url;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 2005, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
package javax.activation;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* Signals that the requested operation does not support the
|
||||
* requested data type.
|
||||
*
|
||||
* @see javax.activation.DataHandler
|
||||
*
|
||||
* @since 1.6
|
||||
*/
|
||||
|
||||
public class UnsupportedDataTypeException extends IOException {
|
||||
/**
|
||||
* Constructs an UnsupportedDataTypeException with no detail
|
||||
* message.
|
||||
*/
|
||||
public UnsupportedDataTypeException() {
|
||||
super();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an UnsupportedDataTypeException with the specified
|
||||
* message.
|
||||
*
|
||||
* @param s The detail message.
|
||||
*/
|
||||
public UnsupportedDataTypeException(String s) {
|
||||
super(s);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
/**
|
||||
* This helps enable whether the JDefinedClass is a Class or Interface or
|
||||
* AnnotationTypeDeclaration or Enum
|
||||
*
|
||||
* @author
|
||||
* Bhakti Mehta (bhakti.mehta@sun.com)
|
||||
*/
|
||||
public final class ClassType {
|
||||
|
||||
/**
|
||||
* The keyword used to declare this type.
|
||||
*/
|
||||
final String declarationToken;
|
||||
|
||||
private ClassType(String token) {
|
||||
this.declarationToken = token;
|
||||
}
|
||||
|
||||
public static final ClassType CLASS = new ClassType("class");
|
||||
public static final ClassType INTERFACE = new ClassType("interface");
|
||||
public static final ClassType ANNOTATION_TYPE_DECL = new ClassType("@interface");
|
||||
public static final ClassType ENUM = new ClassType("enum");
|
||||
}
|
||||
@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.Writer;
|
||||
import java.nio.charset.CharsetEncoder;
|
||||
|
||||
import com.sun.codemodel.internal.util.EncoderFactory;
|
||||
import com.sun.codemodel.internal.util.UnicodeEscapeWriter;
|
||||
|
||||
/**
|
||||
* Receives generated code and writes to the appropriate storage.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public abstract class CodeWriter {
|
||||
|
||||
/**
|
||||
* Encoding to be used by the writer. Null means platform specific encoding.
|
||||
*
|
||||
* @since 2.5
|
||||
*/
|
||||
protected String encoding = null;
|
||||
|
||||
/**
|
||||
* Called by CodeModel to store the specified file.
|
||||
* The callee must allocate a storage to store the specified file.
|
||||
*
|
||||
* <p>
|
||||
* The returned stream will be closed before the next file is
|
||||
* stored. So the callee can assume that only one OutputStream
|
||||
* is active at any given time.
|
||||
*
|
||||
* @param pkg
|
||||
* The package of the file to be written.
|
||||
* @param fileName
|
||||
* File name without the path. Something like
|
||||
* "Foo.java" or "Bar.properties"
|
||||
*/
|
||||
public abstract OutputStream openBinary( JPackage pkg, String fileName ) throws IOException;
|
||||
|
||||
/**
|
||||
* Called by CodeModel to store the specified file.
|
||||
* The callee must allocate a storage to store the specified file.
|
||||
*
|
||||
* <p>
|
||||
* The returned stream will be closed before the next file is
|
||||
* stored. So the callee can assume that only one OutputStream
|
||||
* is active at any given time.
|
||||
*
|
||||
* @param pkg
|
||||
* The package of the file to be written.
|
||||
* @param fileName
|
||||
* File name without the path. Something like
|
||||
* "Foo.java" or "Bar.properties"
|
||||
*/
|
||||
public Writer openSource( JPackage pkg, String fileName ) throws IOException {
|
||||
final OutputStreamWriter bw = encoding != null
|
||||
? new OutputStreamWriter(openBinary(pkg,fileName), encoding)
|
||||
: new OutputStreamWriter(openBinary(pkg,fileName));
|
||||
|
||||
// create writer
|
||||
try {
|
||||
return new UnicodeEscapeWriter(bw) {
|
||||
// can't change this signature to Encoder because
|
||||
// we can't have Encoder in method signature
|
||||
private final CharsetEncoder encoder = EncoderFactory.createEncoder(bw.getEncoding());
|
||||
@Override
|
||||
protected boolean requireEscaping(int ch) {
|
||||
// control characters
|
||||
if( ch<0x20 && " \t\r\n".indexOf(ch)==-1 ) return true;
|
||||
// check ASCII chars, for better performance
|
||||
if( ch<0x80 ) return false;
|
||||
|
||||
return !encoder.canEncode((char)ch);
|
||||
}
|
||||
};
|
||||
} catch( Throwable t ) {
|
||||
return new UnicodeEscapeWriter(bw);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by CodeModel at the end of the process.
|
||||
*/
|
||||
public abstract void close() throws IOException;
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Annotatable program elements.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public interface JAnnotatable {
|
||||
/**
|
||||
* Adds an annotation to this program element.
|
||||
* @param clazz
|
||||
* The annotation class to annotate the program element with
|
||||
*/
|
||||
JAnnotationUse annotate(JClass clazz);
|
||||
|
||||
/**
|
||||
* Adds an annotation to this program element.
|
||||
*
|
||||
* @param clazz
|
||||
* The annotation class to annotate the program element with
|
||||
*/
|
||||
JAnnotationUse annotate(Class <? extends Annotation> clazz);
|
||||
|
||||
/**
|
||||
* Adds an annotation to this program element
|
||||
* and returns a type-safe writer to fill in the values of such annotations.
|
||||
*/
|
||||
<W extends JAnnotationWriter> W annotate2(Class<W> clazz);
|
||||
|
||||
/**
|
||||
* Read-only live view of all annotations on this {@link JAnnotatable}
|
||||
*
|
||||
* @return
|
||||
* Can be empty but never null.
|
||||
*/
|
||||
Collection<JAnnotationUse> annotations();
|
||||
}
|
||||
@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* Represents an arrays as annotation members
|
||||
*
|
||||
* <p>
|
||||
* This class implements {@link JAnnotatable} to allow
|
||||
* new annotations to be added as a member of the array.
|
||||
*
|
||||
* @author
|
||||
* Bhakti Mehta (bhakti.mehta@sun.com)
|
||||
*/
|
||||
public final class JAnnotationArrayMember extends JAnnotationValue implements JAnnotatable {
|
||||
private final List<JAnnotationValue> values = new ArrayList<JAnnotationValue>();
|
||||
private final JCodeModel owner;
|
||||
|
||||
JAnnotationArrayMember(JCodeModel owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a string value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(String value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a boolean value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(boolean value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a byte value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(byte value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a char value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(char value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a double value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(double value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a long value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(long value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a short value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(short value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds an int value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(int value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an array member to this annotation
|
||||
*
|
||||
* @param value Adds a float value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(float value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(JExpr.lit(value));
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a enum array member to this annotation
|
||||
*
|
||||
* @param value Adds a enum value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(final Enum<?> value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationValue() {
|
||||
public void generate(JFormatter f) {
|
||||
f.t(owner.ref(value.getDeclaringClass())).p('.').p(value.name());
|
||||
}
|
||||
};
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a enum array member to this annotation
|
||||
*
|
||||
* @param value Adds a enum value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(final JEnumConstant value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(value);
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an expression array member to this annotation
|
||||
*
|
||||
* @param value Adds an expression value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(final JExpression value) {
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(value);
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a class array member to this annotation
|
||||
*
|
||||
* @param value Adds a class value to the array member
|
||||
* @return The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*/
|
||||
public JAnnotationArrayMember param(final Class<?> value){
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue(
|
||||
new JExpressionImpl() {
|
||||
public void generate(JFormatter f) {
|
||||
f.p(value.getName().replace('$', '.'));
|
||||
f.p(".class");
|
||||
}
|
||||
});
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JAnnotationArrayMember param(JType type){
|
||||
JClass clazz = type.boxify();
|
||||
JAnnotationValue annotationValue = new JAnnotationStringValue ( clazz.dotclass() );
|
||||
values.add(annotationValue);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new annotation to the array.
|
||||
*/
|
||||
public JAnnotationUse annotate(Class<? extends Annotation> clazz){
|
||||
return annotate(owner.ref(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new annotation to the array.
|
||||
*/
|
||||
public JAnnotationUse annotate(JClass clazz){
|
||||
JAnnotationUse a = new JAnnotationUse(clazz);
|
||||
values.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) {
|
||||
return TypedAnnotationWriter.create(clazz,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JAnnotatable#annotations()}
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<JAnnotationUse> annotations() {
|
||||
// this invocation is invalid if the caller isn't adding annotations into an array
|
||||
// so this potentially type-unsafe conversion would be justified.
|
||||
return Collections.<JAnnotationUse>unmodifiableList((List)values);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation member to this annotation array
|
||||
* This can be used for e.g @XmlCollection(values= @XmlCollectionItem(type=Foo.class))
|
||||
* @param value
|
||||
* Adds a annotation to the array member
|
||||
* @return
|
||||
* The JAnnotationArrayMember. More elements can be added by calling
|
||||
* the same method multiple times
|
||||
*
|
||||
* @deprecated
|
||||
* use {@link #annotate}
|
||||
*/
|
||||
public JAnnotationArrayMember param (JAnnotationUse value ){
|
||||
values.add(value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p('{').nl().i();
|
||||
|
||||
boolean first = true;
|
||||
for (JAnnotationValue aValue : values) {
|
||||
if (!first)
|
||||
f.p(',').nl();
|
||||
f.g(aValue);
|
||||
first = false;
|
||||
}
|
||||
f.nl().o().p('}');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Captures the value of the annotation.
|
||||
*
|
||||
* @author
|
||||
* Bhakti Mehta (bhakti.mehta@sun.com)
|
||||
*/
|
||||
final class JAnnotationStringValue extends JAnnotationValue {
|
||||
|
||||
/**
|
||||
* The value of the Annotation member
|
||||
*/
|
||||
private final JExpression value;
|
||||
|
||||
JAnnotationStringValue(JExpression value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.g(value);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,426 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents an annotation on a program element.
|
||||
*
|
||||
* TODO
|
||||
* How to add enums to the annotations
|
||||
* @author
|
||||
* Bhakti Mehta (bhakti.mehta@sun.com)
|
||||
*/
|
||||
public final class JAnnotationUse extends JAnnotationValue {
|
||||
|
||||
/**
|
||||
* The {@link Annotation} class
|
||||
*/
|
||||
private final JClass clazz;
|
||||
|
||||
/**
|
||||
* Map of member values.
|
||||
*/
|
||||
private Map<String,JAnnotationValue> memberValues;
|
||||
|
||||
JAnnotationUse(JClass clazz){
|
||||
this.clazz = clazz;
|
||||
}
|
||||
|
||||
public JClass getAnnotationClass() {
|
||||
return clazz;
|
||||
}
|
||||
|
||||
public Map<String, JAnnotationValue> getAnnotationMembers() {
|
||||
return Collections.unmodifiableMap(memberValues);
|
||||
}
|
||||
|
||||
private JCodeModel owner() {
|
||||
return clazz.owner();
|
||||
}
|
||||
|
||||
private void addValue(String name, JAnnotationValue annotationValue) {
|
||||
// Use ordered map to keep the code generation the same on any JVM.
|
||||
// Lazily created.
|
||||
if(memberValues==null)
|
||||
memberValues = new LinkedHashMap<String, JAnnotationValue>();
|
||||
memberValues.put(name,annotationValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
*
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The boolean value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, boolean value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The byte member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, byte value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The char member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, char value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The double member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, double value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The float member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, float value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The long member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, long value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The short member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, short value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The int member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, int value){
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The String member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, String value){
|
||||
//Escape string values with quotes so that they can
|
||||
//be generated accordingly
|
||||
addValue(name, new JAnnotationStringValue(JExpr.lit(value)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* For adding class values as param
|
||||
* @see #param(String, Class)
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The annotation class which is member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse annotationParam(String name, Class<? extends Annotation> value) {
|
||||
JAnnotationUse annotationUse = new JAnnotationUse(owner().ref(value));
|
||||
addValue(name, annotationUse);
|
||||
return annotationUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The enum class which is member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, final Enum<?> value) {
|
||||
addValue(name, new JAnnotationValue() {
|
||||
public void generate(JFormatter f) {
|
||||
f.t(owner().ref(value.getDeclaringClass())).p('.').p(value.name());
|
||||
}
|
||||
});
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The JEnumConstant which is member value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, JEnumConstant value){
|
||||
addValue(name, new JAnnotationStringValue(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation
|
||||
* This can be used for e.g to specify
|
||||
* <pre>
|
||||
* @XmlCollectionItem(type=Integer.class);
|
||||
* <pre>
|
||||
* For adding a value of Class<? extends Annotation>
|
||||
* @link
|
||||
* #annotationParam(java.lang.String, java.lang.Class<? extends java.lang.annotation.Annotation>)
|
||||
* @param name
|
||||
* The simple name for this annotation param
|
||||
*
|
||||
* @param value
|
||||
* The class type of the param
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, final Class<?> value){
|
||||
addValue(name, new JAnnotationStringValue(
|
||||
new JExpressionImpl() {
|
||||
public void generate(JFormatter f) {
|
||||
f.p(value.getName().replace('$', '.'));
|
||||
f.p(".class");
|
||||
}
|
||||
}));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation based on the
|
||||
* type represented by the given JType
|
||||
*
|
||||
* @param name The simple name for this annotation param
|
||||
* @param type the JType representing the actual type
|
||||
* @return The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*/
|
||||
public JAnnotationUse param(String name, JType type){
|
||||
JClass c = type.boxify();
|
||||
addValue(name, new JAnnotationStringValue ( c.dotclass() ));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair to this annotation.
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @param value
|
||||
* The JExpression which provides the contant value for this annotation
|
||||
* @return
|
||||
* The JAnnotationUse. More member value pairs can
|
||||
* be added to it using the same or the overloaded methods.
|
||||
*
|
||||
*/
|
||||
public JAnnotationUse param(String name, JExpression value){
|
||||
addValue(name, new JAnnotationStringValue(value));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a member value pair which is of type array to this annotation
|
||||
* @param name
|
||||
* The simple name for this annotation
|
||||
*
|
||||
* @return
|
||||
* The JAnnotationArrayMember. For adding array values
|
||||
* @see JAnnotationArrayMember
|
||||
*
|
||||
*/
|
||||
public JAnnotationArrayMember paramArray(String name){
|
||||
JAnnotationArrayMember arrayMember = new JAnnotationArrayMember(owner());
|
||||
addValue(name, arrayMember);
|
||||
return arrayMember;
|
||||
}
|
||||
|
||||
|
||||
// /**
|
||||
// * This can be used to add annotations inside annotations
|
||||
// * for e.g @XmlCollection(values= @XmlCollectionItem(type=Foo.class))
|
||||
// * @param className
|
||||
// * The classname of the annotation to be included
|
||||
// * @return
|
||||
// * The JAnnotationUse that can be used as a member within this JAnnotationUse
|
||||
// * @deprecated
|
||||
// * use {@link JAnnotationArrayMember#annotate}
|
||||
// */
|
||||
// public JAnnotationUse annotate(String className) {
|
||||
// JAnnotationUse annotationUse = new JAnnotationUse(owner().ref(className));
|
||||
// return annotationUse;
|
||||
// }
|
||||
|
||||
/**
|
||||
* This can be used to add annotations inside annotations
|
||||
* for e.g @XmlCollection(values= @XmlCollectionItem(type=Foo.class))
|
||||
* @param clazz
|
||||
* The annotation class to be included
|
||||
* @return
|
||||
* The JAnnotationUse that can be used as a member within this JAnnotationUse
|
||||
* @deprecated
|
||||
* use {@link JAnnotationArrayMember#annotate}
|
||||
*/
|
||||
public JAnnotationUse annotate(Class <? extends Annotation> clazz) {
|
||||
JAnnotationUse annotationUse = new JAnnotationUse(owner().ref(clazz));
|
||||
return annotationUse;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p('@').g(clazz);
|
||||
if(memberValues!=null) {
|
||||
f.p('(');
|
||||
boolean first = true;
|
||||
|
||||
if(isOptimizable()) {
|
||||
// short form
|
||||
f.g(memberValues.get("value"));
|
||||
} else {
|
||||
for (Map.Entry<String, JAnnotationValue> mapEntry : memberValues.entrySet()) {
|
||||
if (!first) f.p(',');
|
||||
f.p(mapEntry.getKey()).p('=').g(mapEntry.getValue());
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
f.p(')');
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isOptimizable() {
|
||||
return memberValues.size()==1 && memberValues.containsKey("value");
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Things that can be values of an annotation element.
|
||||
*
|
||||
* @author
|
||||
* Bhakti Mehta (bhakti.mehta@sun.com)
|
||||
*/
|
||||
public abstract class JAnnotationValue implements JGenerable {
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* Base interface for typed annotation writer.
|
||||
*
|
||||
* <p>
|
||||
* Annotation compiler can generate a strongly typed annotation
|
||||
* writer to assist applications to write uses of annotations.
|
||||
* Such typed annotation writer interfaces all derive from
|
||||
* this common interface.
|
||||
*
|
||||
* <p>
|
||||
* The type parameter 'A' represents the
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public interface JAnnotationWriter<A extends Annotation> {
|
||||
/**
|
||||
* Gets the underlying annotation use object to which we are writing.
|
||||
*/
|
||||
JAnnotationUse getAnnotationUse();
|
||||
|
||||
/**
|
||||
* The type of the annotation that this writer is writing.
|
||||
*/
|
||||
Class<A> getAnnotationType();
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Anonymous class quick hack.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
class JAnonymousClass extends JDefinedClass {
|
||||
|
||||
/**
|
||||
* Base interface/class from which this anonymous class is built.
|
||||
*/
|
||||
private final JClass base;
|
||||
|
||||
JAnonymousClass( JClass _base) {
|
||||
super(_base.owner(), 0, null);
|
||||
this.base = _base;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fullName() {
|
||||
return base.fullName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(JFormatter f) {
|
||||
f.t(base);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* array creation and initialization.
|
||||
*/
|
||||
public final class JArray extends JExpressionImpl {
|
||||
|
||||
private final JType type;
|
||||
private final JExpression size;
|
||||
private List<JExpression> exprs = null;
|
||||
|
||||
/**
|
||||
* Add an element to the array initializer
|
||||
*/
|
||||
public JArray add(JExpression e) {
|
||||
if (exprs == null)
|
||||
exprs = new ArrayList<JExpression>();
|
||||
exprs.add(e);
|
||||
return this;
|
||||
}
|
||||
|
||||
JArray(JType type, JExpression size) {
|
||||
this.type = type;
|
||||
this.size = size;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
|
||||
// generally we produce new T[x], but when T is an array type (T=T'[])
|
||||
// then new T'[][x] is wrong. It has to be new T'[x][].
|
||||
int arrayCount = 0;
|
||||
JType t = type;
|
||||
|
||||
while( t.isArray() ) {
|
||||
t = t.elementType();
|
||||
arrayCount++;
|
||||
}
|
||||
|
||||
f.p("new").g(t).p('[');
|
||||
if (size != null)
|
||||
f.g(size);
|
||||
f.p(']');
|
||||
|
||||
for( int i=0; i<arrayCount; i++ )
|
||||
f.p("[]");
|
||||
|
||||
if ((size == null) || (exprs != null))
|
||||
f.p('{');
|
||||
if (exprs != null) {
|
||||
f.g(exprs);
|
||||
} else {
|
||||
f.p(' ');
|
||||
}
|
||||
if ((size == null) || (exprs != null))
|
||||
f.p('}');
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Array class.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
final class JArrayClass extends JClass {
|
||||
|
||||
// array component type
|
||||
private final JType componentType;
|
||||
|
||||
|
||||
JArrayClass( JCodeModel owner, JType component ) {
|
||||
super(owner);
|
||||
this.componentType = component;
|
||||
}
|
||||
|
||||
|
||||
public String name() {
|
||||
return componentType.name()+"[]";
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
return componentType.fullName()+"[]";
|
||||
}
|
||||
|
||||
public String binaryName() {
|
||||
return componentType.binaryName()+"[]";
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.g(componentType).p("[]");
|
||||
}
|
||||
|
||||
public JPackage _package() {
|
||||
return owner().rootPackage();
|
||||
}
|
||||
|
||||
public JClass _extends() {
|
||||
return owner().ref(Object.class);
|
||||
}
|
||||
|
||||
public Iterator<JClass> _implements() {
|
||||
return Collections.<JClass>emptyList().iterator();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public JType elementType() {
|
||||
return componentType;
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Equality is based on value
|
||||
//
|
||||
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof JArrayClass)) return false;
|
||||
|
||||
if( componentType.equals( ((JArrayClass)obj).componentType ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return componentType.hashCode();
|
||||
}
|
||||
|
||||
protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
|
||||
if( componentType.isPrimitive() )
|
||||
return this;
|
||||
|
||||
JClass c = ((JClass)componentType).substituteParams(variables,bindings);
|
||||
if(c==componentType)
|
||||
return this;
|
||||
|
||||
return new JArrayClass(owner(),c);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* array component reference.
|
||||
*/
|
||||
final class JArrayCompRef extends JExpressionImpl implements JAssignmentTarget {
|
||||
/**
|
||||
* JArray expression upon which this component will be accessed.
|
||||
*/
|
||||
private final JExpression array;
|
||||
|
||||
/**
|
||||
* Integer expression representing index of the component
|
||||
*/
|
||||
private final JExpression index;
|
||||
|
||||
/**
|
||||
* JArray component reference constructor given an array expression
|
||||
* and index.
|
||||
*
|
||||
* @param array
|
||||
* JExpression for the array upon which
|
||||
* the component will be accessed,
|
||||
*
|
||||
* @param index
|
||||
* JExpression for index of component to access
|
||||
*/
|
||||
JArrayCompRef(JExpression array, JExpression index) {
|
||||
if ((array == null) || (index == null)) {
|
||||
throw new NullPointerException();
|
||||
}
|
||||
this.array = array;
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.g(array).p('[').g(index).p(']');
|
||||
}
|
||||
|
||||
public JExpression assign(JExpression rhs) {
|
||||
return JExpr.assign(this,rhs);
|
||||
}
|
||||
public JExpression assignPlus(JExpression rhs) {
|
||||
return JExpr.assignPlus(this,rhs);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Assignment statements, which are also expressions.
|
||||
*/
|
||||
public class JAssignment extends JExpressionImpl implements JStatement {
|
||||
|
||||
JAssignmentTarget lhs;
|
||||
JExpression rhs;
|
||||
String op = "";
|
||||
|
||||
JAssignment(JAssignmentTarget lhs, JExpression rhs) {
|
||||
this.lhs = lhs;
|
||||
this.rhs = rhs;
|
||||
}
|
||||
|
||||
JAssignment(JAssignmentTarget lhs, JExpression rhs, String op) {
|
||||
this.lhs = lhs;
|
||||
this.rhs = rhs;
|
||||
this.op = op;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.g(lhs).p(op + '=').g(rhs);
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.g(this).p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,39 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Marker interface for code components that can be placed to
|
||||
* the left of '=' in an assignment.
|
||||
*
|
||||
* A left hand value can always be a right hand value, so
|
||||
* this interface derives from {@link JExpression}.
|
||||
*/
|
||||
public interface JAssignmentTarget extends JGenerable, JExpression {
|
||||
JExpression assign(JExpression rhs);
|
||||
JExpression assignPlus(JExpression rhs);
|
||||
}
|
||||
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* JAtoms: Simple code components that merely generate themselves.
|
||||
*/
|
||||
final class JAtom extends JExpressionImpl {
|
||||
|
||||
private final String what;
|
||||
|
||||
JAtom(String what) {
|
||||
this.what = what;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p(what);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,454 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* A block of Java code, which may contain statements and local declarations.
|
||||
*
|
||||
* <p>
|
||||
* {@link JBlock} contains a large number of factory methods that creates new
|
||||
* statements/declarations. Those newly created statements/declarations are
|
||||
* inserted into the {@link #pos() "current position"}. The position advances
|
||||
* one every time you add a new instruction.
|
||||
*/
|
||||
public final class JBlock implements JGenerable, JStatement {
|
||||
|
||||
/**
|
||||
* Declarations and statements contained in this block.
|
||||
* Either {@link JStatement} or {@link JDeclaration}.
|
||||
*/
|
||||
private final List<Object> content = new ArrayList<Object>();
|
||||
|
||||
/**
|
||||
* Whether or not this block must be braced and indented
|
||||
*/
|
||||
private boolean bracesRequired = true;
|
||||
private boolean indentRequired = true;
|
||||
|
||||
/**
|
||||
* Current position.
|
||||
*/
|
||||
private int pos;
|
||||
|
||||
public JBlock() {
|
||||
this(true,true);
|
||||
}
|
||||
|
||||
public JBlock(boolean bracesRequired, boolean indentRequired) {
|
||||
this.bracesRequired = bracesRequired;
|
||||
this.indentRequired = indentRequired;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a read-only view of {@link JStatement}s and {@link JDeclaration}
|
||||
* in this block.
|
||||
*/
|
||||
public List<Object> getContents() {
|
||||
return Collections.unmodifiableList(content);
|
||||
}
|
||||
|
||||
private <T> T insert( T statementOrDeclaration ) {
|
||||
content.add(pos,statementOrDeclaration);
|
||||
pos++;
|
||||
return statementOrDeclaration;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current position to which new statements will be inserted.
|
||||
*
|
||||
* For example if the value is 0, newly created instructions will be
|
||||
* inserted at the very beginning of the block.
|
||||
*
|
||||
* @see #pos(int)
|
||||
*/
|
||||
public int pos() {
|
||||
return pos;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the current position.
|
||||
*
|
||||
* @return
|
||||
* the old value of the current position.
|
||||
* @throws IllegalArgumentException
|
||||
* if the new position value is illegal.
|
||||
*
|
||||
* @see #pos()
|
||||
*/
|
||||
public int pos(int newPos) {
|
||||
int r = pos;
|
||||
if(newPos>content.size() || newPos<0)
|
||||
throw new IllegalArgumentException();
|
||||
pos = newPos;
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this block is empty and does not contain
|
||||
* any statement.
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return content.isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a local variable declaration to this block
|
||||
*
|
||||
* @param type
|
||||
* JType of the variable
|
||||
*
|
||||
* @param name
|
||||
* Name of the variable
|
||||
*
|
||||
* @return Newly generated JVar
|
||||
*/
|
||||
public JVar decl(JType type, String name) {
|
||||
return decl(JMod.NONE, type, name, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a local variable declaration to this block
|
||||
*
|
||||
* @param type
|
||||
* JType of the variable
|
||||
*
|
||||
* @param name
|
||||
* Name of the variable
|
||||
*
|
||||
* @param init
|
||||
* Initialization expression for this variable. May be null.
|
||||
*
|
||||
* @return Newly generated JVar
|
||||
*/
|
||||
public JVar decl(JType type, String name, JExpression init) {
|
||||
return decl(JMod.NONE, type, name, init);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a local variable declaration to this block
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for the variable
|
||||
*
|
||||
* @param type
|
||||
* JType of the variable
|
||||
*
|
||||
* @param name
|
||||
* Name of the variable
|
||||
*
|
||||
* @param init
|
||||
* Initialization expression for this variable. May be null.
|
||||
*
|
||||
* @return Newly generated JVar
|
||||
*/
|
||||
public JVar decl(int mods, JType type, String name, JExpression init) {
|
||||
JVar v = new JVar(JMods.forVar(mods), type, name, init);
|
||||
insert(v);
|
||||
bracesRequired = true;
|
||||
indentRequired = true;
|
||||
return v;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an assignment statement and adds it to this block.
|
||||
*
|
||||
* @param lhs
|
||||
* Assignable variable or field for left hand side of expression
|
||||
*
|
||||
* @param exp
|
||||
* Right hand side expression
|
||||
*/
|
||||
public JBlock assign(JAssignmentTarget lhs, JExpression exp) {
|
||||
insert(new JAssignment(lhs, exp));
|
||||
return this;
|
||||
}
|
||||
|
||||
public JBlock assignPlus(JAssignmentTarget lhs, JExpression exp) {
|
||||
insert(new JAssignment(lhs, exp, "+"));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invocation statement and adds it to this block.
|
||||
*
|
||||
* @param expr
|
||||
* JExpression evaluating to the class or object upon which
|
||||
* the named method will be invoked
|
||||
*
|
||||
* @param method
|
||||
* Name of method to invoke
|
||||
*
|
||||
* @return Newly generated JInvocation
|
||||
*/
|
||||
public JInvocation invoke(JExpression expr, String method) {
|
||||
JInvocation i = new JInvocation(expr, method);
|
||||
insert(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invocation statement and adds it to this block.
|
||||
*
|
||||
* @param expr
|
||||
* JExpression evaluating to the class or object upon which
|
||||
* the method will be invoked
|
||||
*
|
||||
* @param method
|
||||
* JMethod to invoke
|
||||
*
|
||||
* @return Newly generated JInvocation
|
||||
*/
|
||||
public JInvocation invoke(JExpression expr, JMethod method) {
|
||||
return insert(new JInvocation(expr, method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a static invocation statement.
|
||||
*/
|
||||
public JInvocation staticInvoke(JClass type, String method) {
|
||||
return insert(new JInvocation(type, method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invocation statement and adds it to this block.
|
||||
*
|
||||
* @param method
|
||||
* Name of method to invoke
|
||||
*
|
||||
* @return Newly generated JInvocation
|
||||
*/
|
||||
public JInvocation invoke(String method) {
|
||||
return insert(new JInvocation((JExpression)null, method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an invocation statement and adds it to this block.
|
||||
*
|
||||
* @param method
|
||||
* JMethod to invoke
|
||||
*
|
||||
* @return Newly generated JInvocation
|
||||
*/
|
||||
public JInvocation invoke(JMethod method) {
|
||||
return insert(new JInvocation((JExpression)null, method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a statement to this block
|
||||
*
|
||||
* @param s
|
||||
* JStatement to be added
|
||||
*
|
||||
* @return This block
|
||||
*/
|
||||
public JBlock add(JStatement s) { // ## Needed?
|
||||
insert(s);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an If statement and add it to this block
|
||||
*
|
||||
* @param expr
|
||||
* JExpression to be tested to determine branching
|
||||
*
|
||||
* @return Newly generated conditional statement
|
||||
*/
|
||||
public JConditional _if(JExpression expr) {
|
||||
return insert(new JConditional(expr));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a For statement and add it to this block
|
||||
*
|
||||
* @return Newly generated For statement
|
||||
*/
|
||||
public JForLoop _for() {
|
||||
return insert(new JForLoop());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a While statement and add it to this block
|
||||
*
|
||||
* @return Newly generated While statement
|
||||
*/
|
||||
public JWhileLoop _while(JExpression test) {
|
||||
return insert(new JWhileLoop(test));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a switch/case statement and add it to this block
|
||||
*/
|
||||
public JSwitch _switch(JExpression test) {
|
||||
return insert(new JSwitch(test));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Do statement and add it to this block
|
||||
*
|
||||
* @return Newly generated Do statement
|
||||
*/
|
||||
public JDoLoop _do(JExpression test) {
|
||||
return insert(new JDoLoop(test));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Try statement and add it to this block
|
||||
*
|
||||
* @return Newly generated Try statement
|
||||
*/
|
||||
public JTryBlock _try() {
|
||||
return insert(new JTryBlock());
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a return statement and add it to this block
|
||||
*/
|
||||
public void _return() {
|
||||
insert(new JReturn(null));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a return statement and add it to this block
|
||||
*/
|
||||
public void _return(JExpression exp) {
|
||||
insert(new JReturn(exp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a throw statement and add it to this block
|
||||
*/
|
||||
public void _throw(JExpression exp) {
|
||||
insert(new JThrow(exp));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a break statement and add it to this block
|
||||
*/
|
||||
public void _break() {
|
||||
_break(null);
|
||||
}
|
||||
|
||||
public void _break(JLabel label) {
|
||||
insert(new JBreak(label));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a label, which can be referenced from
|
||||
* <code>continue</code> and <code>break</code> statements.
|
||||
*/
|
||||
public JLabel label(String name) {
|
||||
JLabel l = new JLabel(name);
|
||||
insert(l);
|
||||
return l;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a continue statement and add it to this block
|
||||
*/
|
||||
public void _continue(JLabel label) {
|
||||
insert(new JContinue(label));
|
||||
}
|
||||
|
||||
public void _continue() {
|
||||
_continue(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sub-block and add it to this block
|
||||
*/
|
||||
public JBlock block() {
|
||||
JBlock b = new JBlock();
|
||||
b.bracesRequired = false;
|
||||
b.indentRequired = false;
|
||||
return insert(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a "literal" statement directly.
|
||||
*
|
||||
* <p>
|
||||
* Specified string is printed as-is.
|
||||
* This is useful as a short-cut.
|
||||
*
|
||||
* <p>
|
||||
* For example, you can invoke this method as:
|
||||
* <code>directStatement("a=b+c;")</code>.
|
||||
*/
|
||||
public JStatement directStatement(final String source) {
|
||||
JStatement s = new JStatement() {
|
||||
public void state(JFormatter f) {
|
||||
f.p(source).nl();
|
||||
}
|
||||
};
|
||||
add(s);
|
||||
return s;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
if (bracesRequired)
|
||||
f.p('{').nl();
|
||||
if (indentRequired)
|
||||
f.i();
|
||||
generateBody(f);
|
||||
if (indentRequired)
|
||||
f.o();
|
||||
if (bracesRequired)
|
||||
f.p('}');
|
||||
}
|
||||
|
||||
void generateBody(JFormatter f) {
|
||||
for (Object o : content) {
|
||||
if (o instanceof JDeclaration)
|
||||
f.d((JDeclaration) o);
|
||||
else
|
||||
f.s((JStatement) o);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an enhanced For statement based on j2se 1.5 JLS
|
||||
* and add it to this block
|
||||
*
|
||||
* @return Newly generated enhanced For statement per j2se 1.5
|
||||
* specification
|
||||
*/
|
||||
public JForEach forEach(JType varType, String name, JExpression collection) {
|
||||
return insert(new JForEach( varType, name, collection));
|
||||
|
||||
}
|
||||
public void state(JFormatter f) {
|
||||
f.g(this);
|
||||
if (bracesRequired)
|
||||
f.nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* JBreak statement
|
||||
*/
|
||||
final class JBreak implements JStatement {
|
||||
|
||||
private final JLabel label;
|
||||
|
||||
/**
|
||||
* JBreak constructor
|
||||
*
|
||||
* @param _label
|
||||
* break label or null.
|
||||
*/
|
||||
JBreak( JLabel _label ) {
|
||||
this.label = _label;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
if( label==null )
|
||||
f.p("break;").nl();
|
||||
else
|
||||
f.p("break").p(label.label).p(';').nl();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Case statement
|
||||
*/
|
||||
public final class JCase implements JStatement {
|
||||
|
||||
/**
|
||||
* label part of the case statement
|
||||
*/
|
||||
private JExpression label;
|
||||
|
||||
/**
|
||||
* JBlock of statements which makes up body of this While statement
|
||||
*/
|
||||
private JBlock body = null;
|
||||
|
||||
/**
|
||||
* is this a regular case statement or a default case statement?
|
||||
*/
|
||||
private boolean isDefaultCase = false;
|
||||
|
||||
/**
|
||||
* Construct a case statement
|
||||
*/
|
||||
JCase(JExpression label) {
|
||||
this(label, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a case statement. If isDefaultCase is true, then
|
||||
* label should be null since default cases don't have a label.
|
||||
*/
|
||||
JCase(JExpression label, boolean isDefaultCase) {
|
||||
this.label = label;
|
||||
this.isDefaultCase = isDefaultCase;
|
||||
}
|
||||
|
||||
public JExpression label() {
|
||||
return label;
|
||||
}
|
||||
|
||||
public JBlock body() {
|
||||
if (body == null) body=new JBlock( false, true );
|
||||
return body;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.i();
|
||||
if( !isDefaultCase ) {
|
||||
f.p("case ").g(label).p(':').nl();
|
||||
} else {
|
||||
f.p("default:").nl();
|
||||
}
|
||||
if (body != null)
|
||||
f.s(body);
|
||||
f.o();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A cast operation.
|
||||
*/
|
||||
final class JCast extends JExpressionImpl {
|
||||
/**
|
||||
* JType to which the expression is to be cast.
|
||||
*/
|
||||
private final JType type;
|
||||
|
||||
/**
|
||||
* JExpression to be cast.
|
||||
*/
|
||||
private final JExpression object;
|
||||
|
||||
/**
|
||||
* JCast constructor
|
||||
*
|
||||
* @param type
|
||||
* JType to which the expression is cast
|
||||
*
|
||||
* @param object
|
||||
* JExpression for the object upon which
|
||||
* the cast is applied
|
||||
*/
|
||||
JCast(JType type, JExpression object) {
|
||||
this.type = type;
|
||||
this.object = object;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p("((").g(type).p(')').g(object).p(')');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Catch block for a try/catch/finally statement
|
||||
*/
|
||||
|
||||
public class JCatchBlock implements JGenerable {
|
||||
|
||||
JClass exception;
|
||||
private JVar var = null;
|
||||
private JBlock body = new JBlock();
|
||||
|
||||
JCatchBlock(JClass exception) {
|
||||
this.exception = exception;
|
||||
}
|
||||
|
||||
public JVar param(String name) {
|
||||
if (var != null) throw new IllegalStateException();
|
||||
var = new JVar(JMods.forVar(JMod.NONE), exception, name, null);
|
||||
return var;
|
||||
}
|
||||
|
||||
public JBlock body() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
if (var == null)
|
||||
var = new JVar(JMods.forVar(JMod.NONE),
|
||||
exception, "_x", null);
|
||||
f.p("catch (").b(var).p(')').g(body);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a Java reference type, such as a class, an interface,
|
||||
* an enum, an array type, a parameterized type.
|
||||
*
|
||||
* <p>
|
||||
* To be exact, this object represents an "use" of a reference type,
|
||||
* not necessarily a declaration of it, which is modeled as {@link JDefinedClass}.
|
||||
*/
|
||||
public abstract class JClass extends JType
|
||||
{
|
||||
protected JClass( JCodeModel _owner ) {
|
||||
this._owner = _owner;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this class.
|
||||
*
|
||||
* @return
|
||||
* name of this class, without any qualification.
|
||||
* For example, this method returns "String" for
|
||||
* <code>java.lang.String</code>.
|
||||
*/
|
||||
abstract public String name();
|
||||
|
||||
/**
|
||||
* Gets the package to which this class belongs.
|
||||
* TODO: shall we move move this down?
|
||||
*/
|
||||
abstract public JPackage _package();
|
||||
|
||||
/**
|
||||
* Returns the class in which this class is nested, or <tt>null</tt> if
|
||||
* this is a top-level class.
|
||||
*/
|
||||
public JClass outer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
private final JCodeModel _owner;
|
||||
/** Gets the JCodeModel object to which this object belongs. */
|
||||
public final JCodeModel owner() { return _owner; }
|
||||
|
||||
/**
|
||||
* Gets the super class of this class.
|
||||
*
|
||||
* @return
|
||||
* Returns the JClass representing the superclass of the
|
||||
* entity (class or interface) represented by this {@link JClass}.
|
||||
* Even if no super class is given explicitly or this {@link JClass}
|
||||
* is not a class, this method still returns
|
||||
* {@link JClass} for {@link Object}.
|
||||
* If this JClass represents {@link Object}, return null.
|
||||
*/
|
||||
abstract public JClass _extends();
|
||||
|
||||
/**
|
||||
* Iterates all super interfaces directly implemented by
|
||||
* this class/interface.
|
||||
*
|
||||
* @return
|
||||
* A non-null valid iterator that iterates all
|
||||
* {@link JClass} objects that represents those interfaces
|
||||
* implemented by this object.
|
||||
*/
|
||||
abstract public Iterator<JClass> _implements();
|
||||
|
||||
/**
|
||||
* Iterates all the type parameters of this class/interface.
|
||||
*
|
||||
* <p>
|
||||
* For example, if this {@link JClass} represents
|
||||
* <code>Set<T></code>, this method returns an array
|
||||
* that contains single {@link JTypeVar} for 'T'.
|
||||
*/
|
||||
public JTypeVar[] typeParams() {
|
||||
return EMPTY_ARRAY;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sometimes useful reusable empty array.
|
||||
*/
|
||||
protected static final JTypeVar[] EMPTY_ARRAY = new JTypeVar[0];
|
||||
|
||||
/**
|
||||
* Checks if this object represents an interface.
|
||||
*/
|
||||
abstract public boolean isInterface();
|
||||
|
||||
/**
|
||||
* Checks if this class is an abstract class.
|
||||
*/
|
||||
abstract public boolean isAbstract();
|
||||
|
||||
/**
|
||||
* If this class represents one of the wrapper classes
|
||||
* defined in the java.lang package, return the corresponding
|
||||
* primitive type. Otherwise null.
|
||||
*/
|
||||
public JPrimitiveType getPrimitiveType() { return null; }
|
||||
|
||||
/**
|
||||
* @deprecated calling this method from {@link JClass}
|
||||
* would be meaningless, since it's always guaranteed to
|
||||
* return <tt>this</tt>.
|
||||
*/
|
||||
public JClass boxify() { return this; }
|
||||
|
||||
public JType unboxify() {
|
||||
JPrimitiveType pt = getPrimitiveType();
|
||||
return pt==null ? (JType)this : pt;
|
||||
}
|
||||
|
||||
public JClass erasure() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the relationship between two classes.
|
||||
* <p>
|
||||
* This method works in the same way as {@link Class#isAssignableFrom(Class)}
|
||||
* works. For example, baseClass.isAssignableFrom(derivedClass)==true.
|
||||
*/
|
||||
public final boolean isAssignableFrom( JClass derived ) {
|
||||
// to avoid the confusion, always use "this" explicitly in this method.
|
||||
|
||||
// null can be assigned to any type.
|
||||
if( derived instanceof JNullType ) return true;
|
||||
|
||||
if( this==derived ) return true;
|
||||
|
||||
// the only class that is assignable from an interface is
|
||||
// java.lang.Object
|
||||
if( this==_package().owner().ref(Object.class) ) return true;
|
||||
|
||||
JClass b = derived._extends();
|
||||
if( b!=null && this.isAssignableFrom(b) )
|
||||
return true;
|
||||
|
||||
if( this.isInterface() ) {
|
||||
Iterator<JClass> itfs = derived._implements();
|
||||
while( itfs.hasNext() )
|
||||
if( this.isAssignableFrom(itfs.next()) )
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parameterization of the given base type.
|
||||
*
|
||||
* <p>
|
||||
* For example, given the following
|
||||
* <pre><xmp>
|
||||
* interface Foo<T> extends List<List<T>> {}
|
||||
* interface Bar extends Foo<String> {}
|
||||
* </xmp></pre>
|
||||
* This method works like this:
|
||||
* <pre><xmp>
|
||||
* getBaseClass( Bar, List ) = List<List<String>
|
||||
* getBaseClass( Bar, Foo ) = Foo<String>
|
||||
* getBaseClass( Foo<? extends Number>, Collection ) = Collection<List<? extends Number>>
|
||||
* getBaseClass( ArrayList<? extends BigInteger>, List ) = List<? extends BigInteger>
|
||||
* </xmp></pre>
|
||||
*
|
||||
* @param baseType
|
||||
* The class whose parameterization we are interested in.
|
||||
* @return
|
||||
* The use of {@code baseType} in {@code this} type.
|
||||
* or null if the type is not assignable to the base type.
|
||||
*/
|
||||
public final JClass getBaseClass( JClass baseType ) {
|
||||
|
||||
if( this.erasure().equals(baseType) )
|
||||
return this;
|
||||
|
||||
JClass b = _extends();
|
||||
if( b!=null ) {
|
||||
JClass bc = b.getBaseClass(baseType);
|
||||
if(bc!=null)
|
||||
return bc;
|
||||
}
|
||||
|
||||
Iterator<JClass> itfs = _implements();
|
||||
while( itfs.hasNext() ) {
|
||||
JClass bc = itfs.next().getBaseClass(baseType);
|
||||
if(bc!=null)
|
||||
return bc;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public final JClass getBaseClass( Class<?> baseType ) {
|
||||
return getBaseClass(owner().ref(baseType));
|
||||
}
|
||||
|
||||
|
||||
private JClass arrayClass;
|
||||
public JClass array() {
|
||||
if(arrayClass==null)
|
||||
arrayClass = new JArrayClass(owner(),this);
|
||||
return arrayClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* "Narrows" a generic class to a concrete class by specifying
|
||||
* a type argument.
|
||||
*
|
||||
* <p>
|
||||
* <code>.narrow(X)</code> builds <code>Set<X></code> from <code>Set</code>.
|
||||
*/
|
||||
public JClass narrow( Class<?> clazz ) {
|
||||
return narrow(owner().ref(clazz));
|
||||
}
|
||||
|
||||
public JClass narrow( Class<?>... clazz ) {
|
||||
JClass[] r = new JClass[clazz.length];
|
||||
for( int i=0; i<clazz.length; i++ )
|
||||
r[i] = owner().ref(clazz[i]);
|
||||
return narrow(r);
|
||||
}
|
||||
|
||||
/**
|
||||
* "Narrows" a generic class to a concrete class by specifying
|
||||
* a type argument.
|
||||
*
|
||||
* <p>
|
||||
* <code>.narrow(X)</code> builds <code>Set<X></code> from <code>Set</code>.
|
||||
*/
|
||||
public JClass narrow( JClass clazz ) {
|
||||
return new JNarrowedClass(this,clazz);
|
||||
}
|
||||
|
||||
public JClass narrow( JType type ) {
|
||||
return narrow(type.boxify());
|
||||
}
|
||||
|
||||
public JClass narrow( JClass... clazz ) {
|
||||
return new JNarrowedClass(this,Arrays.asList(clazz.clone()));
|
||||
}
|
||||
|
||||
public JClass narrow( List<? extends JClass> clazz ) {
|
||||
return new JNarrowedClass(this,new ArrayList<JClass>(clazz));
|
||||
}
|
||||
|
||||
/**
|
||||
* If this class is parameterized, return the type parameter of the given index.
|
||||
*/
|
||||
public List<JClass> getTypeParameters() {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this class is a parameterized class.
|
||||
*/
|
||||
public final boolean isParameterized() {
|
||||
return erasure()!=this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create "? extends T" from T.
|
||||
*
|
||||
* @return never null
|
||||
*/
|
||||
public final JClass wildcard() {
|
||||
return new JTypeWildcard(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Substitutes the type variables with their actual arguments.
|
||||
*
|
||||
* <p>
|
||||
* For example, when this class is Map<String,Map<V>>,
|
||||
* (where V then doing
|
||||
* substituteParams( V, Integer ) returns a {@link JClass}
|
||||
* for <code>Map<String,Map<Integer>></code>.
|
||||
*
|
||||
* <p>
|
||||
* This method needs to work recursively.
|
||||
*/
|
||||
protected abstract JClass substituteParams( JTypeVar[] variables, List<JClass> bindings );
|
||||
|
||||
public String toString() {
|
||||
return this.getClass().getName() + '(' + name() + ')';
|
||||
}
|
||||
|
||||
|
||||
public final JExpression dotclass() {
|
||||
return JExpr.dotclass(this);
|
||||
}
|
||||
|
||||
/** Generates a static method invocation. */
|
||||
public final JInvocation staticInvoke(JMethod method) {
|
||||
return new JInvocation(this,method);
|
||||
}
|
||||
|
||||
/** Generates a static method invocation. */
|
||||
public final JInvocation staticInvoke(String method) {
|
||||
return new JInvocation(this,method);
|
||||
}
|
||||
|
||||
/** Static field reference. */
|
||||
public final JFieldRef staticRef(String field) {
|
||||
return new JFieldRef(this, field);
|
||||
}
|
||||
|
||||
/** Static field reference. */
|
||||
public final JFieldRef staticRef(JVar field) {
|
||||
return new JFieldRef(this, field);
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.t(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the class name in javadoc @link format.
|
||||
*/
|
||||
void printLink(JFormatter f) {
|
||||
f.p("{@link ").g(this).p('}');
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Indicates that the class is already created.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public class JClassAlreadyExistsException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final JDefinedClass existing;
|
||||
|
||||
public JClassAlreadyExistsException( JDefinedClass _existing ) {
|
||||
this.existing = _existing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the existing {@link JDefinedClass}.
|
||||
*
|
||||
* @return
|
||||
* This method always return non-null valid object.
|
||||
*/
|
||||
public JDefinedClass getExistingClass() {
|
||||
return existing;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* The common aspect of a package and a class.
|
||||
*/
|
||||
public interface JClassContainer {
|
||||
|
||||
/**
|
||||
* Returns true if the container is a class.
|
||||
*/
|
||||
boolean isClass();
|
||||
/**
|
||||
* Returns true if the container is a package.
|
||||
*/
|
||||
boolean isPackage();
|
||||
|
||||
/**
|
||||
* Add a new class to this package/class.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this class declaration
|
||||
*
|
||||
* @param name
|
||||
* Name of class to be added to this package
|
||||
*
|
||||
* @return Newly generated class
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
JDefinedClass _class(int mods, String name) throws JClassAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Add a new public class to this class/package.
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
public JDefinedClass _class(String name) throws JClassAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Add an interface to this class/package.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this interface declaration
|
||||
*
|
||||
* @param name
|
||||
* Name of interface to be added to this package
|
||||
*
|
||||
* @return Newly generated interface
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
public JDefinedClass _interface(int mods, String name) throws JClassAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Adds a public interface to this package.
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
public JDefinedClass _interface(String name) throws JClassAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Create a new class or a new interface.
|
||||
*
|
||||
* @deprecated
|
||||
* use {@link #_class(int, String, ClassType)}
|
||||
*/
|
||||
public JDefinedClass _class(int mods, String name, boolean isInterface )
|
||||
throws JClassAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Creates a new class/enum/interface/annotation.
|
||||
*/
|
||||
public JDefinedClass _class(int mods, String name, ClassType kind )
|
||||
throws JClassAlreadyExistsException;
|
||||
|
||||
|
||||
/**
|
||||
* Returns an iterator that walks the nested classes defined in this
|
||||
* class.
|
||||
*/
|
||||
public Iterator<JDefinedClass> classes();
|
||||
|
||||
/**
|
||||
* Parent JClassContainer.
|
||||
*
|
||||
* If this is a package, this method returns a parent package,
|
||||
* or null if this package is the root package.
|
||||
*
|
||||
* If this is an outer-most class, this method returns a package
|
||||
* to which it belongs.
|
||||
*
|
||||
* If this is an inner class, this method returns the outer
|
||||
* class.
|
||||
*/
|
||||
public JClassContainer parentContainer();
|
||||
|
||||
/**
|
||||
* Gets the nearest package parent.
|
||||
*
|
||||
* <p>
|
||||
* If <tt>this.isPackage()</tt>, then return <tt>this</tt>.
|
||||
*/
|
||||
public JPackage getPackage();
|
||||
|
||||
/**
|
||||
* Get the root code model object.
|
||||
*/
|
||||
public JCodeModel owner();
|
||||
|
||||
/**
|
||||
* Add an annotationType Declaration to this package
|
||||
* @param name
|
||||
* Name of the annotation Type declaration to be added to this package
|
||||
* @return
|
||||
* newly created Annotation Type Declaration
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
|
||||
*/
|
||||
public JDefinedClass _annotationTypeDeclaration(String name) throws JClassAlreadyExistsException;
|
||||
|
||||
/**
|
||||
* Add a public enum to this package
|
||||
* @param name
|
||||
* Name of the enum to be added to this package
|
||||
* @return
|
||||
* newly created Enum
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
|
||||
*/
|
||||
public JDefinedClass _enum (String name) throws JClassAlreadyExistsException;
|
||||
|
||||
}
|
||||
@ -0,0 +1,667 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintStream;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.sun.codemodel.internal.writer.FileCodeWriter;
|
||||
import com.sun.codemodel.internal.writer.ProgressCodeWriter;
|
||||
|
||||
|
||||
/**
|
||||
* Root of the code DOM.
|
||||
*
|
||||
* <p>
|
||||
* Here's your typical CodeModel application.
|
||||
*
|
||||
* <pre>
|
||||
* JCodeModel cm = new JCodeModel();
|
||||
*
|
||||
* // generate source code by populating the 'cm' tree.
|
||||
* cm._class(...);
|
||||
* ...
|
||||
*
|
||||
* // write them out
|
||||
* cm.build(new File("."));
|
||||
* </pre>
|
||||
*
|
||||
* <p>
|
||||
* Every CodeModel node is always owned by one {@link JCodeModel} object
|
||||
* at any given time (which can be often accesesd by the <tt>owner()</tt> method.)
|
||||
*
|
||||
* As such, when you generate Java code, most of the operation works
|
||||
* in a top-down fashion. For example, you create a class from {@link JCodeModel},
|
||||
* which gives you a {@link JDefinedClass}. Then you invoke a method on it
|
||||
* to generate a new method, which gives you {@link JMethod}, and so on.
|
||||
*
|
||||
* There are a few exceptions to this, most notably building {@link JExpression}s,
|
||||
* but generally you work with CodeModel in a top-down fashion.
|
||||
*
|
||||
* Because of this design, most of the CodeModel classes aren't directly instanciable.
|
||||
*
|
||||
*
|
||||
* <h2>Where to go from here?</h2>
|
||||
* <p>
|
||||
* Most of the time you'd want to populate new type definitions in a {@link JCodeModel}.
|
||||
* See {@link #_class(String, ClassType)}.
|
||||
*/
|
||||
public final class JCodeModel {
|
||||
|
||||
/** The packages that this JCodeWriter contains. */
|
||||
private HashMap<String,JPackage> packages = new HashMap<String,JPackage>();
|
||||
|
||||
/** All JReferencedClasses are pooled here. */
|
||||
private final HashMap<Class<?>,JReferencedClass> refClasses = new HashMap<Class<?>,JReferencedClass>();
|
||||
|
||||
|
||||
/** Obtains a reference to the special "null" type. */
|
||||
public final JNullType NULL = new JNullType(this);
|
||||
// primitive types
|
||||
public final JPrimitiveType VOID = new JPrimitiveType(this,"void", Void.class);
|
||||
public final JPrimitiveType BOOLEAN = new JPrimitiveType(this,"boolean",Boolean.class);
|
||||
public final JPrimitiveType BYTE = new JPrimitiveType(this,"byte", Byte.class);
|
||||
public final JPrimitiveType SHORT = new JPrimitiveType(this,"short", Short.class);
|
||||
public final JPrimitiveType CHAR = new JPrimitiveType(this,"char", Character.class);
|
||||
public final JPrimitiveType INT = new JPrimitiveType(this,"int", Integer.class);
|
||||
public final JPrimitiveType FLOAT = new JPrimitiveType(this,"float", Float.class);
|
||||
public final JPrimitiveType LONG = new JPrimitiveType(this,"long", Long.class);
|
||||
public final JPrimitiveType DOUBLE = new JPrimitiveType(this,"double", Double.class);
|
||||
|
||||
/**
|
||||
* If the flag is true, we will consider two classes "Foo" and "foo"
|
||||
* as a collision.
|
||||
*/
|
||||
protected static final boolean isCaseSensitiveFileSystem = getFileSystemCaseSensitivity();
|
||||
|
||||
private static boolean getFileSystemCaseSensitivity() {
|
||||
try {
|
||||
// let the system property override, in case the user really
|
||||
// wants to override.
|
||||
if( System.getProperty("com.sun.codemodel.internal.FileSystemCaseSensitive")!=null )
|
||||
return true;
|
||||
} catch( Exception e ) {}
|
||||
|
||||
// on Unix, it's case sensitive.
|
||||
return (File.separatorChar == '/');
|
||||
}
|
||||
|
||||
|
||||
public JCodeModel() {}
|
||||
|
||||
/**
|
||||
* Add a package to the list of packages to be generated
|
||||
*
|
||||
* @param name
|
||||
* Name of the package. Use "" to indicate the root package.
|
||||
*
|
||||
* @return Newly generated package
|
||||
*/
|
||||
public JPackage _package(String name) {
|
||||
JPackage p = packages.get(name);
|
||||
if (p == null) {
|
||||
p = new JPackage(name, this);
|
||||
packages.put(name, p);
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
public final JPackage rootPackage() {
|
||||
return _package("");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator that walks the packages defined using this code
|
||||
* writer.
|
||||
*/
|
||||
public Iterator<JPackage> packages() {
|
||||
return packages.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new generated class.
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
public JDefinedClass _class(String fullyqualifiedName) throws JClassAlreadyExistsException {
|
||||
return _class(fullyqualifiedName,ClassType.CLASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a dummy, unknown {@link JClass} that represents a given name.
|
||||
*
|
||||
* <p>
|
||||
* This method is useful when the code generation needs to include the user-specified
|
||||
* class that may or may not exist, and only thing known about it is a class name.
|
||||
*/
|
||||
public JClass directClass(String name) {
|
||||
return new JDirectClass(this,name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new generated class.
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
public JDefinedClass _class(int mods, String fullyqualifiedName,ClassType t) throws JClassAlreadyExistsException {
|
||||
int idx = fullyqualifiedName.lastIndexOf('.');
|
||||
if( idx<0 ) return rootPackage()._class(fullyqualifiedName);
|
||||
else
|
||||
return _package(fullyqualifiedName.substring(0,idx))
|
||||
._class(mods, fullyqualifiedName.substring(idx+1), t );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new generated class.
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
public JDefinedClass _class(String fullyqualifiedName,ClassType t) throws JClassAlreadyExistsException {
|
||||
return _class( JMod.PUBLIC, fullyqualifiedName, t );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the already created generated class.
|
||||
*
|
||||
* @return null
|
||||
* If the class is not yet created.
|
||||
* @see JPackage#_getClass(String)
|
||||
*/
|
||||
public JDefinedClass _getClass(String fullyQualifiedName) {
|
||||
int idx = fullyQualifiedName.lastIndexOf('.');
|
||||
if( idx<0 ) return rootPackage()._getClass(fullyQualifiedName);
|
||||
else
|
||||
return _package(fullyQualifiedName.substring(0,idx))
|
||||
._getClass( fullyQualifiedName.substring(idx+1) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new anonymous class.
|
||||
*
|
||||
* @deprecated
|
||||
* The naming convention doesn't match the rest of the CodeModel.
|
||||
* Use {@link #anonymousClass(JClass)} instead.
|
||||
*/
|
||||
public JDefinedClass newAnonymousClass(JClass baseType) {
|
||||
return new JAnonymousClass(baseType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new anonymous class.
|
||||
*/
|
||||
public JDefinedClass anonymousClass(JClass baseType) {
|
||||
return new JAnonymousClass(baseType);
|
||||
}
|
||||
|
||||
public JDefinedClass anonymousClass(Class<?> baseType) {
|
||||
return anonymousClass(ref(baseType));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates Java source code.
|
||||
* A convenience method for <code>build(destDir,destDir,System.out)</code>.
|
||||
*
|
||||
* @param destDir
|
||||
* source files are generated into this directory.
|
||||
* @param status
|
||||
* if non-null, progress indication will be sent to this stream.
|
||||
*/
|
||||
public void build( File destDir, PrintStream status ) throws IOException {
|
||||
build(destDir,destDir,status);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates Java source code.
|
||||
* A convenience method that calls {@link #build(CodeWriter,CodeWriter)}.
|
||||
*
|
||||
* @param srcDir
|
||||
* Java source files are generated into this directory.
|
||||
* @param resourceDir
|
||||
* Other resource files are generated into this directory.
|
||||
* @param status
|
||||
* if non-null, progress indication will be sent to this stream.
|
||||
*/
|
||||
public void build( File srcDir, File resourceDir, PrintStream status ) throws IOException {
|
||||
CodeWriter src = new FileCodeWriter(srcDir);
|
||||
CodeWriter res = new FileCodeWriter(resourceDir);
|
||||
if(status!=null) {
|
||||
src = new ProgressCodeWriter(src, status );
|
||||
res = new ProgressCodeWriter(res, status );
|
||||
}
|
||||
build(src,res);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for <code>build(destDir,System.out)</code>.
|
||||
*/
|
||||
public void build( File destDir ) throws IOException {
|
||||
build(destDir,System.out);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for <code>build(srcDir,resourceDir,System.out)</code>.
|
||||
*/
|
||||
public void build( File srcDir, File resourceDir ) throws IOException {
|
||||
build(srcDir,resourceDir,System.out);
|
||||
}
|
||||
|
||||
/**
|
||||
* A convenience method for <code>build(out,out)</code>.
|
||||
*/
|
||||
public void build( CodeWriter out ) throws IOException {
|
||||
build(out,out);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates Java source code.
|
||||
*/
|
||||
public void build( CodeWriter source, CodeWriter resource ) throws IOException {
|
||||
JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
|
||||
// avoid concurrent modification exception
|
||||
for( JPackage pkg : pkgs )
|
||||
pkg.build(source,resource);
|
||||
source.close();
|
||||
resource.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of files to be generated if
|
||||
* {@link #build} is invoked now.
|
||||
*/
|
||||
public int countArtifacts() {
|
||||
int r = 0;
|
||||
JPackage[] pkgs = packages.values().toArray(new JPackage[packages.size()]);
|
||||
// avoid concurrent modification exception
|
||||
for( JPackage pkg : pkgs )
|
||||
r += pkg.countArtifacts();
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Obtains a reference to an existing class from its Class object.
|
||||
*
|
||||
* <p>
|
||||
* The parameter may not be primitive.
|
||||
*
|
||||
* @see #_ref(Class) for the version that handles more cases.
|
||||
*/
|
||||
public JClass ref(Class<?> clazz) {
|
||||
JReferencedClass jrc = (JReferencedClass)refClasses.get(clazz);
|
||||
if (jrc == null) {
|
||||
if (clazz.isPrimitive())
|
||||
throw new IllegalArgumentException(clazz+" is a primitive");
|
||||
if (clazz.isArray()) {
|
||||
return new JArrayClass(this, _ref(clazz.getComponentType()));
|
||||
} else {
|
||||
jrc = new JReferencedClass(clazz);
|
||||
refClasses.put(clazz, jrc);
|
||||
}
|
||||
}
|
||||
return jrc;
|
||||
}
|
||||
|
||||
public JType _ref(Class<?> c) {
|
||||
if(c.isPrimitive())
|
||||
return JType.parse(this,c.getName());
|
||||
else
|
||||
return ref(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a reference to an existing class from its fully-qualified
|
||||
* class name.
|
||||
*
|
||||
* <p>
|
||||
* First, this method attempts to load the class of the given name.
|
||||
* If that fails, we assume that the class is derived straight from
|
||||
* {@link Object}, and return a {@link JClass}.
|
||||
*/
|
||||
public JClass ref(String fullyQualifiedClassName) {
|
||||
try {
|
||||
// try the context class loader first
|
||||
return ref(SecureLoader.getContextClassLoader().loadClass(fullyQualifiedClassName));
|
||||
} catch (ClassNotFoundException e) {
|
||||
// fall through
|
||||
}
|
||||
// then the default mechanism.
|
||||
try {
|
||||
return ref(Class.forName(fullyQualifiedClassName));
|
||||
} catch (ClassNotFoundException e1) {
|
||||
// fall through
|
||||
}
|
||||
|
||||
// assume it's not visible to us.
|
||||
return new JDirectClass(this,fullyQualifiedClassName);
|
||||
}
|
||||
|
||||
/**
|
||||
* Cached for {@link #wildcard()}.
|
||||
*/
|
||||
private JClass wildcard;
|
||||
|
||||
/**
|
||||
* Gets a {@link JClass} representation for "?",
|
||||
* which is equivalent to "? extends Object".
|
||||
*/
|
||||
public JClass wildcard() {
|
||||
if(wildcard==null)
|
||||
wildcard = ref(Object.class).wildcard();
|
||||
return wildcard;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains a type object from a type name.
|
||||
*
|
||||
* <p>
|
||||
* This method handles primitive types, arrays, and existing {@link Class}es.
|
||||
*
|
||||
* @exception ClassNotFoundException
|
||||
* If the specified type is not found.
|
||||
*/
|
||||
public JType parseType(String name) throws ClassNotFoundException {
|
||||
// array
|
||||
if(name.endsWith("[]"))
|
||||
return parseType(name.substring(0,name.length()-2)).array();
|
||||
|
||||
// try primitive type
|
||||
try {
|
||||
return JType.parse(this,name);
|
||||
} catch (IllegalArgumentException e) {
|
||||
;
|
||||
}
|
||||
|
||||
// existing class
|
||||
return new TypeNameParser(name).parseTypeName();
|
||||
}
|
||||
|
||||
private final class TypeNameParser {
|
||||
private final String s;
|
||||
private int idx;
|
||||
|
||||
public TypeNameParser(String s) {
|
||||
this.s = s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a type name token T (which can be potentially of the form Tr&ly;T1,T2,...>,
|
||||
* or "? extends/super T".)
|
||||
*
|
||||
* @return the index of the character next to T.
|
||||
*/
|
||||
JClass parseTypeName() throws ClassNotFoundException {
|
||||
int start = idx;
|
||||
|
||||
if(s.charAt(idx)=='?') {
|
||||
// wildcard
|
||||
idx++;
|
||||
ws();
|
||||
String head = s.substring(idx);
|
||||
if(head.startsWith("extends")) {
|
||||
idx+=7;
|
||||
ws();
|
||||
return parseTypeName().wildcard();
|
||||
} else
|
||||
if(head.startsWith("super")) {
|
||||
throw new UnsupportedOperationException("? super T not implemented");
|
||||
} else {
|
||||
// not supported
|
||||
throw new IllegalArgumentException("only extends/super can follow ?, but found "+s.substring(idx));
|
||||
}
|
||||
}
|
||||
|
||||
while(idx<s.length()) {
|
||||
char ch = s.charAt(idx);
|
||||
if(Character.isJavaIdentifierStart(ch)
|
||||
|| Character.isJavaIdentifierPart(ch)
|
||||
|| ch=='.')
|
||||
idx++;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
JClass clazz = ref(s.substring(start,idx));
|
||||
|
||||
return parseSuffix(clazz);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses additional left-associative suffixes, like type arguments
|
||||
* and array specifiers.
|
||||
*/
|
||||
private JClass parseSuffix(JClass clazz) throws ClassNotFoundException {
|
||||
if(idx==s.length())
|
||||
return clazz; // hit EOL
|
||||
|
||||
char ch = s.charAt(idx);
|
||||
|
||||
if(ch=='<')
|
||||
return parseSuffix(parseArguments(clazz));
|
||||
|
||||
if(ch=='[') {
|
||||
if(s.charAt(idx+1)==']') {
|
||||
idx+=2;
|
||||
return parseSuffix(clazz.array());
|
||||
}
|
||||
throw new IllegalArgumentException("Expected ']' but found "+s.substring(idx+1));
|
||||
}
|
||||
|
||||
return clazz;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips whitespaces
|
||||
*/
|
||||
private void ws() {
|
||||
while(Character.isWhitespace(s.charAt(idx)) && idx<s.length())
|
||||
idx++;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses '<T1,T2,...,Tn>'
|
||||
*
|
||||
* @return the index of the character next to '>'
|
||||
*/
|
||||
private JClass parseArguments(JClass rawType) throws ClassNotFoundException {
|
||||
if(s.charAt(idx)!='<')
|
||||
throw new IllegalArgumentException();
|
||||
idx++;
|
||||
|
||||
List<JClass> args = new ArrayList<JClass>();
|
||||
|
||||
while(true) {
|
||||
args.add(parseTypeName());
|
||||
if(idx==s.length())
|
||||
throw new IllegalArgumentException("Missing '>' in "+s);
|
||||
char ch = s.charAt(idx);
|
||||
if(ch=='>')
|
||||
return rawType.narrow(args.toArray(new JClass[args.size()]));
|
||||
|
||||
if(ch!=',')
|
||||
throw new IllegalArgumentException(s);
|
||||
idx++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* References to existing classes.
|
||||
*
|
||||
* <p>
|
||||
* JReferencedClass is kept in a pool so that they are shared.
|
||||
* There is one pool for each JCodeModel object.
|
||||
*
|
||||
* <p>
|
||||
* It is impossible to cache JReferencedClass globally only because
|
||||
* there is the _package() method, which obtains the owner JPackage
|
||||
* object, which is scoped to JCodeModel.
|
||||
*/
|
||||
private class JReferencedClass extends JClass implements JDeclaration {
|
||||
private final Class<?> _class;
|
||||
|
||||
JReferencedClass(Class<?> _clazz) {
|
||||
super(JCodeModel.this);
|
||||
this._class = _clazz;
|
||||
assert !_class.isArray();
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return _class.getSimpleName().replace('$','.');
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
return _class.getName().replace('$','.');
|
||||
}
|
||||
|
||||
public String binaryName() {
|
||||
return _class.getName();
|
||||
}
|
||||
|
||||
public JClass outer() {
|
||||
Class<?> p = _class.getDeclaringClass();
|
||||
if(p==null) return null;
|
||||
return ref(p);
|
||||
}
|
||||
|
||||
public JPackage _package() {
|
||||
String name = fullName();
|
||||
|
||||
// this type is array
|
||||
if (name.indexOf('[') != -1)
|
||||
return JCodeModel.this._package("");
|
||||
|
||||
// other normal case
|
||||
int idx = name.lastIndexOf('.');
|
||||
if (idx < 0)
|
||||
return JCodeModel.this._package("");
|
||||
else
|
||||
return JCodeModel.this._package(name.substring(0, idx));
|
||||
}
|
||||
|
||||
public JClass _extends() {
|
||||
Class<?> sp = _class.getSuperclass();
|
||||
if (sp == null) {
|
||||
if(isInterface())
|
||||
return owner().ref(Object.class);
|
||||
return null;
|
||||
} else
|
||||
return ref(sp);
|
||||
}
|
||||
|
||||
public Iterator<JClass> _implements() {
|
||||
final Class<?>[] interfaces = _class.getInterfaces();
|
||||
return new Iterator<JClass>() {
|
||||
private int idx = 0;
|
||||
public boolean hasNext() {
|
||||
return idx < interfaces.length;
|
||||
}
|
||||
public JClass next() {
|
||||
return JCodeModel.this.ref(interfaces[idx++]);
|
||||
}
|
||||
public void remove() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return _class.isInterface();
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return Modifier.isAbstract(_class.getModifiers());
|
||||
}
|
||||
|
||||
public JPrimitiveType getPrimitiveType() {
|
||||
Class<?> v = boxToPrimitive.get(_class);
|
||||
if(v!=null)
|
||||
return JType.parse(JCodeModel.this,v.getName());
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void declare(JFormatter f) {
|
||||
}
|
||||
|
||||
public JTypeVar[] typeParams() {
|
||||
// TODO: does JDK 1.5 reflection provides these information?
|
||||
return super.typeParams();
|
||||
}
|
||||
|
||||
protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
|
||||
// TODO: does JDK 1.5 reflection provides these information?
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion from primitive type {@link Class} (such as {@link Integer#TYPE}
|
||||
* to its boxed type (such as <tt>Integer.class</tt>)
|
||||
*/
|
||||
public static final Map<Class<?>,Class<?>> primitiveToBox;
|
||||
/**
|
||||
* The reverse look up for {@link #primitiveToBox}
|
||||
*/
|
||||
public static final Map<Class<?>,Class<?>> boxToPrimitive;
|
||||
|
||||
static {
|
||||
Map<Class<?>,Class<?>> m1 = new HashMap<Class<?>,Class<?>>();
|
||||
Map<Class<?>,Class<?>> m2 = new HashMap<Class<?>,Class<?>>();
|
||||
|
||||
m1.put(Boolean.class,Boolean.TYPE);
|
||||
m1.put(Byte.class,Byte.TYPE);
|
||||
m1.put(Character.class,Character.TYPE);
|
||||
m1.put(Double.class,Double.TYPE);
|
||||
m1.put(Float.class,Float.TYPE);
|
||||
m1.put(Integer.class,Integer.TYPE);
|
||||
m1.put(Long.class,Long.TYPE);
|
||||
m1.put(Short.class,Short.TYPE);
|
||||
m1.put(Void.class,Void.TYPE);
|
||||
|
||||
for (Map.Entry<Class<?>, Class<?>> e : m1.entrySet())
|
||||
m2.put(e.getValue(),e.getKey());
|
||||
|
||||
boxToPrimitive = Collections.unmodifiableMap(m1);
|
||||
primitiveToBox = Collections.unmodifiableMap(m2);
|
||||
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,137 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
|
||||
/**
|
||||
* A part is a part of a javadoc comment, and it is a list of values.
|
||||
*
|
||||
* <p>
|
||||
* A part can contain a free-form text. This text is modeled as a collection of 'values'
|
||||
* in this class. A value can be a {@link JType} (which will be prinited with a @link tag),
|
||||
* anything that can be turned into a {@link String} via the {@link Object#toString()} method,
|
||||
* or a {@link Collection}/array of those objects.
|
||||
*
|
||||
* <p>
|
||||
* Values can be added through the various append methods one by one or in a bulk.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
public class JCommentPart extends ArrayList<Object> {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/**
|
||||
* Appends a new value.
|
||||
*
|
||||
* If the value is {@link JType} it will be printed as a @link tag.
|
||||
* Otherwise it will be converted to String via {@link Object#toString()}.
|
||||
*/
|
||||
public JCommentPart append(Object o) {
|
||||
add(o);
|
||||
return this;
|
||||
}
|
||||
|
||||
public boolean add(Object o) {
|
||||
flattenAppend(o);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void flattenAppend(Object value) {
|
||||
if(value==null) return;
|
||||
if(value instanceof Object[]) {
|
||||
for( Object o : (Object[])value)
|
||||
flattenAppend(o);
|
||||
} else
|
||||
if(value instanceof Collection<?>) {
|
||||
for( Object o : (Collection<?>)value)
|
||||
flattenAppend(o);
|
||||
} else
|
||||
super.add(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes this part into the formatter by using the specified indentation.
|
||||
*/
|
||||
protected void format( JFormatter f, String indent ) {
|
||||
if(!f.isPrinting()) {
|
||||
// quickly pass the types to JFormatter, as that's all we care.
|
||||
// we don't need to worry about the exact formatting of text.
|
||||
for( Object o : this )
|
||||
if(o instanceof JClass)
|
||||
f.g((JClass)o);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!isEmpty())
|
||||
f.p(indent);
|
||||
|
||||
Iterator<Object> itr = iterator();
|
||||
while(itr.hasNext()) {
|
||||
Object o = itr.next();
|
||||
|
||||
if(o instanceof String) {
|
||||
int idx;
|
||||
String s = (String)o;
|
||||
while( (idx=s.indexOf('\n'))!=-1 ) {
|
||||
String line = s.substring(0,idx);
|
||||
if(line.length()>0)
|
||||
f.p(escape(line));
|
||||
s = s.substring(idx+1);
|
||||
f.nl().p(indent);
|
||||
}
|
||||
if(s.length()!=0)
|
||||
f.p(escape(s));
|
||||
} else
|
||||
if(o instanceof JClass) {
|
||||
// TODO: this doesn't print the parameterized type properly
|
||||
((JClass)o).printLink(f);
|
||||
} else
|
||||
if(o instanceof JType) {
|
||||
f.g((JType)o);
|
||||
} else
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
if(!isEmpty())
|
||||
f.nl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Escapes the appearance of the comment terminator.
|
||||
*/
|
||||
private String escape(String s) {
|
||||
while(true) {
|
||||
int idx = s.indexOf("*/");
|
||||
if(idx <0) return s;
|
||||
|
||||
s = s.substring(0,idx+1)+"<!---->"+s.substring(idx+1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* If statement, with optional else clause
|
||||
*/
|
||||
|
||||
public class JConditional implements JStatement {
|
||||
|
||||
/**
|
||||
* JExpression to test to determine branching
|
||||
*/
|
||||
private JExpression test = null;
|
||||
|
||||
/**
|
||||
* JBlock of statements for "then" clause
|
||||
*/
|
||||
private JBlock _then = new JBlock();
|
||||
|
||||
/**
|
||||
* JBlock of statements for optional "else" clause
|
||||
*/
|
||||
private JBlock _else = null;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param test
|
||||
* JExpression which will determine branching
|
||||
*/
|
||||
JConditional(JExpression test) {
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the block to be excuted by the "then" branch
|
||||
*
|
||||
* @return Then block
|
||||
*/
|
||||
public JBlock _then() {
|
||||
return _then;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a block to be executed by "else" branch
|
||||
*
|
||||
* @return Newly generated else block
|
||||
*/
|
||||
public JBlock _else() {
|
||||
if (_else == null) _else = new JBlock();
|
||||
return _else;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates <tt>... else if(...) ...</tt> code.
|
||||
*/
|
||||
public JConditional _elseif(JExpression boolExp) {
|
||||
return _else()._if(boolExp);
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
if(test==JExpr.TRUE) {
|
||||
_then.generateBody(f);
|
||||
return;
|
||||
}
|
||||
if(test==JExpr.FALSE) {
|
||||
_else.generateBody(f);
|
||||
return;
|
||||
}
|
||||
|
||||
if (JOp.hasTopOp(test)) {
|
||||
f.p("if ").g(test);
|
||||
} else {
|
||||
f.p("if (").g(test).p(')');
|
||||
}
|
||||
f.g(_then);
|
||||
if (_else != null)
|
||||
f.p("else").g(_else);
|
||||
f.nl();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* JContinue statement
|
||||
*/
|
||||
class JContinue implements JStatement {
|
||||
|
||||
private final JLabel label;
|
||||
|
||||
/**
|
||||
* JContinue constructor.
|
||||
*
|
||||
* @param _label
|
||||
* a valid label or null.
|
||||
*/
|
||||
JContinue(JLabel _label) {
|
||||
this.label = _label;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
if( label==null )
|
||||
f.p("continue;").nl();
|
||||
else
|
||||
f.p("continue").p(label.label).p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Common interface for code components that can generate declarations
|
||||
* of themselves.
|
||||
*/
|
||||
|
||||
public interface JDeclaration {
|
||||
|
||||
public void declare(JFormatter f);
|
||||
|
||||
}
|
||||
@ -0,0 +1,898 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.TreeSet;
|
||||
|
||||
/**
|
||||
* A generated Java class/interface/enum/....
|
||||
*
|
||||
* <p>
|
||||
* This class models a declaration, and since a declaration can be always
|
||||
* used as a reference, it inherits {@link JClass}.
|
||||
*
|
||||
* <h2>Where to go from here?</h2>
|
||||
* <p>
|
||||
* You'd want to generate fields and methods on a class.
|
||||
* See {@link #method(int, JType, String)} and {@link #field(int, JType, String)}.
|
||||
*/
|
||||
public class JDefinedClass
|
||||
extends JClass
|
||||
implements JDeclaration, JClassContainer, JGenerifiable, JAnnotatable, JDocCommentable {
|
||||
|
||||
/** Name of this class. Null if anonymous. */
|
||||
private String name = null;
|
||||
|
||||
/** Modifiers for the class declaration */
|
||||
private JMods mods;
|
||||
|
||||
/** Name of the super class of this class. */
|
||||
private JClass superClass;
|
||||
|
||||
/** List of interfaces that this class implements */
|
||||
private final Set<JClass> interfaces = new TreeSet<JClass>();
|
||||
|
||||
/** Fields keyed by their names. */
|
||||
/*package*/ final Map<String,JFieldVar> fields = new LinkedHashMap<String,JFieldVar>();
|
||||
|
||||
/** Static initializer, if this class has one */
|
||||
private JBlock init = null;
|
||||
|
||||
/** class javadoc */
|
||||
private JDocComment jdoc = null;
|
||||
|
||||
/** Set of constructors for this class, if any */
|
||||
private final List<JMethod> constructors = new ArrayList<JMethod>();
|
||||
|
||||
/** Set of methods that are members of this class */
|
||||
private final List<JMethod> methods = new ArrayList<JMethod>();
|
||||
|
||||
/**
|
||||
* Nested classes as a map from name to JDefinedClass.
|
||||
* The name is all capitalized in a case sensitive file system
|
||||
* ({@link JCodeModel#isCaseSensitiveFileSystem}) to avoid conflicts.
|
||||
*
|
||||
* Lazily created to save footprint.
|
||||
*
|
||||
* @see #getClasses()
|
||||
*/
|
||||
private Map<String,JDefinedClass> classes;
|
||||
|
||||
|
||||
/**
|
||||
* Flag that controls whether this class should be really generated or not.
|
||||
*
|
||||
* Sometimes it is useful to generate code that refers to class X,
|
||||
* without actually generating the code of X.
|
||||
* This flag is used to surpress X.java file in the output.
|
||||
*/
|
||||
private boolean hideFile = false;
|
||||
|
||||
/**
|
||||
* Client-app spcific metadata associated with this user-created class.
|
||||
*/
|
||||
public Object metadata;
|
||||
|
||||
/**
|
||||
* String that will be put directly inside the generated code.
|
||||
* Can be null.
|
||||
*/
|
||||
private String directBlock;
|
||||
|
||||
/**
|
||||
* If this is a package-member class, this is {@link JPackage}.
|
||||
* If this is a nested class, this is {@link JDefinedClass}.
|
||||
* If this is an anonymous class, this constructor shouldn't be used.
|
||||
*/
|
||||
private JClassContainer outer = null;
|
||||
|
||||
|
||||
/** Default value is class or interface
|
||||
* or annotationTypeDeclaration
|
||||
* or enum
|
||||
*
|
||||
*/
|
||||
private final ClassType classType;
|
||||
|
||||
/** List containing the enum value declarations
|
||||
*
|
||||
*/
|
||||
// private List enumValues = new ArrayList();
|
||||
|
||||
/**
|
||||
* Set of enum constants that are keyed by names.
|
||||
* In Java, enum constant order is actually significant,
|
||||
* because of order ID they get. So let's preserve the order.
|
||||
*/
|
||||
private final Map<String,JEnumConstant> enumConstantsByName = new LinkedHashMap<String,JEnumConstant>();
|
||||
|
||||
/**
|
||||
* Annotations on this variable. Lazily created.
|
||||
*/
|
||||
private List<JAnnotationUse> annotations = null;
|
||||
|
||||
|
||||
/**
|
||||
* Helper class to implement {@link JGenerifiable}.
|
||||
*/
|
||||
private final JGenerifiableImpl generifiable = new JGenerifiableImpl() {
|
||||
protected JCodeModel owner() {
|
||||
return JDefinedClass.this.owner();
|
||||
}
|
||||
};
|
||||
|
||||
JDefinedClass(JClassContainer parent, int mods, String name, ClassType classTypeval) {
|
||||
this(mods, name, parent, parent.owner(), classTypeval);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for creating anonymous inner class.
|
||||
*/
|
||||
JDefinedClass(
|
||||
JCodeModel owner,
|
||||
int mods,
|
||||
String name) {
|
||||
this(mods, name, null, owner);
|
||||
}
|
||||
|
||||
private JDefinedClass(
|
||||
int mods,
|
||||
String name,
|
||||
JClassContainer parent,
|
||||
JCodeModel owner) {
|
||||
this (mods,name,parent,owner,ClassType.CLASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* JClass constructor
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this class declaration
|
||||
*
|
||||
* @param name
|
||||
* Name of this class
|
||||
*/
|
||||
private JDefinedClass(
|
||||
int mods,
|
||||
String name,
|
||||
JClassContainer parent,
|
||||
JCodeModel owner,
|
||||
ClassType classTypeVal) {
|
||||
super(owner);
|
||||
|
||||
if(name!=null) {
|
||||
if (name.trim().length() == 0)
|
||||
throw new IllegalArgumentException("JClass name empty");
|
||||
|
||||
if (!Character.isJavaIdentifierStart(name.charAt(0))) {
|
||||
String msg =
|
||||
"JClass name "
|
||||
+ name
|
||||
+ " contains illegal character"
|
||||
+ " for beginning of identifier: "
|
||||
+ name.charAt(0);
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
for (int i = 1; i < name.length(); i++) {
|
||||
if (!Character.isJavaIdentifierPart(name.charAt(i))) {
|
||||
String msg =
|
||||
"JClass name "
|
||||
+ name
|
||||
+ " contains illegal character "
|
||||
+ name.charAt(i);
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this.classType = classTypeVal;
|
||||
if (isInterface())
|
||||
this.mods = JMods.forInterface(mods);
|
||||
else
|
||||
this.mods = JMods.forClass(mods);
|
||||
|
||||
this.name = name;
|
||||
|
||||
this.outer = parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is an anonymous class.
|
||||
*/
|
||||
public final boolean isAnonymous() {
|
||||
return name == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class extends the specifed class.
|
||||
*
|
||||
* @param superClass
|
||||
* Superclass for this class
|
||||
*
|
||||
* @return This class
|
||||
*/
|
||||
public JDefinedClass _extends(JClass superClass) {
|
||||
if (this.classType==ClassType.INTERFACE)
|
||||
if(superClass.isInterface()){
|
||||
return this._implements(superClass);
|
||||
} else throw new IllegalArgumentException("unable to set the super class for an interface");
|
||||
if (superClass == null)
|
||||
throw new NullPointerException();
|
||||
|
||||
for( JClass o=superClass.outer(); o!=null; o=o.outer() ){
|
||||
if(this==o){
|
||||
throw new IllegalArgumentException("Illegal class inheritance loop." +
|
||||
" Outer class " + this.name + " may not subclass from inner class: " + o.name());
|
||||
}
|
||||
}
|
||||
|
||||
this.superClass = superClass;
|
||||
return this;
|
||||
}
|
||||
|
||||
public JDefinedClass _extends(Class<?> superClass) {
|
||||
return _extends(owner().ref(superClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class extended by this class.
|
||||
*/
|
||||
public JClass _extends() {
|
||||
if(superClass==null)
|
||||
superClass = owner().ref(Object.class);
|
||||
return superClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* This class implements the specifed interface.
|
||||
*
|
||||
* @param iface
|
||||
* Interface that this class implements
|
||||
*
|
||||
* @return This class
|
||||
*/
|
||||
public JDefinedClass _implements(JClass iface) {
|
||||
interfaces.add(iface);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JDefinedClass _implements(Class<?> iface) {
|
||||
return _implements(owner().ref(iface));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator that walks the nested classes defined in this
|
||||
* class.
|
||||
*/
|
||||
public Iterator<JClass> _implements() {
|
||||
return interfaces.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* JClass name accessor.
|
||||
*
|
||||
* <p>
|
||||
* For example, for <code>java.util.List</code>, this method
|
||||
* returns <code>"List"</code>"
|
||||
*
|
||||
* @return Name of this class
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the named enum already exists, the reference to it is returned.
|
||||
* Otherwise this method generates a new enum reference with the given
|
||||
* name and returns it.
|
||||
*
|
||||
* @param name
|
||||
* The name of the constant.
|
||||
* @return
|
||||
* The generated type-safe enum constant.
|
||||
*/
|
||||
public JEnumConstant enumConstant(String name){
|
||||
JEnumConstant ec = enumConstantsByName.get(name);
|
||||
if (null == ec) {
|
||||
ec = new JEnumConstant(this, name);
|
||||
enumConstantsByName.put(name, ec);
|
||||
}
|
||||
return ec;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fully qualified name of this class.
|
||||
*/
|
||||
public String fullName() {
|
||||
if (outer instanceof JDefinedClass)
|
||||
return ((JDefinedClass) outer).fullName() + '.' + name();
|
||||
|
||||
JPackage p = _package();
|
||||
if (p.isUnnamed())
|
||||
return name();
|
||||
else
|
||||
return p.name() + '.' + name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String binaryName() {
|
||||
if (outer instanceof JDefinedClass)
|
||||
return ((JDefinedClass) outer).binaryName() + '$' + name();
|
||||
else
|
||||
return fullName();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return this.classType==ClassType.INTERFACE;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return mods.isAbstract();
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a field to the list of field members of this JDefinedClass.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this field
|
||||
*
|
||||
* @param type
|
||||
* JType of this field
|
||||
*
|
||||
* @param name
|
||||
* Name of this field
|
||||
*
|
||||
* @return Newly generated field
|
||||
*/
|
||||
public JFieldVar field(int mods, JType type, String name) {
|
||||
return field(mods, type, name, null);
|
||||
}
|
||||
|
||||
public JFieldVar field(int mods, Class<?> type, String name) {
|
||||
return field(mods, owner()._ref(type), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a field to the list of field members of this JDefinedClass.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this field.
|
||||
* @param type
|
||||
* JType of this field.
|
||||
* @param name
|
||||
* Name of this field.
|
||||
* @param init
|
||||
* Initial value of this field.
|
||||
*
|
||||
* @return Newly generated field
|
||||
*/
|
||||
public JFieldVar field(
|
||||
int mods,
|
||||
JType type,
|
||||
String name,
|
||||
JExpression init) {
|
||||
JFieldVar f = new JFieldVar(this,JMods.forField(mods), type, name, init);
|
||||
|
||||
if (fields.containsKey(name)) {
|
||||
throw new IllegalArgumentException("trying to create the same field twice: "+name);
|
||||
}
|
||||
|
||||
fields.put(name, f);
|
||||
return f;
|
||||
}
|
||||
|
||||
/** This method indicates if the interface
|
||||
* is an annotationTypeDeclaration
|
||||
*
|
||||
*/
|
||||
public boolean isAnnotationTypeDeclaration() {
|
||||
return this.classType==ClassType.ANNOTATION_TYPE_DECL;
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an annotationType Declaration to this package
|
||||
* @param name
|
||||
* Name of the annotation Type declaration to be added to this package
|
||||
* @return
|
||||
* newly created Annotation Type Declaration
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
|
||||
*/
|
||||
public JDefinedClass _annotationTypeDeclaration(String name) throws JClassAlreadyExistsException {
|
||||
return _class (JMod.PUBLIC,name,ClassType.ANNOTATION_TYPE_DECL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a public enum to this package
|
||||
* @param name
|
||||
* Name of the enum to be added to this package
|
||||
* @return
|
||||
* newly created Enum
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
|
||||
*/
|
||||
public JDefinedClass _enum (String name) throws JClassAlreadyExistsException {
|
||||
return _class (JMod.PUBLIC,name,ClassType.ENUM);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a public enum to this package
|
||||
* @param name
|
||||
* Name of the enum to be added to this package
|
||||
* @param mods
|
||||
* Modifiers for this enum declaration
|
||||
* @return
|
||||
* newly created Enum
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
|
||||
*/
|
||||
public JDefinedClass _enum (int mods,String name) throws JClassAlreadyExistsException {
|
||||
return _class (mods,name,ClassType.ENUM);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
public ClassType getClassType(){
|
||||
return this.classType;
|
||||
}
|
||||
|
||||
public JFieldVar field(
|
||||
int mods,
|
||||
Class<?> type,
|
||||
String name,
|
||||
JExpression init) {
|
||||
return field(mods, owner()._ref(type), name, init);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the fields declred in this class.
|
||||
* The returned {@link Map} is a read-only live view.
|
||||
*
|
||||
* @return always non-null.
|
||||
*/
|
||||
public Map<String,JFieldVar> fields() {
|
||||
return Collections.unmodifiableMap(fields);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a {@link JFieldVar} from this class.
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* if the given field is not a field on this class.
|
||||
*/
|
||||
public void removeField(JFieldVar field) {
|
||||
if(fields.remove(field.name())!=field)
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates, if necessary, and returns the static initializer
|
||||
* for this class.
|
||||
*
|
||||
* @return JBlock containing initialization statements for this class
|
||||
*/
|
||||
public JBlock init() {
|
||||
if (init == null)
|
||||
init = new JBlock();
|
||||
return init;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a constructor to this class.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this constructor
|
||||
*/
|
||||
public JMethod constructor(int mods) {
|
||||
JMethod c = new JMethod(mods, this);
|
||||
constructors.add(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator that walks the constructors defined in this class.
|
||||
*/
|
||||
public Iterator<JMethod> constructors() {
|
||||
return constructors.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a method that has the specified method signature
|
||||
* and return it.
|
||||
*
|
||||
* @return
|
||||
* null if not found.
|
||||
*/
|
||||
public JMethod getConstructor(JType[] argTypes) {
|
||||
for (JMethod m : constructors) {
|
||||
if (m.hasSignature(argTypes))
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a method to the list of method members of this JDefinedClass instance.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this method
|
||||
*
|
||||
* @param type
|
||||
* Return type for this method
|
||||
*
|
||||
* @param name
|
||||
* Name of the method
|
||||
*
|
||||
* @return Newly generated JMethod
|
||||
*/
|
||||
public JMethod method(int mods, JType type, String name) {
|
||||
// XXX problems caught in M constructor
|
||||
JMethod m = new JMethod(this, mods, type, name);
|
||||
methods.add(m);
|
||||
return m;
|
||||
}
|
||||
|
||||
public JMethod method(int mods, Class<?> type, String name) {
|
||||
return method(mods, owner()._ref(type), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the set of methods defined in this class.
|
||||
*/
|
||||
public Collection<JMethod> methods() {
|
||||
return methods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Looks for a method that has the specified method signature
|
||||
* and return it.
|
||||
*
|
||||
* @return
|
||||
* null if not found.
|
||||
*/
|
||||
public JMethod getMethod(String name, JType[] argTypes) {
|
||||
for (JMethod m : methods) {
|
||||
if (!m.name().equals(name))
|
||||
continue;
|
||||
|
||||
if (m.hasSignature(argTypes))
|
||||
return m;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean isClass() {
|
||||
return true;
|
||||
}
|
||||
public boolean isPackage() {
|
||||
return false;
|
||||
}
|
||||
public JPackage getPackage() { return parentContainer().getPackage(); }
|
||||
|
||||
/**
|
||||
* Add a new nested class to this class.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this class declaration
|
||||
*
|
||||
* @param name
|
||||
* Name of class to be added to this package
|
||||
*
|
||||
* @return Newly generated class
|
||||
*/
|
||||
public JDefinedClass _class(int mods, String name)
|
||||
throws JClassAlreadyExistsException {
|
||||
return _class(mods, name, ClassType.CLASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*
|
||||
* @deprecated
|
||||
*/
|
||||
public JDefinedClass _class(int mods, String name, boolean isInterface) throws JClassAlreadyExistsException {
|
||||
return _class(mods,name,isInterface?ClassType.INTERFACE:ClassType.CLASS);
|
||||
}
|
||||
|
||||
public JDefinedClass _class(int mods, String name, ClassType classTypeVal)
|
||||
throws JClassAlreadyExistsException {
|
||||
|
||||
String NAME;
|
||||
if (JCodeModel.isCaseSensitiveFileSystem)
|
||||
NAME = name.toUpperCase();
|
||||
else
|
||||
NAME = name;
|
||||
|
||||
if (getClasses().containsKey(NAME))
|
||||
throw new JClassAlreadyExistsException(getClasses().get(NAME));
|
||||
else {
|
||||
// XXX problems caught in the NC constructor
|
||||
JDefinedClass c = new JDefinedClass(this, mods, name, classTypeVal);
|
||||
getClasses().put(NAME,c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a new public nested class to this class.
|
||||
*/
|
||||
public JDefinedClass _class(String name)
|
||||
throws JClassAlreadyExistsException {
|
||||
return _class(JMod.PUBLIC, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an interface to this package.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this interface declaration
|
||||
*
|
||||
* @param name
|
||||
* Name of interface to be added to this package
|
||||
*
|
||||
* @return Newly generated interface
|
||||
*/
|
||||
public JDefinedClass _interface(int mods, String name)
|
||||
throws JClassAlreadyExistsException {
|
||||
return _class(mods, name, ClassType.INTERFACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a public interface to this package.
|
||||
*/
|
||||
public JDefinedClass _interface(String name)
|
||||
throws JClassAlreadyExistsException {
|
||||
return _interface(JMod.PUBLIC, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates, if necessary, and returns the class javadoc for this
|
||||
* JDefinedClass
|
||||
*
|
||||
* @return JDocComment containing javadocs for this class
|
||||
*/
|
||||
public JDocComment javadoc() {
|
||||
if (jdoc == null)
|
||||
jdoc = new JDocComment(owner());
|
||||
return jdoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark this file as hidden, so that this file won't be
|
||||
* generated.
|
||||
*
|
||||
* <p>
|
||||
* This feature could be used to generate code that refers
|
||||
* to class X, without actually generating X.java.
|
||||
*/
|
||||
public void hide() {
|
||||
hideFile = true;
|
||||
}
|
||||
|
||||
public boolean isHidden() {
|
||||
return hideFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator that walks the nested classes defined in this
|
||||
* class.
|
||||
*/
|
||||
public final Iterator<JDefinedClass> classes() {
|
||||
if(classes==null)
|
||||
return Collections.<JDefinedClass>emptyList().iterator();
|
||||
else
|
||||
return classes.values().iterator();
|
||||
}
|
||||
|
||||
private Map<String,JDefinedClass> getClasses() {
|
||||
if(classes==null)
|
||||
classes = new TreeMap<String,JDefinedClass>();
|
||||
return classes;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns all the nested classes defined in this class.
|
||||
*/
|
||||
public final JClass[] listClasses() {
|
||||
if(classes==null)
|
||||
return new JClass[0];
|
||||
else
|
||||
return classes.values().toArray(new JClass[classes.values().size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JClass outer() {
|
||||
if (outer.isClass())
|
||||
return (JClass) outer;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
public void declare(JFormatter f) {
|
||||
if (jdoc != null)
|
||||
f.nl().g(jdoc);
|
||||
|
||||
if (annotations != null){
|
||||
for (JAnnotationUse annotation : annotations)
|
||||
f.g(annotation).nl();
|
||||
}
|
||||
|
||||
f.g(mods).p(classType.declarationToken).id(name).d(generifiable);
|
||||
|
||||
if (superClass != null && superClass != owner().ref(Object.class))
|
||||
f.nl().i().p("extends").g(superClass).nl().o();
|
||||
|
||||
if (!interfaces.isEmpty()) {
|
||||
if (superClass == null)
|
||||
f.nl();
|
||||
f.i().p(classType==ClassType.INTERFACE ? "extends" : "implements");
|
||||
f.g(interfaces);
|
||||
f.nl().o();
|
||||
}
|
||||
declareBody(f);
|
||||
}
|
||||
|
||||
/**
|
||||
* prints the body of a class.
|
||||
*/
|
||||
protected void declareBody(JFormatter f) {
|
||||
f.p('{').nl().nl().i();
|
||||
boolean first = true;
|
||||
|
||||
if (!enumConstantsByName.isEmpty()) {
|
||||
for (JEnumConstant c : enumConstantsByName.values()) {
|
||||
if (!first) f.p(',').nl();
|
||||
f.d(c);
|
||||
first = false;
|
||||
}
|
||||
f.p(';').nl();
|
||||
}
|
||||
|
||||
for( JFieldVar field : fields.values() )
|
||||
f.d(field);
|
||||
if (init != null)
|
||||
f.nl().p("static").s(init);
|
||||
for (JMethod m : constructors) {
|
||||
f.nl().d(m);
|
||||
}
|
||||
for (JMethod m : methods) {
|
||||
f.nl().d(m);
|
||||
}
|
||||
if(classes!=null)
|
||||
for (JDefinedClass dc : classes.values())
|
||||
f.nl().d(dc);
|
||||
|
||||
|
||||
if (directBlock != null)
|
||||
f.p(directBlock);
|
||||
f.nl().o().p('}').nl();
|
||||
}
|
||||
|
||||
/**
|
||||
* Places the given string directly inside the generated class.
|
||||
*
|
||||
* This method can be used to add methods/fields that are not
|
||||
* generated by CodeModel.
|
||||
* This method should be used only as the last resort.
|
||||
*/
|
||||
public void direct(String string) {
|
||||
if (directBlock == null)
|
||||
directBlock = string;
|
||||
else
|
||||
directBlock += string;
|
||||
}
|
||||
|
||||
public final JPackage _package() {
|
||||
JClassContainer p = outer;
|
||||
while (!(p instanceof JPackage))
|
||||
p = p.parentContainer();
|
||||
return (JPackage) p;
|
||||
}
|
||||
|
||||
public final JClassContainer parentContainer() {
|
||||
return outer;
|
||||
}
|
||||
|
||||
public JTypeVar generify(String name) {
|
||||
return generifiable.generify(name);
|
||||
}
|
||||
public JTypeVar generify(String name, Class<?> bound) {
|
||||
return generifiable.generify(name, bound);
|
||||
}
|
||||
public JTypeVar generify(String name, JClass bound) {
|
||||
return generifiable.generify(name, bound);
|
||||
}
|
||||
@Override
|
||||
public JTypeVar[] typeParams() {
|
||||
return generifiable.typeParams();
|
||||
}
|
||||
|
||||
protected JClass substituteParams(
|
||||
JTypeVar[] variables,
|
||||
List<JClass> bindings) {
|
||||
return this;
|
||||
}
|
||||
|
||||
/** Adding ability to annotate a class
|
||||
* @param clazz
|
||||
* The annotation class to annotate the class with
|
||||
*/
|
||||
public JAnnotationUse annotate(Class <? extends Annotation> clazz){
|
||||
return annotate(owner().ref(clazz));
|
||||
}
|
||||
|
||||
/** Adding ability to annotate a class
|
||||
* @param clazz
|
||||
* The annotation class to annotate the class with
|
||||
*/
|
||||
public JAnnotationUse annotate(JClass clazz){
|
||||
if(annotations==null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
JAnnotationUse a = new JAnnotationUse(clazz);
|
||||
annotations.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) {
|
||||
return TypedAnnotationWriter.create(clazz,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JAnnotatable#annotations()}
|
||||
*/
|
||||
public Collection<JAnnotationUse> annotations() {
|
||||
if (annotations == null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
return Collections.unmodifiableCollection(annotations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* the current modifiers of this class.
|
||||
* Always return non-null valid object.
|
||||
*/
|
||||
public JMods mods() {
|
||||
return mods;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
|
||||
/**
|
||||
* A special {@link JClass} that represents an unknown class (except its name.)
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
* @see JCodeModel#directClass(String)
|
||||
*/
|
||||
final class JDirectClass extends JClass {
|
||||
|
||||
private final String fullName;
|
||||
|
||||
public JDirectClass(JCodeModel _owner,String fullName) {
|
||||
super(_owner);
|
||||
this.fullName = fullName;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
int i = fullName.lastIndexOf('.');
|
||||
if(i>=0) return fullName.substring(i+1);
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
return fullName;
|
||||
}
|
||||
|
||||
public JPackage _package() {
|
||||
int i = fullName.lastIndexOf('.');
|
||||
if(i>=0) return owner()._package(fullName.substring(0,i));
|
||||
else return owner().rootPackage();
|
||||
}
|
||||
|
||||
public JClass _extends() {
|
||||
return owner().ref(Object.class);
|
||||
}
|
||||
|
||||
public Iterator<JClass> _implements() {
|
||||
return Collections.<JClass>emptyList().iterator();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Do loops
|
||||
*/
|
||||
|
||||
public class JDoLoop implements JStatement {
|
||||
|
||||
/**
|
||||
* Test part of Do statement for determining exit state
|
||||
*/
|
||||
private JExpression test;
|
||||
|
||||
/**
|
||||
* JBlock of statements which makes up body of this Do statement
|
||||
*/
|
||||
private JBlock body = null;
|
||||
|
||||
/**
|
||||
* Construct a Do statment
|
||||
*/
|
||||
JDoLoop(JExpression test) {
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
public JBlock body() {
|
||||
if (body == null) body = new JBlock();
|
||||
return body;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.p("do");
|
||||
if (body != null)
|
||||
f.g(body);
|
||||
else
|
||||
f.p("{ }");
|
||||
|
||||
if (JOp.hasTopOp(test)) {
|
||||
f.p("while ").g(test);
|
||||
} else {
|
||||
f.p("while (").g(test).p(')');
|
||||
}
|
||||
f.p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,197 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* JavaDoc comment.
|
||||
*
|
||||
* <p>
|
||||
* A javadoc comment consists of multiple parts. There's the main part (that comes the first in
|
||||
* in the comment section), then the parameter parts (@param), the return part (@return),
|
||||
* and the throws parts (@throws).
|
||||
*
|
||||
* TODO: it would be nice if we have JComment class and we can derive this class from there.
|
||||
*/
|
||||
public class JDocComment extends JCommentPart implements JGenerable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** list of @param tags */
|
||||
private final Map<String,JCommentPart> atParams = new HashMap<String,JCommentPart>();
|
||||
|
||||
/** list of xdoclets */
|
||||
private final Map<String,Map<String,String>> atXdoclets = new HashMap<String,Map<String,String>>();
|
||||
|
||||
/** list of @throws tags */
|
||||
private final Map<JClass,JCommentPart> atThrows = new HashMap<JClass,JCommentPart>();
|
||||
|
||||
/**
|
||||
* The @return tag part.
|
||||
*/
|
||||
private JCommentPart atReturn = null;
|
||||
|
||||
/** The @deprecated tag */
|
||||
private JCommentPart atDeprecated = null;
|
||||
|
||||
private final JCodeModel owner;
|
||||
|
||||
|
||||
public JDocComment(JCodeModel owner) {
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
public JDocComment append(Object o) {
|
||||
add(o);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a text to a @param tag to the javadoc
|
||||
*/
|
||||
public JCommentPart addParam( String param ) {
|
||||
JCommentPart p = atParams.get(param);
|
||||
if(p==null)
|
||||
atParams.put(param,p=new JCommentPart());
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Append a text to an @param tag.
|
||||
*/
|
||||
public JCommentPart addParam( JVar param ) {
|
||||
return addParam( param.name() );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* add an @throws tag to the javadoc
|
||||
*/
|
||||
public JCommentPart addThrows( Class<? extends Throwable> exception ) {
|
||||
return addThrows( owner.ref(exception) );
|
||||
}
|
||||
|
||||
/**
|
||||
* add an @throws tag to the javadoc
|
||||
*/
|
||||
public JCommentPart addThrows( JClass exception ) {
|
||||
JCommentPart p = atThrows.get(exception);
|
||||
if(p==null)
|
||||
atThrows.put(exception,p=new JCommentPart());
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a text to @return tag.
|
||||
*/
|
||||
public JCommentPart addReturn() {
|
||||
if(atReturn==null)
|
||||
atReturn = new JCommentPart();
|
||||
return atReturn;
|
||||
}
|
||||
|
||||
/**
|
||||
* add an @deprecated tag to the javadoc, with the associated message.
|
||||
*/
|
||||
public JCommentPart addDeprecated() {
|
||||
if(atDeprecated==null)
|
||||
atDeprecated = new JCommentPart();
|
||||
return atDeprecated;
|
||||
}
|
||||
|
||||
/**
|
||||
* add an xdoclet.
|
||||
*/
|
||||
public Map<String,String> addXdoclet(String name) {
|
||||
Map<String,String> p = atXdoclets.get(name);
|
||||
if(p==null)
|
||||
atXdoclets.put(name,p=new HashMap<String,String>());
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* add an xdoclet.
|
||||
*/
|
||||
public Map<String,String> addXdoclet(String name, Map<String,String> attributes) {
|
||||
Map<String,String> p = atXdoclets.get(name);
|
||||
if(p==null)
|
||||
atXdoclets.put(name,p=new HashMap<String,String>());
|
||||
p.putAll(attributes);
|
||||
return p;
|
||||
}
|
||||
|
||||
/**
|
||||
* add an xdoclet.
|
||||
*/
|
||||
public Map<String,String> addXdoclet(String name, String attribute, String value) {
|
||||
Map<String,String> p = atXdoclets.get(name);
|
||||
if(p==null)
|
||||
atXdoclets.put(name,p=new HashMap<String,String>());
|
||||
p.put(attribute, value);
|
||||
return p;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
// I realized that we can't use StringTokenizer because
|
||||
// this will recognize multiple \n as one token.
|
||||
|
||||
f.p("/**").nl();
|
||||
|
||||
format(f," * ");
|
||||
|
||||
f.p(" * ").nl();
|
||||
for (Map.Entry<String,JCommentPart> e : atParams.entrySet()) {
|
||||
f.p(" * @param ").p(e.getKey()).nl();
|
||||
e.getValue().format(f,INDENT);
|
||||
}
|
||||
if( atReturn != null ) {
|
||||
f.p(" * @return").nl();
|
||||
atReturn.format(f,INDENT);
|
||||
}
|
||||
for (Map.Entry<JClass,JCommentPart> e : atThrows.entrySet()) {
|
||||
f.p(" * @throws ").t(e.getKey()).nl();
|
||||
e.getValue().format(f,INDENT);
|
||||
}
|
||||
if( atDeprecated != null ) {
|
||||
f.p(" * @deprecated").nl();
|
||||
atDeprecated.format(f,INDENT);
|
||||
}
|
||||
for (Map.Entry<String,Map<String,String>> e : atXdoclets.entrySet()) {
|
||||
f.p(" * @").p(e.getKey());
|
||||
if (e.getValue() != null) {
|
||||
for (Map.Entry<String,String> a : e.getValue().entrySet()) {
|
||||
f.p(" ").p(a.getKey()).p("= \"").p(a.getValue()).p("\"");
|
||||
}
|
||||
}
|
||||
f.nl();
|
||||
}
|
||||
f.p(" */").nl();
|
||||
}
|
||||
|
||||
private static final String INDENT = " * ";
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Program elements that can have Javadoc
|
||||
*
|
||||
* @author Jonas von Malottki
|
||||
*/
|
||||
public interface JDocCommentable {
|
||||
/**
|
||||
* @return the JavaDoc of the Element
|
||||
*/
|
||||
JDocComment javadoc();
|
||||
}
|
||||
@ -0,0 +1,160 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.lang.annotation.Annotation;
|
||||
|
||||
/**
|
||||
* Enum Constant.
|
||||
*
|
||||
* When used as an {@link JExpression}, this object represents a reference to the enum constant.
|
||||
*
|
||||
* @author
|
||||
* Bhakti Mehta (Bhakti.Mehta@sun.com)
|
||||
*/
|
||||
public final class JEnumConstant extends JExpressionImpl implements JDeclaration, JAnnotatable, JDocCommentable {
|
||||
|
||||
/**
|
||||
* The constant.
|
||||
*/
|
||||
private final String name;
|
||||
/**
|
||||
* The enum class.
|
||||
*/
|
||||
private final JDefinedClass type;
|
||||
/**
|
||||
* javadoc comments, if any.
|
||||
*/
|
||||
private JDocComment jdoc = null;
|
||||
|
||||
/**
|
||||
* Annotations on this variable. Lazily created.
|
||||
*/
|
||||
private List<JAnnotationUse> annotations = null;
|
||||
|
||||
|
||||
/**
|
||||
* List of the constructor argument expressions.
|
||||
* Lazily constructed.
|
||||
*/
|
||||
private List<JExpression> args = null;
|
||||
|
||||
JEnumConstant(JDefinedClass type,String name) {
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to this constructor's argument list
|
||||
*
|
||||
* @param arg
|
||||
* Argument to add to argument list
|
||||
*/
|
||||
public JEnumConstant arg(JExpression arg) {
|
||||
if(arg==null) throw new IllegalArgumentException();
|
||||
if(args==null)
|
||||
args = new ArrayList<JExpression>();
|
||||
args.add(arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this constant.
|
||||
*
|
||||
* @return never null.
|
||||
*/
|
||||
public String getName() {
|
||||
return this.type.fullName().concat(".").concat(this.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates, if necessary, and returns the enum constant javadoc.
|
||||
*
|
||||
* @return JDocComment containing javadocs for this constant.
|
||||
*/
|
||||
public JDocComment javadoc() {
|
||||
if (jdoc == null)
|
||||
jdoc = new JDocComment(type.owner());
|
||||
return jdoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation to this variable.
|
||||
* @param clazz
|
||||
* The annotation class to annotate the field with
|
||||
*/
|
||||
public JAnnotationUse annotate(JClass clazz){
|
||||
if(annotations==null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
JAnnotationUse a = new JAnnotationUse(clazz);
|
||||
annotations.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation to this variable.
|
||||
*
|
||||
* @param clazz
|
||||
* The annotation class to annotate the field with
|
||||
*/
|
||||
public JAnnotationUse annotate(Class <? extends Annotation> clazz){
|
||||
return annotate(type.owner().ref(clazz));
|
||||
}
|
||||
|
||||
public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) {
|
||||
return TypedAnnotationWriter.create(clazz,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link JAnnotatable#annotations()}
|
||||
*/
|
||||
public Collection<JAnnotationUse> annotations() {
|
||||
if (annotations == null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
return Collections.unmodifiableList(annotations);
|
||||
}
|
||||
|
||||
public void declare(JFormatter f) {
|
||||
if( jdoc != null )
|
||||
f.nl().g( jdoc );
|
||||
if (annotations != null) {
|
||||
for( int i=0; i<annotations.size(); i++ )
|
||||
f.g(annotations.get(i)).nl();
|
||||
}
|
||||
f.id(name);
|
||||
if(args!=null) {
|
||||
f.p('(').g(args).p(')');
|
||||
}
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.t(type).p('.').p(name);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,289 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Factory methods that generate various {@link JExpression}s.
|
||||
*/
|
||||
public abstract class JExpr {
|
||||
|
||||
/**
|
||||
* This class is not instanciable.
|
||||
*/
|
||||
private JExpr() { }
|
||||
|
||||
public static JExpression assign(JAssignmentTarget lhs, JExpression rhs) {
|
||||
return new JAssignment(lhs, rhs);
|
||||
}
|
||||
|
||||
public static JExpression assignPlus(JAssignmentTarget lhs, JExpression rhs) {
|
||||
return new JAssignment(lhs, rhs, "+");
|
||||
}
|
||||
|
||||
public static JInvocation _new(JClass c) {
|
||||
return new JInvocation(c);
|
||||
}
|
||||
|
||||
public static JInvocation _new(JType t) {
|
||||
return new JInvocation(t);
|
||||
}
|
||||
|
||||
public static JInvocation invoke(String method) {
|
||||
return new JInvocation((JExpression)null, method);
|
||||
}
|
||||
|
||||
public static JInvocation invoke(JMethod method) {
|
||||
return new JInvocation((JExpression)null,method);
|
||||
}
|
||||
|
||||
public static JInvocation invoke(JExpression lhs, JMethod method) {
|
||||
return new JInvocation(lhs, method);
|
||||
}
|
||||
|
||||
public static JInvocation invoke(JExpression lhs, String method) {
|
||||
return new JInvocation(lhs, method);
|
||||
}
|
||||
|
||||
public static JFieldRef ref(String field) {
|
||||
return new JFieldRef((JExpression)null, field);
|
||||
}
|
||||
|
||||
public static JFieldRef ref(JExpression lhs, JVar field) {
|
||||
return new JFieldRef(lhs,field);
|
||||
}
|
||||
|
||||
public static JFieldRef ref(JExpression lhs, String field) {
|
||||
return new JFieldRef(lhs, field);
|
||||
}
|
||||
|
||||
public static JFieldRef refthis(String field) {
|
||||
return new JFieldRef(null, field, true);
|
||||
}
|
||||
|
||||
public static JExpression dotclass(final JClass cl) {
|
||||
return new JExpressionImpl() {
|
||||
public void generate(JFormatter f) {
|
||||
JClass c;
|
||||
if(cl instanceof JNarrowedClass)
|
||||
c = ((JNarrowedClass)cl).basis;
|
||||
else
|
||||
c = cl;
|
||||
f.g(c).p(".class");
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static JArrayCompRef component(JExpression lhs, JExpression index) {
|
||||
return new JArrayCompRef(lhs, index);
|
||||
}
|
||||
|
||||
public static JCast cast(JType type, JExpression expr) {
|
||||
return new JCast(type, expr);
|
||||
}
|
||||
|
||||
public static JArray newArray(JType type) {
|
||||
return newArray(type,null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates {@code new T[size]}.
|
||||
*
|
||||
* @param type
|
||||
* The type of the array component. 'T' or {@code new T[size]}.
|
||||
*/
|
||||
public static JArray newArray(JType type, JExpression size) {
|
||||
// you cannot create an array whose component type is a generic
|
||||
return new JArray(type.erasure(), size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates {@code new T[size]}.
|
||||
*
|
||||
* @param type
|
||||
* The type of the array component. 'T' or {@code new T[size]}.
|
||||
*/
|
||||
public static JArray newArray(JType type, int size) {
|
||||
return newArray(type,lit(size));
|
||||
}
|
||||
|
||||
|
||||
private static final JExpression __this = new JAtom("this");
|
||||
/**
|
||||
* Returns a reference to "this", an implicit reference
|
||||
* to the current object.
|
||||
*/
|
||||
public static JExpression _this() { return __this; }
|
||||
|
||||
private static final JExpression __super = new JAtom("super");
|
||||
/**
|
||||
* Returns a reference to "super", an implicit reference
|
||||
* to the super class.
|
||||
*/
|
||||
public static JExpression _super() { return __super; }
|
||||
|
||||
|
||||
/* -- Literals -- */
|
||||
|
||||
private static final JExpression __null = new JAtom("null");
|
||||
public static JExpression _null() {
|
||||
return __null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Boolean constant that represents <code>true</code>
|
||||
*/
|
||||
public static final JExpression TRUE = new JAtom("true");
|
||||
|
||||
/**
|
||||
* Boolean constant that represents <code>false</code>
|
||||
*/
|
||||
public static final JExpression FALSE = new JAtom("false");
|
||||
|
||||
public static JExpression lit(boolean b) {
|
||||
return b?TRUE:FALSE;
|
||||
}
|
||||
|
||||
public static JExpression lit(int n) {
|
||||
return new JAtom(Integer.toString(n));
|
||||
}
|
||||
|
||||
public static JExpression lit(long n) {
|
||||
return new JAtom(Long.toString(n) + "L");
|
||||
}
|
||||
|
||||
public static JExpression lit(float f) {
|
||||
if (f == Float.NEGATIVE_INFINITY)
|
||||
{
|
||||
return new JAtom("java.lang.Float.NEGATIVE_INFINITY");
|
||||
}
|
||||
else if (f == Float.POSITIVE_INFINITY)
|
||||
{
|
||||
return new JAtom("java.lang.Float.POSITIVE_INFINITY");
|
||||
}
|
||||
else if (Float.isNaN(f))
|
||||
{
|
||||
return new JAtom("java.lang.Float.NaN");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new JAtom(Float.toString(f) + "F");
|
||||
}
|
||||
}
|
||||
|
||||
public static JExpression lit(double d) {
|
||||
if (d == Double.NEGATIVE_INFINITY)
|
||||
{
|
||||
return new JAtom("java.lang.Double.NEGATIVE_INFINITY");
|
||||
}
|
||||
else if (d == Double.POSITIVE_INFINITY)
|
||||
{
|
||||
return new JAtom("java.lang.Double.POSITIVE_INFINITY");
|
||||
}
|
||||
else if (Double.isNaN(d))
|
||||
{
|
||||
return new JAtom("java.lang.Double.NaN");
|
||||
}
|
||||
else
|
||||
{
|
||||
return new JAtom(Double.toString(d) + "D");
|
||||
}
|
||||
}
|
||||
|
||||
static final String charEscape = "\b\t\n\f\r\"\'\\";
|
||||
static final String charMacro = "btnfr\"'\\";
|
||||
|
||||
/**
|
||||
* Escapes the given string, then surrounds it by the specified
|
||||
* quotation mark.
|
||||
*/
|
||||
public static String quotify(char quote, String s) {
|
||||
int n = s.length();
|
||||
StringBuilder sb = new StringBuilder(n + 2);
|
||||
sb.append(quote);
|
||||
for (int i = 0; i < n; i++) {
|
||||
char c = s.charAt(i);
|
||||
int j = charEscape.indexOf(c);
|
||||
if(j>=0) {
|
||||
if((quote=='"' && c=='\'') || (quote=='\'' && c=='"')) {
|
||||
sb.append(c);
|
||||
} else {
|
||||
sb.append('\\');
|
||||
sb.append(charMacro.charAt(j));
|
||||
}
|
||||
} else {
|
||||
// technically Unicode escape shouldn't be done here,
|
||||
// for it's a lexical level handling.
|
||||
//
|
||||
// However, various tools are so broken around this area,
|
||||
// so just to be on the safe side, it's better to do
|
||||
// the escaping here (regardless of the actual file encoding)
|
||||
//
|
||||
// see bug
|
||||
if( c<0x20 || 0x7E<c ) {
|
||||
// not printable. use Unicode escape
|
||||
sb.append("\\u");
|
||||
String hex = Integer.toHexString(((int)c)&0xFFFF);
|
||||
for( int k=hex.length(); k<4; k++ )
|
||||
sb.append('0');
|
||||
sb.append(hex);
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
sb.append(quote);
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static JExpression lit(char c) {
|
||||
return new JAtom(quotify('\'', "" + c));
|
||||
}
|
||||
|
||||
public static JExpression lit(String s) {
|
||||
return new JStringLiteral(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression directly from a source code fragment.
|
||||
*
|
||||
* <p>
|
||||
* This method can be used as a short-cut to create a JExpression.
|
||||
* For example, instead of <code>_a.gt(_b)</code>, you can write
|
||||
* it as: <code>JExpr.direct("a>b")</code>.
|
||||
*
|
||||
* <p>
|
||||
* Be warned that there is a danger in using this method,
|
||||
* as it obfuscates the object model.
|
||||
*/
|
||||
public static JExpression direct( final String source ) {
|
||||
return new JExpressionImpl(){
|
||||
public void generate( JFormatter f ) {
|
||||
f.p('(').p(source).p(')');
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* A Java expression.
|
||||
*
|
||||
* <p>
|
||||
* Unlike most of CodeModel, JExpressions are built bottom-up (
|
||||
* meaning you start from leaves and then gradually build compliated expressions
|
||||
* by combining them.)
|
||||
*
|
||||
* <p>
|
||||
* {@link JExpression} defines a series of composer methods,
|
||||
* which returns a complicated expression (by often taking other {@link JExpression}s
|
||||
* as parameters.
|
||||
* For example, you can build "5+2" by
|
||||
* <tt>JExpr.lit(5).add(JExpr.lit(2))</tt>
|
||||
*/
|
||||
public interface JExpression extends JGenerable {
|
||||
/**
|
||||
* Returns "-[this]" from "[this]".
|
||||
*/
|
||||
JExpression minus();
|
||||
|
||||
/**
|
||||
* Returns "![this]" from "[this]".
|
||||
*/
|
||||
JExpression not();
|
||||
/**
|
||||
* Returns "~[this]" from "[this]".
|
||||
*/
|
||||
JExpression complement();
|
||||
|
||||
/**
|
||||
* Returns "[this]++" from "[this]".
|
||||
*/
|
||||
JExpression incr();
|
||||
|
||||
/**
|
||||
* Returns "[this]--" from "[this]".
|
||||
*/
|
||||
JExpression decr();
|
||||
|
||||
/**
|
||||
* Returns "[this]+[right]"
|
||||
*/
|
||||
JExpression plus(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this]-[right]"
|
||||
*/
|
||||
JExpression minus(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this]*[right]"
|
||||
*/
|
||||
JExpression mul(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this]/[right]"
|
||||
*/
|
||||
JExpression div(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this]%[right]"
|
||||
*/
|
||||
JExpression mod(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this]<<[right]"
|
||||
*/
|
||||
JExpression shl(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this]>>[right]"
|
||||
*/
|
||||
JExpression shr(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this]>>>[right]"
|
||||
*/
|
||||
JExpression shrz(JExpression right);
|
||||
|
||||
/** Bit-wise AND '&'. */
|
||||
JExpression band(JExpression right);
|
||||
|
||||
/** Bit-wise OR '|'. */
|
||||
JExpression bor(JExpression right);
|
||||
|
||||
/** Logical AND '&&'. */
|
||||
JExpression cand(JExpression right);
|
||||
|
||||
/** Logical OR '||'. */
|
||||
JExpression cor(JExpression right);
|
||||
|
||||
JExpression xor(JExpression right);
|
||||
JExpression lt(JExpression right);
|
||||
JExpression lte(JExpression right);
|
||||
JExpression gt(JExpression right);
|
||||
JExpression gte(JExpression right);
|
||||
JExpression eq(JExpression right);
|
||||
JExpression ne(JExpression right);
|
||||
|
||||
/**
|
||||
* Returns "[this] instanceof [right]"
|
||||
*/
|
||||
JExpression _instanceof(JType right);
|
||||
|
||||
/**
|
||||
* Returns "[this].[method]".
|
||||
*
|
||||
* Arguments shall be added to the returned {@link JInvocation} object.
|
||||
*/
|
||||
JInvocation invoke(JMethod method);
|
||||
|
||||
/**
|
||||
* Returns "[this].[method]".
|
||||
*
|
||||
* Arguments shall be added to the returned {@link JInvocation} object.
|
||||
*/
|
||||
JInvocation invoke(String method);
|
||||
JFieldRef ref(JVar field);
|
||||
JFieldRef ref(String field);
|
||||
JArrayCompRef component(JExpression index);
|
||||
}
|
||||
@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Provides default implementations for {@link JExpression}.
|
||||
*/
|
||||
public abstract class JExpressionImpl implements JExpression
|
||||
{
|
||||
//
|
||||
//
|
||||
// from JOp
|
||||
//
|
||||
//
|
||||
public final JExpression minus() {
|
||||
return JOp.minus(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logical not <tt>'!x'</tt>.
|
||||
*/
|
||||
public final JExpression not() {
|
||||
return JOp.not(this);
|
||||
}
|
||||
|
||||
public final JExpression complement() {
|
||||
return JOp.complement(this);
|
||||
}
|
||||
|
||||
public final JExpression incr() {
|
||||
return JOp.incr(this);
|
||||
}
|
||||
|
||||
public final JExpression decr() {
|
||||
return JOp.decr(this);
|
||||
}
|
||||
|
||||
public final JExpression plus(JExpression right) {
|
||||
return JOp.plus(this, right);
|
||||
}
|
||||
|
||||
public final JExpression minus(JExpression right) {
|
||||
return JOp.minus(this, right);
|
||||
}
|
||||
|
||||
public final JExpression mul(JExpression right) {
|
||||
return JOp.mul(this, right);
|
||||
}
|
||||
|
||||
public final JExpression div(JExpression right) {
|
||||
return JOp.div(this, right);
|
||||
}
|
||||
|
||||
public final JExpression mod(JExpression right) {
|
||||
return JOp.mod(this, right);
|
||||
}
|
||||
|
||||
public final JExpression shl(JExpression right) {
|
||||
return JOp.shl(this, right);
|
||||
}
|
||||
|
||||
public final JExpression shr(JExpression right) {
|
||||
return JOp.shr(this, right);
|
||||
}
|
||||
|
||||
public final JExpression shrz(JExpression right) {
|
||||
return JOp.shrz(this, right);
|
||||
}
|
||||
|
||||
public final JExpression band(JExpression right) {
|
||||
return JOp.band(this, right);
|
||||
}
|
||||
|
||||
public final JExpression bor(JExpression right) {
|
||||
return JOp.bor(this, right);
|
||||
}
|
||||
|
||||
public final JExpression cand(JExpression right) {
|
||||
return JOp.cand(this, right);
|
||||
}
|
||||
|
||||
public final JExpression cor(JExpression right) {
|
||||
return JOp.cor(this, right);
|
||||
}
|
||||
|
||||
public final JExpression xor(JExpression right) {
|
||||
return JOp.xor(this, right);
|
||||
}
|
||||
|
||||
public final JExpression lt(JExpression right) {
|
||||
return JOp.lt(this, right);
|
||||
}
|
||||
|
||||
public final JExpression lte(JExpression right) {
|
||||
return JOp.lte(this, right);
|
||||
}
|
||||
|
||||
public final JExpression gt(JExpression right) {
|
||||
return JOp.gt(this, right);
|
||||
}
|
||||
|
||||
public final JExpression gte(JExpression right) {
|
||||
return JOp.gte(this, right);
|
||||
}
|
||||
|
||||
public final JExpression eq(JExpression right) {
|
||||
return JOp.eq(this, right);
|
||||
}
|
||||
|
||||
public final JExpression ne(JExpression right) {
|
||||
return JOp.ne(this, right);
|
||||
}
|
||||
|
||||
public final JExpression _instanceof(JType right) {
|
||||
return JOp._instanceof(this, right);
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
// from JExpr
|
||||
//
|
||||
//
|
||||
public final JInvocation invoke(JMethod method) {
|
||||
return JExpr.invoke(this, method);
|
||||
}
|
||||
|
||||
public final JInvocation invoke(String method) {
|
||||
return JExpr.invoke(this, method);
|
||||
}
|
||||
|
||||
public final JFieldRef ref(JVar field) {
|
||||
return JExpr.ref(this, field);
|
||||
}
|
||||
|
||||
public final JFieldRef ref(String field) {
|
||||
return JExpr.ref(this, field);
|
||||
}
|
||||
|
||||
public final JArrayCompRef component(JExpression index) {
|
||||
return JExpr.component(this, index);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Field Reference
|
||||
*/
|
||||
|
||||
public class JFieldRef extends JExpressionImpl implements JAssignmentTarget {
|
||||
/**
|
||||
* Object expression upon which this field will be accessed, or
|
||||
* null for the implicit 'this'.
|
||||
*/
|
||||
private JGenerable object;
|
||||
|
||||
/**
|
||||
* Name of the field to be accessed. Either this or {@link #var} is set.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Variable to be accessed.
|
||||
*/
|
||||
private JVar var;
|
||||
|
||||
/**
|
||||
* Indicates if an explicit this should be generated
|
||||
*/
|
||||
private boolean explicitThis;
|
||||
|
||||
/**
|
||||
* Field reference constructor given an object expression and field name
|
||||
*
|
||||
* @param object
|
||||
* JExpression for the object upon which
|
||||
* the named field will be accessed,
|
||||
*
|
||||
* @param name
|
||||
* Name of field to access
|
||||
*/
|
||||
JFieldRef(JExpression object, String name) {
|
||||
this(object, name, false);
|
||||
}
|
||||
|
||||
JFieldRef(JExpression object, JVar v) {
|
||||
this(object, v, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Static field reference.
|
||||
*/
|
||||
JFieldRef(JType type, String name) {
|
||||
this(type, name, false);
|
||||
}
|
||||
|
||||
JFieldRef(JType type, JVar v) {
|
||||
this(type, v, false);
|
||||
}
|
||||
|
||||
JFieldRef(JGenerable object, String name, boolean explicitThis) {
|
||||
this.explicitThis = explicitThis;
|
||||
this.object = object;
|
||||
if (name.indexOf('.') >= 0)
|
||||
throw new IllegalArgumentException("Field name contains '.': " + name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
JFieldRef(JGenerable object, JVar var, boolean explicitThis) {
|
||||
this.explicitThis = explicitThis;
|
||||
this.object = object;
|
||||
this.var = var;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
String name = this.name;
|
||||
if(name==null) name=var.name();
|
||||
|
||||
if (object != null) {
|
||||
f.g(object).p('.').p(name);
|
||||
} else {
|
||||
if (explicitThis) {
|
||||
f.p("this.").p(name);
|
||||
} else {
|
||||
f.id(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public JExpression assign(JExpression rhs) {
|
||||
return JExpr.assign(this, rhs);
|
||||
}
|
||||
public JExpression assignPlus(JExpression rhs) {
|
||||
return JExpr.assignPlus(this, rhs);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A field that can have a {@link JDocComment} associated with it
|
||||
*/
|
||||
public class JFieldVar extends JVar implements JDocCommentable {
|
||||
|
||||
/**
|
||||
* javadoc comments for this JFieldVar
|
||||
*/
|
||||
private JDocComment jdoc = null;
|
||||
|
||||
private final JDefinedClass owner;
|
||||
|
||||
|
||||
/**
|
||||
* JFieldVar constructor
|
||||
*
|
||||
* @param type
|
||||
* Datatype of this variable
|
||||
*
|
||||
* @param name
|
||||
* Name of this variable
|
||||
*
|
||||
* @param init
|
||||
* Value to initialize this variable to
|
||||
*/
|
||||
JFieldVar(JDefinedClass owner, JMods mods, JType type, String name, JExpression init) {
|
||||
super( mods, type, name, init );
|
||||
this.owner = owner;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void name(String name) {
|
||||
// make sure that the new name is available
|
||||
if(owner.fields.containsKey(name))
|
||||
throw new IllegalArgumentException("name "+name+" is already in use");
|
||||
String oldName = name();
|
||||
super.name(name);
|
||||
owner.fields.remove(oldName);
|
||||
owner.fields.put(name,this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates, if necessary, and returns the class javadoc for this
|
||||
* JDefinedClass
|
||||
*
|
||||
* @return JDocComment containing javadocs for this class
|
||||
*/
|
||||
public JDocComment javadoc() {
|
||||
if( jdoc == null )
|
||||
jdoc = new JDocComment(owner.owner());
|
||||
return jdoc;
|
||||
}
|
||||
|
||||
public void declare(JFormatter f) {
|
||||
if( jdoc != null )
|
||||
f.g( jdoc );
|
||||
super.declare( f );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* ForEach Statement
|
||||
* This will generate the code for statement based on the new
|
||||
* j2se 1.5 j.l.s.
|
||||
*
|
||||
* @author Bhakti
|
||||
*/
|
||||
public final class JForEach implements JStatement {
|
||||
|
||||
private final JType type;
|
||||
private final String var;
|
||||
private JBlock body = null; // lazily created
|
||||
private final JExpression collection;
|
||||
private final JVar loopVar;
|
||||
|
||||
public JForEach(JType vartype, String variable, JExpression collection) {
|
||||
|
||||
this.type = vartype;
|
||||
this.var = variable;
|
||||
this.collection = collection;
|
||||
loopVar = new JVar(JMods.forVar(JMod.NONE), type, var, collection);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a reference to the loop variable.
|
||||
*/
|
||||
public JVar var() {
|
||||
return loopVar;
|
||||
}
|
||||
|
||||
public JBlock body() {
|
||||
if (body == null)
|
||||
body = new JBlock();
|
||||
return body;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.p("for (");
|
||||
f.g(type).id(var).p(": ").g(collection);
|
||||
f.p(')');
|
||||
if (body != null)
|
||||
f.g(body).nl();
|
||||
else
|
||||
f.p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* For statement
|
||||
*/
|
||||
|
||||
public class JForLoop implements JStatement {
|
||||
|
||||
private List<Object> inits = new ArrayList<Object>();
|
||||
private JExpression test = null;
|
||||
private List<JExpression> updates = new ArrayList<JExpression>();
|
||||
private JBlock body = null;
|
||||
|
||||
public JVar init(int mods, JType type, String var, JExpression e) {
|
||||
JVar v = new JVar(JMods.forVar(mods), type, var, e);
|
||||
inits.add(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
public JVar init(JType type, String var, JExpression e) {
|
||||
return init(JMod.NONE, type, var, e);
|
||||
}
|
||||
|
||||
public void init(JVar v, JExpression e) {
|
||||
inits.add(JExpr.assign(v, e));
|
||||
}
|
||||
|
||||
public void test(JExpression e) {
|
||||
this.test = e;
|
||||
}
|
||||
|
||||
public void update(JExpression e) {
|
||||
updates.add(e);
|
||||
}
|
||||
|
||||
public JBlock body() {
|
||||
if (body == null) body = new JBlock();
|
||||
return body;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.p("for (");
|
||||
boolean first = true;
|
||||
for (Object o : inits) {
|
||||
if (!first) f.p(',');
|
||||
if (o instanceof JVar)
|
||||
f.b((JVar) o);
|
||||
else
|
||||
f.g((JExpression) o);
|
||||
first = false;
|
||||
}
|
||||
f.p(';').g(test).p(';').g(updates).p(')');
|
||||
if (body != null)
|
||||
f.g(body).nl();
|
||||
else
|
||||
f.p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,555 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* This is a utility class for managing indentation and other basic
|
||||
* formatting for PrintWriter.
|
||||
*/
|
||||
public final class JFormatter {
|
||||
/** all classes and ids encountered during the collection mode **/
|
||||
/** map from short type name to ReferenceList (list of JClass and ids sharing that name) **/
|
||||
private HashMap<String,ReferenceList> collectedReferences;
|
||||
|
||||
/** set of imported types (including package java types, eventhough we won't generate imports for them) */
|
||||
private HashSet<JClass> importedClasses;
|
||||
|
||||
private static enum Mode {
|
||||
/**
|
||||
* Collect all the type names and identifiers.
|
||||
* In this mode we don't actually generate anything.
|
||||
*/
|
||||
COLLECTING,
|
||||
/**
|
||||
* Print the actual source code.
|
||||
*/
|
||||
PRINTING
|
||||
}
|
||||
|
||||
/**
|
||||
* The current running mode.
|
||||
* Set to PRINTING so that a casual client can use a formatter just like before.
|
||||
*/
|
||||
private Mode mode = Mode.PRINTING;
|
||||
|
||||
/**
|
||||
* Current number of indentation strings to print
|
||||
*/
|
||||
private int indentLevel;
|
||||
|
||||
/**
|
||||
* String to be used for each indentation.
|
||||
* Defaults to four spaces.
|
||||
*/
|
||||
private final String indentSpace;
|
||||
|
||||
/**
|
||||
* Stream associated with this JFormatter
|
||||
*/
|
||||
private final PrintWriter pw;
|
||||
|
||||
/**
|
||||
* Creates a JFormatter.
|
||||
*
|
||||
* @param s
|
||||
* PrintWriter to JFormatter to use.
|
||||
*
|
||||
* @param space
|
||||
* Incremental indentation string, similar to tab value.
|
||||
*/
|
||||
public JFormatter(PrintWriter s, String space) {
|
||||
pw = s;
|
||||
indentSpace = space;
|
||||
collectedReferences = new HashMap<String,ReferenceList>();
|
||||
//ids = new HashSet<String>();
|
||||
importedClasses = new HashSet<JClass>();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a formatter with default incremental indentations of
|
||||
* four spaces.
|
||||
*/
|
||||
public JFormatter(PrintWriter s) {
|
||||
this(s, " ");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a formatter with default incremental indentations of
|
||||
* four spaces.
|
||||
*/
|
||||
public JFormatter(Writer w) {
|
||||
this(new PrintWriter(w));
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes this formatter.
|
||||
*/
|
||||
public void close() {
|
||||
pw.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we are in the printing mode,
|
||||
* where we actually produce text.
|
||||
*
|
||||
* The other mode is the "collecting mode'
|
||||
*/
|
||||
public boolean isPrinting() {
|
||||
return mode == Mode.PRINTING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the indentation level.
|
||||
*/
|
||||
public JFormatter o() {
|
||||
indentLevel--;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the indentation level.
|
||||
*/
|
||||
public JFormatter i() {
|
||||
indentLevel++;
|
||||
return this;
|
||||
}
|
||||
|
||||
private boolean needSpace(char c1, char c2) {
|
||||
if ((c1 == ']') && (c2 == '{')) return true;
|
||||
if (c1 == ';') return true;
|
||||
if (c1 == CLOSE_TYPE_ARGS) {
|
||||
// e.g., "public Foo<Bar> test;"
|
||||
if(c2=='(') // but not "new Foo<Bar>()"
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if ((c1 == ')') && (c2 == '{')) return true;
|
||||
if ((c1 == ',') || (c1 == '=')) return true;
|
||||
if (c2 == '=') return true;
|
||||
if (Character.isDigit(c1)) {
|
||||
if ((c2 == '(') || (c2 == ')') || (c2 == ';') || (c2 == ','))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
if (Character.isJavaIdentifierPart(c1)) {
|
||||
switch (c2) {
|
||||
case '{':
|
||||
case '}':
|
||||
case '+':
|
||||
case '>':
|
||||
case '@':
|
||||
return true;
|
||||
default:
|
||||
return Character.isJavaIdentifierStart(c2);
|
||||
}
|
||||
}
|
||||
if (Character.isJavaIdentifierStart(c2)) {
|
||||
switch (c1) {
|
||||
case ']':
|
||||
case ')':
|
||||
case '}':
|
||||
case '+':
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (Character.isDigit(c2)) {
|
||||
if (c1 == '(') return false;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private char lastChar = 0;
|
||||
private boolean atBeginningOfLine = true;
|
||||
|
||||
private void spaceIfNeeded(char c) {
|
||||
if (atBeginningOfLine) {
|
||||
for (int i = 0; i < indentLevel; i++)
|
||||
pw.print(indentSpace);
|
||||
atBeginningOfLine = false;
|
||||
} else if ((lastChar != 0) && needSpace(lastChar, c))
|
||||
pw.print(' ');
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a char into the stream
|
||||
*
|
||||
* @param c the char
|
||||
*/
|
||||
public JFormatter p(char c) {
|
||||
if(mode==Mode.PRINTING) {
|
||||
if(c==CLOSE_TYPE_ARGS) {
|
||||
pw.print('>');
|
||||
} else {
|
||||
spaceIfNeeded(c);
|
||||
pw.print(c);
|
||||
}
|
||||
lastChar = c;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a String into the stream
|
||||
*
|
||||
* @param s the String
|
||||
*/
|
||||
public JFormatter p(String s) {
|
||||
if(mode==Mode.PRINTING) {
|
||||
spaceIfNeeded(s.charAt(0));
|
||||
pw.print(s);
|
||||
lastChar = s.charAt(s.length() - 1);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public JFormatter t(JType type) {
|
||||
if(type.isReference()) {
|
||||
return t((JClass)type);
|
||||
} else {
|
||||
return g(type);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a type name.
|
||||
*
|
||||
* <p>
|
||||
* In the collecting mode we use this information to
|
||||
* decide what types to import and what not to.
|
||||
*/
|
||||
public JFormatter t(JClass type) {
|
||||
switch(mode) {
|
||||
case PRINTING:
|
||||
// many of the JTypes in this list are either primitive or belong to package java
|
||||
// so we don't need a FQCN
|
||||
if(importedClasses.contains(type)) {
|
||||
p(type.name()); // FQCN imported or not necessary, so generate short name
|
||||
} else {
|
||||
if(type.outer()!=null)
|
||||
t(type.outer()).p('.').p(type.name());
|
||||
else
|
||||
p(type.fullName()); // collision was detected, so generate FQCN
|
||||
}
|
||||
break;
|
||||
case COLLECTING:
|
||||
final String shortName = type.name();
|
||||
if(collectedReferences.containsKey(shortName)) {
|
||||
collectedReferences.get(shortName).add(type);
|
||||
} else {
|
||||
ReferenceList tl = new ReferenceList();
|
||||
tl.add(type);
|
||||
collectedReferences.put(shortName, tl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an identifier
|
||||
*/
|
||||
public JFormatter id(String id) {
|
||||
switch(mode) {
|
||||
case PRINTING:
|
||||
p(id);
|
||||
break;
|
||||
case COLLECTING:
|
||||
// see if there is a type name that collides with this id
|
||||
if(collectedReferences.containsKey(id)) {
|
||||
if( !collectedReferences.get(id).getClasses().isEmpty() ) {
|
||||
for( JClass type : collectedReferences.get(id).getClasses() ) {
|
||||
if (type.outer()!=null) {
|
||||
collectedReferences.get(id).setId(false);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
}
|
||||
collectedReferences.get(id).setId(true);
|
||||
} else {
|
||||
// not a type, but we need to create a place holder to
|
||||
// see if there might be a collision with a type
|
||||
ReferenceList tl = new ReferenceList();
|
||||
tl.setId(true);
|
||||
collectedReferences.put(id, tl);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a new line into the stream
|
||||
*/
|
||||
public JFormatter nl() {
|
||||
if(mode==Mode.PRINTING) {
|
||||
pw.println();
|
||||
lastChar = 0;
|
||||
atBeginningOfLine = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause the JGenerable object to generate source for iteself
|
||||
*
|
||||
* @param g the JGenerable object
|
||||
*/
|
||||
public JFormatter g(JGenerable g) {
|
||||
g.generate(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Produces {@link JGenerable}s separated by ','
|
||||
*/
|
||||
public JFormatter g(Collection<? extends JGenerable> list) {
|
||||
boolean first = true;
|
||||
if(!list.isEmpty()) {
|
||||
for (JGenerable item : list) {
|
||||
if (!first)
|
||||
p(',');
|
||||
g(item);
|
||||
first = false;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause the JDeclaration to generate source for itself
|
||||
*
|
||||
* @param d the JDeclaration object
|
||||
*/
|
||||
public JFormatter d(JDeclaration d) {
|
||||
d.declare(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause the JStatement to generate source for itself
|
||||
*
|
||||
* @param s the JStatement object
|
||||
*/
|
||||
public JFormatter s(JStatement s) {
|
||||
s.state(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Cause the JVar to generate source for itself
|
||||
*
|
||||
* @param v the JVar object
|
||||
*/
|
||||
public JFormatter b(JVar v) {
|
||||
v.bind(this);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the whole source code out of the specified class.
|
||||
*/
|
||||
void write(JDefinedClass c) {
|
||||
// first collect all the types and identifiers
|
||||
mode = Mode.COLLECTING;
|
||||
d(c);
|
||||
|
||||
javaLang = c.owner()._package("java.lang");
|
||||
|
||||
// collate type names and identifiers to determine which types can be imported
|
||||
for( ReferenceList tl : collectedReferences.values() ) {
|
||||
if(!tl.collisions(c) && !tl.isId()) {
|
||||
assert tl.getClasses().size() == 1;
|
||||
|
||||
// add to list of collected types
|
||||
importedClasses.add(tl.getClasses().get(0));
|
||||
}
|
||||
}
|
||||
|
||||
// the class itself that we will be generating is always accessible
|
||||
importedClasses.add(c);
|
||||
|
||||
// then print the declaration
|
||||
mode = Mode.PRINTING;
|
||||
|
||||
assert c.parentContainer().isPackage() : "this method is only for a pacakge-level class";
|
||||
JPackage pkg = (JPackage) c.parentContainer();
|
||||
if (!pkg.isUnnamed()) {
|
||||
nl().d(pkg);
|
||||
nl();
|
||||
}
|
||||
|
||||
// generate import statements
|
||||
JClass[] imports = importedClasses.toArray(new JClass[importedClasses.size()]);
|
||||
Arrays.sort(imports);
|
||||
for (JClass clazz : imports) {
|
||||
// suppress import statements for primitive types, built-in types,
|
||||
// types in the root package, and types in
|
||||
// the same package as the current type
|
||||
if(!supressImport(clazz, c)) {
|
||||
if (clazz instanceof JNarrowedClass) {
|
||||
clazz = clazz.erasure();
|
||||
}
|
||||
|
||||
p("import").p(clazz.fullName()).p(';').nl();
|
||||
}
|
||||
}
|
||||
nl();
|
||||
|
||||
d(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* determine if an import statement should be supressed
|
||||
*
|
||||
* @param clazz JType that may or may not have an import
|
||||
* @param c JType that is the current class being processed
|
||||
* @return true if an import statement should be suppressed, false otherwise
|
||||
*/
|
||||
private boolean supressImport(JClass clazz, JClass c) {
|
||||
if (clazz instanceof JNarrowedClass) {
|
||||
clazz = clazz.erasure();
|
||||
}
|
||||
if (clazz instanceof JAnonymousClass) {
|
||||
clazz = clazz._extends();
|
||||
}
|
||||
|
||||
if(clazz._package().isUnnamed())
|
||||
return true;
|
||||
|
||||
final String packageName = clazz._package().name();
|
||||
if(packageName.equals("java.lang"))
|
||||
return true; // no need to explicitly import java.lang classes
|
||||
|
||||
if (clazz._package() == c._package()){
|
||||
// inner classes require an import stmt.
|
||||
// All other pkg local classes do not need an
|
||||
// import stmt for ref.
|
||||
if(clazz.outer()==null) {
|
||||
return true; // no need to explicitly import a class into itself
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private JPackage javaLang;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Special character token we use to differenciate '>' as an operator and
|
||||
* '>' as the end of the type arguments. The former uses '>' and it requires
|
||||
* a preceding whitespace. The latter uses this, and it does not have a preceding
|
||||
* whitespace.
|
||||
*/
|
||||
/*package*/ static final char CLOSE_TYPE_ARGS = '\uFFFF';
|
||||
|
||||
/**
|
||||
* Used during the optimization of class imports.
|
||||
*
|
||||
* List of {@link JClass}es whose short name is the same.
|
||||
*
|
||||
* @author Ryan.Shoemaker@Sun.COM
|
||||
*/
|
||||
final class ReferenceList {
|
||||
private final ArrayList<JClass> classes = new ArrayList<JClass>();
|
||||
|
||||
/** true if this name is used as an identifier (like a variable name.) **/
|
||||
private boolean id;
|
||||
|
||||
/**
|
||||
* Returns true if the symbol represented by the short name
|
||||
* is "importable".
|
||||
*/
|
||||
public boolean collisions(JDefinedClass enclosingClass) {
|
||||
// special case where a generated type collides with a type in package java
|
||||
|
||||
// more than one type with the same name
|
||||
if(classes.size() > 1)
|
||||
return true;
|
||||
|
||||
// an id and (at least one) type with the same name
|
||||
if(id && classes.size() != 0)
|
||||
return true;
|
||||
|
||||
for(JClass c : classes) {
|
||||
if (c instanceof JAnonymousClass) {
|
||||
c = c._extends();
|
||||
}
|
||||
if(c._package()==javaLang) {
|
||||
// make sure that there's no other class with this name within the same package
|
||||
Iterator<JDefinedClass> itr = enclosingClass._package().classes();
|
||||
while(itr.hasNext()) {
|
||||
// even if this is the only "String" class we use,
|
||||
// if the class called "String" is in the same package,
|
||||
// we still need to import it.
|
||||
JDefinedClass n = itr.next();
|
||||
if(n.name().equals(c.name()))
|
||||
return true; //collision
|
||||
}
|
||||
}
|
||||
if(c.outer()!=null)
|
||||
return true; // avoid importing inner class to work around 6431987. Also see jaxb issue 166
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void add(JClass clazz) {
|
||||
if(!classes.contains(clazz))
|
||||
classes.add(clazz);
|
||||
}
|
||||
|
||||
public List<JClass> getClasses() {
|
||||
return classes;
|
||||
}
|
||||
|
||||
public void setId(boolean value) {
|
||||
id = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true iff this is strictly an id, meaning that there
|
||||
* are no collisions with type names.
|
||||
*/
|
||||
public boolean isId() {
|
||||
return id && classes.size() == 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Common interface for code components that can generate
|
||||
* uses of themselves.
|
||||
*/
|
||||
|
||||
public interface JGenerable {
|
||||
|
||||
public void generate(JFormatter f);
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Declarations that can have type variables.
|
||||
*
|
||||
* Something that can be made into a generic.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public interface JGenerifiable {
|
||||
/**
|
||||
* Adds a new type variable to this declaration.
|
||||
*/
|
||||
JTypeVar generify( String name );
|
||||
|
||||
/**
|
||||
* Adds a new type variable to this declaration with a bound.
|
||||
*/
|
||||
JTypeVar generify( String name, Class<?> bound );
|
||||
|
||||
/**
|
||||
* Adds a new type variable to this declaration with a bound.
|
||||
*/
|
||||
JTypeVar generify( String name, JClass bound );
|
||||
|
||||
/**
|
||||
* Iterates all the type parameters of this class/interface.
|
||||
*/
|
||||
JTypeVar[] typeParams();
|
||||
}
|
||||
@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Implementation of {@link JGenerifiable}.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
abstract class JGenerifiableImpl implements JGenerifiable, JDeclaration {
|
||||
|
||||
/** Lazily created list of {@link JTypeVar}s. */
|
||||
private List<JTypeVar> typeVariables = null;
|
||||
|
||||
protected abstract JCodeModel owner();
|
||||
|
||||
public void declare( JFormatter f ) {
|
||||
if(typeVariables!=null) {
|
||||
f.p('<');
|
||||
for (int i = 0; i < typeVariables.size(); i++) {
|
||||
if(i!=0) f.p(',');
|
||||
f.d(typeVariables.get(i));
|
||||
}
|
||||
f.p('>');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public JTypeVar generify(String name) {
|
||||
JTypeVar v = new JTypeVar(owner(),name);
|
||||
if(typeVariables==null)
|
||||
typeVariables = new ArrayList<JTypeVar>(3);
|
||||
typeVariables.add(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
public JTypeVar generify(String name, Class<?> bound) {
|
||||
return generify(name,owner().ref(bound));
|
||||
}
|
||||
|
||||
public JTypeVar generify(String name, JClass bound) {
|
||||
return generify(name).bound(bound);
|
||||
}
|
||||
|
||||
public JTypeVar[] typeParams() {
|
||||
if(typeVariables==null)
|
||||
return JTypeVar.EMPTY_ARRAY;
|
||||
else
|
||||
return typeVariables.toArray(new JTypeVar[typeVariables.size()]);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,186 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* JMethod invocation
|
||||
*/
|
||||
public final class JInvocation extends JExpressionImpl implements JStatement {
|
||||
|
||||
/**
|
||||
* Object expression upon which this method will be invoked, or null if
|
||||
* this is a constructor invocation
|
||||
*/
|
||||
private JGenerable object;
|
||||
|
||||
/**
|
||||
* Name of the method to be invoked.
|
||||
* Either this field is set, or {@link #method}, or {@link #type} (in which case it's a
|
||||
* constructor invocation.)
|
||||
* This allows {@link JMethod#name(String) the name of the method to be changed later}.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
private JMethod method;
|
||||
|
||||
private boolean isConstructor = false;
|
||||
|
||||
/**
|
||||
* List of argument expressions for this method invocation
|
||||
*/
|
||||
private List<JExpression> args = new ArrayList<JExpression>();
|
||||
|
||||
/**
|
||||
* If isConstructor==true, this field keeps the type to be created.
|
||||
*/
|
||||
private JType type = null;
|
||||
|
||||
/**
|
||||
* Invokes a method on an object.
|
||||
*
|
||||
* @param object
|
||||
* JExpression for the object upon which
|
||||
* the named method will be invoked,
|
||||
* or null if none
|
||||
*
|
||||
* @param name
|
||||
* Name of method to invoke
|
||||
*/
|
||||
JInvocation(JExpression object, String name) {
|
||||
this( (JGenerable)object, name );
|
||||
}
|
||||
|
||||
JInvocation(JExpression object, JMethod method) {
|
||||
this( (JGenerable)object, method );
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a static method on a class.
|
||||
*/
|
||||
JInvocation(JClass type, String name) {
|
||||
this( (JGenerable)type, name );
|
||||
}
|
||||
|
||||
JInvocation(JClass type, JMethod method) {
|
||||
this( (JGenerable)type, method );
|
||||
}
|
||||
|
||||
private JInvocation(JGenerable object, String name) {
|
||||
this.object = object;
|
||||
if (name.indexOf('.') >= 0)
|
||||
throw new IllegalArgumentException("method name contains '.': " + name);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
private JInvocation(JGenerable object, JMethod method) {
|
||||
this.object = object;
|
||||
this.method =method;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invokes a constructor of an object (i.e., creates
|
||||
* a new object.)
|
||||
*
|
||||
* @param c
|
||||
* Type of the object to be created. If this type is
|
||||
* an array type, added arguments are treated as array
|
||||
* initializer. Thus you can create an expression like
|
||||
* <code>new int[]{1,2,3,4,5}</code>.
|
||||
*/
|
||||
JInvocation(JType c) {
|
||||
this.isConstructor = true;
|
||||
this.type = c;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an expression to this invocation's argument list
|
||||
*
|
||||
* @param arg
|
||||
* Argument to add to argument list
|
||||
*/
|
||||
public JInvocation arg(JExpression arg) {
|
||||
if(arg==null) throw new IllegalArgumentException();
|
||||
args.add(arg);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a literal argument.
|
||||
*
|
||||
* Short for {@code arg(JExpr.lit(v))}
|
||||
*/
|
||||
public JInvocation arg(String v) {
|
||||
return arg(JExpr.lit(v));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all arguments of the invocation.
|
||||
* @return
|
||||
* If there's no arguments, an empty array will be returned.
|
||||
*/
|
||||
public JExpression[] listArgs() {
|
||||
return args.toArray(new JExpression[args.size()]);
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
if (isConstructor && type.isArray()) {
|
||||
// [RESULT] new T[]{arg1,arg2,arg3,...};
|
||||
f.p("new").g(type).p('{');
|
||||
} else {
|
||||
if (isConstructor)
|
||||
f.p("new").g(type).p('(');
|
||||
else {
|
||||
String name = this.name;
|
||||
if(name==null) name=this.method.name();
|
||||
|
||||
if (object != null)
|
||||
f.g(object).p('.').p(name).p('(');
|
||||
else
|
||||
f.id(name).p('(');
|
||||
}
|
||||
}
|
||||
|
||||
f.g(args);
|
||||
|
||||
if (isConstructor && type.isArray())
|
||||
f.p('}');
|
||||
else
|
||||
f.p(')');
|
||||
|
||||
if( type instanceof JDefinedClass && ((JDefinedClass)type).isAnonymous() ) {
|
||||
((JAnonymousClass)type).declareBody(f);
|
||||
}
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.g(this).p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,252 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Utility methods that convert arbitrary strings into Java identifiers.
|
||||
*/
|
||||
public class JJavaName {
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a given string is usable as a Java identifier.
|
||||
*/
|
||||
public static boolean isJavaIdentifier(String s) {
|
||||
if(s.length()==0) return false;
|
||||
if( reservedKeywords.contains(s) ) return false;
|
||||
|
||||
if(!Character.isJavaIdentifierStart(s.charAt(0))) return false;
|
||||
|
||||
for (int i = 1; i < s.length(); i++)
|
||||
if (!Character.isJavaIdentifierPart(s.charAt(i)))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given string is a valid fully qualified name.
|
||||
*/
|
||||
public static boolean isFullyQualifiedClassName(String s) {
|
||||
return isJavaPackageName(s);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the given string is a valid Java package name.
|
||||
*/
|
||||
public static boolean isJavaPackageName(String s) {
|
||||
while(s.length()!=0) {
|
||||
int idx = s.indexOf('.');
|
||||
if(idx==-1) idx=s.length();
|
||||
if( !isJavaIdentifier(s.substring(0,idx)) )
|
||||
return false;
|
||||
|
||||
s = s.substring(idx);
|
||||
if(s.length()!=0) s = s.substring(1); // remove '.'
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* <b>Experimental API:</b> converts an English word into a plural form.
|
||||
*
|
||||
* @param word
|
||||
* a word, such as "child", "apple". Must not be null.
|
||||
* It accepts word concatanation forms
|
||||
* that are common in programming languages, such as "my_child", "MyChild",
|
||||
* "myChild", "MY-CHILD", "CODE003-child", etc, and mostly tries to do the right thing.
|
||||
* ("my_children","MyChildren","myChildren", and "MY-CHILDREN", "CODE003-children" respectively)
|
||||
* <p>
|
||||
* Although this method only works for English words, it handles non-English
|
||||
* words gracefully (by just returning it as-is.) For example, 日本語
|
||||
* will be returned as-is without modified, not "日本語s"
|
||||
* <p>
|
||||
* This method doesn't handle suffixes very well. For example, passing
|
||||
* "person56" will return "person56s", not "people56".
|
||||
*
|
||||
* @return
|
||||
* always non-null.
|
||||
*/
|
||||
public static String getPluralForm(String word) {
|
||||
// remember the casing of the word
|
||||
boolean allUpper = true;
|
||||
|
||||
// check if the word looks like an English word.
|
||||
// if we see non-ASCII characters, abort
|
||||
for(int i=0; i<word.length(); i++ ) {
|
||||
char ch = word.charAt(i);
|
||||
if(ch >=0x80)
|
||||
return word;
|
||||
|
||||
// note that this isn't the same as allUpper &= Character.isUpperCase(ch);
|
||||
allUpper &= !Character.isLowerCase(ch);
|
||||
}
|
||||
|
||||
for (Entry e : TABLE) {
|
||||
String r = e.apply(word);
|
||||
if(r!=null) {
|
||||
if(allUpper) r=r.toUpperCase();
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
// failed
|
||||
return word;
|
||||
}
|
||||
|
||||
|
||||
/** All reserved keywords of Java. */
|
||||
private static HashSet<String> reservedKeywords = new HashSet<String>();
|
||||
|
||||
static {
|
||||
// see http://java.sun.com/docs/books/tutorial/java/nutsandbolts/_keywords.html
|
||||
String[] words = new String[]{
|
||||
"abstract",
|
||||
"boolean",
|
||||
"break",
|
||||
"byte",
|
||||
"case",
|
||||
"catch",
|
||||
"char",
|
||||
"class",
|
||||
"const",
|
||||
"continue",
|
||||
"default",
|
||||
"do",
|
||||
"double",
|
||||
"else",
|
||||
"extends",
|
||||
"final",
|
||||
"finally",
|
||||
"float",
|
||||
"for",
|
||||
"goto",
|
||||
"if",
|
||||
"implements",
|
||||
"import",
|
||||
"instanceof",
|
||||
"int",
|
||||
"interface",
|
||||
"long",
|
||||
"native",
|
||||
"new",
|
||||
"package",
|
||||
"private",
|
||||
"protected",
|
||||
"public",
|
||||
"return",
|
||||
"short",
|
||||
"static",
|
||||
"strictfp",
|
||||
"super",
|
||||
"switch",
|
||||
"synchronized",
|
||||
"this",
|
||||
"throw",
|
||||
"throws",
|
||||
"transient",
|
||||
"try",
|
||||
"void",
|
||||
"volatile",
|
||||
"while",
|
||||
|
||||
// technically these are not reserved words but they cannot be used as identifiers.
|
||||
"true",
|
||||
"false",
|
||||
"null",
|
||||
|
||||
// and I believe assert is also a new keyword
|
||||
"assert",
|
||||
|
||||
// and 5.0 keywords
|
||||
"enum"
|
||||
};
|
||||
for (String w : words)
|
||||
reservedKeywords.add(w);
|
||||
}
|
||||
|
||||
|
||||
private static class Entry {
|
||||
private final Pattern pattern;
|
||||
private final String replacement;
|
||||
|
||||
public Entry(String pattern, String replacement) {
|
||||
this.pattern = Pattern.compile(pattern,Pattern.CASE_INSENSITIVE);
|
||||
this.replacement = replacement;
|
||||
}
|
||||
|
||||
String apply(String word) {
|
||||
Matcher m = pattern.matcher(word);
|
||||
if(m.matches()) {
|
||||
StringBuffer buf = new StringBuffer();
|
||||
m.appendReplacement(buf,replacement);
|
||||
return buf.toString();
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static final Entry[] TABLE;
|
||||
|
||||
static {
|
||||
String[] source = {
|
||||
"(.*)child","$1children",
|
||||
"(.+)fe","$1ves",
|
||||
"(.*)mouse","$1mise",
|
||||
"(.+)f","$1ves",
|
||||
"(.+)ch","$1ches",
|
||||
"(.+)sh","$1shes",
|
||||
"(.*)tooth","$1teeth",
|
||||
"(.+)um","$1a",
|
||||
"(.+)an","$1en",
|
||||
"(.+)ato","$1atoes",
|
||||
"(.*)basis","$1bases",
|
||||
"(.*)axis","$1axes",
|
||||
"(.+)is","$1ises",
|
||||
"(.+)ss","$1sses",
|
||||
"(.+)us","$1uses",
|
||||
"(.+)s","$1s",
|
||||
"(.*)foot","$1feet",
|
||||
"(.+)ix","$1ixes",
|
||||
"(.+)ex","$1ices",
|
||||
"(.+)nx","$1nxes",
|
||||
"(.+)x","$1xes",
|
||||
"(.+)y","$1ies",
|
||||
"(.+)","$1s",
|
||||
};
|
||||
|
||||
TABLE = new Entry[source.length/2];
|
||||
|
||||
for( int i=0; i<source.length; i+=2 ) {
|
||||
TABLE[i/2] = new Entry(source[i],source[i+1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* Label that can be used for continue and break.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public class JLabel implements JStatement {
|
||||
|
||||
final String label;
|
||||
|
||||
/**
|
||||
* JBreak constructor
|
||||
*
|
||||
* @param _label
|
||||
* break label or null.
|
||||
*/
|
||||
JLabel( String _label ) {
|
||||
this.label = _label;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.p(label+':').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,474 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.TreeSet;
|
||||
import java.util.Collections;
|
||||
import java.util.Collection;
|
||||
|
||||
import com.sun.codemodel.internal.util.ClassNameComparator;
|
||||
|
||||
/**
|
||||
* Java method.
|
||||
*/
|
||||
public class JMethod extends JGenerifiableImpl implements JDeclaration, JAnnotatable, JDocCommentable {
|
||||
|
||||
/**
|
||||
* Modifiers for this method
|
||||
*/
|
||||
private JMods mods;
|
||||
|
||||
/**
|
||||
* Return type for this method
|
||||
*/
|
||||
private JType type = null;
|
||||
|
||||
/**
|
||||
* Name of this method
|
||||
*/
|
||||
private String name = null;
|
||||
|
||||
/**
|
||||
* List of parameters for this method's declaration
|
||||
*/
|
||||
private final List<JVar> params = new ArrayList<JVar>();
|
||||
|
||||
/**
|
||||
* Set of exceptions that this method may throw.
|
||||
* A set instance lazily created.
|
||||
*/
|
||||
private Set<JClass> _throws;
|
||||
|
||||
/**
|
||||
* JBlock of statements that makes up the body this method
|
||||
*/
|
||||
private JBlock body = null;
|
||||
|
||||
private JDefinedClass outer;
|
||||
|
||||
/**
|
||||
* javadoc comments for this JMethod
|
||||
*/
|
||||
private JDocComment jdoc = null;
|
||||
|
||||
/**
|
||||
* Variable parameter for this method's varargs declaration
|
||||
* introduced in J2SE 1.5
|
||||
*/
|
||||
private JVar varParam = null;
|
||||
|
||||
/**
|
||||
* Annotations on this variable. Lazily created.
|
||||
*/
|
||||
private List<JAnnotationUse> annotations = null;
|
||||
|
||||
|
||||
private boolean isConstructor() {
|
||||
return type == null;
|
||||
}
|
||||
|
||||
/** To set the default value for the
|
||||
* annotation member
|
||||
*/
|
||||
private JExpression defaultValue = null;
|
||||
|
||||
|
||||
/**
|
||||
* JMethod constructor
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this method's declaration
|
||||
*
|
||||
* @param type
|
||||
* Return type for the method
|
||||
*
|
||||
* @param name
|
||||
* Name of this method
|
||||
*/
|
||||
JMethod(JDefinedClass outer, int mods, JType type, String name) {
|
||||
this.mods = JMods.forMethod(mods);
|
||||
this.type = type;
|
||||
this.name = name;
|
||||
this.outer = outer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor constructor
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this constructor's declaration
|
||||
*
|
||||
* @param _class
|
||||
* JClass containing this constructor
|
||||
*/
|
||||
JMethod(int mods, JDefinedClass _class) {
|
||||
this.mods = JMods.forMethod(mods);
|
||||
this.type = null;
|
||||
this.name = _class.name();
|
||||
this.outer = _class;
|
||||
}
|
||||
|
||||
private Set<JClass> getThrows() {
|
||||
if(_throws==null)
|
||||
_throws = new TreeSet<JClass>(ClassNameComparator.theInstance);
|
||||
return _throws;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an exception to the list of exceptions that this
|
||||
* method may throw.
|
||||
*
|
||||
* @param exception
|
||||
* Name of an exception that this method may throw
|
||||
*/
|
||||
public JMethod _throws(JClass exception) {
|
||||
getThrows().add(exception);
|
||||
return this;
|
||||
}
|
||||
|
||||
public JMethod _throws(Class<? extends Throwable> exception) {
|
||||
return _throws(outer.owner().ref(exception));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the list of variable of this method.
|
||||
*
|
||||
* @return List of parameters of this method. This list is not modifiable.
|
||||
*/
|
||||
public List<JVar> params() {
|
||||
return Collections.<JVar>unmodifiableList(params);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the specified variable to the list of parameters
|
||||
* for this method signature.
|
||||
*
|
||||
* @param type
|
||||
* JType of the parameter being added
|
||||
*
|
||||
* @param name
|
||||
* Name of the parameter being added
|
||||
*
|
||||
* @return New parameter variable
|
||||
*/
|
||||
public JVar param(int mods, JType type, String name) {
|
||||
JVar v = new JVar(JMods.forVar(mods), type, name, null);
|
||||
params.add(v);
|
||||
return v;
|
||||
}
|
||||
|
||||
public JVar param(JType type, String name) {
|
||||
return param(JMod.NONE, type, name);
|
||||
}
|
||||
|
||||
public JVar param(int mods, Class<?> type, String name) {
|
||||
return param(mods, outer.owner()._ref(type), name);
|
||||
}
|
||||
|
||||
public JVar param(Class<?> type, String name) {
|
||||
return param(outer.owner()._ref(type), name);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see #varParam(JType, String)
|
||||
*/
|
||||
public JVar varParam(Class<?> type, String name) {
|
||||
return varParam(outer.owner()._ref(type),name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the specified variable argument to the list of parameters
|
||||
* for this method signature.
|
||||
*
|
||||
* @param type
|
||||
* Type of the parameter being added.
|
||||
*
|
||||
* @param name
|
||||
* Name of the parameter being added
|
||||
*
|
||||
* @return the variable parameter
|
||||
*
|
||||
* @throws IllegalStateException
|
||||
* If this method is called twice.
|
||||
* varargs in J2SE 1.5 can appear only once in the
|
||||
* method signature.
|
||||
*/
|
||||
public JVar varParam(JType type, String name) {
|
||||
if (!hasVarArgs()) {
|
||||
|
||||
varParam =
|
||||
new JVar(
|
||||
JMods.forVar(JMod.NONE),
|
||||
type.array(),
|
||||
name,
|
||||
null);
|
||||
return varParam;
|
||||
} else {
|
||||
throw new IllegalStateException(
|
||||
"Cannot have two varargs in a method,\n"
|
||||
+ "Check if varParam method of JMethod is"
|
||||
+ " invoked more than once");
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation to this variable.
|
||||
* @param clazz
|
||||
* The annotation class to annotate the field with
|
||||
*/
|
||||
public JAnnotationUse annotate(JClass clazz){
|
||||
if(annotations==null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
JAnnotationUse a = new JAnnotationUse(clazz);
|
||||
annotations.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an annotation to this variable.
|
||||
*
|
||||
* @param clazz
|
||||
* The annotation class to annotate the field with
|
||||
*/
|
||||
public JAnnotationUse annotate(Class <? extends Annotation> clazz){
|
||||
return annotate(owner().ref(clazz));
|
||||
}
|
||||
|
||||
public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) {
|
||||
return TypedAnnotationWriter.create(clazz,this);
|
||||
}
|
||||
|
||||
public Collection<JAnnotationUse> annotations() {
|
||||
if (annotations == null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
return Collections.unmodifiableList(annotations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if there are any varargs declared
|
||||
* for this method signature.
|
||||
*/
|
||||
public boolean hasVarArgs() {
|
||||
return this.varParam!=null;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Changes the name of the method.
|
||||
*/
|
||||
public void name(String n) {
|
||||
this.name = n;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the return type.
|
||||
*/
|
||||
public JType type() {
|
||||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Overrides the return type.
|
||||
*/
|
||||
public void type(JType t) {
|
||||
this.type = t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the parameter types in an array.
|
||||
* @return
|
||||
* If there's no parameter, an empty array will be returned.
|
||||
*/
|
||||
public JType[] listParamTypes() {
|
||||
JType[] r = new JType[params.size()];
|
||||
for (int i = 0; i < r.length; i++)
|
||||
r[i] = params.get(i).type();
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the varags parameter type.
|
||||
* @return
|
||||
* If there's no vararg parameter type, null will be returned.
|
||||
*/
|
||||
public JType listVarParamType() {
|
||||
if (varParam != null)
|
||||
return varParam.type();
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the parameters in an array.
|
||||
* @return
|
||||
* If there's no parameter, an empty array will be returned.
|
||||
*/
|
||||
public JVar[] listParams() {
|
||||
return params.toArray(new JVar[params.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the variable parameter
|
||||
* @return
|
||||
* If there's no parameter, null will be returned.
|
||||
*/
|
||||
public JVar listVarParam() {
|
||||
return varParam;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the method has the specified signature.
|
||||
*/
|
||||
public boolean hasSignature(JType[] argTypes) {
|
||||
JVar[] p = listParams();
|
||||
if (p.length != argTypes.length)
|
||||
return false;
|
||||
|
||||
for (int i = 0; i < p.length; i++)
|
||||
if (!p[i].type().equals(argTypes[i]))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the block that makes up body of this method
|
||||
*
|
||||
* @return Body of method
|
||||
*/
|
||||
public JBlock body() {
|
||||
if (body == null)
|
||||
body = new JBlock();
|
||||
return body;
|
||||
}
|
||||
|
||||
/**
|
||||
* Specify the default value for this annotation member
|
||||
* @param value
|
||||
* Default value for the annotation member
|
||||
*
|
||||
*/
|
||||
public void declareDefaultValue(JExpression value){
|
||||
this.defaultValue = value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates, if necessary, and returns the class javadoc for this
|
||||
* JDefinedClass
|
||||
*
|
||||
* @return JDocComment containing javadocs for this class
|
||||
*/
|
||||
public JDocComment javadoc() {
|
||||
if (jdoc == null)
|
||||
jdoc = new JDocComment(owner());
|
||||
return jdoc;
|
||||
}
|
||||
|
||||
public void declare(JFormatter f) {
|
||||
if (jdoc != null)
|
||||
f.g(jdoc);
|
||||
|
||||
if (annotations != null){
|
||||
for (JAnnotationUse a : annotations)
|
||||
f.g(a).nl();
|
||||
}
|
||||
|
||||
f.g(mods);
|
||||
|
||||
// declare the generics parameters
|
||||
super.declare(f);
|
||||
|
||||
if (!isConstructor())
|
||||
f.g(type);
|
||||
f.id(name).p('(').i();
|
||||
// when parameters are printed in new lines, we want them to be indented.
|
||||
// there's a good chance no newlines happen, too, but just in case it does.
|
||||
boolean first = true;
|
||||
for (JVar var : params) {
|
||||
if (!first)
|
||||
f.p(',');
|
||||
if(var.isAnnotated())
|
||||
f.nl();
|
||||
f.b(var);
|
||||
first = false;
|
||||
}
|
||||
if (hasVarArgs()) {
|
||||
if (!first)
|
||||
f.p(',');
|
||||
f.g(varParam.type().elementType());
|
||||
f.p("... ");
|
||||
f.id(varParam.name());
|
||||
}
|
||||
|
||||
f.o().p(')');
|
||||
if (_throws!=null && !_throws.isEmpty()) {
|
||||
f.nl().i().p("throws").g(_throws).nl().o();
|
||||
}
|
||||
|
||||
if (defaultValue != null) {
|
||||
f.p("default ");
|
||||
f.g(defaultValue);
|
||||
}
|
||||
if (body != null) {
|
||||
f.s(body);
|
||||
} else if (
|
||||
!outer.isInterface() && !outer.isAnnotationTypeDeclaration() && !mods.isAbstract() && !mods.isNative()) {
|
||||
// Print an empty body for non-native, non-abstract methods
|
||||
f.s(new JBlock());
|
||||
} else {
|
||||
f.p(';').nl();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return
|
||||
* the current modifiers of this method.
|
||||
* Always return non-null valid object.
|
||||
*/
|
||||
public JMods mods() {
|
||||
return mods;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #mods()}
|
||||
*/
|
||||
public JMods getMods() {
|
||||
return mods;
|
||||
}
|
||||
|
||||
protected JCodeModel owner() {
|
||||
return outer.owner();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Modifier constants.
|
||||
*/
|
||||
public final class JMod {
|
||||
public final static int NONE = 0x000;
|
||||
public final static int PUBLIC = 0x001;
|
||||
public final static int PROTECTED = 0x002;
|
||||
public final static int PRIVATE = 0x004;
|
||||
public final static int FINAL = 0x008;
|
||||
public final static int STATIC = 0x010;
|
||||
public final static int ABSTRACT = 0x020;
|
||||
public final static int NATIVE = 0x040;
|
||||
public final static int SYNCHRONIZED = 0x080;
|
||||
public final static int TRANSIENT = 0x100;
|
||||
public final static int VOLATILE = 0x200;
|
||||
}
|
||||
@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.io.StringWriter;
|
||||
|
||||
/**
|
||||
* Modifier groups.
|
||||
*/
|
||||
public class JMods implements JGenerable {
|
||||
|
||||
//
|
||||
// mask
|
||||
//
|
||||
private static int VAR = JMod.FINAL;
|
||||
private static int FIELD = (JMod.PUBLIC | JMod.PRIVATE | JMod.PROTECTED
|
||||
| JMod.STATIC | JMod.FINAL
|
||||
| JMod.TRANSIENT | JMod.VOLATILE);
|
||||
private static int METHOD = (JMod.PUBLIC | JMod.PRIVATE | JMod.PROTECTED | JMod.FINAL
|
||||
| JMod.ABSTRACT | JMod.STATIC | JMod.NATIVE | JMod.SYNCHRONIZED);
|
||||
private static int CLASS = (JMod.PUBLIC | JMod.PRIVATE | JMod.PROTECTED
|
||||
| JMod.STATIC | JMod.FINAL | JMod.ABSTRACT);
|
||||
private static int INTERFACE = JMod.PUBLIC;
|
||||
/** bit-packed representation of modifiers. */
|
||||
private int mods;
|
||||
|
||||
private JMods(int mods) {
|
||||
this.mods = mods;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the bit-packed representaion of modifiers.
|
||||
*/
|
||||
public int getValue() {
|
||||
return mods;
|
||||
}
|
||||
|
||||
private static void check(int mods, int legal, String what) {
|
||||
if ((mods & ~legal) != 0) {
|
||||
throw new IllegalArgumentException("Illegal modifiers for "
|
||||
+ what + ": "
|
||||
+ new JMods(mods).toString());
|
||||
}
|
||||
/* ## check for illegal combinations too */
|
||||
}
|
||||
|
||||
static JMods forVar(int mods) {
|
||||
check(mods, VAR, "variable");
|
||||
return new JMods(mods);
|
||||
}
|
||||
|
||||
static JMods forField(int mods) {
|
||||
check(mods, FIELD, "field");
|
||||
return new JMods(mods);
|
||||
}
|
||||
|
||||
static JMods forMethod(int mods) {
|
||||
check(mods, METHOD, "method");
|
||||
return new JMods(mods);
|
||||
}
|
||||
|
||||
static JMods forClass(int mods) {
|
||||
check(mods, CLASS, "class");
|
||||
return new JMods(mods);
|
||||
}
|
||||
|
||||
static JMods forInterface(int mods) {
|
||||
check(mods, INTERFACE, "class");
|
||||
return new JMods(mods);
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return (mods & JMod.ABSTRACT) != 0;
|
||||
}
|
||||
|
||||
public boolean isNative() {
|
||||
return (mods & JMod.NATIVE) != 0;
|
||||
}
|
||||
|
||||
public boolean isSynchronized() {
|
||||
return (mods & JMod.SYNCHRONIZED) != 0;
|
||||
}
|
||||
|
||||
public void setSynchronized(boolean newValue) {
|
||||
setFlag(JMod.SYNCHRONIZED, newValue);
|
||||
}
|
||||
|
||||
public void setPrivate() {
|
||||
setFlag(JMod.PUBLIC, false);
|
||||
setFlag(JMod.PROTECTED, false);
|
||||
setFlag(JMod.PRIVATE, true);
|
||||
}
|
||||
|
||||
public void setProtected() {
|
||||
setFlag(JMod.PUBLIC, false);
|
||||
setFlag(JMod.PROTECTED, true);
|
||||
setFlag(JMod.PRIVATE, false);
|
||||
}
|
||||
|
||||
public void setPublic() {
|
||||
setFlag(JMod.PUBLIC, true);
|
||||
setFlag(JMod.PROTECTED, false);
|
||||
setFlag(JMod.PRIVATE, false);
|
||||
}
|
||||
|
||||
public void setFinal(boolean newValue) {
|
||||
setFlag(JMod.FINAL, newValue);
|
||||
}
|
||||
|
||||
private void setFlag(int bit, boolean newValue) {
|
||||
mods = (mods & ~bit) | (newValue ? bit : 0);
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
if ((mods & JMod.PUBLIC) != 0) f.p("public");
|
||||
if ((mods & JMod.PROTECTED) != 0) f.p("protected");
|
||||
if ((mods & JMod.PRIVATE) != 0) f.p("private");
|
||||
if ((mods & JMod.FINAL) != 0) f.p("final");
|
||||
if ((mods & JMod.STATIC) != 0) f.p("static");
|
||||
if ((mods & JMod.ABSTRACT) != 0) f.p("abstract");
|
||||
if ((mods & JMod.NATIVE) != 0) f.p("native");
|
||||
if ((mods & JMod.SYNCHRONIZED) != 0) f.p("synchronized");
|
||||
if ((mods & JMod.TRANSIENT) != 0) f.p("transient");
|
||||
if ((mods & JMod.VOLATILE) != 0) f.p("volatile");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
StringWriter s = new StringWriter();
|
||||
JFormatter f = new JFormatter(new PrintWriter(s));
|
||||
this.generate(f);
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Collections;
|
||||
import java.util.ArrayList;
|
||||
|
||||
/**
|
||||
* Represents X<Y>.
|
||||
*
|
||||
* TODO: consider separating the decl and the use.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
class JNarrowedClass extends JClass {
|
||||
/**
|
||||
* A generic class with type parameters.
|
||||
*/
|
||||
final JClass basis;
|
||||
/**
|
||||
* Arguments to those parameters.
|
||||
*/
|
||||
private final List<JClass> args;
|
||||
|
||||
JNarrowedClass(JClass basis, JClass arg) {
|
||||
this(basis,Collections.singletonList(arg));
|
||||
}
|
||||
|
||||
JNarrowedClass(JClass basis, List<JClass> args) {
|
||||
super(basis.owner());
|
||||
this.basis = basis;
|
||||
assert !(basis instanceof JNarrowedClass);
|
||||
this.args = args;
|
||||
}
|
||||
|
||||
@Override
|
||||
public JClass narrow( JClass clazz ) {
|
||||
List<JClass> newArgs = new ArrayList<JClass>(args);
|
||||
newArgs.add(clazz);
|
||||
return new JNarrowedClass(basis,newArgs);
|
||||
}
|
||||
|
||||
@Override
|
||||
public JClass narrow( JClass... clazz ) {
|
||||
List<JClass> newArgs = new ArrayList<JClass>(args);
|
||||
newArgs.addAll(Arrays.asList(clazz));
|
||||
return new JNarrowedClass(basis,newArgs);
|
||||
}
|
||||
|
||||
public String name() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(basis.name());
|
||||
buf.append('<');
|
||||
boolean first = true;
|
||||
for (JClass c : args) {
|
||||
if(first)
|
||||
first = false;
|
||||
else
|
||||
buf.append(',');
|
||||
buf.append(c.name());
|
||||
}
|
||||
buf.append('>');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(basis.fullName());
|
||||
buf.append('<');
|
||||
boolean first = true;
|
||||
for (JClass c : args) {
|
||||
if(first)
|
||||
first = false;
|
||||
else
|
||||
buf.append(',');
|
||||
buf.append(c.fullName());
|
||||
}
|
||||
buf.append('>');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String binaryName() {
|
||||
StringBuilder buf = new StringBuilder();
|
||||
buf.append(basis.binaryName());
|
||||
buf.append('<');
|
||||
boolean first = true;
|
||||
for (JClass c : args) {
|
||||
if(first)
|
||||
first = false;
|
||||
else
|
||||
buf.append(',');
|
||||
buf.append(c.binaryName());
|
||||
}
|
||||
buf.append('>');
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void generate(JFormatter f) {
|
||||
f.t(basis).p('<').g(args).p(JFormatter.CLOSE_TYPE_ARGS);
|
||||
}
|
||||
|
||||
@Override
|
||||
void printLink(JFormatter f) {
|
||||
basis.printLink(f);
|
||||
f.p("{@code <}");
|
||||
boolean first = true;
|
||||
for( JClass c : args ) {
|
||||
if(first)
|
||||
first = false;
|
||||
else
|
||||
f.p(',');
|
||||
c.printLink(f);
|
||||
}
|
||||
f.p("{@code >}");
|
||||
}
|
||||
|
||||
public JPackage _package() {
|
||||
return basis._package();
|
||||
}
|
||||
|
||||
public JClass _extends() {
|
||||
JClass base = basis._extends();
|
||||
if(base==null) return base;
|
||||
return base.substituteParams(basis.typeParams(),args);
|
||||
}
|
||||
|
||||
public Iterator<JClass> _implements() {
|
||||
return new Iterator<JClass>() {
|
||||
private final Iterator<JClass> core = basis._implements();
|
||||
public void remove() {
|
||||
core.remove();
|
||||
}
|
||||
public JClass next() {
|
||||
return core.next().substituteParams(basis.typeParams(),args);
|
||||
}
|
||||
public boolean hasNext() {
|
||||
return core.hasNext();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public JClass erasure() {
|
||||
return basis;
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return basis.isInterface();
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return basis.isAbstract();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// Equality is based on value
|
||||
//
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj) {
|
||||
if(!(obj instanceof JNarrowedClass)) return false;
|
||||
return fullName().equals(((JClass)obj).fullName());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return fullName().hashCode();
|
||||
}
|
||||
|
||||
protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
|
||||
JClass b = basis.substituteParams(variables,bindings);
|
||||
boolean different = b!=basis;
|
||||
|
||||
List<JClass> clazz = new ArrayList<JClass>(args.size());
|
||||
for( int i=0; i<clazz.size(); i++ ) {
|
||||
JClass c = args.get(i).substituteParams(variables,bindings);
|
||||
clazz.set(i,c);
|
||||
different |= c != args.get(i);
|
||||
}
|
||||
|
||||
if(different)
|
||||
return new JNarrowedClass(b,clazz);
|
||||
else
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<JClass> getTypeParameters() {
|
||||
return args;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Special class object that represents the type of "null".
|
||||
*
|
||||
* <p>
|
||||
* Use this class with care.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class JNullType extends JClass {
|
||||
|
||||
JNullType(JCodeModel _owner) {
|
||||
super(_owner);
|
||||
}
|
||||
|
||||
public String name() { return "null"; }
|
||||
public String fullName() { return "null"; }
|
||||
|
||||
public JPackage _package() { return owner()._package(""); }
|
||||
|
||||
public JClass _extends() { return null; }
|
||||
|
||||
public Iterator<JClass> _implements() {
|
||||
return Collections.<JClass>emptyList().iterator();
|
||||
}
|
||||
|
||||
public boolean isInterface() { return false; }
|
||||
public boolean isAbstract() { return false; }
|
||||
|
||||
protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* JClass for generating expressions containing operators
|
||||
*/
|
||||
|
||||
abstract public class JOp {
|
||||
|
||||
private JOp() {
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Determine whether the top level of an expression involves an
|
||||
* operator.
|
||||
*/
|
||||
static boolean hasTopOp(JExpression e) {
|
||||
return (e instanceof UnaryOp) || (e instanceof BinaryOp);
|
||||
}
|
||||
|
||||
/* -- Unary operators -- */
|
||||
|
||||
static private class UnaryOp extends JExpressionImpl {
|
||||
|
||||
protected String op;
|
||||
protected JExpression e;
|
||||
protected boolean opFirst = true;
|
||||
|
||||
UnaryOp(String op, JExpression e) {
|
||||
this.op = op;
|
||||
this.e = e;
|
||||
}
|
||||
|
||||
UnaryOp(JExpression e, String op) {
|
||||
this.op = op;
|
||||
this.e = e;
|
||||
opFirst = false;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
if (opFirst)
|
||||
f.p('(').p(op).g(e).p(')');
|
||||
else
|
||||
f.p('(').g(e).p(op).p(')');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static JExpression minus(JExpression e) {
|
||||
return new UnaryOp("-", e);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logical not <tt>'!x'</tt>.
|
||||
*/
|
||||
public static JExpression not(JExpression e) {
|
||||
if (e == JExpr.TRUE) return JExpr.FALSE;
|
||||
if (e == JExpr.FALSE) return JExpr.TRUE;
|
||||
return new UnaryOp("!", e);
|
||||
}
|
||||
|
||||
public static JExpression complement(JExpression e) {
|
||||
return new UnaryOp("~", e);
|
||||
}
|
||||
|
||||
static private class TightUnaryOp extends UnaryOp {
|
||||
|
||||
TightUnaryOp(JExpression e, String op) {
|
||||
super(e, op);
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
if (opFirst)
|
||||
f.p(op).g(e);
|
||||
else
|
||||
f.g(e).p(op);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static JExpression incr(JExpression e) {
|
||||
return new TightUnaryOp(e, "++");
|
||||
}
|
||||
|
||||
public static JExpression decr(JExpression e) {
|
||||
return new TightUnaryOp(e, "--");
|
||||
}
|
||||
|
||||
|
||||
/* -- Binary operators -- */
|
||||
|
||||
static private class BinaryOp extends JExpressionImpl {
|
||||
|
||||
String op;
|
||||
JExpression left;
|
||||
JGenerable right;
|
||||
|
||||
BinaryOp(String op, JExpression left, JGenerable right) {
|
||||
this.left = left;
|
||||
this.op = op;
|
||||
this.right = right;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p('(').g(left).p(op).g(right).p(')');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static JExpression plus(JExpression left, JExpression right) {
|
||||
return new BinaryOp("+", left, right);
|
||||
}
|
||||
|
||||
public static JExpression minus(JExpression left, JExpression right) {
|
||||
return new BinaryOp("-", left, right);
|
||||
}
|
||||
|
||||
public static JExpression mul(JExpression left, JExpression right) {
|
||||
return new BinaryOp("*", left, right);
|
||||
}
|
||||
|
||||
public static JExpression div(JExpression left, JExpression right) {
|
||||
return new BinaryOp("/", left, right);
|
||||
}
|
||||
|
||||
public static JExpression mod(JExpression left, JExpression right) {
|
||||
return new BinaryOp("%", left, right);
|
||||
}
|
||||
|
||||
public static JExpression shl(JExpression left, JExpression right) {
|
||||
return new BinaryOp("<<", left, right);
|
||||
}
|
||||
|
||||
public static JExpression shr(JExpression left, JExpression right) {
|
||||
return new BinaryOp(">>", left, right);
|
||||
}
|
||||
|
||||
public static JExpression shrz(JExpression left, JExpression right) {
|
||||
return new BinaryOp(">>>", left, right);
|
||||
}
|
||||
|
||||
public static JExpression band(JExpression left, JExpression right) {
|
||||
return new BinaryOp("&", left, right);
|
||||
}
|
||||
|
||||
public static JExpression bor(JExpression left, JExpression right) {
|
||||
return new BinaryOp("|", left, right);
|
||||
}
|
||||
|
||||
public static JExpression cand(JExpression left, JExpression right) {
|
||||
if (left == JExpr.TRUE) return right;
|
||||
if (right == JExpr.TRUE) return left;
|
||||
if (left == JExpr.FALSE) return left; // JExpr.FALSE
|
||||
if (right == JExpr.FALSE) return right; // JExpr.FALSE
|
||||
return new BinaryOp("&&", left, right);
|
||||
}
|
||||
|
||||
public static JExpression cor(JExpression left, JExpression right) {
|
||||
if (left == JExpr.TRUE) return left; // JExpr.TRUE
|
||||
if (right == JExpr.TRUE) return right; // JExpr.FALSE
|
||||
if (left == JExpr.FALSE) return right;
|
||||
if (right == JExpr.FALSE) return left;
|
||||
return new BinaryOp("||", left, right);
|
||||
}
|
||||
|
||||
public static JExpression xor(JExpression left, JExpression right) {
|
||||
return new BinaryOp("^", left, right);
|
||||
}
|
||||
|
||||
public static JExpression lt(JExpression left, JExpression right) {
|
||||
return new BinaryOp("<", left, right);
|
||||
}
|
||||
|
||||
public static JExpression lte(JExpression left, JExpression right) {
|
||||
return new BinaryOp("<=", left, right);
|
||||
}
|
||||
|
||||
public static JExpression gt(JExpression left, JExpression right) {
|
||||
return new BinaryOp(">", left, right);
|
||||
}
|
||||
|
||||
public static JExpression gte(JExpression left, JExpression right) {
|
||||
return new BinaryOp(">=", left, right);
|
||||
}
|
||||
|
||||
public static JExpression eq(JExpression left, JExpression right) {
|
||||
return new BinaryOp("==", left, right);
|
||||
}
|
||||
|
||||
public static JExpression ne(JExpression left, JExpression right) {
|
||||
return new BinaryOp("!=", left, right);
|
||||
}
|
||||
|
||||
public static JExpression _instanceof(JExpression left, JType right) {
|
||||
return new BinaryOp("instanceof", left, right);
|
||||
}
|
||||
|
||||
/* -- Ternary operators -- */
|
||||
|
||||
static private class TernaryOp extends JExpressionImpl {
|
||||
|
||||
String op1;
|
||||
String op2;
|
||||
JExpression e1;
|
||||
JExpression e2;
|
||||
JExpression e3;
|
||||
|
||||
TernaryOp(String op1, String op2,
|
||||
JExpression e1, JExpression e2, JExpression e3) {
|
||||
this.e1 = e1;
|
||||
this.op1 = op1;
|
||||
this.e2 = e2;
|
||||
this.op2 = op2;
|
||||
this.e3 = e3;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p('(').g(e1).p(op1).g(e2).p(op2).g(e3).p(')');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static JExpression cond(JExpression cond,
|
||||
JExpression ifTrue, JExpression ifFalse) {
|
||||
return new TernaryOp("?", ":", cond, ifTrue, ifFalse);
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,474 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.io.BufferedOutputStream;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.TreeMap;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
|
||||
/**
|
||||
* A Java package.
|
||||
*/
|
||||
public final class JPackage implements JDeclaration, JGenerable, JClassContainer, JAnnotatable, Comparable<JPackage>, JDocCommentable {
|
||||
|
||||
/**
|
||||
* Name of the package.
|
||||
* May be the empty string for the root package.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
private final JCodeModel owner;
|
||||
|
||||
/**
|
||||
* List of classes contained within this package keyed by their name.
|
||||
*/
|
||||
private final Map<String,JDefinedClass> classes = new TreeMap<String,JDefinedClass>();
|
||||
|
||||
/**
|
||||
* List of resources files inside this package.
|
||||
*/
|
||||
private final Set<JResourceFile> resources = new HashSet<JResourceFile>();
|
||||
|
||||
/**
|
||||
* All {@link JClass}s in this package keyed the upper case class name.
|
||||
*
|
||||
* This field is non-null only on Windows, to detect
|
||||
* "Foo" and "foo" as a collision.
|
||||
*/
|
||||
private final Map<String,JDefinedClass> upperCaseClassMap;
|
||||
|
||||
/**
|
||||
* Lazily created list of package annotations.
|
||||
*/
|
||||
private List<JAnnotationUse> annotations = null;
|
||||
|
||||
/**
|
||||
* package javadoc.
|
||||
*/
|
||||
private JDocComment jdoc = null;
|
||||
|
||||
/**
|
||||
* JPackage constructor
|
||||
*
|
||||
* @param name
|
||||
* Name of package
|
||||
*
|
||||
* @param cw The code writer being used to create this package
|
||||
*
|
||||
* @throws IllegalArgumentException
|
||||
* If each part of the package name is not a valid identifier
|
||||
*/
|
||||
JPackage(String name, JCodeModel cw) {
|
||||
this.owner = cw;
|
||||
if (name.equals(".")) {
|
||||
String msg = "Package name . is not allowed";
|
||||
throw new IllegalArgumentException(msg);
|
||||
}
|
||||
|
||||
if(JCodeModel.isCaseSensitiveFileSystem)
|
||||
upperCaseClassMap = null;
|
||||
else
|
||||
upperCaseClassMap = new HashMap<String,JDefinedClass>();
|
||||
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
|
||||
public JClassContainer parentContainer() {
|
||||
return parent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the parent package, or null if this class is the root package.
|
||||
*/
|
||||
public JPackage parent() {
|
||||
if(name.length()==0) return null;
|
||||
|
||||
int idx = name.lastIndexOf('.');
|
||||
return owner._package(name.substring(0,idx));
|
||||
}
|
||||
|
||||
public boolean isClass() { return false; }
|
||||
public boolean isPackage() { return true; }
|
||||
public JPackage getPackage() { return this; }
|
||||
|
||||
/**
|
||||
* Add a class to this package.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this class declaration
|
||||
*
|
||||
* @param name
|
||||
* Name of class to be added to this package
|
||||
*
|
||||
* @return Newly generated class
|
||||
*
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
*/
|
||||
public JDefinedClass _class(int mods, String name) throws JClassAlreadyExistsException {
|
||||
return _class(mods,name,ClassType.CLASS);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* @deprecated
|
||||
*/
|
||||
public JDefinedClass _class( int mods, String name, boolean isInterface ) throws JClassAlreadyExistsException {
|
||||
return _class(mods,name, isInterface?ClassType.INTERFACE:ClassType.CLASS );
|
||||
}
|
||||
|
||||
public JDefinedClass _class( int mods, String name, ClassType classTypeVal ) throws JClassAlreadyExistsException {
|
||||
if(classes.containsKey(name))
|
||||
throw new JClassAlreadyExistsException(classes.get(name));
|
||||
else {
|
||||
// XXX problems caught in the NC constructor
|
||||
JDefinedClass c = new JDefinedClass(this, mods, name, classTypeVal);
|
||||
|
||||
if( upperCaseClassMap!=null ) {
|
||||
JDefinedClass dc = upperCaseClassMap.get(name.toUpperCase());
|
||||
if(dc!=null)
|
||||
throw new JClassAlreadyExistsException(dc);
|
||||
upperCaseClassMap.put(name.toUpperCase(),c);
|
||||
}
|
||||
classes.put(name,c);
|
||||
return c;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a public class to this package.
|
||||
*/
|
||||
public JDefinedClass _class(String name) throws JClassAlreadyExistsException {
|
||||
return _class( JMod.PUBLIC, name );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to the already created {@link JDefinedClass}.
|
||||
*
|
||||
* @return null
|
||||
* If the class is not yet created.
|
||||
*/
|
||||
public JDefinedClass _getClass(String name) {
|
||||
if(classes.containsKey(name))
|
||||
return classes.get(name);
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Order is based on the lexicological order of the package name.
|
||||
*/
|
||||
public int compareTo(JPackage that) {
|
||||
return this.name.compareTo(that.name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an interface to this package.
|
||||
*
|
||||
* @param mods
|
||||
* Modifiers for this interface declaration
|
||||
*
|
||||
* @param name
|
||||
* Name of interface to be added to this package
|
||||
*
|
||||
* @return Newly generated interface
|
||||
*/
|
||||
public JDefinedClass _interface(int mods, String name) throws JClassAlreadyExistsException {
|
||||
return _class(mods,name,ClassType.INTERFACE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a public interface to this package.
|
||||
*/
|
||||
public JDefinedClass _interface(String name) throws JClassAlreadyExistsException {
|
||||
return _interface(JMod.PUBLIC, name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an annotationType Declaration to this package
|
||||
* @param name
|
||||
* Name of the annotation Type declaration to be added to this package
|
||||
* @return
|
||||
* newly created Annotation Type Declaration
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
|
||||
*/
|
||||
public JDefinedClass _annotationTypeDeclaration(String name) throws JClassAlreadyExistsException {
|
||||
return _class (JMod.PUBLIC,name,ClassType.ANNOTATION_TYPE_DECL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a public enum to this package
|
||||
* @param name
|
||||
* Name of the enum to be added to this package
|
||||
* @return
|
||||
* newly created Enum
|
||||
* @exception JClassAlreadyExistsException
|
||||
* When the specified class/interface was already created.
|
||||
|
||||
*/
|
||||
public JDefinedClass _enum (String name) throws JClassAlreadyExistsException {
|
||||
return _class (JMod.PUBLIC,name,ClassType.ENUM);
|
||||
}
|
||||
/**
|
||||
* Adds a new resource file to this package.
|
||||
*/
|
||||
public JResourceFile addResourceFile(JResourceFile rsrc) {
|
||||
resources.add(rsrc);
|
||||
return rsrc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a resource of the given name exists.
|
||||
*/
|
||||
public boolean hasResourceFile(String name) {
|
||||
for (JResourceFile r : resources)
|
||||
if (r.name().equals(name))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Iterates all resource files in this package.
|
||||
*/
|
||||
public Iterator<JResourceFile> propertyFiles() {
|
||||
return resources.iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates, if necessary, and returns the package javadoc for this
|
||||
* JDefinedClass.
|
||||
*
|
||||
* @return JDocComment containing javadocs for this class
|
||||
*/
|
||||
public JDocComment javadoc() {
|
||||
if (jdoc == null)
|
||||
jdoc = new JDocComment(owner());
|
||||
return jdoc;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a class from this package.
|
||||
*/
|
||||
public void remove(JClass c) {
|
||||
if (c._package() != this)
|
||||
throw new IllegalArgumentException(
|
||||
"the specified class is not a member of this package," + " or it is a referenced class");
|
||||
|
||||
// note that c may not be a member of classes.
|
||||
// this happens when someone is trying to remove a non generated class
|
||||
classes.remove(c.name());
|
||||
if (upperCaseClassMap != null)
|
||||
upperCaseClassMap.remove(c.name().toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* Reference a class within this package.
|
||||
*/
|
||||
public JClass ref(String name) throws ClassNotFoundException {
|
||||
if (name.indexOf('.') >= 0)
|
||||
throw new IllegalArgumentException("JClass name contains '.': " + name);
|
||||
|
||||
String n = "";
|
||||
if (!isUnnamed())
|
||||
n = this.name + '.';
|
||||
n += name;
|
||||
|
||||
return owner.ref(Class.forName(n));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a reference to a sub package of this package.
|
||||
*/
|
||||
public JPackage subPackage( String pkg ) {
|
||||
if(isUnnamed()) return owner()._package(pkg);
|
||||
else return owner()._package(name+'.'+pkg);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an iterator that walks the top-level classes defined in this
|
||||
* package.
|
||||
*/
|
||||
public Iterator<JDefinedClass> classes() {
|
||||
return classes.values().iterator();
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given name is already defined as a class/interface
|
||||
*/
|
||||
public boolean isDefined(String classLocalName) {
|
||||
Iterator<JDefinedClass> itr = classes();
|
||||
while (itr.hasNext()) {
|
||||
if ((itr.next()).name().equals(classLocalName))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if this package is the root, unnamed package.
|
||||
*/
|
||||
public final boolean isUnnamed() { return name.length() == 0; }
|
||||
|
||||
/**
|
||||
* Get the name of this package
|
||||
*
|
||||
* @return
|
||||
* The name of this package, or the empty string if this is the
|
||||
* null package. For example, this method returns strings like
|
||||
* <code>"java.lang"</code>
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the code model root object being used to create this package.
|
||||
*/
|
||||
public final JCodeModel owner() { return owner; }
|
||||
|
||||
|
||||
public JAnnotationUse annotate(JClass clazz) {
|
||||
if(isUnnamed())
|
||||
throw new IllegalArgumentException("the root package cannot be annotated");
|
||||
if(annotations==null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
JAnnotationUse a = new JAnnotationUse(clazz);
|
||||
annotations.add(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
public JAnnotationUse annotate(Class<? extends Annotation> clazz) {
|
||||
return annotate(owner.ref(clazz));
|
||||
}
|
||||
|
||||
public <W extends JAnnotationWriter> W annotate2(Class<W> clazz) {
|
||||
return TypedAnnotationWriter.create(clazz,this);
|
||||
}
|
||||
|
||||
public Collection<JAnnotationUse> annotations() {
|
||||
if (annotations == null)
|
||||
annotations = new ArrayList<JAnnotationUse>();
|
||||
return Collections.unmodifiableList(annotations);
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert the package name to directory path equivalent
|
||||
*/
|
||||
File toPath(File dir) {
|
||||
if (name == null) return dir;
|
||||
return new File(dir, name.replace('.', File.separatorChar));
|
||||
}
|
||||
|
||||
public void declare(JFormatter f ) {
|
||||
if (name.length() != 0)
|
||||
f.p("package").p(name).p(';').nl();
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p(name);
|
||||
}
|
||||
|
||||
|
||||
void build( CodeWriter src, CodeWriter res ) throws IOException {
|
||||
|
||||
// write classes
|
||||
for (JDefinedClass c : classes.values()) {
|
||||
if (c.isHidden())
|
||||
continue; // don't generate this file
|
||||
|
||||
JFormatter f = createJavaSourceFileWriter(src, c.name());
|
||||
f.write(c);
|
||||
f.close();
|
||||
}
|
||||
|
||||
// write package annotations
|
||||
if(annotations!=null || jdoc!=null) {
|
||||
JFormatter f = createJavaSourceFileWriter(src,"package-info");
|
||||
|
||||
if (jdoc != null)
|
||||
f.g(jdoc);
|
||||
|
||||
// TODO: think about importing
|
||||
if (annotations != null){
|
||||
for (JAnnotationUse a : annotations)
|
||||
f.g(a).nl();
|
||||
}
|
||||
f.d(this);
|
||||
|
||||
f.close();
|
||||
}
|
||||
|
||||
// write resources
|
||||
for (JResourceFile rsrc : resources) {
|
||||
CodeWriter cw = rsrc.isResource() ? res : src;
|
||||
OutputStream os = new BufferedOutputStream(cw.openBinary(this, rsrc.name()));
|
||||
rsrc.build(os);
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
|
||||
/*package*/ int countArtifacts() {
|
||||
int r = 0;
|
||||
for (JDefinedClass c : classes.values()) {
|
||||
if (c.isHidden())
|
||||
continue; // don't generate this file
|
||||
r++;
|
||||
}
|
||||
|
||||
if(annotations!=null || jdoc!=null) {
|
||||
r++;
|
||||
}
|
||||
|
||||
r+= resources.size();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private JFormatter createJavaSourceFileWriter(CodeWriter src, String className) throws IOException {
|
||||
Writer bw = new BufferedWriter(src.openSource(this,className+".java"));
|
||||
return new JFormatter(new PrintWriter(bw));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Java built-in primitive types.
|
||||
*
|
||||
* Instances of this class can be obtained as constants of {@link JCodeModel},
|
||||
* such as {@link JCodeModel#BOOLEAN}.
|
||||
*/
|
||||
public final class JPrimitiveType extends JType {
|
||||
|
||||
private final String typeName;
|
||||
private final JCodeModel owner;
|
||||
/**
|
||||
* Corresponding wrapper class.
|
||||
* For example, this would be "java.lang.Short" for short.
|
||||
*/
|
||||
private final JClass wrapperClass;
|
||||
|
||||
JPrimitiveType(JCodeModel owner, String typeName, Class<?> wrapper ) {
|
||||
this.owner = owner;
|
||||
this.typeName = typeName;
|
||||
this.wrapperClass = owner.ref(wrapper);
|
||||
}
|
||||
|
||||
public JCodeModel owner() { return owner; }
|
||||
|
||||
public String fullName() {
|
||||
return typeName;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return fullName();
|
||||
}
|
||||
|
||||
public boolean isPrimitive() {
|
||||
return true;
|
||||
}
|
||||
|
||||
private JClass arrayClass;
|
||||
public JClass array() {
|
||||
if(arrayClass==null)
|
||||
arrayClass = new JArrayClass(owner,this);
|
||||
return arrayClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Obtains the wrapper class for this primitive type.
|
||||
* For example, this method returns a reference to java.lang.Integer
|
||||
* if this object represents int.
|
||||
*/
|
||||
public JClass boxify() {
|
||||
return wrapperClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated calling this method from {@link JPrimitiveType}
|
||||
* would be meaningless, since it's always guaranteed to
|
||||
* return <tt>this</tt>.
|
||||
*/
|
||||
public JType unboxify() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
* Use {@link #boxify()}.
|
||||
*/
|
||||
public JClass getWrapperClass() {
|
||||
return boxify();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wraps an expression of this type to the corresponding wrapper class.
|
||||
* For example, if this class represents "float", this method will return
|
||||
* the expression <code>new Float(x)</code> for the paramter x.
|
||||
*
|
||||
* REVISIT: it's not clear how this method works for VOID.
|
||||
*/
|
||||
public JExpression wrap( JExpression exp ) {
|
||||
return JExpr._new(boxify()).arg(exp);
|
||||
}
|
||||
|
||||
/**
|
||||
* Do the opposite of the wrap method.
|
||||
*
|
||||
* REVISIT: it's not clear how this method works for VOID.
|
||||
*/
|
||||
public JExpression unwrap( JExpression exp ) {
|
||||
// it just so happens that the unwrap method is always
|
||||
// things like "intValue" or "booleanValue".
|
||||
return exp.invoke(typeName+"Value");
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p(typeName);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Represents a resource file in the application-specific file format.
|
||||
*/
|
||||
public abstract class JResourceFile {
|
||||
|
||||
private final String name;
|
||||
|
||||
protected JResourceFile( String name ) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this property file
|
||||
*/
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this file should be generated into the directory
|
||||
* that the resource files go into.
|
||||
*
|
||||
* <p>
|
||||
* Returns false if this file should be generated into the directory
|
||||
* where other source files go.
|
||||
*/
|
||||
protected boolean isResource() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* called by JPackage to produce the file image.
|
||||
*/
|
||||
protected abstract void build( OutputStream os ) throws IOException;
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* A return statement
|
||||
*/
|
||||
class JReturn implements JStatement {
|
||||
|
||||
/**
|
||||
* JExpression to return; may be null.
|
||||
*/
|
||||
private JExpression expr;
|
||||
|
||||
/**
|
||||
* JReturn constructor
|
||||
*
|
||||
* @param expr
|
||||
* JExpression which evaluates to return value
|
||||
*/
|
||||
JReturn(JExpression expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.p("return ");
|
||||
if (expr != null) f.g(expr);
|
||||
f.p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* Common interface for code components that can generate
|
||||
* uses of themselves as statements.
|
||||
*/
|
||||
|
||||
public interface JStatement {
|
||||
|
||||
public void state(JFormatter f);
|
||||
|
||||
}
|
||||
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
/**
|
||||
* String literal.
|
||||
*
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public class JStringLiteral extends JExpressionImpl {
|
||||
|
||||
public final String str;
|
||||
|
||||
|
||||
JStringLiteral(String what) {
|
||||
this.str = what;
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.p(JExpr.quotify('"', str));
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Switch statement
|
||||
*/
|
||||
public final class JSwitch implements JStatement {
|
||||
|
||||
/**
|
||||
* Test part of switch statement.
|
||||
*/
|
||||
private JExpression test;
|
||||
|
||||
/**
|
||||
* vector of JCases.
|
||||
*/
|
||||
private List<JCase> cases = new ArrayList<JCase>();
|
||||
|
||||
/**
|
||||
* a single default case
|
||||
*/
|
||||
private JCase defaultCase = null;
|
||||
|
||||
/**
|
||||
* Construct a While statment
|
||||
*/
|
||||
JSwitch(JExpression test) {
|
||||
this.test = test;
|
||||
}
|
||||
|
||||
public JExpression test() { return test; }
|
||||
|
||||
public Iterator<JCase> cases() { return cases.iterator(); }
|
||||
|
||||
public JCase _case( JExpression label ) {
|
||||
JCase c = new JCase( label );
|
||||
cases.add(c);
|
||||
return c;
|
||||
}
|
||||
|
||||
public JCase _default() {
|
||||
// what if (default != null) ???
|
||||
|
||||
// default cases statements don't have a label
|
||||
defaultCase = new JCase(null, true);
|
||||
return defaultCase;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
if (JOp.hasTopOp(test)) {
|
||||
f.p("switch ").g(test).p(" {").nl();
|
||||
} else {
|
||||
f.p("switch (").g(test).p(')').p(" {").nl();
|
||||
}
|
||||
for( JCase c : cases )
|
||||
f.s(c);
|
||||
if( defaultCase != null )
|
||||
f.s( defaultCase );
|
||||
f.p('}').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* JThrow statement
|
||||
*/
|
||||
|
||||
class JThrow implements JStatement {
|
||||
|
||||
/**
|
||||
* JExpression to throw
|
||||
*/
|
||||
private JExpression expr;
|
||||
|
||||
/**
|
||||
* JThrow constructor
|
||||
*
|
||||
* @param expr
|
||||
* JExpression which evaluates to JThrow value
|
||||
*/
|
||||
JThrow(JExpression expr) {
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.p("throw");
|
||||
f.g(expr);
|
||||
f.p(';').nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
/**
|
||||
* Try statement with Catch and/or Finally clause
|
||||
*/
|
||||
|
||||
public class JTryBlock implements JStatement {
|
||||
|
||||
private JBlock body = new JBlock();
|
||||
private List<JCatchBlock> catches = new ArrayList<JCatchBlock>();
|
||||
private JBlock _finally = null;
|
||||
|
||||
JTryBlock() {
|
||||
}
|
||||
|
||||
public JBlock body() {
|
||||
return body;
|
||||
}
|
||||
|
||||
public JCatchBlock _catch(JClass exception) {
|
||||
JCatchBlock cb = new JCatchBlock(exception);
|
||||
catches.add(cb);
|
||||
return cb;
|
||||
}
|
||||
|
||||
public JBlock _finally() {
|
||||
if (_finally == null) _finally = new JBlock();
|
||||
return _finally;
|
||||
}
|
||||
|
||||
public void state(JFormatter f) {
|
||||
f.p("try").g(body);
|
||||
for (JCatchBlock cb : catches)
|
||||
f.g(cb);
|
||||
if (_finally != null)
|
||||
f.p("finally").g(_finally);
|
||||
f.nl();
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1,182 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
|
||||
/**
|
||||
* A representation of a type in codeModel.
|
||||
*
|
||||
* A type is always either primitive ({@link JPrimitiveType}) or
|
||||
* a reference type ({@link JClass}).
|
||||
*/
|
||||
public abstract class JType implements JGenerable, Comparable<JType> {
|
||||
|
||||
/**
|
||||
* Obtains a reference to the primitive type object from a type name.
|
||||
*/
|
||||
public static JPrimitiveType parse(JCodeModel codeModel, String typeName) {
|
||||
if (typeName.equals("void"))
|
||||
return codeModel.VOID;
|
||||
else if (typeName.equals("boolean"))
|
||||
return codeModel.BOOLEAN;
|
||||
else if (typeName.equals("byte"))
|
||||
return codeModel.BYTE;
|
||||
else if (typeName.equals("short"))
|
||||
return codeModel.SHORT;
|
||||
else if (typeName.equals("char"))
|
||||
return codeModel.CHAR;
|
||||
else if (typeName.equals("int"))
|
||||
return codeModel.INT;
|
||||
else if (typeName.equals("float"))
|
||||
return codeModel.FLOAT;
|
||||
else if (typeName.equals("long"))
|
||||
return codeModel.LONG;
|
||||
else if (typeName.equals("double"))
|
||||
return codeModel.DOUBLE;
|
||||
else
|
||||
throw new IllegalArgumentException("Not a primitive type: " + typeName);
|
||||
}
|
||||
|
||||
/** Gets the owner code model object. */
|
||||
public abstract JCodeModel owner();
|
||||
|
||||
/**
|
||||
* Gets the full name of the type.
|
||||
*
|
||||
* See http://java.sun.com/docs/books/jls/second_edition/html/names.doc.html#25430 for the details.
|
||||
*
|
||||
* @return
|
||||
* Strings like "int", "java.lang.String",
|
||||
* "java.io.File[]". Never null.
|
||||
*/
|
||||
public abstract String fullName();
|
||||
|
||||
/**
|
||||
* Gets the binary name of the type.
|
||||
*
|
||||
* See http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.html#44909
|
||||
*
|
||||
* @return
|
||||
* Name like "Foo$Bar", "int", "java.lang.String", "java.io.File[]". Never null.
|
||||
*/
|
||||
public String binaryName() {
|
||||
return fullName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the name of this type.
|
||||
*
|
||||
* @return
|
||||
* Names like "int", "void", "BigInteger".
|
||||
*/
|
||||
public abstract String name();
|
||||
|
||||
/**
|
||||
* Create an array type of this type.
|
||||
*
|
||||
* This method is undefined for primitive void type, which
|
||||
* doesn't have any corresponding array representation.
|
||||
*
|
||||
* @return A {@link JClass} representing the array type
|
||||
* whose element type is this type
|
||||
*/
|
||||
public abstract JClass array();
|
||||
|
||||
/** Tell whether or not this is an array type. */
|
||||
public boolean isArray() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Tell whether or not this is a built-in primitive type, such as int or void. */
|
||||
public boolean isPrimitive() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* If this class is a primitive type, return the boxed class. Otherwise return <tt>this</tt>.
|
||||
*
|
||||
* <p>
|
||||
* For example, for "int", this method returns "java.lang.Integer".
|
||||
*/
|
||||
public abstract JClass boxify();
|
||||
|
||||
/**
|
||||
* If this class is a wrapper type for a primitive, return the primitive type.
|
||||
* Otherwise return <tt>this</tt>.
|
||||
*
|
||||
* <p>
|
||||
* For example, for "java.lang.Integer", this method returns "int".
|
||||
*/
|
||||
public abstract JType unboxify();
|
||||
|
||||
/**
|
||||
* Returns the erasure of this type.
|
||||
*/
|
||||
public JType erasure() {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this is a referenced type.
|
||||
*/
|
||||
public final boolean isReference() {
|
||||
return !isPrimitive();
|
||||
}
|
||||
|
||||
/**
|
||||
* If this is an array, returns the component type of the array.
|
||||
* (T of T[])
|
||||
*/
|
||||
public JType elementType() {
|
||||
throw new IllegalArgumentException("Not an array type");
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
return this.getClass().getName()
|
||||
+ '(' + fullName() + ')';
|
||||
}
|
||||
|
||||
/**
|
||||
* Compare two JTypes by FQCN, giving sorting precedence to types
|
||||
* that belong to packages java and javax over all others.
|
||||
*
|
||||
* This method is used to sort generated import statments in a
|
||||
* conventional way for readability.
|
||||
*/
|
||||
public int compareTo(JType o) {
|
||||
final String rhs = o.fullName();
|
||||
boolean p = fullName().startsWith("java");
|
||||
boolean q = rhs.startsWith("java");
|
||||
|
||||
if( p && !q ) {
|
||||
return -1;
|
||||
} else if( !p && q ) {
|
||||
return 1;
|
||||
} else {
|
||||
return fullName().compareTo(rhs);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,121 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Type variable used to declare generics.
|
||||
*
|
||||
* @see JGenerifiable
|
||||
* @author
|
||||
* Kohsuke Kawaguchi (kohsuke.kawaguchi@sun.com)
|
||||
*/
|
||||
public final class JTypeVar extends JClass implements JDeclaration {
|
||||
|
||||
private final String name;
|
||||
|
||||
private JClass bound;
|
||||
|
||||
JTypeVar(JCodeModel owner, String _name) {
|
||||
super(owner);
|
||||
this.name = _name;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public JPackage _package() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a bound to this variable.
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public JTypeVar bound( JClass c ) {
|
||||
if(bound!=null)
|
||||
throw new IllegalArgumentException("type variable has an existing class bound "+bound);
|
||||
bound = c;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class bound of this variable.
|
||||
*
|
||||
* <p>
|
||||
* If no bound is given, this method returns {@link Object}.
|
||||
*/
|
||||
public JClass _extends() {
|
||||
if(bound!=null)
|
||||
return bound;
|
||||
else
|
||||
return owner().ref(Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the interface bounds of this variable.
|
||||
*/
|
||||
public Iterator<JClass> _implements() {
|
||||
return bound._implements();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints out the declaration of the variable.
|
||||
*/
|
||||
public void declare(JFormatter f) {
|
||||
f.id(name);
|
||||
if(bound!=null)
|
||||
f.p("extends").g(bound);
|
||||
}
|
||||
|
||||
|
||||
protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
|
||||
for(int i=0;i<variables.length;i++)
|
||||
if(variables[i]==this)
|
||||
return bindings.get(i);
|
||||
return this;
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
f.id(name);
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 1997, 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 com.sun.codemodel.internal;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Represents a wildcard type like "? extends Foo".
|
||||
*
|
||||
* <p>
|
||||
* Instances of this class can be obtained from {@link JClass#wildcard()}
|
||||
*
|
||||
* TODO: extend this to cover "? super Integer".
|
||||
*
|
||||
* <p>
|
||||
* Our modeling of types are starting to look really ugly.
|
||||
* ideally it should have been done somewhat like APT,
|
||||
* but it's too late now.
|
||||
*
|
||||
* @author Kohsuke Kawaguchi
|
||||
*/
|
||||
final class JTypeWildcard extends JClass {
|
||||
|
||||
private final JClass bound;
|
||||
|
||||
JTypeWildcard(JClass bound) {
|
||||
super(bound.owner());
|
||||
this.bound = bound;
|
||||
}
|
||||
|
||||
public String name() {
|
||||
return "? extends "+bound.name();
|
||||
}
|
||||
|
||||
public String fullName() {
|
||||
return "? extends "+bound.fullName();
|
||||
}
|
||||
|
||||
public JPackage _package() {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the class bound of this variable.
|
||||
*
|
||||
* <p>
|
||||
* If no bound is given, this method returns {@link Object}.
|
||||
*/
|
||||
public JClass _extends() {
|
||||
if(bound!=null)
|
||||
return bound;
|
||||
else
|
||||
return owner().ref(Object.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the interface bounds of this variable.
|
||||
*/
|
||||
public Iterator<JClass> _implements() {
|
||||
return bound._implements();
|
||||
}
|
||||
|
||||
public boolean isInterface() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean isAbstract() {
|
||||
return false;
|
||||
}
|
||||
|
||||
protected JClass substituteParams(JTypeVar[] variables, List<JClass> bindings) {
|
||||
JClass nb = bound.substituteParams(variables,bindings);
|
||||
if(nb==bound)
|
||||
return this;
|
||||
else
|
||||
return new JTypeWildcard(nb);
|
||||
}
|
||||
|
||||
public void generate(JFormatter f) {
|
||||
if(bound._extends()==null)
|
||||
f.p("?"); // instead of "? extends Object"
|
||||
else
|
||||
f.p("? extends").g(bound);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user