main project

This commit is contained in:
林轩 2015-12-19 17:34:31 +08:00
parent a3ec6e7ac8
commit 728acc5d4e
863 changed files with 38776 additions and 0 deletions

28
.gitignore vendored Normal file
View File

@ -0,0 +1,28 @@
.idea
logs
out
*.iml
.project
.classpath
.settings
*/target
*/.settings
*/.classpath
*/.project
*/*.iml
*/*.ipr
*/*.iws
*/build
.DS_Store
*/logs
*/scripts/*.pyc
*/scripts/*.*~
src/main/webapp/WEB-INF/classes
src/main/webapp/META-INF/
src/test/resources/conf_path.properties
target
.module-cache
.sass-cache
$*
src/main/webapp/static/css/**/*.css*
*/*.py

12
pom.xml Normal file
View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lindaxuan</groupId>
<artifactId>thinkinginjava</artifactId>
<version>1.0-SNAPSHOT</version>
</project>

66
src/main/java/Copyright.txt Executable file
View File

@ -0,0 +1,66 @@
This computer source code is Copyright (c)2006 MindView, Inc.
All Rights Reserved.
Permission to use, copy, modify, and distribute this
computer source code (Source Code) and its documentation
without fee and without a written agreement for the
purposes set forth below is hereby granted, provided that
the above copyright notice, this paragraph and the
following five numbered paragraphs appear in all copies.
1. Permission is granted to compile the Source Code and to
include the compiled code, in executable format only, in
personal and commercial software programs.
2. Permission is granted to use the Source Code without
modification in classroom situations, including in
presentation materials, provided that the book "Thinking in
Java" is cited as the origin.
3. Permission to incorporate the Source Code into printed
media may be obtained by contacting:
MindView, Inc. 5343 Valle Vista La Mesa, California 91941
Wayne@MindView.net
4. The Source Code and documentation are copyrighted by
MindView, Inc. The Source code is provided without express
or implied warranty of any kind, including any implied
warranty of merchantability, fitness for a particular
purpose or non-infringement. MindView, Inc. does not
warrant that the operation of any program that includes the Source Code will be uninterrupted or error-free. MindView,
Inc. makes no representation about the suitability of the
Source Code or of any software that includes the Source
Code for any purpose. The entire risk as to the quality
and performance of any program that includes the Source
Code is with the user of the Source Code. The user
understands that the Source Code was developed for research and instructional purposes and is advised not to rely
exclusively for any reason on the Source Code or any
program that includes the Source Code. Should the Source
Code or any resulting software prove defective, the user
assumes the cost of all necessary servicing, repair, or
correction.
5. IN NO EVENT SHALL MINDVIEW, INC., OR ITS PUBLISHER BE
LIABLE TO ANY PARTY UNDER ANY LEGAL THEORY FOR DIRECT,
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES,
INCLUDING LOST PROFITS, BUSINESS INTERRUPTION, LOSS OF
BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS, OR FOR
PERSONAL INJURIES, ARISING OUT OF THE USE OF THIS SOURCE
CODE AND ITS DOCUMENTATION, OR ARISING OUT OF THE INABILITY TO USE ANY RESULTING PROGRAM, EVEN IF MINDVIEW, INC., OR
ITS PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE. MINDVIEW, INC. SPECIFICALLY DISCLAIMS ANY
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE SOURCE CODE AND DOCUMENTATION PROVIDED
HEREUNDER IS ON AN "AS IS" BASIS, WITHOUT ANY ACCOMPANYING
SERVICES FROM MINDVIEW, INC., AND MINDVIEW, INC. HAS NO
OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
ENHANCEMENTS, OR MODIFICATIONS.
Please note that MindView, Inc. maintains a Web site which
is the sole distribution point for electronic copies of the Source Code, http://www.MindView.net (and official mirror
sites), where it is freely available under the terms stated above.
If you think you've found an error in the Source Code,
please submit a correction using the feedback system that you will find at http://www.MindView.net.

25
src/main/java/DEclipse.py Executable file
View File

@ -0,0 +1,25 @@
#!/usr/bin/python
"""
DEclipse.py by Bruce Eckel, for Thinking in Java 4e
Undoes the effect of Eclipse.py, so that Ant can be used
again to build the code tree.
You must have Python 2.3 installed to run this program. See www.python.org.
"""
import os
for path, dirs, files in os.walk('.'):
for file in files:
if file.endswith(".java"):
filepath = path + os.sep + file
code = open(filepath).readlines()
found = False
for n, line in enumerate(code):
if line.find(" /* Added by Eclipse.py */") != -1:
del code[n]
open(filepath, 'w').writelines(code)
print "Project ready to be built with Ant."

115
src/main/java/Eclipse.py Executable file
View File

@ -0,0 +1,115 @@
#!/usr/bin/python
"""
Eclipse.py by Bruce Eckel, for Thinking in Java 4e
Modify or insert package statments so that Eclipse is happy with the code tree.
Run this with no arguments from the root of the code tree.
The Ant build will not work once you run this program!
You may also want to modify the dotproject and dotclasspath text below.
You must have Python 2.3 installed to run this program. See www.python.org.
"""
import os
os.remove("reusing/Lisa.java");
for path, dirs, files in os.walk('.'):
for file in files:
if file.endswith(".java"):
filepath = path + os.sep + file
firstLine = open(filepath).readline().strip()
tagPath = firstLine.split()[1]
tagPath = ".".join(tagPath.split('/')[:-1])
packageStatement = "package " + tagPath + ";"
code = open(filepath).readlines()
found = False
for line in code:
if line.startswith("package "):
found = True
if not found:
code.insert(1, packageStatement + " /* Added by Eclipse.py */\n")
open(filepath, 'w').writelines(code)
here = os.path.abspath('.').replace("\\", "/")
if here.startswith("/cygdrive/"): # If using cygwin
here = here.replace("/cygdrive/", "", 1)
here = here[0] + ":" + here[1:]
print "here", here
open(".classpath", 'w').write(\
"""<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry excluding="polymorphism/|holding/|flow/|exceptions/|concurrency/|typeinfo/|innerclasses/|arrays/|interfaces/|reusing/|initialization/|cloning/|io/|containers/|generics/|xml/|hiding/|io/xfiles/|passing/|gui/|annotations/|enumerated/|discovering/|object/|strings/|swt/" kind="src" path=""/>
<classpathentry kind="src" path="annotations"/>
<classpathentry kind="src" path="arrays"/>
<classpathentry kind="src" path="cloning"/>
<classpathentry kind="src" path="concurrency"/>
<classpathentry kind="src" path="containers"/>
<classpathentry kind="src" path="discovering"/>
<classpathentry kind="src" path="enumerated"/>
<classpathentry kind="src" path="exceptions"/>
<classpathentry kind="src" path="flow"/>
<classpathentry kind="src" path="generics"/>
<classpathentry kind="src" path="gui"/>
<classpathentry kind="src" path="hiding"/>
<classpathentry kind="src" path="holding"/>
<classpathentry kind="src" path="initialization"/>
<classpathentry kind="src" path="innerclasses"/>
<classpathentry kind="src" path="interfaces"/>
<classpathentry excluding="xfiles/" kind="src" path="io"/>
<classpathentry kind="src" path="io/xfiles"/>
<classpathentry kind="src" path="object"/>
<classpathentry kind="src" path="passing"/>
<classpathentry kind="src" path="polymorphism"/>
<classpathentry kind="src" path="reusing"/>
<classpathentry kind="src" path="strings"/>
<classpathentry kind="src" path="swt"/>
<classpathentry kind="src" path="typeinfo"/>
<classpathentry kind="src" path="xml"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/jre1.5.0_01"/>
<classpathentry kind="output" path="bin"/>
</classpath>
""") # % (here, here))
open(".project", 'w').write(\
"""<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>TIJ4</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
""")
if not os.path.exists(".settings"):
os.mkdir(".settings")
os.chdir(".settings")
open("org.eclipse.jdt.core.prefs", 'w').write(\
"""#Fri Jan 14 11:03:37 MST 2005
org.eclipse.jdt.core.compiler.debug.localVariable=generate
org.eclipse.jdt.core.compiler.compliance=1.5
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.source=1.5
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
""")
print """Project ready to be opened with Eclipse (see www.Eclipse.org)
Use DEclipse.py if you want to go back to building with Ant."""

View File

@ -0,0 +1,53 @@
"""FindBugsExcluder.py
Creates a filter file from the xml and text output of FindBugs
To prepare, you must run
findbugs -textui . > findbugs.txt
findbugs -textui -xml . > findbugs.xml
Once you've run this program you can then run
findbugs -textui -exclude FindBugsFilter-auto.xml .
To exclude the bugs that have been discovered.
The program includes the suggested changes with each exclusion,
so you can go through FindBugsFilter-auto.xml and decide
to fix things and remove their "Match" nodes.
"""
from xml.dom.minidom import parse
import xml.dom
import os, sys, re, pprint
xml_buglist = 'findbugs.xml' #'D:\\aaa-TIJ4\\code\\findbugs.xml'
text_buglist = 'findbugs.txt' # 'D:\\aaa-TIJ4\\code\\findbugs.txt'
findbugs_filter = 'FindBugsFilter-auto.xml' # 'D:\\aaa-TIJ4\\code\\FindBugsFilter-auto.xml'
def main():
textbugs = [bug.split(':', 1) for bug in file(text_buglist)
if bug.startswith("M ") or bug.startswith("H ")]
textbugs = [(bug[0].split()[2], bug[1].strip()) for bug in textbugs]
dom1 = parse(xml_buglist)
dom2 = xml.dom.getDOMImplementation().createDocument(
None, "FindBugsFilter", None)
bugsDone = []
for bugNode in [bug for bug in dom1.firstChild.childNodes
if bug.nodeName == "BugInstance"]:
for child in bugNode.childNodes:
if child.nodeName == "Class":
classname = child.attributes.item(0).value
bugtype = bugNode.attributes.item(2).value
if (bugtype, classname) in bugsDone:
continue
else:
bugsDone.append((bugtype, classname))
match = dom2.createElement("Match")
match.setAttribute("class", classname)
bugCode = dom2.createElement("BugCode")
bugCode.setAttribute("name", bugtype)
match.appendChild(bugCode)
for textbug in textbugs:
if textbug[0] == bugtype and classname in textbug[1]:
match.appendChild(dom2.createComment(textbug[1]))
dom2.documentElement.appendChild(match)
break # out of inner for loop
file(findbugs_filter, 'w').write(dom2.toprettyxml(' ', '\n'))
if __name__ == "__main__": main()

547
src/main/java/FindBugsFilter.xml Executable file
View File

@ -0,0 +1,547 @@
<?xml version="1.0" ?>
<FindBugsFilter>
<Match class="AUnitExample2">
<BugCode name="OS"/>
<!--AUnitExample2.exceptionExample() may fail to close stream At AUnitExample2.java:[line 21]-->
</Match>
<Match class="BangBean2">
<BugCode name="IS2"/>
<!--Inconsistent synchronization of BangBean2.fontSize; locked 66% of time Unsynchronized access at BangBean2.java:[line 74]-->
<!--Inconsistent synchronization of BangBean2.tColor; locked 66% of time Unsynchronized access at BangBean2.java:[line 73]-->
</Match>
<Match class="Beetle">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Beetle.main(String[]) At Beetle.java:[line 30]-->
</Match>
<Match class="BerryBrokers$1">
<BugCode name="DE"/>
<!--BerryBrokers$1.<clinit>() might ignore java.lang.NoSuchFieldError At Thwonk.java:[line 90]-->
</Match>
<Match class="BigEgg$Yolk">
<BugCode name="SIC"/>
<!--Should BigEgg$Yolk be a _static_ inner class?-->
</Match>
<Match class="Bird">
<BugCode name="UuF"/>
<!--Unused field: Bird.i-->
</Match>
<Match class="BlankFinal">
<BugCode name="SS"/>
<!--Unread field: BlankFinal.i; should this field be static?-->
</Match>
<Match class="Blip2">
<BugCode name="Se"/>
<!--Blip2 is Externalizable but doesn't define a void constructor-->
</Match>
<Match class="ButtonGroups">
<BugCode name="REC"/>
<!--Method ButtonGroups.makeBPanel(Class,String[]) catches Exception, but Exception is not thrown in the try block and RuntimeException is not explicitly caught At ButtonGroups.java:[line 29]-->
</Match>
<Match class="Card">
<BugCode name="UrF"/>
<!--Unread field: Card.t1-->
<!--Unread field: Card.t2-->
<!--Unread field: Card.t3-->
</Match>
<Match class="Cartoon">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Cartoon.main(String[]) At Cartoon.java:[line 16]-->
</Match>
<Match class="Casting">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Casting.main(String[]) At Casting.java:[line 11]-->
<!--Dead store to local variable in method ClassCasting.main(String[]) At ClassCasting.java:[line 7]-->
</Match>
<Match class="CheckCloneable">
<BugCode name="DLS"/>
<!--Dead store to local variable in method CheckCloneable.main(String[]) At CheckCloneable.java:[line 81]-->
</Match>
<Match class="Chef">
<BugCode name="UW"/>
<!--Unconditional wait in Chef.run() At Restaurant.java:[line 45]-->
<!--(It's not clear to me why this is a problem. I think it's a false positive)-->
</Match>
<Match class="Chess">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Chess.main(String[]) At Chess.java:[line 24]-->
</Match>
<Match class="ChocolateChip">
<BugCode name="DLS"/>
<!--Dead store to local variable in method ChocolateChip.main(String[]) At ChocolateChip.java:[line 10]-->
</Match>
<Match class="ClassAsFactory">
<BugCode name="UrF"/>
<!--Unread field: ClassAsFactory.x-->
</Match>
<Match class="ClassCasting">
<BugCode name="DLS"/>
<!--Dead store to local variable in method ClassCasting.main(String[]) At ClassCasting.java:[line 7]-->
</Match>
<Match class="CloseResource">
<BugCode name="DLS"/>
<!--Dead store to local variable in method CloseResource.main(String[]) At CloseResource.java:[line 12]-->
</Match>
<Match class="CovariantGenerics">
<BugCode name="DLS"/>
<!--Dead store to local variable in method CovariantGenerics.main(String[]) At CovariantGenerics.java:[line 11]-->
</Match>
<Match class="Cupboard">
<BugCode name="UrF"/>
<!--Unread field: Cupboard.b3-->
</Match>
<Match class="DefaultConstructor">
<BugCode name="DLS"/>
<!--Dead store to local variable in method DefaultConstructor.main(String[]) At DefaultConstructor.java:[line 9]-->
</Match>
<Match class="Dinner">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Dinner.main(String[]) At Dinner.java:[line 7]-->
</Match>
<Match class="Dinosaur">
<BugCode name="UrF"/>
<!--Unread field: Dinosaur.i-->
<!--Unread field: Dinosaur.x-->
</Match>
<Match class="Egg">
<BugCode name="UrF"/>
<!--Unread field: Egg.y-->
</Match>
<Match class="Egg$Yolk">
<BugCode name="SIC"/>
<!--Should BigEgg$Yolk be a _static_ inner class?-->
<!--Should Egg$Yolk be a _static_ inner class?-->
</Match>
<!-------- Checked to here ------------------------------------------------->
<Match class="Equivalence">
<BugCode name="RC"/>
<!--Suspicious comparison of java.lang.Integer references in Equivalence.main(String[]) At Equivalence.java:[line 7]-->
</Match>
<Match class="Faces">
<BugCode name="UI"/>
<!--Usage of GetResource in Faces.<init>() may be unsafe if class is extended At Faces.java:[line 13]-->
</Match>
<Match class="FillTest">
<BugCode name="DLS"/>
<!--Dead store to local variable in method FillTest.main(String[]) At Fill.java:[line 40]-->
</Match>
<Match class="FinalArguments">
<BugCode name="IP"/>
<!--A parameter to FinalArguments.without(Gizmo) is dead upon entry but overwritten At FinalArguments.java:[line 13]-->
</Match>
<Match class="FinalData">
<BugCode name="SS"/>
<!--Unread field: FinalData.valueOne; should this field be static?-->
</Match>
<Match class="FinalData">
<BugCode name="UrF"/>
<!--Unread field: FinalData.v1-->
</Match>
<Match class="Foo2">
<BugCode name="UrF"/>
<!--Unread field: Foo2.x-->
</Match>
<Match class="GreenhouseControls">
<BugCode name="UrF"/>
<!--Unread field: GreenhouseControls.light-->
<!--Unread field: GreenhouseControls.thermostat-->
<!--Unread field: GreenhouseControls.water-->
</Match>
<Match class="Holder">
<BugCode name="EC"/>
<!--Call to equals() comparing different types in Holder.main(String[]) At Holder.java:[line 28]-->
<!--Call to equals() comparing different types in WildcardRules.f(Holder) At WildcardRules.java:[line 11]-->
<!--Call to equals() comparing different types in WildcardRules.g(Holder) At WildcardRules.java:[line 17]-->
</Match>
<Match class="Holder">
<BugCode name="HE"/>
<!--Holder defines equals and uses Object.hashCode()-->
</Match>
<Match class="IInterface$Inner">
<BugCode name="UuF"/>
<!--Unused field: IInterface$Inner.i-->
<!--Unused field: IInterface$Inner.k-->
</Match>
<Match class="InheritInner">
<BugCode name="DLS"/>
<!--Dead store to local variable in method InheritInner.main(String[]) At InheritInner.java:[line 15]-->
</Match>
<Match class="InitialValues">
<BugCode name="UwF"/>
<!--Unwritten field: InitialValues.b-->
<!--Unwritten field: InitialValues.c-->
<!--Unwritten field: InitialValues.d-->
<!--Unwritten field: InitialValues.f-->
<!--Unwritten field: InitialValues.i-->
<!--Unwritten field: InitialValues.l-->
<!--Unwritten field: InitialValues.s-->
<!--Unwritten field: InitialValues.t-->
</Match>
<Match class="InnerRunnable1">
<BugCode name="UrF"/>
<!--Unread field: InnerRunnable1.inner-->
</Match>
<Match class="InnerThread1">
<BugCode name="UrF"/>
<!--Unread field: InnerThread1.inner-->
</Match>
<Match class="Insect">
<BugCode name="UR"/>
<!--Uninitialized read of Insect.j in Insect.<init>() At Beetle.java:[line 9]-->
</Match>
<Match class="InstantiateGenericType">
<BugCode name="DLS"/>
<!--Dead store to local variable in method InstantiateGenericType.main(String[]) At InstantiateGenericType.java:[line 19]-->
<!--Dead store to local variable in method InstantiateGenericType.main(String[]) At InstantiateGenericType.java:[line 23]-->
</Match>
<Match class="JUnitDemo">
<BugCode name="IJU"/>
<!--TestCase JUnitDemo implements setUp but doesn't call super.setUp() At JUnitDemo.java:[lines 30-31]-->
<!--TestCase JUnitDemo implements tearDown but doesn't call super.tearDown() At JUnitDemo.java:[lines 36-37]-->
</Match>
<Match class="Joining">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Joining.main(String[]) At Joining.java:[line 47]-->
<!--Dead store to local variable in method Joining.main(String[]) At Joining.java:[line 48]-->
</Match>
<Match class="LibTest">
<BugCode name="DLS"/>
<!--Dead store to local variable in method LibTest.main(String[]) At LibTest.java:[line 7]-->
<!--Dead store to local variable in method LibTest.main(String[]) At LibTest.java:[line 8]-->
</Match>
<Match class="Literals">
<BugCode name="UrF"/>
<!--Unread field: Literals.b-->
<!--Unread field: Literals.c-->
<!--Unread field: Literals.d1-->
<!--Unread field: Literals.d2-->
<!--Unread field: Literals.d3-->
<!--Unread field: Literals.f1-->
<!--Unread field: Literals.f2-->
<!--Unread field: Literals.f3-->
<!--Unread field: Literals.f4-->
<!--Unread field: Literals.f5-->
<!--Unread field: Literals.i1-->
<!--Unread field: Literals.i2-->
<!--Unread field: Literals.i3-->
<!--Unread field: Literals.n1-->
<!--Unread field: Literals.n2-->
<!--Unread field: Literals.n3-->
<!--Unread field: Literals.s-->
</Match>
<Match class="LockingMappedFiles">
<BugCode name="RV"/>
<!--LockingMappedFiles.main(String[]) ignores return value of LockingMappedFiles$LockAndModify.<init>(java.nio.ByteBuffer,int,int) At LockingMappedFiles.java:[line 19]-->
<!--LockingMappedFiles.main(String[]) ignores return value of LockingMappedFiles$LockAndModify.<init>(java.nio.ByteBuffer,int,int) At LockingMappedFiles.java:[line 20]-->
</Match>
<Match class="Lunch">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Lunch.test() At Lunch.java:[line 30]-->
</Match>
<Match class="MPair">
<BugCode name="HE"/>
<!--MPair defines equals and uses Object.hashCode()-->
</Match>
<Match class="MappedIO$4">
<BugCode name="OS"/>
<!--MappedIO$4.test() may fail to close stream At MappedIO.java:[line 61]-->
</Match>
<Match class="Mugs">
<BugCode name="UrF"/>
<!--Unread field: Mugs.c1-->
<!--Unread field: Mugs.c2-->
</Match>
<Match class="NIOInterruption">
<BugCode name="DLS"/>
<!--Dead store to local variable in method NIOInterruption.main(String[]) At NIOInterruption.java:[line 31]-->
</Match>
<Match class="Parcel1">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Parcel1.ship(String) At Parcel1.java:[line 19]-->
<!--Dead store to local variable in method Parcel11.main(String[]) At Parcel11.java:[line 18]-->
<!--Dead store to local variable in method Parcel11.main(String[]) At Parcel11.java:[line 19]-->
</Match>
<Match class="Parcel1$Contents">
<BugCode name="SIC"/>
<!--Should Parcel1$Contents be a _static_ inner class?-->
</Match>
<Match class="Parcel1$Destination">
<BugCode name="SIC"/>
<!--Should Parcel1$Destination be a _static_ inner class?-->
</Match>
<Match class="Parcel11">
<BugCode name="DLS"/>
<!--Dead store to local variable in method Parcel11.main(String[]) At Parcel11.java:[line 18]-->
<!--Dead store to local variable in method Parcel11.main(String[]) At Parcel11.java:[line 19]-->
</Match>
<Match class="Parcel11$Contents">
<BugCode name="SIC"/>
<!--Should Parcel11$Contents be a _static_ inner class?-->
</Match>
<Match class="Parcel11$Destination">
<BugCode name="SIC"/>
<!--Should Parcel11$Destination be a _static_ inner class?-->
</Match>
<Match class="Parcel2$Contents">
<BugCode name="SIC"/>
<!--Should Parcel2$Contents be a _static_ inner class?-->
</Match>
<Match class="Parcel2$Destination">
<BugCode name="SIC"/>
<!--Should Parcel2$Destination be a _static_ inner class?-->
</Match>
<Match class="Parcel3$PContents">
<BugCode name="SIC"/>
<!--Should Parcel3$PContents be a _static_ inner class?-->
</Match>
<Match class="Parcel3$PDestination">
<BugCode name="SIC"/>
<!--Should Parcel3$PDestination be a _static_ inner class?-->
</Match>
<Match class="Parcel4$1PDestination">
<BugCode name="SIC"/>
<!--Should Parcel4$1PDestination be a _static_ inner class?-->
</Match>
<Match class="Parcel5$1TrackingSlip">
<BugCode name="SIC"/>
<!--Should Parcel5$1TrackingSlip be a _static_ inner class?-->
</Match>
<Match class="PlaceSetting">
<BugCode name="DLS"/>
<!--Dead store to local variable in method PlaceSetting.main(String[]) At PlaceSetting.java:[line 66]-->
</Match>
<Match class="PlaceSetting">
<BugCode name="UrF"/>
<!--Unread field: PlaceSetting.frk-->
<!--Unread field: PlaceSetting.kn-->
<!--Unread field: PlaceSetting.pl-->
<!--Unread field: PlaceSetting.sp-->
</Match>
<Match class="Pool">
<BugCode name="UrF"/>
<!--Unread field: Pool.classObject-->
</Match>
<Match class="Poppet">
<BugCode name="UrF"/>
<!--Unread field: Poppet.i-->
</Match>
<Match class="References">
<BugCode name="DLS"/>
<!--Dead store to local variable in method References.main(String[]) At References.java:[line 45]-->
<!--Dead store to local variable in method References.main(String[]) At References.java:[line 47]-->
</Match>
<Match class="ResponsiveUI">
<BugCode name="RV"/>
<!--ResponsiveUI.main(String[]) ignores return value of ResponsiveUI.<init>() At ResponsiveUI.java:[line 27]-->
</Match>
<Match class="ResponsiveUI">
<BugCode name="SC"/>
<!--ResponsiveUI.<init>() invokes ResponsiveUI.start() At ResponsiveUI.java:[line 18]-->
</Match>
<Match class="ReversibleArrayList$1$1">
<BugCode name="It"/>
<!--ReversibleArrayList$1$1.next() can't throw NoSuchElement exception At AdapterMethodIdiom.java:[line 14]-->
</Match>
<Match class="RobotPool">
<BugCode name="Wa"/>
<!--Wait not in loop in RobotPool.hire(Class,Assembler) At CarBuilder.java:[line 168]-->
</Match>
<Match class="SelfManaged">
<BugCode name="SC"/>
<!--SelfManaged.<init>() invokes java.lang.Thread.start() At SelfManaged.java:[line 7]-->
</Match>
<Match class="SimpleQueue">
<BugCode name="RV"/>
<!--SimpleQueue.add(Object) ignores return value of java.util.LinkedList.offer(Object) At SimpleQueue.java:[line 7]-->
</Match>
<Match class="SimpleThread">
<BugCode name="RV"/>
<!--SimpleThread.main(String[]) ignores return value of SimpleThread.<init>() At SimpleThread.java:[line 23]-->
</Match>
<Match class="SimpleThread">
<BugCode name="SC"/>
<!--SimpleThread.<init>() invokes SimpleThread.start() At SimpleThread.java:[line 9]-->
</Match>
<Match class="SprinklerSystem">
<BugCode name="UwF"/>
<!--Unwritten field: SprinklerSystem.f-->
<!--Unwritten field: SprinklerSystem.i-->
<!--Unwritten field: SprinklerSystem.source-->
<!--Unwritten field: SprinklerSystem.valve1-->
<!--Unwritten field: SprinklerSystem.valve2-->
<!--Unwritten field: SprinklerSystem.valve3-->
<!--Unwritten field: SprinklerSystem.valve4-->
</Match>
<Match class="TellerManager">
<BugCode name="RV"/>
<!--TellerManager.adjustTellerNumber() ignores return value of java.util.PriorityQueue.offer(Object) At BankTellerSimulation.java:[line 127]-->
<!--TellerManager.reassignOneTeller() ignores return value of java.util.Queue.offer(Object) At BankTellerSimulation.java:[line 150]-->
</Match>
<Match class="TemperatureReading">
<BugCode name="UrF"/>
<!--Unread field: TemperatureReading.time-->
</Match>
<Match class="URShift">
<BugCode name="DLS"/>
<!--Dead store to local variable in method URShift.main(String[]) At URShift.java:[line 8]-->
<!--Dead store to local variable in method URShift.main(String[]) At URShift.java:[line 10]-->
<!--Dead store to local variable in method URShift.main(String[]) At URShift.java:[line 12]-->
</Match>
<Match class="UsingStringBuilder">
<BugCode name="MS"/>
<!--UsingStringBuilder.rand isn't final but should be-->
</Match>
<Match class="VeryBig">
<BugCode name="UrF"/>
<!--Unread field: VeryBig.d-->
</Match>
<Match class="WaitPerson">
<BugCode name="UW"/>
<!--Unconditional wait in WaitPerson.run() At Restaurant.java:[line 22]-->
</Match>
<Match class="WhitherStringBuilder">
<BugCode name="SBSC"/>
<!--Method WhitherStringBuilder.implicit(String[]) concatenates strings using + in a loop At WhitherStringBuilder.java:[line 7]-->
</Match>
<Match class="WildcardRules">
<BugCode name="EC"/>
<!--Call to equals() comparing different types in WildcardRules.f(Holder) At WildcardRules.java:[line 11]-->
<!--Call to equals() comparing different types in WildcardRules.g(Holder) At WildcardRules.java:[line 17]-->
</Match>
<Match class="Derived">
<BugCode name="EC"/>
</Match>
<Match class="WildcardRules">
<BugCode name="RV"/>
<!--WildcardRules.f(Holder) ignores return value of Holder.equals(Object) At WildcardRules.java:[line 11]-->
<!--WildcardRules.g(Holder) ignores return value of Holder.equals(Object) At WildcardRules.java:[line 17]-->
</Match>
<Match class="annotations.database.Member">
<BugCode name="UwF"/>
<!--Unwritten field: annotations.database.Member.age-->
<!--Unwritten field: annotations.database.Member.firstName-->
<!--Unwritten field: annotations.database.Member.handle-->
<!--Unwritten field: annotations.database.Member.lastName-->
</Match>
<Match class="cloning.HorrorFlick">
<BugCode name="DLS"/>
<!--Dead store to local variable in method cloning.HorrorFlick.main(String[]) At HorrorFlick.java:[line 24]-->
<!--Dead store to local variable in method cloning.HorrorFlick.main(String[]) At HorrorFlick.java:[line 25]-->
</Match>
<Match class="discovering.DocletTestClass">
<BugCode name="UuF"/>
<!--Unused field: discovering.DocletTestClass.BadCapitalizationField-->
<!--Unused field: discovering.DocletTestClass.i-->
<!--Unused field: discovering.DocletTestClass$BadInner.BadCapitalizationFieldInner-->
</Match>
<Match class="discovering.DocletTestClass$BadInner">
<BugCode name="UuF"/>
<!--Unused field: discovering.DocletTestClass$BadInner.BadCapitalizationFieldInner-->
</Match>
<Match class="discovering.DocletTestClass$BadInner$badCapitalizationClassInner">
<BugCode name="SIC"/>
<!--Should discovering.DocletTestClass$BadInner$badCapitalizationClassInner be a _static_ inner class?-->
</Match>
<Match class="discovering.DocletTestClass$Inner">
<BugCode name="SIC"/>
<!--Should discovering.DocletTestClass$Inner be a _static_ inner class?-->
</Match>
<Match class="discovering.DocletTestClass$badCapitalizationClass">
<BugCode name="SIC"/>
<!--Should discovering.DocletTestClass$badCapitalizationClass be a _static_ inner class?-->
</Match>
<Match class="holding.MapOfList">
<BugCode name="MS"/>
<!--holding.MapOfList.petPeople isn't final but should be-->
</Match>
<Match class="interfaces.nesting.A$BImp">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.A$BImp be a _static_ inner class?-->
</Match>
<Match class="interfaces.nesting.A$CImp">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.A$CImp be a _static_ inner class?-->
</Match>
<Match class="interfaces.nesting.A$DImp">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.A$DImp be a _static_ inner class?-->
</Match>
<Match class="interfaces.nesting.NestingInterfaces$BImp">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.NestingInterfaces$BImp be a _static_ inner class?-->
</Match>
<Match class="interfaces.nesting.NestingInterfaces$CImp">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.NestingInterfaces$CImp be a _static_ inner class?-->
</Match>
<Match class="interfaces.nesting.NestingInterfaces$EGImp">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.NestingInterfaces$EGImp be a _static_ inner class?-->
</Match>
<Match class="interfaces.nesting.NestingInterfaces$EImp">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.NestingInterfaces$EImp be a _static_ inner class?-->
<!--Should interfaces.nesting.NestingInterfaces$EImp2$EG be a _static_ inner class?-->
</Match>
<Match class="interfaces.nesting.NestingInterfaces$EImp2$EG">
<BugCode name="SIC"/>
<!--Should interfaces.nesting.NestingInterfaces$EImp2$EG be a _static_ inner class?-->
</Match>
<Match class="net.mindview.util.AUnit">
<BugCode name="SBSC"/>
<!--Method net.mindview.util.AUnit.main(String[]) concatenates strings using + in a loop At unknown source line-->
</Match>
<Match class="net.mindview.util.AbstractGenerator$Basic">
<BugCode name="It"/>
<!--net.mindview.util.AbstractGenerator$Basic.next() can't throw NoSuchElement exception At unknown source line-->
</Match>
<Match class="net.mindview.util.ClassNameFinder">
<BugCode name="DLS"/>
<!--Dead store to local variable in method net.mindview.util.ClassNameFinder.thisClass(byte[]) At <Unknown>:[line -1]-->
</Match>
<Match class="net.mindview.util.ClassNameFinder">
<BugCode name="REC"/>
<!--Method net.mindview.util.ClassNameFinder.thisClass(byte[]) catches Exception, but Exception is not thrown in the try block and RuntimeException is not explicitly caught At unknown source line-->
</Match>
<Match class="net.mindview.util.Collections2">
<BugCode name="MS"/>
<!--net.mindview.util.Collections2.rsp isn't final but should be-->
<!--net.mindview.util.Collections2.simpleStrings isn't final but should be-->
<!--net.mindview.util.Collections2.geography isn't final but should be-->
<!--net.mindview.util.Collections2.countries isn't final but should be-->
<!--net.mindview.util.Collections2.capitals isn't final but should be-->
</Match>
<Match class="net.mindview.util.Collections2$StringGenerator">
<BugCode name="EI2"/>
<!--net.mindview.util.Collections2$StringGenerator.<init>(String[][],int) may expose internal representation by storing an externally mutable object into net.mindview.util.Collections2$StringGenerator.d At unknown source line-->
</Match>
<Match class="net.mindview.util.Collections2$StringPairGenerator">
<BugCode name="EI2"/>
<!--net.mindview.util.Collections2$StringPairGenerator.<init>(String[][]) may expose internal representation by storing an externally mutable object into net.mindview.util.Collections2$StringPairGenerator.d At unknown source line-->
</Match>
<Match class="net.mindview.util.CountryCapitals">
<BugCode name="MS"/>
<!--net.mindview.util.CountryCapitals.pairs is a mutable array-->
</Match>
<Match class="net.mindview.util.OSExecute">
<BugCode name="OS"/>
<!--net.mindview.util.OSExecute.command(String) may fail to close stream At <Unknown>:[line -1]-->
</Match>
<Match class="polymorphism.Sandwich">
<BugCode name="UrF"/>
<!--Unread field: polymorphism.Sandwich.b-->
<!--Unread field: polymorphism.Sandwich.c-->
<!--Unread field: polymorphism.Sandwich.l-->
</Match>
<Match class="polymorphism.music4.Instrument">
<BugCode name="UuF"/>
<!--Unused field: polymorphism.music4.Instrument.i-->
</Match>
<Match class="typeinfo.pets.ForNameCreator">
<BugCode name="EI"/>
<!--typeinfo.pets.ForNameCreator.getTypes() may expose internal representation by returning typeinfo.pets.ForNameCreator.types At unknown source line-->
</Match>
<Match class="typeinfo.pets.LiteralPetCreator">
<BugCode name="EI"/>
<!--typeinfo.pets.LiteralPetCreator.getTypes() may expose internal representation by returning typeinfo.pets.LiteralPetCreator.types At unknown source line-->
</Match>
</FindBugsFilter>

31
src/main/java/JavaLint.py Executable file
View File

@ -0,0 +1,31 @@
#!/usr/bin/python
"""
Runs javac -Xlint on all files in all subdirectories.
Collects results into JavaLint.txt
"""
import os
outputfile = "JavaLint.txt"
javadirs = []
for path, dirs, files in os.walk('.'):
for file in files:
if file.endswith(".java"):
javadirs.append(path)
break
start = os.getcwd()
for jd in javadirs:
os.chdir(jd)
print jd
os.system("javac -source 1.5 -Xlint -Xlint:-serial *.java -Xstdout " + outputfile)
os.chdir(start)
results = open(start + os.sep + outputfile, 'w')
for jd in javadirs:
messages = open(jd + os.sep + outputfile).read()
if len(messages):
print >>results, '='*40 + "\n" + jd + "\n" + '='*40 + "\n" + messages

133
src/main/java/OutputGenerator.py Executable file
View File

@ -0,0 +1,133 @@
#!/usr/bin/python
"""
Runs a Java program, appends output if it's not there
-force as first argument when doing batch files forces overwrite
"""
import os, re, sys
argTag = '// {Args: '
oldOutput = re.compile("/* Output:.*?\n(.*)\n\*///:~(?s)")
def makeOutputIncludedFile(path, fileName, changeReport, force = False):
oldDir = os.getcwd()
os.chdir(path)
base = fileName.split('.')[0]
package = ''
args = ''
command = None
for line in file(fileName):
if line.startswith("} /*"):
break # Out of for loop
if line.startswith("package"):
words = line.strip().split()
package = words[1][:-1] + '.' # remove ';'
if line.startswith(argTag):
args = line[len(argTag):].strip()
assert args.rfind('}') != -1, "%s, %s" % (args, fileName)
args = " " +args[:args.rfind('}')]
if line.startswith("// {main:"):
base = line.split()[-1]
base = base[:-1]
if line.startswith("// {Exec:"):
command = line.split(':', 1)[1].strip()[:-1]
if not command:
command = "java " + package + base + args
command += " > " + base + "-output.txt"
print command
result = os.system(command)
if(result != 0):
raise Exception, "Command returned nonzero value: " + str(result)
# Read output file that was just generated:
results = file(base + "-output.txt").read().strip()
# Strip off trailing spaces on each line:
results = "\n".join([line.rstrip() for line in results.split("\n")])
results = results.replace('\t', ' ')
if results:
if force or not oldOutput.findall(file(fileName).read()):
processedText = createProcessedJavaText(results, fileName)
open(fileName, 'w').write(processedText + "\n")
if changeReport:
changeReport.write(os.path.join(path, fileName) + "\n")
return # Don't need to try for error output
##### Duplicate for standard error output:
command += " 2> " + base + "-erroroutput.txt"
print command
result = os.system(command)
if(result != 0):
raise Exception, "Command returned nonzero value: " + str(result)
# Read error file that was just generated:
results = file(base + "-erroroutput.txt").read().strip()
# Strip off trailing spaces on each line:
results = "\n".join([line.rstrip() for line in results.split("\n")])
results = results.replace('\t', ' ')
if results:
if force or not oldOutput.findall(file(fileName).read()):
processedText = createProcessedJavaText(results, fileName)
open(fileName, 'w').write(processedText + "\n")
if changeReport:
changeReport.write(os.path.join(path, fileName) + "\n")
os.chdir(oldDir)
def createProcessedJavaText(results, fileName):
processedJava = ''
for line in [line.rstrip() for line in file(fileName)]:
if line.startswith("} ///:~"):
processedJava += "} /* Output:\n" + results + "\n*///:~"
return processedJava
if line.startswith("} /* Output:"):
processedJava += line + "\n" + results + "\n*///:~" # Preserve modifiers
return processedJava
processedJava += line + "\n"
raise Exception, "No marker found at end of file " + path + " " + fileName
class ReportFile:
def __init__(self, filePath):
self.filePath = filePath
self.file = None
def write(self, line):
if not self.file:
self.file = file(self.filePath, 'w')
self.file.write(line)
print line
def close(self):
if self.file:
self.file.close()
if __name__ == "__main__":
start = os.getcwd()
args = sys.argv[1:]
forceFlag = False
if len(args):
if args[0] == "-force":
forceFlag = True
print "forceFlag = ", forceFlag
del args[0]
if len(args) > 0:
for javaSource in args:
if javaSource.endswith("."): javaSource = javaSource[:-1]
if not javaSource.endswith(".java"): javaSource += ".java"
os.system("javac " + javaSource)
makeOutputIncludedFile(os.getcwd(), javaSource, None, force = True)
else:
changeReport = ReportFile(os.path.join(start, "Changes.txt"))
for root, dirs, files in os.walk('.'):
if (os.sep + "gui") in root: continue
path = os.path.normpath(os.path.join(start,root))
print path
for name in [name for name in files if name.endswith(".java")]:
java = file(os.path.join(path, name)).read()
if "public static void main(String" in java and \
not "{RunByHand}" in java and \
not "{ThrowsException}" in java and \
not "/* (Execute to see output) *///:~" in java and \
not "} /* Same output as" in java:
if forceFlag or not "} /* Output:" in java:
print "\t", name
makeOutputIncludedFile(path, name, changeReport, force = forceFlag)
changeReport.close()
os.system("uedit32 /f Changes.txt &")

200
src/main/java/OutputVerifier.py Executable file
View File

@ -0,0 +1,200 @@
#!/usr/bin/python
"""
To do:
3) command-line argument (to test a single file)
- What about exceptions and aborts?
-If ...is embedded anywhere in a line, that portion becomes a .*? regexp
---------------
Find files with
/* Output:
Run the programs and capture the output, compare with anticipated output.
/* Output: (80% match)
For files that vary from run to run
Complete punt:
/* Output: (Sample)
(More elaborate design in SimpleTest1.py)
"""
import os, re, glob, sys, string, codecs
from difflib import SequenceMatcher
argTag = '// {Args: '
targetOutput = re.compile("/* Output:(.*?)\n(.*)\n\*///:~", re.DOTALL)
class SimpleTest:
def __init__(self, fileName, text, referencePath, reportFile):
self.fileName = fileName
self.normalOutput = self.fileName + "-output.txt"
self.errorOutput = self.fileName + "-erroroutput.txt"
self.text = text
self.referencePath = referencePath
self.reportFile = reportFile
self.package = ""
self.args = ""
self.runTest = True
self.insertOutput = True
self.EmbeddedComparisonOutput = False
self.comparisonFile = None
self.lines = self.text.split("\n")
for line in self.lines:
if "{RunByHand}" in line or \
line.startswith("import javax.swing.*;") or \
"c12:ZipCompress.java" in line or \
"/* (Execute to see output) *///:~" in line:
self.runTest = False
if line.startswith("package"):
self.package = line.split()[1][:-1] + "."
if line.startswith(argTag):
self.args = line[len(argTag):].strip()
assert self.args.rfind('}') != -1, "%s, %s" % (self.args, referencePath)
self.args = self.args[:self.args.rfind('}')]
if line.startswith("// {main:"):
self.fileName = line.split()[-1][:-1]
if line.startswith("// {Exec:"):
self.command = line.split(':', 1)[1].strip()[:-1]
if "/* Output:" in line:
self.EmbeddedComparisonOutput = True
if line.startswith("} /*"):
break # Out of for loop
#if "} ///:~" in line: # Extra space
# self.insertOutput = False
def run(self):
if not self.runTest: return
if not hasattr(self, "command"):
self.command = "java " + self.package + self.fileName + " " + self.args
# Capture standard output into a local file.
self.command = self.command + " > " + self.normalOutput
print self.command
os.system(self.command)
if os.stat(self.normalOutput).st_size:
return self.compareResults(self.normalOutput)
# Capture error output into a local file.
# The '2>' requires cygwin under Windows, or *nix:
self.command = self.command + " 2> " + self.errorOutput
print self.command
os.system(self.command)
return self.compareResults(self.errorOutput)
def compareResults(self, fileName):
# Read output file that was just generated:
results = makePrintable(file(fileName).read())
results = results.replace('\t', ' ')
results = results.strip()
file("Generated.txt",'w').write(results)
# Strip off trailing spaces on each line:
results = "\n".join([line.rstrip() for line in results.split("\n")])
controlSample = self.getControlSample()
ratio = 1.0
if controlSample:
controlOutput = controlSample.group(2).rstrip()
if "\n..." in controlOutput:
controlLines = controlOutput.split("\n")[:-1]
resultLines = results.split("\n")[:len(controlLines)]
controlOutput = "\n".join(controlLines)
results = "\n".join(resultLines)
file("controlOutput.txt",'w').write(controlOutput)
modifier = controlSample.group(1)
if "match" in modifier:
ratio = float(re.findall("\d+", modifier)[0]) / 100
print "Looking for", ratio, "match"
if "Sample" in modifier:
ratio = 0.0
actualRatio = SequenceMatcher(None, controlOutput, results).ratio()
if actualRatio < ratio:
self.reportFile.write("mismatch in " + self.referencePath + "\n")
self.reportFile.write("Actual ratio " + str(actualRatio) + "\n")
self.reportFile.write("expected:\n")
self.reportFile.write(controlOutput + "\n")
self.reportFile.write("----------actual:----------\n")
self.reportFile.write(results + "\n")
file(self.fileName + "-control.txt", 'w').write(controlOutput)
file(self.fileName + "-results.txt", 'w').write(results)
self.reportFile.write("---------------------------\n")
os.system("cmp " + self.fileName + "-control.txt "
+ self.fileName + "-results.txt"
+ " > cmp-out.txt")
self.reportFile.write(file("cmp-out.txt").read())
self.reportFile.write("=" * 40 + "\n")
else:
pass #!!! No control sample, create initial one here
def appendOutput(self):
if self.insertOutput:
# Rewrite the tail of the source file if the result is nonzero
self.lines[-2] = '}'
self.lines[-1] = "/* Output:"
for tline in file(self.fileName + "-output.txt"):
self.lines.append(tline.rstrip())
self.lines.append("*///:~")
self.lines.append("")
file(self.fileName + ".java", 'w').write("\n".join(self.lines))
def getControlSample(self):
"""Finds the control sample, returns an re group
First element is the arguments, second is the actual data"""
if self.EmbeddedComparisonOutput:
self.sourceOutput = targetOutput.search(self.text)
else:
return None
return self.sourceOutput
def makePrintable(s):
for c in s:
if c not in string.printable: return _makePrintable(s)
return s
def _makePrintable(s):
result = ''
for c in s:
if c not in string.printable: result += ' '
else: result += c
return result
class ReportFile:
def __init__(self, filePath):
self.filePath = filePath
self.file = None
def write(self, line):
if not self.file:
self.file = file(self.filePath, 'w')
self.file.write(line)
print line
def close(self):
if self.file:
self.file.close()
if __name__ == "__main__":
if len(sys.argv) > 1:
javaSource = sys.argv[1]
if javaSource.endswith("."): javaSource = javaSource[:-1]
if not javaSource.endswith(".java"): javaSource += ".java"
os.system("javac " + javaSource)
SimpleTest(javaSource.split('.')[0], file(javaSource).read(), javaSource, sys.stdout).run()
sys.exit()
start = os.getcwd()
reportFile = ReportFile(start + os.sep + "OutputErrors.txt")
for root, dirs, files in os.walk('.'):
print root
os.chdir(root)
for f in [name.split('.')[0] for name in files if name.endswith(".java")]:
text = file(f + ".java").read()
# Only perform verification if there is an output tag:
if text.find("/* Output:") != -1:
referencePath = os.path.join(root, f + ".java")
SimpleTest(f, text, referencePath, reportFile).run()
os.chdir(start)
reportFile.close()
if reportFile.file:
print "Errors in OutputErrors.txt"

View File

@ -0,0 +1,54 @@
"""RedundantImportDetector.py
Discover redundant java imports using brute force.
Requires Python 2.3"""
import os, sys, re
from glob import glob
reportFile = file("RedundantImports.txt", 'w')
startDir = 'D:\\aaa-TIJ4\\code'
# Regular expression to find the block of import statements:
findImports = re.compile("\n(?:import .*?\n)+")
baseDir = os.path.abspath(".")
print "basDir:", baseDir
def main():
for javaFile in glob("*.java") + glob("**/*.java"):
print javaFile
checkImports(os.path.join(baseDir, javaFile))
def checkImports(javaFile):
java = file(javaFile).read()
imports = findImports.search(java)
if imports:
imports = [f for f in imports.group(0).split('\n') if f != '']
fileParts = findImports.split(java)
assert len(fileParts) == 2
for mutated in mutateImports(imports):
file(javaFile, 'w').write(fileParts[0] + mutated + fileParts[1])
print "changing to", os.path.dirname(javaFile)
os.chdir(os.path.dirname(javaFile))
if os.system("javac " + os.path.basename(javaFile)) == 0:
print >>reportFile, javaFile + "\n" + mutated
redundantRemoved = "\n".join(
[m for m in mutated.split("\n")
if not m.startswith("//")])
print >>reportFile, redundantRemoved
file(javaFile, 'w').write(fileParts[0] +
redundantRemoved + fileParts[1])
return # No further attempts
file(javaFile, 'w').write(java) # Restore original file
def mutateImports(imports):
'''Generates different versions of imports, each with a
different line commented out'''
for i in range(len(imports)):
mutated = imports[:]
mutated[i] = '//' + mutated[i]
yield "\n".join([''] + mutated + [''])
if __name__ == "__main__": main()

12
src/main/java/access/Cake.java Executable file
View File

@ -0,0 +1,12 @@
//: access/Cake.java
package access; /* Added by Eclipse.py */
// Accesses a class in a separate compilation unit.
class Cake {
public static void main(String[] args) {
Pie x = new Pie();
x.f();
}
} /* Output:
Pie.f()
*///:~

View File

@ -0,0 +1,20 @@
//: access/ChocolateChip.java
package access; /* Added by Eclipse.py */
// Can't use package-access member from another package.
import access.dessert.*;
public class ChocolateChip extends Cookie {
public ChocolateChip() {
System.out.println("ChocolateChip constructor");
}
public void chomp() {
//! bite(); // Can't access bite
}
public static void main(String[] args) {
ChocolateChip x = new ChocolateChip();
x.chomp();
}
} /* Output:
Cookie constructor
ChocolateChip constructor
*///:~

View File

@ -0,0 +1,18 @@
//: access/ChocolateChip2.java
package access; /* Added by Eclipse.py */
import access.cookie2.*;
public class ChocolateChip2 extends Cookie {
public ChocolateChip2() {
System.out.println("ChocolateChip2 constructor");
}
public void chomp() { bite(); } // Protected method
public static void main(String[] args) {
ChocolateChip2 x = new ChocolateChip2();
x.chomp();
}
} /* Output:
Cookie constructor
ChocolateChip2 constructor
bite
*///:~

View File

@ -0,0 +1,13 @@
//: access/Dinner.java
package access; /* Added by Eclipse.py */
// Uses the library.
import access.dessert.*;
public class Dinner {
public static void main(String[] args) {
Cookie x = new Cookie();
//! x.bite(); // Can't access
}
} /* Output:
Cookie constructor
*///:~

View File

@ -0,0 +1,8 @@
//: access/FullQualification.java
package access; /* Added by Eclipse.py */
public class FullQualification {
public static void main(String[] args) {
java.util.ArrayList list = new java.util.ArrayList();
}
} ///:~

View File

@ -0,0 +1,17 @@
//: access/IceCream.java
package access; /* Added by Eclipse.py */
// Demonstrates "private" keyword.
class Sundae {
private Sundae() {}
static Sundae makeASundae() {
return new Sundae();
}
}
public class IceCream {
public static void main(String[] args) {
//! Sundae x = new Sundae();
Sundae x = Sundae.makeASundae();
}
} ///:~

View File

@ -0,0 +1,9 @@
//: access/ImportedMyClass.java
package access; /* Added by Eclipse.py */
import access.mypackage.*;
public class ImportedMyClass {
public static void main(String[] args) {
MyClass m = new MyClass();
}
} ///:~

View File

@ -0,0 +1,14 @@
//: access/LibTest.java
package access; /* Added by Eclipse.py */
// Uses the library.
import net.mindview.simple.*;
public class LibTest {
public static void main(String[] args) {
Vector v = new Vector();
List l = new List();
}
} /* Output:
net.mindview.simple.Vector
net.mindview.simple.List
*///:~

37
src/main/java/access/Lunch.java Executable file
View File

@ -0,0 +1,37 @@
//: access/Lunch.java
package access; /* Added by Eclipse.py */
// Demonstrates class access specifiers. Make a class
// effectively private with private constructors:
class Soup1 {
private Soup1() {}
// (1) Allow creation via static method:
public static Soup1 makeSoup() {
return new Soup1();
}
}
class Soup2 {
private Soup2() {}
// (2) Create a static object and return a reference
// upon request.(The "Singleton" pattern):
private static Soup2 ps1 = new Soup2();
public static Soup2 access() {
return ps1;
}
public void f() {}
}
// Only one public class allowed per file:
public class Lunch {
void testPrivate() {
// Can't do this! Private constructor:
//! Soup1 soup = new Soup1();
}
void testStatic() {
Soup1 soup = Soup1.makeSoup();
}
void testSingleton() {
Soup2.access().f();
}
} ///:~

View File

@ -0,0 +1,13 @@
//: access/OrganizedByAccess.java
package access; /* Added by Eclipse.py */
public class OrganizedByAccess {
public void pub1() { /* ... */ }
public void pub2() { /* ... */ }
public void pub3() { /* ... */ }
private void priv1() { /* ... */ }
private void priv2() { /* ... */ }
private void priv3() { /* ... */ }
private int i;
// ...
} ///:~

7
src/main/java/access/Pie.java Executable file
View File

@ -0,0 +1,7 @@
//: access/Pie.java
package access; /* Added by Eclipse.py */
// The other class.
class Pie {
void f() { System.out.println("Pie.f()"); }
} ///:~

View File

@ -0,0 +1,18 @@
//: access/PrintTest.java
package access; /* Added by Eclipse.py */
// Uses the static printing methods in Print.java.
import static net.mindview.util.Print.*;
public class PrintTest {
public static void main(String[] args) {
print("Available from now on!");
print(100);
print(100L);
print(3.14159);
}
} /* Output:
Available from now on!
100
100
3.14159
*///:~

View File

@ -0,0 +1,9 @@
//: access/QualifiedMyClass.java
package access; /* Added by Eclipse.py */
public class QualifiedMyClass {
public static void main(String[] args) {
access.mypackage.MyClass m =
new access.mypackage.MyClass();
}
} ///:~

View File

@ -0,0 +1,9 @@
//: access/SingleImport.java
package access; /* Added by Eclipse.py */
import java.util.ArrayList;
public class SingleImport {
public static void main(String[] args) {
ArrayList list = new java.util.ArrayList();
}
} ///:~

189
src/main/java/access/build.xml Executable file
View File

@ -0,0 +1,189 @@
<?xml version="1.0" ?>
<project
basedir="."
default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: access)">
<description>
build.xml for the source code for the access chapter of
Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt
Ant available from: http://jakarta.apache.org/ant
To see options, type: ant -p
This file was automatically generated by AntBuilder
</description>
<condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/>
</condition>
<target name="net_mindview_util">
<javac
classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/util/">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
</target>
<target name="net_mindview_simple">
<javac
classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/simple/">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
</target>
<target
depends="net_mindview_util,net_mindview_simple"
description="Build all classes in this directory"
name="build">
<fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'access'"/>
<javac
classpath="${basedir}/.."
debug="true"
srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
<echo message="Build 'access' succeeded"/>
</target>
<target name="Cake">
<java
classname="Cake"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="ChocolateChip">
<java
classname="ChocolateChip"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="ChocolateChip2">
<java
classname="ChocolateChip2"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="Dinner">
<java
classname="Dinner"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="FullQualification">
<java
classname="FullQualification"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="IceCream">
<java
classname="IceCream"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="ImportedMyClass">
<java
classname="ImportedMyClass"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="LibTest">
<java
classname="LibTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="PrintTest">
<java
classname="PrintTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="QualifiedMyClass">
<java
classname="QualifiedMyClass"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target name="SingleImport">
<java
classname="SingleImport"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../access/"
failonerror="true"
fork="true"/>
</target>
<target
depends="build"
description="Compile and run"
name="run">
<touch file="failures"/>
<antcall target="Cake"/>
<antcall target="ChocolateChip"/>
<antcall target="ChocolateChip2"/>
<antcall target="Dinner"/>
<antcall target="FullQualification"/>
<antcall target="IceCream"/>
<antcall target="ImportedMyClass"/>
<antcall target="LibTest"/>
<antcall target="PrintTest"/>
<antcall target="QualifiedMyClass"/>
<antcall target="SingleImport"/>
<delete file="failures"/>
</target>
<target description="delete all byproducts" name="clean">
<delete>
<fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/>
</delete>
<echo message="clean successful"/>
</target>
</project>

View File

@ -0,0 +1,11 @@
//: access/cookie2/Cookie.java
package access.cookie2;
public class Cookie {
public Cookie() {
System.out.println("Cookie constructor");
}
protected void bite() {
System.out.println("bite");
}
} ///:~

View File

@ -0,0 +1,10 @@
//: access/dessert/Cookie.java
// Creates a library.
package access.dessert;
public class Cookie {
public Cookie() {
System.out.println("Cookie constructor");
}
void bite() { System.out.println("bite"); }
} ///:~

View File

@ -0,0 +1,6 @@
//: access/mypackage/MyClass.java
package access.mypackage;
public class MyClass {
// ...
} ///:~

View File

@ -0,0 +1,26 @@
//: annotations/AtUnitComposition.java
// Creating non-embedded tests.
package annotations;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class AtUnitComposition {
AtUnitExample1 testObject = new AtUnitExample1();
@Test boolean _methodOne() {
return
testObject.methodOne().equals("This is methodOne");
}
@Test boolean _methodTwo() {
return testObject.methodTwo() == 2;
}
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitComposition");
}
} /* Output:
annotations.AtUnitComposition
. _methodOne
. _methodTwo This is methodTwo
OK (2 tests)
*///:~

View File

@ -0,0 +1,39 @@
//: annotations/AtUnitExample1.java
package annotations;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class AtUnitExample1 {
public String methodOne() {
return "This is methodOne";
}
public int methodTwo() {
System.out.println("This is methodTwo");
return 2;
}
@Test boolean methodOneTest() {
return methodOne().equals("This is methodOne");
}
@Test boolean m2() { return methodTwo() == 2; }
@Test private boolean m3() { return true; }
// Shows output for failure:
@Test boolean failureTest() { return false; }
@Test boolean anotherDisappointment() { return false; }
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitExample1");
}
} /* Output:
annotations.AtUnitExample1
. methodOneTest
. m2 This is methodTwo
. m3
. failureTest (failed)
. anotherDisappointment (failed)
(5 tests)
>>> 2 FAILURES <<<
annotations.AtUnitExample1: failureTest
annotations.AtUnitExample1: anotherDisappointment
*///:~

View File

@ -0,0 +1,48 @@
//: annotations/AtUnitExample2.java
// Assertions and exceptions can be used in @Tests.
package annotations;
import java.io.*;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class AtUnitExample2 {
public String methodOne() {
return "This is methodOne";
}
public int methodTwo() {
System.out.println("This is methodTwo");
return 2;
}
@Test void assertExample() {
assert methodOne().equals("This is methodOne");
}
@Test void assertFailureExample() {
assert 1 == 2: "What a surprise!";
}
@Test void exceptionExample() throws IOException {
new FileInputStream("nofile.txt"); // Throws
}
@Test boolean assertAndReturn() {
// Assertion with message:
assert methodTwo() == 2: "methodTwo must equal 2";
return methodOne().equals("This is methodOne");
}
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitExample2");
}
} /* Output:
annotations.AtUnitExample2
. assertExample
. assertFailureExample java.lang.AssertionError: What a surprise!
(failed)
. exceptionExample java.io.FileNotFoundException: nofile.txt (The system cannot find the file specified)
(failed)
. assertAndReturn This is methodTwo
(4 tests)
>>> 2 FAILURES <<<
annotations.AtUnitExample2: assertFailureExample
annotations.AtUnitExample2: exceptionExample
*///:~

View File

@ -0,0 +1,36 @@
//: annotations/AtUnitExample3.java
package annotations;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class AtUnitExample3 {
private int n;
public AtUnitExample3(int n) { this.n = n; }
public int getN() { return n; }
public String methodOne() {
return "This is methodOne";
}
public int methodTwo() {
System.out.println("This is methodTwo");
return 2;
}
@TestObjectCreate static AtUnitExample3 create() {
return new AtUnitExample3(47);
}
@Test boolean initialization() { return n == 47; }
@Test boolean methodOneTest() {
return methodOne().equals("This is methodOne");
}
@Test boolean m2() { return methodTwo() == 2; }
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitExample3");
}
} /* Output:
annotations.AtUnitExample3
. initialization
. methodOneTest
. m2 This is methodTwo
OK (3 tests)
*///:~

View File

@ -0,0 +1,72 @@
//: annotations/AtUnitExample4.java
package annotations;
import java.util.*;
import net.mindview.atunit.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
public class AtUnitExample4 {
static String theory = "All brontosauruses " +
"are thin at one end, much MUCH thicker in the " +
"middle, and then thin again at the far end.";
private String word;
private Random rand = new Random(); // Time-based seed
public AtUnitExample4(String word) { this.word = word; }
public String getWord() { return word; }
public String scrambleWord() {
List<Character> chars = new ArrayList<Character>();
for(Character c : word.toCharArray())
chars.add(c);
Collections.shuffle(chars, rand);
StringBuilder result = new StringBuilder();
for(char ch : chars)
result.append(ch);
return result.toString();
}
@TestProperty static List<String> input =
Arrays.asList(theory.split(" "));
@TestProperty
static Iterator<String> words = input.iterator();
@TestObjectCreate static AtUnitExample4 create() {
if(words.hasNext())
return new AtUnitExample4(words.next());
else
return null;
}
@Test boolean words() {
print("'" + getWord() + "'");
return getWord().equals("are");
}
@Test boolean scramble1() {
// Change to a specific seed to get verifiable results:
rand = new Random(47);
print("'" + getWord() + "'");
String scrambled = scrambleWord();
print(scrambled);
return scrambled.equals("lAl");
}
@Test boolean scramble2() {
rand = new Random(74);
print("'" + getWord() + "'");
String scrambled = scrambleWord();
print(scrambled);
return scrambled.equals("tsaeborornussu");
}
public static void main(String[] args) throws Exception {
System.out.println("starting");
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitExample4");
}
} /* Output:
starting
annotations.AtUnitExample4
. scramble1 'All'
lAl
. scramble2 'brontosauruses'
tsaeborornussu
. words 'are'
OK (3 tests)
*///:~

View File

@ -0,0 +1,52 @@
//: annotations/AtUnitExample5.java
package annotations;
import java.io.*;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class AtUnitExample5 {
private String text;
public AtUnitExample5(String text) { this.text = text; }
public String toString() { return text; }
@TestProperty static PrintWriter output;
@TestProperty static int counter;
@TestObjectCreate static AtUnitExample5 create() {
String id = Integer.toString(counter++);
try {
output = new PrintWriter("Test" + id + ".txt");
} catch(IOException e) {
throw new RuntimeException(e);
}
return new AtUnitExample5(id);
}
@TestObjectCleanup static void
cleanup(AtUnitExample5 tobj) {
System.out.println("Running cleanup");
output.close();
}
@Test boolean test1() {
output.print("test1");
return true;
}
@Test boolean test2() {
output.print("test2");
return true;
}
@Test boolean test3() {
output.print("test3");
return true;
}
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitExample5");
}
} /* Output:
annotations.AtUnitExample5
. test1
Running cleanup
. test2
Running cleanup
. test3
Running cleanup
OK (3 tests)
*///:~

View File

@ -0,0 +1,22 @@
//: annotations/AtUnitExternalTest.java
// Creating non-embedded tests.
package annotations;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class AtUnitExternalTest extends AtUnitExample1 {
@Test boolean _methodOne() {
return methodOne().equals("This is methodOne");
}
@Test boolean _methodTwo() { return methodTwo() == 2; }
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit AtUnitExternalTest");
}
} /* Output:
annotations.AtUnitExternalTest
. _methodOne
. _methodTwo This is methodTwo
OK (2 tests)
*///:~

View File

@ -0,0 +1,10 @@
//: annotations/ExtractInterface.java
// APT-based annotation processing.
package annotations;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.SOURCE)
public @interface ExtractInterface {
public String value();
} ///:~

View File

@ -0,0 +1,31 @@
//: annotations/HashSetTest.java
package annotations;
import java.util.*;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class HashSetTest {
HashSet<String> testObject = new HashSet<String>();
@Test void initialization() {
assert testObject.isEmpty();
}
@Test void _contains() {
testObject.add("one");
assert testObject.contains("one");
}
@Test void _remove() {
testObject.add("one");
testObject.remove("one");
assert testObject.isEmpty();
}
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit HashSetTest");
}
} /* Output:
annotations.HashSetTest
. initialization
. _remove
. _contains
OK (3 tests)
*///:~

View File

@ -0,0 +1,60 @@
//: annotations/InterfaceExtractorProcessor.java
// APT-based annotation processing.
// {Exec: apt -factory
// annotations.InterfaceExtractorProcessorFactory
// Multiplier.java -s ../annotations}
package annotations;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import java.io.*;
import java.util.*;
public class InterfaceExtractorProcessor
implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
private ArrayList<MethodDeclaration> interfaceMethods =
new ArrayList<MethodDeclaration>();
public InterfaceExtractorProcessor(
AnnotationProcessorEnvironment env) { this.env = env; }
public void process() {
for(TypeDeclaration typeDecl :
env.getSpecifiedTypeDeclarations()) {
ExtractInterface annot =
typeDecl.getAnnotation(ExtractInterface.class);
if(annot == null)
break;
for(MethodDeclaration m : typeDecl.getMethods())
if(m.getModifiers().contains(Modifier.PUBLIC) &&
!(m.getModifiers().contains(Modifier.STATIC)))
interfaceMethods.add(m);
if(interfaceMethods.size() > 0) {
try {
PrintWriter writer =
env.getFiler().createSourceFile(annot.value());
writer.println("package " +
typeDecl.getPackage().getQualifiedName() +";");
writer.println("public interface " +
annot.value() + " {");
for(MethodDeclaration m : interfaceMethods) {
writer.print(" public ");
writer.print(m.getReturnType() + " ");
writer.print(m.getSimpleName() + " (");
int i = 0;
for(ParameterDeclaration parm :
m.getParameters()) {
writer.print(parm.getType() + " " +
parm.getSimpleName());
if(++i < m.getParameters().size())
writer.print(", ");
}
writer.println(");");
}
writer.println("}");
writer.close();
} catch(IOException ioe) {
throw new RuntimeException(ioe);
}
}
}
}
} ///:~

View File

@ -0,0 +1,22 @@
//: annotations/InterfaceExtractorProcessorFactory.java
// APT-based annotation processing.
package annotations;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import java.util.*;
public class InterfaceExtractorProcessorFactory
implements AnnotationProcessorFactory {
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
return new InterfaceExtractorProcessor(env);
}
public Collection<String> supportedAnnotationTypes() {
return
Collections.singleton("annotations.ExtractInterface");
}
public Collection<String> supportedOptions() {
return Collections.emptySet();
}
} ///:~

View File

@ -0,0 +1,20 @@
//: annotations/Multiplier.java
// APT-based annotation processing.
package annotations;
@ExtractInterface("IMultiplier")
public class Multiplier {
public int multiply(int x, int y) {
int total = 0;
for(int i = 0; i < x; i++)
total = add(total, y);
return total;
}
private int add(int x, int y) { return x + y; }
public static void main(String[] args) {
Multiplier m = new Multiplier();
System.out.println("11*16 = " + m.multiply(11, 16));
}
} /* Output:
11*16 = 176
*///:~

View File

@ -0,0 +1,21 @@
//: annotations/PasswordUtils.java
package annotations; /* Added by Eclipse.py */
import java.util.*;
public class PasswordUtils {
@UseCase(id = 47, description =
"Passwords must contain at least one numeric")
public boolean validatePassword(String password) {
return (password.matches("\\w*\\d\\w*"));
}
@UseCase(id = 48)
public String encryptPassword(String password) {
return new StringBuilder(password).reverse().toString();
}
@UseCase(id = 49, description =
"New passwords can't equal previously used ones")
public boolean checkForNewPassword(
List<String> prevPasswords, String password) {
return !prevPasswords.contains(password);
}
} ///:~

View File

@ -0,0 +1,10 @@
//: annotations/SimulatingNull.java
package annotations; /* Added by Eclipse.py */
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SimulatingNull {
public int id() default -1;
public String description() default "";
} ///:~

View File

@ -0,0 +1,11 @@
//: annotations/StackL.java
// A stack built on a linkedList.
package annotations;
import java.util.*;
public class StackL<T> {
private LinkedList<T> list = new LinkedList<T>();
public void push(T v) { list.addFirst(v); }
public T top() { return list.getFirst(); }
public T pop() { return list.removeFirst(); }
} ///:~

View File

@ -0,0 +1,36 @@
//: annotations/StackLStringTest.java
// Applying @Unit to generics.
package annotations;
import net.mindview.atunit.*;
import net.mindview.util.*;
public class StackLStringTest extends StackL<String> {
@Test void _push() {
push("one");
assert top().equals("one");
push("two");
assert top().equals("two");
}
@Test void _pop() {
push("one");
push("two");
assert pop().equals("two");
assert pop().equals("one");
}
@Test void _top() {
push("A");
push("B");
assert top().equals("B");
assert top().equals("B");
}
public static void main(String[] args) throws Exception {
OSExecute.command(
"java net.mindview.atunit.AtUnit StackLStringTest");
}
} /* Output:
annotations.StackLStringTest
. _push
. _pop
. _top
OK (3 tests)
*///:~

View File

@ -0,0 +1,10 @@
//: annotations/Testable.java
package annotations;
import net.mindview.atunit.*;
public class Testable {
public void execute() {
System.out.println("Executing..");
}
@Test void testExecute() { execute(); }
} ///:~

View File

@ -0,0 +1,10 @@
//: annotations/UseCase.java
package annotations; /* Added by Eclipse.py */
import java.lang.annotation.*;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface UseCase {
public int id();
public String description() default "no description";
} ///:~

View File

@ -0,0 +1,31 @@
//: annotations/UseCaseTracker.java
package annotations; /* Added by Eclipse.py */
import java.lang.reflect.*;
import java.util.*;
public class UseCaseTracker {
public static void
trackUseCases(List<Integer> useCases, Class<?> cl) {
for(Method m : cl.getDeclaredMethods()) {
UseCase uc = m.getAnnotation(UseCase.class);
if(uc != null) {
System.out.println("Found Use Case:" + uc.id() +
" " + uc.description());
useCases.remove(new Integer(uc.id()));
}
}
for(int i : useCases) {
System.out.println("Warning: Missing use case-" + i);
}
}
public static void main(String[] args) {
List<Integer> useCases = new ArrayList<Integer>();
Collections.addAll(useCases, 47, 48, 49, 50);
trackUseCases(useCases, PasswordUtils.class);
}
} /* Output:
Found Use Case:47 Passwords must contain at least one numeric
Found Use Case:48 no description
Found Use Case:49 New passwords can't equal previously used ones
Warning: Missing use case-50
*///:~

View File

@ -0,0 +1,225 @@
<?xml version="1.0" ?>
<project
basedir="."
default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: annotations)">
<description>
build.xml for the source code for the annotations chapter of
Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt
Ant available from: http://jakarta.apache.org/ant
To see options, type: ant -p
This file was automatically generated by AntBuilder
</description>
<condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/>
</condition>
<target name="net_mindview_util">
<javac
classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/util/">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
</target>
<target name="net_mindview_atunit">
<javac
classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/atunit/">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
</target>
<target
depends="net_mindview_util,net_mindview_atunit"
description="Build all classes in this directory"
name="build">
<fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'annotations'"/>
<javac
classpath="${basedir}/.."
debug="true"
srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
<echo message="Build 'annotations' succeeded"/>
</target>
<target name="AtUnitComposition">
<java
classname="annotations.AtUnitComposition"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="AtUnitExample1">
<java
classname="annotations.AtUnitExample1"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="AtUnitExample2">
<java
classname="annotations.AtUnitExample2"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="AtUnitExample3">
<java
classname="annotations.AtUnitExample3"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="AtUnitExample4">
<java
classname="annotations.AtUnitExample4"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="AtUnitExample5">
<java
classname="annotations.AtUnitExample5"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="AtUnitExternalTest">
<java
classname="annotations.AtUnitExternalTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="HashSetTest">
<java
classname="annotations.HashSetTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="Multiplier">
<java
classname="annotations.Multiplier"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="StackLStringTest">
<java
classname="annotations.StackLStringTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="UseCaseTracker">
<java
classname="UseCaseTracker"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/"
failonerror="true"
fork="true"/>
</target>
<target name="TableCreator">
<java
classname="annotations.database.TableCreator"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../annotations/database/"
failonerror="true"
fork="true">
<arg line="annotations.database.Member"/>
</java>
</target>
<target name="InterfaceExtractorProcessor">
<exec executable="apt">
<arg value="-factory"/>
<arg
value="annotations.InterfaceExtractorProcessorFactory"/>
<arg value="Multiplier.java"/>
<arg value="-s"/>
<arg value="../annotations"/>
</exec>
</target>
<target name="TableCreationProcessorFactory">
<exec executable="apt">
<arg value="-factory"/>
<arg
value="annotations.database.TableCreationProcessorFactory"/>
<arg value="database/Member.java"/>
<arg value="-s"/>
<arg value="database"/>
</exec>
</target>
<target
depends="build"
description="Compile and run"
name="run">
<touch file="failures"/>
<antcall target="AtUnitComposition"/>
<antcall target="AtUnitExample1"/>
<antcall target="AtUnitExample2"/>
<antcall target="AtUnitExample3"/>
<antcall target="AtUnitExample4"/>
<antcall target="AtUnitExample5"/>
<antcall target="AtUnitExternalTest"/>
<antcall target="HashSetTest"/>
<antcall target="Multiplier"/>
<antcall target="StackLStringTest"/>
<antcall target="UseCaseTracker"/>
<antcall target="TableCreator"/>
<antcall target="InterfaceExtractorProcessor"/>
<antcall target="TableCreationProcessorFactory"/>
<delete file="failures"/>
</target>
<target description="delete all byproducts" name="clean">
<delete>
<fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/>
</delete>
<echo message="clean successful"/>
</target>
</project>

View File

@ -0,0 +1,11 @@
//: annotations/database/Constraints.java
package annotations.database;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Constraints {
boolean primaryKey() default false;
boolean allowNull() default true;
boolean unique() default false;
} ///:~

View File

@ -0,0 +1,9 @@
//: annotations/database/DBTable.java
package annotations.database;
import java.lang.annotation.*;
@Target(ElementType.TYPE) // Applies to classes only
@Retention(RetentionPolicy.RUNTIME)
public @interface DBTable {
public String name() default "";
} ///:~

View File

@ -0,0 +1,18 @@
//: annotations/database/Member.java
package annotations.database;
@DBTable(name = "MEMBER")
public class Member {
@SQLString(30) String firstName;
@SQLString(50) String lastName;
@SQLInteger Integer age;
@SQLString(value = 30,
constraints = @Constraints(primaryKey = true))
String handle;
static int memberCount;
public String getHandle() { return handle; }
public String getFirstName() { return firstName; }
public String getLastName() { return lastName; }
public String toString() { return handle; }
public Integer getAge() { return age; }
} ///:~

View File

@ -0,0 +1,10 @@
//: annotations/database/SQLInteger.java
package annotations.database;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLInteger {
String name() default "";
Constraints constraints() default @Constraints;
} ///:~

View File

@ -0,0 +1,11 @@
//: annotations/database/SQLString.java
package annotations.database;
import java.lang.annotation.*;
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface SQLString {
int value() default 0;
String name() default "";
Constraints constraints() default @Constraints;
} ///:~

View File

@ -0,0 +1,100 @@
//: annotations/database/TableCreationProcessorFactory.java
// The database example using Visitor.
// {Exec: apt -factory
// annotations.database.TableCreationProcessorFactory
// database/Member.java -s database}
package annotations.database;
import com.sun.mirror.apt.*;
import com.sun.mirror.declaration.*;
import com.sun.mirror.util.*;
import java.util.*;
import static com.sun.mirror.util.DeclarationVisitors.*;
public class TableCreationProcessorFactory
implements AnnotationProcessorFactory {
public AnnotationProcessor getProcessorFor(
Set<AnnotationTypeDeclaration> atds,
AnnotationProcessorEnvironment env) {
return new TableCreationProcessor(env);
}
public Collection<String> supportedAnnotationTypes() {
return Arrays.asList(
"annotations.database.DBTable",
"annotations.database.Constraints",
"annotations.database.SQLString",
"annotations.database.SQLInteger");
}
public Collection<String> supportedOptions() {
return Collections.emptySet();
}
private static class TableCreationProcessor
implements AnnotationProcessor {
private final AnnotationProcessorEnvironment env;
private String sql = "";
public TableCreationProcessor(
AnnotationProcessorEnvironment env) {
this.env = env;
}
public void process() {
for(TypeDeclaration typeDecl :
env.getSpecifiedTypeDeclarations()) {
typeDecl.accept(getDeclarationScanner(
new TableCreationVisitor(), NO_OP));
sql = sql.substring(0, sql.length() - 1) + ");";
System.out.println("creation SQL is :\n" + sql);
sql = "";
}
}
private class TableCreationVisitor
extends SimpleDeclarationVisitor {
public void visitClassDeclaration(
ClassDeclaration d) {
DBTable dbTable = d.getAnnotation(DBTable.class);
if(dbTable != null) {
sql += "CREATE TABLE ";
sql += (dbTable.name().length() < 1)
? d.getSimpleName().toUpperCase()
: dbTable.name();
sql += " (";
}
}
public void visitFieldDeclaration(
FieldDeclaration d) {
String columnName = "";
if(d.getAnnotation(SQLInteger.class) != null) {
SQLInteger sInt = d.getAnnotation(
SQLInteger.class);
// Use field name if name not specified
if(sInt.name().length() < 1)
columnName = d.getSimpleName().toUpperCase();
else
columnName = sInt.name();
sql += "\n " + columnName + " INT" +
getConstraints(sInt.constraints()) + ",";
}
if(d.getAnnotation(SQLString.class) != null) {
SQLString sString = d.getAnnotation(
SQLString.class);
// Use field name if name not specified.
if(sString.name().length() < 1)
columnName = d.getSimpleName().toUpperCase();
else
columnName = sString.name();
sql += "\n " + columnName + " VARCHAR(" +
sString.value() + ")" +
getConstraints(sString.constraints()) + ",";
}
}
private String getConstraints(Constraints con) {
String constraints = "";
if(!con.allowNull())
constraints += " NOT NULL";
if(con.primaryKey())
constraints += " PRIMARY KEY";
if(con.unique())
constraints += " UNIQUE";
return constraints;
}
}
}
} ///:~

View File

@ -0,0 +1,95 @@
//: annotations/database/TableCreator.java
// Reflection-based annotation processor.
// {Args: annotations.database.Member}
package annotations.database;
import java.lang.annotation.*;
import java.lang.reflect.*;
import java.util.*;
public class TableCreator {
public static void main(String[] args) throws Exception {
if(args.length < 1) {
System.out.println("arguments: annotated classes");
System.exit(0);
}
for(String className : args) {
Class<?> cl = Class.forName(className);
DBTable dbTable = cl.getAnnotation(DBTable.class);
if(dbTable == null) {
System.out.println(
"No DBTable annotations in class " + className);
continue;
}
String tableName = dbTable.name();
// If the name is empty, use the Class name:
if(tableName.length() < 1)
tableName = cl.getName().toUpperCase();
List<String> columnDefs = new ArrayList<String>();
for(Field field : cl.getDeclaredFields()) {
String columnName = null;
Annotation[] anns = field.getDeclaredAnnotations();
if(anns.length < 1)
continue; // Not a db table column
if(anns[0] instanceof SQLInteger) {
SQLInteger sInt = (SQLInteger) anns[0];
// Use field name if name not specified
if(sInt.name().length() < 1)
columnName = field.getName().toUpperCase();
else
columnName = sInt.name();
columnDefs.add(columnName + " INT" +
getConstraints(sInt.constraints()));
}
if(anns[0] instanceof SQLString) {
SQLString sString = (SQLString) anns[0];
// Use field name if name not specified.
if(sString.name().length() < 1)
columnName = field.getName().toUpperCase();
else
columnName = sString.name();
columnDefs.add(columnName + " VARCHAR(" +
sString.value() + ")" +
getConstraints(sString.constraints()));
}
StringBuilder createCommand = new StringBuilder(
"CREATE TABLE " + tableName + "(");
for(String columnDef : columnDefs)
createCommand.append("\n " + columnDef + ",");
// Remove trailing comma
String tableCreate = createCommand.substring(
0, createCommand.length() - 1) + ");";
System.out.println("Table Creation SQL for " +
className + " is :\n" + tableCreate);
}
}
}
private static String getConstraints(Constraints con) {
String constraints = "";
if(!con.allowNull())
constraints += " NOT NULL";
if(con.primaryKey())
constraints += " PRIMARY KEY";
if(con.unique())
constraints += " UNIQUE";
return constraints;
}
} /* Output:
Table Creation SQL for annotations.database.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30));
Table Creation SQL for annotations.database.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50));
Table Creation SQL for annotations.database.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50),
AGE INT);
Table Creation SQL for annotations.database.Member is :
CREATE TABLE MEMBER(
FIRSTNAME VARCHAR(30),
LASTNAME VARCHAR(50),
AGE INT,
HANDLE VARCHAR(30) PRIMARY KEY);
*///:~

View File

@ -0,0 +1,8 @@
//: annotations/database/Uniqueness.java
// Sample of nested annotations
package annotations.database;
public @interface Uniqueness {
Constraints constraints()
default @Constraints(unique=true);
} ///:~

View File

@ -0,0 +1,21 @@
//: arrays/AlphabeticSearch.java
package arrays; /* Added by Eclipse.py */
// Searching with a Comparator.
import java.util.*;
import net.mindview.util.*;
public class AlphabeticSearch {
public static void main(String[] args) {
String[] sa = Generated.array(new String[30],
new RandomGenerator.String(5));
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
System.out.println(Arrays.toString(sa));
int index = Arrays.binarySearch(sa, sa[10],
String.CASE_INSENSITIVE_ORDER);
System.out.println("Index: "+ index + "\n"+ sa[index]);
}
} /* Output:
[bkIna, cQrGs, cXZJo, dLsmw, eGZMm, EqUCB, gwsqP, hKcxr, HLGEa, HqXum, HxxHv, JMRoE, JmzMs, Mesbt, MNvqe, nyGcF, ogoYW, OneOE, OWZnT, RFJQA, rUkZP, sgqia, slJrL, suEcU, uTpnX, vpfFv, WHkjU, xxEAJ, YNzbr, zDyCy]
Index: 10
HxxHv
*///:~

View File

@ -0,0 +1,14 @@
//: arrays/ArrayOfGenericType.java
package arrays; /* Added by Eclipse.py */
// Arrays of generic types won't compile.
public class ArrayOfGenericType<T> {
T[] array; // OK
@SuppressWarnings("unchecked")
public ArrayOfGenericType(int size) {
//! array = new T[size]; // Illegal
array = (T[])new Object[size]; // "unchecked" Warning
}
// Illegal:
//! public <U> U[] makeArray() { return new U[10]; }
} ///:~

View File

@ -0,0 +1,29 @@
//: arrays/ArrayOfGenerics.java
package arrays; /* Added by Eclipse.py */
// It is possible to create arrays of generics.
import java.util.*;
public class ArrayOfGenerics {
@SuppressWarnings("unchecked")
public static void main(String[] args) {
List<String>[] ls;
List[] la = new List[10];
ls = (List<String>[])la; // "Unchecked" warning
ls[0] = new ArrayList<String>();
// Compile-time checking produces an error:
//! ls[1] = new ArrayList<Integer>();
// The problem: List<String> is a subtype of Object
Object[] objects = ls; // So assignment is OK
// Compiles and runs without complaint:
objects[1] = new ArrayList<Integer>();
// However, if your needs are straightforward it is
// possible to create an array of generics, albeit
// with an "unchecked" warning:
List<BerylliumSphere>[] spheres =
(List<BerylliumSphere>[])new List[10];
for(int i = 0; i < spheres.length; i++)
spheres[i] = new ArrayList<BerylliumSphere>();
}
} ///:~

View File

@ -0,0 +1,68 @@
//: arrays/ArrayOptions.java
package arrays; /* Added by Eclipse.py */
// Initialization & re-assignment of arrays.
import java.util.*;
import static net.mindview.util.Print.*;
public class ArrayOptions {
public static void main(String[] args) {
// Arrays of objects:
BerylliumSphere[] a; // Local uninitialized variable
BerylliumSphere[] b = new BerylliumSphere[5];
// The references inside the array are
// automatically initialized to null:
print("b: " + Arrays.toString(b));
BerylliumSphere[] c = new BerylliumSphere[4];
for(int i = 0; i < c.length; i++)
if(c[i] == null) // Can test for null reference
c[i] = new BerylliumSphere();
// Aggregate initialization:
BerylliumSphere[] d = { new BerylliumSphere(),
new BerylliumSphere(), new BerylliumSphere()
};
// Dynamic aggregate initialization:
a = new BerylliumSphere[]{
new BerylliumSphere(), new BerylliumSphere(),
};
// (Trailing comma is optional in both cases)
print("a.length = " + a.length);
print("b.length = " + b.length);
print("c.length = " + c.length);
print("d.length = " + d.length);
a = d;
print("a.length = " + a.length);
// Arrays of primitives:
int[] e; // Null reference
int[] f = new int[5];
// The primitives inside the array are
// automatically initialized to zero:
print("f: " + Arrays.toString(f));
int[] g = new int[4];
for(int i = 0; i < g.length; i++)
g[i] = i*i;
int[] h = { 11, 47, 93 };
// Compile error: variable e not initialized:
//!print("e.length = " + e.length);
print("f.length = " + f.length);
print("g.length = " + g.length);
print("h.length = " + h.length);
e = h;
print("e.length = " + e.length);
e = new int[]{ 1, 2 };
print("e.length = " + e.length);
}
} /* Output:
b: [null, null, null, null, null]
a.length = 2
b.length = 5
c.length = 4
d.length = 3
a.length = 3
f: [0, 0, 0, 0, 0]
f.length = 5
g.length = 4
h.length = 3
e.length = 3
e.length = 2
*///:~

View File

@ -0,0 +1,29 @@
//: arrays/ArraySearching.java
package arrays; /* Added by Eclipse.py */
// Using Arrays.binarySearch().
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
public class ArraySearching {
public static void main(String[] args) {
Generator<Integer> gen =
new RandomGenerator.Integer(1000);
int[] a = ConvertTo.primitive(
Generated.array(new Integer[25], gen));
Arrays.sort(a);
print("Sorted array: " + Arrays.toString(a));
while(true) {
int r = gen.next();
int location = Arrays.binarySearch(a, r);
if(location >= 0) {
print("Location of " + r + " is " + location +
", a[" + location + "] = " + a[location]);
break; // Out of while loop
}
}
}
} /* Output:
Sorted array: [128, 140, 200, 207, 258, 258, 278, 288, 322, 429, 511, 520, 522, 551, 555, 589, 693, 704, 809, 861, 861, 868, 916, 961, 998]
Location of 322 is 8, a[8] = 322
*///:~

View File

@ -0,0 +1,19 @@
//: arrays/AssemblingMultidimensionalArrays.java
package arrays; /* Added by Eclipse.py */
// Creating multidimensional arrays.
import java.util.*;
public class AssemblingMultidimensionalArrays {
public static void main(String[] args) {
Integer[][] a;
a = new Integer[3][];
for(int i = 0; i < a.length; i++) {
a[i] = new Integer[3];
for(int j = 0; j < a[i].length; j++)
a[i][j] = i * j; // Autoboxing
}
System.out.println(Arrays.deepToString(a));
}
} /* Output:
[[0, 0, 0], [0, 1, 2], [0, 2, 4]]
*///:~

View File

@ -0,0 +1,17 @@
//: arrays/AutoboxingArrays.java
package arrays; /* Added by Eclipse.py */
import java.util.*;
public class AutoboxingArrays {
public static void main(String[] args) {
Integer[][] a = { // Autoboxing:
{ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 },
{ 21, 22, 23, 24, 25, 26, 27, 28, 29, 30 },
{ 51, 52, 53, 54, 55, 56, 57, 58, 59, 60 },
{ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80 },
};
System.out.println(Arrays.deepToString(a));
}
} /* Output:
[[1, 2, 3, 4, 5, 6, 7, 8, 9, 10], [21, 22, 23, 24, 25, 26, 27, 28, 29, 30], [51, 52, 53, 54, 55, 56, 57, 58, 59, 60], [71, 72, 73, 74, 75, 76, 77, 78, 79, 80]]
*///:~

View File

@ -0,0 +1,55 @@
//: arrays/CompType.java
package arrays; /* Added by Eclipse.py */
// Implementing Comparable in a class.
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
public class CompType implements Comparable<CompType> {
int i;
int j;
private static int count = 1;
public CompType(int n1, int n2) {
i = n1;
j = n2;
}
public String toString() {
String result = "[i = " + i + ", j = " + j + "]";
if(count++ % 3 == 0)
result += "\n";
return result;
}
public int compareTo(CompType rv) {
return (i < rv.i ? -1 : (i == rv.i ? 0 : 1));
}
private static Random r = new Random(47);
public static Generator<CompType> generator() {
return new Generator<CompType>() {
public CompType next() {
return new CompType(r.nextInt(100),r.nextInt(100));
}
};
}
public static void main(String[] args) {
CompType[] a =
Generated.array(new CompType[12], generator());
print("before sorting:");
print(Arrays.toString(a));
Arrays.sort(a);
print("after sorting:");
print(Arrays.toString(a));
}
} /* Output:
before sorting:
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28]
, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61]
, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22]
]
after sorting:
[[i = 9, j = 78], [i = 11, j = 22], [i = 16, j = 40]
, [i = 20, j = 58], [i = 22, j = 7], [i = 51, j = 89]
, [i = 58, j = 55], [i = 61, j = 29], [i = 68, j = 0]
, [i = 88, j = 28], [i = 93, j = 61], [i = 98, j = 61]
]
*///:~

View File

@ -0,0 +1,37 @@
//: arrays/ComparatorTest.java
package arrays; /* Added by Eclipse.py */
// Implementing a Comparator for a class.
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
class CompTypeComparator implements Comparator<CompType> {
public int compare(CompType o1, CompType o2) {
return (o1.j < o2.j ? -1 : (o1.j == o2.j ? 0 : 1));
}
}
public class ComparatorTest {
public static void main(String[] args) {
CompType[] a = Generated.array(
new CompType[12], CompType.generator());
print("before sorting:");
print(Arrays.toString(a));
Arrays.sort(a, new CompTypeComparator());
print("after sorting:");
print(Arrays.toString(a));
}
} /* Output:
before sorting:
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28]
, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61]
, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22]
]
after sorting:
[[i = 68, j = 0], [i = 22, j = 7], [i = 11, j = 22]
, [i = 88, j = 28], [i = 61, j = 29], [i = 16, j = 40]
, [i = 58, j = 55], [i = 20, j = 58], [i = 93, j = 61]
, [i = 98, j = 61], [i = 9, j = 78], [i = 51, j = 89]
]
*///:~

View File

@ -0,0 +1,26 @@
//: arrays/ComparingArrays.java
package arrays; /* Added by Eclipse.py */
// Using Arrays.equals()
import java.util.*;
import static net.mindview.util.Print.*;
public class ComparingArrays {
public static void main(String[] args) {
int[] a1 = new int[10];
int[] a2 = new int[10];
Arrays.fill(a1, 47);
Arrays.fill(a2, 47);
print(Arrays.equals(a1, a2));
a2[3] = 11;
print(Arrays.equals(a1, a2));
String[] s1 = new String[4];
Arrays.fill(s1, "Hi");
String[] s2 = { new String("Hi"), new String("Hi"),
new String("Hi"), new String("Hi") };
print(Arrays.equals(s1, s2));
}
} /* Output:
true
false
true
*///:~

View File

@ -0,0 +1,46 @@
//: arrays/ContainerComparison.java
package arrays; /* Added by Eclipse.py */
import java.util.*;
import static net.mindview.util.Print.*;
class BerylliumSphere {
private static long counter;
private final long id = counter++;
public String toString() { return "Sphere " + id; }
}
public class ContainerComparison {
public static void main(String[] args) {
BerylliumSphere[] spheres = new BerylliumSphere[10];
for(int i = 0; i < 5; i++)
spheres[i] = new BerylliumSphere();
print(Arrays.toString(spheres));
print(spheres[4]);
List<BerylliumSphere> sphereList =
new ArrayList<BerylliumSphere>();
for(int i = 0; i < 5; i++)
sphereList.add(new BerylliumSphere());
print(sphereList);
print(sphereList.get(4));
int[] integers = { 0, 1, 2, 3, 4, 5 };
print(Arrays.toString(integers));
print(integers[4]);
List<Integer> intList = new ArrayList<Integer>(
Arrays.asList(0, 1, 2, 3, 4, 5));
intList.add(97);
print(intList);
print(intList.get(4));
}
} /* Output:
[Sphere 0, Sphere 1, Sphere 2, Sphere 3, Sphere 4, null, null, null, null, null]
Sphere 4
[Sphere 5, Sphere 6, Sphere 7, Sphere 8, Sphere 9]
Sphere 9
[0, 1, 2, 3, 4, 5]
4
[0, 1, 2, 3, 4, 5, 97]
4
*///:~

View File

@ -0,0 +1,43 @@
//: arrays/CopyingArrays.java
package arrays; /* Added by Eclipse.py */
// Using System.arraycopy()
import java.util.*;
import static net.mindview.util.Print.*;
public class CopyingArrays {
public static void main(String[] args) {
int[] i = new int[7];
int[] j = new int[10];
Arrays.fill(i, 47);
Arrays.fill(j, 99);
print("i = " + Arrays.toString(i));
print("j = " + Arrays.toString(j));
System.arraycopy(i, 0, j, 0, i.length);
print("j = " + Arrays.toString(j));
int[] k = new int[5];
Arrays.fill(k, 103);
System.arraycopy(i, 0, k, 0, k.length);
print("k = " + Arrays.toString(k));
Arrays.fill(k, 103);
System.arraycopy(k, 0, i, 0, k.length);
print("i = " + Arrays.toString(i));
// Objects:
Integer[] u = new Integer[10];
Integer[] v = new Integer[5];
Arrays.fill(u, new Integer(47));
Arrays.fill(v, new Integer(99));
print("u = " + Arrays.toString(u));
print("v = " + Arrays.toString(v));
System.arraycopy(v, 0, u, u.length/2, v.length);
print("u = " + Arrays.toString(u));
}
} /* Output:
i = [47, 47, 47, 47, 47, 47, 47]
j = [99, 99, 99, 99, 99, 99, 99, 99, 99, 99]
j = [47, 47, 47, 47, 47, 47, 47, 99, 99, 99]
k = [47, 47, 47, 47, 47]
i = [103, 103, 103, 103, 103, 47, 47]
u = [47, 47, 47, 47, 47, 47, 47, 47, 47, 47]
v = [99, 99, 99, 99, 99]
u = [47, 47, 47, 47, 47, 99, 99, 99, 99, 99]
*///:~

View File

@ -0,0 +1,52 @@
//: arrays/FillingArrays.java
package arrays; /* Added by Eclipse.py */
// Using Arrays.fill()
import java.util.*;
import static net.mindview.util.Print.*;
public class FillingArrays {
public static void main(String[] args) {
int size = 6;
boolean[] a1 = new boolean[size];
byte[] a2 = new byte[size];
char[] a3 = new char[size];
short[] a4 = new short[size];
int[] a5 = new int[size];
long[] a6 = new long[size];
float[] a7 = new float[size];
double[] a8 = new double[size];
String[] a9 = new String[size];
Arrays.fill(a1, true);
print("a1 = " + Arrays.toString(a1));
Arrays.fill(a2, (byte)11);
print("a2 = " + Arrays.toString(a2));
Arrays.fill(a3, 'x');
print("a3 = " + Arrays.toString(a3));
Arrays.fill(a4, (short)17);
print("a4 = " + Arrays.toString(a4));
Arrays.fill(a5, 19);
print("a5 = " + Arrays.toString(a5));
Arrays.fill(a6, 23);
print("a6 = " + Arrays.toString(a6));
Arrays.fill(a7, 29);
print("a7 = " + Arrays.toString(a7));
Arrays.fill(a8, 47);
print("a8 = " + Arrays.toString(a8));
Arrays.fill(a9, "Hello");
print("a9 = " + Arrays.toString(a9));
// Manipulating ranges:
Arrays.fill(a9, 3, 5, "World");
print("a9 = " + Arrays.toString(a9));
}
} /* Output:
a1 = [true, true, true, true, true, true]
a2 = [11, 11, 11, 11, 11, 11]
a3 = [x, x, x, x, x, x]
a4 = [17, 17, 17, 17, 17, 17]
a5 = [19, 19, 19, 19, 19, 19]
a6 = [23, 23, 23, 23, 23, 23]
a7 = [29.0, 29.0, 29.0, 29.0, 29.0, 29.0]
a8 = [47.0, 47.0, 47.0, 47.0, 47.0, 47.0]
a9 = [Hello, Hello, Hello, Hello, Hello, Hello]
a9 = [Hello, Hello, Hello, World, World, Hello]
*///:~

View File

@ -0,0 +1,33 @@
//: arrays/GeneratorsTest.java
package arrays; /* Added by Eclipse.py */
import net.mindview.util.*;
public class GeneratorsTest {
public static int size = 10;
public static void test(Class<?> surroundingClass) {
for(Class<?> type : surroundingClass.getClasses()) {
System.out.print(type.getSimpleName() + ": ");
try {
Generator<?> g = (Generator<?>)type.newInstance();
for(int i = 0; i < size; i++)
System.out.printf(g.next() + " ");
System.out.println();
} catch(Exception e) {
throw new RuntimeException(e);
}
}
}
public static void main(String[] args) {
test(CountingGenerator.class);
}
} /* Output:
Double: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
Float: 0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0
Long: 0 1 2 3 4 5 6 7 8 9
Integer: 0 1 2 3 4 5 6 7 8 9
Short: 0 1 2 3 4 5 6 7 8 9
String: abcdefg hijklmn opqrstu vwxyzAB CDEFGHI JKLMNOP QRSTUVW XYZabcd efghijk lmnopqr
Character: a b c d e f g h i j
Byte: 0 1 2 3 4 5 6 7 8 9
Boolean: true false true false true false true false true false
*///:~

View File

@ -0,0 +1,40 @@
//: arrays/IceCream.java
package arrays; /* Added by Eclipse.py */
// Returning arrays from methods.
import java.util.*;
public class IceCream {
private static Random rand = new Random(47);
static final String[] FLAVORS = {
"Chocolate", "Strawberry", "Vanilla Fudge Swirl",
"Mint Chip", "Mocha Almond Fudge", "Rum Raisin",
"Praline Cream", "Mud Pie"
};
public static String[] flavorSet(int n) {
if(n > FLAVORS.length)
throw new IllegalArgumentException("Set too big");
String[] results = new String[n];
boolean[] picked = new boolean[FLAVORS.length];
for(int i = 0; i < n; i++) {
int t;
do
t = rand.nextInt(FLAVORS.length);
while(picked[t]);
results[i] = FLAVORS[t];
picked[t] = true;
}
return results;
}
public static void main(String[] args) {
for(int i = 0; i < 7; i++)
System.out.println(Arrays.toString(flavorSet(3)));
}
} /* Output:
[Rum Raisin, Mint Chip, Mocha Almond Fudge]
[Chocolate, Strawberry, Mocha Almond Fudge]
[Strawberry, Mint Chip, Mocha Almond Fudge]
[Rum Raisin, Vanilla Fudge Swirl, Mud Pie]
[Vanilla Fudge Swirl, Chocolate, Mocha Almond Fudge]
[Praline Cream, Strawberry, Mocha Almond Fudge]
[Mocha Almond Fudge, Strawberry, Mint Chip]
*///:~

View File

@ -0,0 +1,30 @@
//: arrays/MultiDimWrapperArray.java
package arrays; /* Added by Eclipse.py */
// Multidimensional arrays of "wrapper" objects.
import java.util.*;
public class MultiDimWrapperArray {
public static void main(String[] args) {
Integer[][] a1 = { // Autoboxing
{ 1, 2, 3, },
{ 4, 5, 6, },
};
Double[][][] a2 = { // Autoboxing
{ { 1.1, 2.2 }, { 3.3, 4.4 } },
{ { 5.5, 6.6 }, { 7.7, 8.8 } },
{ { 9.9, 1.2 }, { 2.3, 3.4 } },
};
String[][] a3 = {
{ "The", "Quick", "Sly", "Fox" },
{ "Jumped", "Over" },
{ "The", "Lazy", "Brown", "Dog", "and", "friend" },
};
System.out.println("a1: " + Arrays.deepToString(a1));
System.out.println("a2: " + Arrays.deepToString(a2));
System.out.println("a3: " + Arrays.deepToString(a3));
}
} /* Output:
a1: [[1, 2, 3], [4, 5, 6]]
a2: [[[1.1, 2.2], [3.3, 4.4]], [[5.5, 6.6], [7.7, 8.8]], [[9.9, 1.2], [2.3, 3.4]]]
a3: [[The, Quick, Sly, Fox], [Jumped, Over], [The, Lazy, Brown, Dog, and, friend]]
*///:~

View File

@ -0,0 +1,20 @@
//: arrays/MultidimensionalObjectArrays.java
package arrays; /* Added by Eclipse.py */
import java.util.*;
public class MultidimensionalObjectArrays {
public static void main(String[] args) {
BerylliumSphere[][] spheres = {
{ new BerylliumSphere(), new BerylliumSphere() },
{ new BerylliumSphere(), new BerylliumSphere(),
new BerylliumSphere(), new BerylliumSphere() },
{ new BerylliumSphere(), new BerylliumSphere(),
new BerylliumSphere(), new BerylliumSphere(),
new BerylliumSphere(), new BerylliumSphere(),
new BerylliumSphere(), new BerylliumSphere() },
};
System.out.println(Arrays.deepToString(spheres));
}
} /* Output:
[[Sphere 0, Sphere 1], [Sphere 2, Sphere 3, Sphere 4, Sphere 5], [Sphere 6, Sphere 7, Sphere 8, Sphere 9, Sphere 10, Sphere 11, Sphere 12, Sphere 13]]
*///:~

View File

@ -0,0 +1,16 @@
//: arrays/MultidimensionalPrimitiveArray.java
package arrays; /* Added by Eclipse.py */
// Creating multidimensional arrays.
import java.util.*;
public class MultidimensionalPrimitiveArray {
public static void main(String[] args) {
int[][] a = {
{ 1, 2, 3, },
{ 4, 5, 6, },
};
System.out.println(Arrays.deepToString(a));
}
} /* Output:
[[1, 2, 3], [4, 5, 6]]
*///:~

View File

@ -0,0 +1,23 @@
//: arrays/ParameterizedArrayType.java
package arrays; /* Added by Eclipse.py */
class ClassParameter<T> {
public T[] f(T[] arg) { return arg; }
}
class MethodParameter {
public static <T> T[] f(T[] arg) { return arg; }
}
public class ParameterizedArrayType {
public static void main(String[] args) {
Integer[] ints = { 1, 2, 3, 4, 5 };
Double[] doubles = { 1.1, 2.2, 3.3, 4.4, 5.5 };
Integer[] ints2 =
new ClassParameter<Integer>().f(ints);
Double[] doubles2 =
new ClassParameter<Double>().f(doubles);
ints2 = MethodParameter.f(ints);
doubles2 = MethodParameter.f(doubles);
}
} ///:~

View File

@ -0,0 +1,20 @@
//: arrays/PrimitiveConversionDemonstration.java
package arrays; /* Added by Eclipse.py */
import java.util.*;
import net.mindview.util.*;
public class PrimitiveConversionDemonstration {
public static void main(String[] args) {
Integer[] a = Generated.array(Integer.class,
new CountingGenerator.Integer(), 15);
int[] b = ConvertTo.primitive(a);
System.out.println(Arrays.toString(b));
boolean[] c = ConvertTo.primitive(
Generated.array(Boolean.class,
new CountingGenerator.Boolean(), 7));
System.out.println(Arrays.toString(c));
}
} /* Output:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
[true, false, true, false, true, false, true]
*///:~

View File

@ -0,0 +1,19 @@
//: arrays/RaggedArray.java
package arrays; /* Added by Eclipse.py */
import java.util.*;
public class RaggedArray {
public static void main(String[] args) {
Random rand = new Random(47);
// 3-D array with varied-length vectors:
int[][][] a = new int[rand.nextInt(7)][][];
for(int i = 0; i < a.length; i++) {
a[i] = new int[rand.nextInt(5)][];
for(int j = 0; j < a[i].length; j++)
a[i][j] = new int[rand.nextInt(5)];
}
System.out.println(Arrays.deepToString(a));
}
} /* Output:
[[], [[0], [0], [0, 0, 0, 0]], [[], [0, 0], [0, 0]], [[0, 0, 0], [0], [0, 0, 0, 0]], [[0, 0, 0], [0, 0, 0], [0], []], [[0], [], [0]]]
*///:~

View File

@ -0,0 +1,19 @@
//: arrays/RandomGeneratorsTest.java
package arrays; /* Added by Eclipse.py */
import net.mindview.util.*;
public class RandomGeneratorsTest {
public static void main(String[] args) {
GeneratorsTest.test(RandomGenerator.class);
}
} /* Output:
Double: 0.73 0.53 0.16 0.19 0.52 0.27 0.26 0.05 0.8 0.76
Float: 0.53 0.16 0.53 0.4 0.49 0.25 0.8 0.11 0.02 0.8
Long: 7674 8804 8950 7826 4322 896 8033 2984 2344 5810
Integer: 8303 3141 7138 6012 9966 8689 7185 6992 5746 3976
Short: 3358 20592 284 26791 12834 -8092 13656 29324 -1423 5327
String: bkInaMe sbtWHkj UrUkZPg wsqPzDy CyRFJQA HxxHvHq XumcXZJ oogoYWM NvqeuTp nXsgqia
Character: x x E A J J m z M s
Byte: -60 -17 55 -14 -5 115 39 -37 79 115
Boolean: false true false false true true true true true true
*///:~

View File

@ -0,0 +1,31 @@
//: arrays/Reverse.java
package arrays; /* Added by Eclipse.py */
// The Collections.reverseOrder() Comparator
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
public class Reverse {
public static void main(String[] args) {
CompType[] a = Generated.array(
new CompType[12], CompType.generator());
print("before sorting:");
print(Arrays.toString(a));
Arrays.sort(a, Collections.reverseOrder());
print("after sorting:");
print(Arrays.toString(a));
}
} /* Output:
before sorting:
[[i = 58, j = 55], [i = 93, j = 61], [i = 61, j = 29]
, [i = 68, j = 0], [i = 22, j = 7], [i = 88, j = 28]
, [i = 51, j = 89], [i = 9, j = 78], [i = 98, j = 61]
, [i = 20, j = 58], [i = 16, j = 40], [i = 11, j = 22]
]
after sorting:
[[i = 98, j = 61], [i = 93, j = 61], [i = 88, j = 28]
, [i = 68, j = 0], [i = 61, j = 29], [i = 58, j = 55]
, [i = 51, j = 89], [i = 22, j = 7], [i = 20, j = 58]
, [i = 16, j = 40], [i = 11, j = 22], [i = 9, j = 78]
]
*///:~

View File

@ -0,0 +1,25 @@
//: arrays/StringSorting.java
package arrays; /* Added by Eclipse.py */
// Sorting an array of Strings.
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
public class StringSorting {
public static void main(String[] args) {
String[] sa = Generated.array(new String[20],
new RandomGenerator.String(5));
print("Before sort: " + Arrays.toString(sa));
Arrays.sort(sa);
print("After sort: " + Arrays.toString(sa));
Arrays.sort(sa, Collections.reverseOrder());
print("Reverse sort: " + Arrays.toString(sa));
Arrays.sort(sa, String.CASE_INSENSITIVE_ORDER);
print("Case-insensitive sort: " + Arrays.toString(sa));
}
} /* Output:
Before sort: [YNzbr, nyGcF, OWZnT, cQrGs, eGZMm, JMRoE, suEcU, OneOE, dLsmw, HLGEa, hKcxr, EqUCB, bkIna, Mesbt, WHkjU, rUkZP, gwsqP, zDyCy, RFJQA, HxxHv]
After sort: [EqUCB, HLGEa, HxxHv, JMRoE, Mesbt, OWZnT, OneOE, RFJQA, WHkjU, YNzbr, bkIna, cQrGs, dLsmw, eGZMm, gwsqP, hKcxr, nyGcF, rUkZP, suEcU, zDyCy]
Reverse sort: [zDyCy, suEcU, rUkZP, nyGcF, hKcxr, gwsqP, eGZMm, dLsmw, cQrGs, bkIna, YNzbr, WHkjU, RFJQA, OneOE, OWZnT, Mesbt, JMRoE, HxxHv, HLGEa, EqUCB]
Case-insensitive sort: [bkIna, cQrGs, dLsmw, eGZMm, EqUCB, gwsqP, hKcxr, HLGEa, HxxHv, JMRoE, Mesbt, nyGcF, OneOE, OWZnT, RFJQA, rUkZP, suEcU, WHkjU, YNzbr, zDyCy]
*///:~

View File

@ -0,0 +1,46 @@
//: arrays/TestArrayGeneration.java
package arrays; /* Added by Eclipse.py */
// Test the tools that use generators to fill arrays.
import java.util.*;
import net.mindview.util.*;
import static net.mindview.util.Print.*;
public class TestArrayGeneration {
public static void main(String[] args) {
int size = 6;
boolean[] a1 = ConvertTo.primitive(Generated.array(
Boolean.class, new RandomGenerator.Boolean(), size));
print("a1 = " + Arrays.toString(a1));
byte[] a2 = ConvertTo.primitive(Generated.array(
Byte.class, new RandomGenerator.Byte(), size));
print("a2 = " + Arrays.toString(a2));
char[] a3 = ConvertTo.primitive(Generated.array(
Character.class,
new RandomGenerator.Character(), size));
print("a3 = " + Arrays.toString(a3));
short[] a4 = ConvertTo.primitive(Generated.array(
Short.class, new RandomGenerator.Short(), size));
print("a4 = " + Arrays.toString(a4));
int[] a5 = ConvertTo.primitive(Generated.array(
Integer.class, new RandomGenerator.Integer(), size));
print("a5 = " + Arrays.toString(a5));
long[] a6 = ConvertTo.primitive(Generated.array(
Long.class, new RandomGenerator.Long(), size));
print("a6 = " + Arrays.toString(a6));
float[] a7 = ConvertTo.primitive(Generated.array(
Float.class, new RandomGenerator.Float(), size));
print("a7 = " + Arrays.toString(a7));
double[] a8 = ConvertTo.primitive(Generated.array(
Double.class, new RandomGenerator.Double(), size));
print("a8 = " + Arrays.toString(a8));
}
} /* Output:
a1 = [true, false, true, false, false, true]
a2 = [104, -79, -76, 126, 33, -64]
a3 = [Z, n, T, c, Q, r]
a4 = [-13408, 22612, 15401, 15161, -28466, -12603]
a5 = [7704, 7383, 7706, 575, 8410, 6342]
a6 = [7674, 8804, 8950, 7826, 4322, 896]
a7 = [0.01, 0.2, 0.4, 0.79, 0.27, 0.45]
a8 = [0.16, 0.87, 0.7, 0.66, 0.87, 0.59]
*///:~

View File

@ -0,0 +1,20 @@
//: arrays/TestGenerated.java
package arrays; /* Added by Eclipse.py */
import java.util.*;
import net.mindview.util.*;
public class TestGenerated {
public static void main(String[] args) {
Integer[] a = { 9, 8, 7, 6 };
System.out.println(Arrays.toString(a));
a = Generated.array(a,new CountingGenerator.Integer());
System.out.println(Arrays.toString(a));
Integer[] b = Generated.array(Integer.class,
new CountingGenerator.Integer(), 15);
System.out.println(Arrays.toString(b));
}
} /* Output:
[9, 8, 7, 6]
[0, 1, 2, 3]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]
*///:~

View File

@ -0,0 +1,13 @@
//: arrays/ThreeDWithNew.java
package arrays; /* Added by Eclipse.py */
import java.util.*;
public class ThreeDWithNew {
public static void main(String[] args) {
// 3-D array with fixed length:
int[][][] a = new int[2][2][4];
System.out.println(Arrays.deepToString(a));
}
} /* Output:
[[[0, 0, 0, 0], [0, 0, 0, 0]], [[0, 0, 0, 0], [0, 0, 0, 0]]]
*///:~

330
src/main/java/arrays/build.xml Executable file
View File

@ -0,0 +1,330 @@
<?xml version="1.0" ?>
<project
basedir="."
default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: arrays)">
<description>
build.xml for the source code for the arrays chapter of
Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt
Ant available from: http://jakarta.apache.org/ant
To see options, type: ant -p
This file was automatically generated by AntBuilder
</description>
<condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/>
</condition>
<target name="net_mindview_util">
<javac
classpath="${basedir}/.."
srcdir="${basedir}/../net/mindview/util/">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
</target>
<target
depends="net_mindview_util"
description="Build all classes in this directory"
name="build">
<fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'arrays'"/>
<javac
classpath="${basedir}/.."
debug="true"
srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
<echo message="Build 'arrays' succeeded"/>
</target>
<target name="AlphabeticSearch">
<java
classname="AlphabeticSearch"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ArrayOfGenerics">
<java
classname="ArrayOfGenerics"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ArrayOptions">
<java
classname="ArrayOptions"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ArraySearching">
<java
classname="ArraySearching"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="AssemblingMultidimensionalArrays">
<java
classname="AssemblingMultidimensionalArrays"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="AutoboxingArrays">
<java
classname="AutoboxingArrays"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ComparatorTest">
<java
classname="ComparatorTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ComparingArrays">
<java
classname="ComparingArrays"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="CompType">
<java
classname="CompType"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ContainerComparison">
<java
classname="ContainerComparison"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="CopyingArrays">
<java
classname="CopyingArrays"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="FillingArrays">
<java
classname="FillingArrays"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="GeneratorsTest">
<java
classname="GeneratorsTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="IceCream">
<java
classname="IceCream"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="MultidimensionalObjectArrays">
<java
classname="MultidimensionalObjectArrays"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="MultidimensionalPrimitiveArray">
<java
classname="MultidimensionalPrimitiveArray"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="MultiDimWrapperArray">
<java
classname="MultiDimWrapperArray"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ParameterizedArrayType">
<java
classname="ParameterizedArrayType"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="PrimitiveConversionDemonstration">
<java
classname="PrimitiveConversionDemonstration"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="RaggedArray">
<java
classname="RaggedArray"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="RandomGeneratorsTest">
<java
classname="RandomGeneratorsTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="Reverse">
<java
classname="Reverse"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="StringSorting">
<java
classname="StringSorting"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="TestArrayGeneration">
<java
classname="TestArrayGeneration"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="TestGenerated">
<java
classname="TestGenerated"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target name="ThreeDWithNew">
<java
classname="ThreeDWithNew"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../arrays/"
failonerror="true"
fork="true"/>
</target>
<target
depends="build"
description="Compile and run"
name="run">
<touch file="failures"/>
<antcall target="AlphabeticSearch"/>
<antcall target="ArrayOfGenerics"/>
<antcall target="ArrayOptions"/>
<antcall target="ArraySearching"/>
<antcall target="AssemblingMultidimensionalArrays"/>
<antcall target="AutoboxingArrays"/>
<antcall target="ComparatorTest"/>
<antcall target="ComparingArrays"/>
<antcall target="CompType"/>
<antcall target="ContainerComparison"/>
<antcall target="CopyingArrays"/>
<antcall target="FillingArrays"/>
<antcall target="GeneratorsTest"/>
<antcall target="IceCream"/>
<antcall target="MultidimensionalObjectArrays"/>
<antcall target="MultidimensionalPrimitiveArray"/>
<antcall target="MultiDimWrapperArray"/>
<antcall target="ParameterizedArrayType"/>
<antcall target="PrimitiveConversionDemonstration"/>
<antcall target="RaggedArray"/>
<antcall target="RandomGeneratorsTest"/>
<antcall target="Reverse"/>
<antcall target="StringSorting"/>
<antcall target="TestArrayGeneration"/>
<antcall target="TestGenerated"/>
<antcall target="ThreeDWithNew"/>
<delete file="failures"/>
</target>
<target description="delete all byproducts" name="clean">
<delete>
<fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/>
</delete>
<echo message="clean successful"/>
</target>
</project>

View File

@ -0,0 +1,81 @@
//: bangbean/BangBean.java
// A graphical Bean.
package bangbean;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
public class
BangBean extends JPanel implements Serializable {
private int xm, ym;
private int cSize = 20; // Circle size
private String text = "Bang!";
private int fontSize = 48;
private Color tColor = Color.RED;
private ActionListener actionListener;
public BangBean() {
addMouseListener(new ML());
addMouseMotionListener(new MML());
}
public int getCircleSize() { return cSize; }
public void setCircleSize(int newSize) {
cSize = newSize;
}
public String getBangText() { return text; }
public void setBangText(String newText) {
text = newText;
}
public int getFontSize() { return fontSize; }
public void setFontSize(int newSize) {
fontSize = newSize;
}
public Color getTextColor() { return tColor; }
public void setTextColor(Color newColor) {
tColor = newColor;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawOval(xm - cSize/2, ym - cSize/2, cSize, cSize);
}
// This is a unicast listener, which is
// the simplest form of listener management:
public void addActionListener(ActionListener l)
throws TooManyListenersException {
if(actionListener != null)
throw new TooManyListenersException();
actionListener = l;
}
public void removeActionListener(ActionListener l) {
actionListener = null;
}
class ML extends MouseAdapter {
public void mousePressed(MouseEvent e) {
Graphics g = getGraphics();
g.setColor(tColor);
g.setFont(
new Font("TimesRoman", Font.BOLD, fontSize));
int width = g.getFontMetrics().stringWidth(text);
g.drawString(text, (getSize().width - width) /2,
getSize().height/2);
g.dispose();
// Call the listener's method:
if(actionListener != null)
actionListener.actionPerformed(
new ActionEvent(BangBean.this,
ActionEvent.ACTION_PERFORMED, null));
}
}
class MML extends MouseMotionAdapter {
public void mouseMoved(MouseEvent e) {
xm = e.getX();
ym = e.getY();
repaint();
}
}
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
} ///:~

View File

@ -0,0 +1,32 @@
//: bangbean/BangBeanTest.java
// {Timeout: 5} Abort after 5 seconds when testing
package bangbean;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import static net.mindview.util.SwingConsole.*;
public class BangBeanTest extends JFrame {
private JTextField txt = new JTextField(20);
// During testing, report actions:
class BBL implements ActionListener {
private int count = 0;
public void actionPerformed(ActionEvent e) {
txt.setText("BangBean action "+ count++);
}
}
public BangBeanTest() {
BangBean bb = new BangBean();
try {
bb.addActionListener(new BBL());
} catch(TooManyListenersException e) {
txt.setText("Too many listeners");
}
add(bb);
add(BorderLayout.SOUTH, txt);
}
public static void main(String[] args) {
run(new BangBeanTest(), 400, 500);
}
} ///:~

View File

@ -0,0 +1,73 @@
<?xml version="1.0" ?>
<project
basedir="."
default="run"
name="Thinking in Java, 4th Edition by Bruce Eckel (chapter: bangbean)">
<description>
build.xml for the source code for the bangbean chapter of
Thinking in Java, 4th Edition by Bruce Eckel
Source code available at http://www.MindView.net
See copyright notice in CopyRight.txt
Ant available from: http://jakarta.apache.org/ant
To see options, type: ant -p
This file was automatically generated by AntBuilder
</description>
<condition property="version1.5">
<equals arg1="1.5" arg2="${ant.java.version}"/>
</condition>
<target
depends=""
description="Build all classes in this directory"
name="build">
<fail message="J2SE5 required" unless="version1.5"/>
<echo message="Building 'bangbean'"/>
<javac
classpath="${basedir}/.."
debug="true"
srcdir="${basedir}">
<compilerarg value="-Xmaxerrs"/>
<compilerarg value="10"/>
</javac>
<echo message="Build 'bangbean' succeeded"/>
</target>
<target name="BangBeanTest">
<java
classname="bangbean.BangBeanTest"
classpath="${java.class.path};${basedir};${basedir}/.."
dir="../bangbean/"
failonerror="false"
fork="true"
timeout="5000"/>
<echo message="* Exception was expected *"/>
</target>
<target
depends="build"
description="Compile and run"
name="run">
<touch file="failures"/>
<antcall target="BangBeanTest"/>
<delete file="failures"/>
</target>
<target description="delete all byproducts" name="clean">
<delete>
<fileset dir="${basedir}" includes="**/*.class"/>
<fileset dir="${basedir}" includes="**/*Output.txt"/>
<fileset dir="${basedir}" includes="**/log.txt"/>
<fileset dir="${basedir}" includes="failures"/>
</delete>
<echo message="clean successful"/>
</target>
</project>

28
src/main/java/chapterOrder.xml Executable file
View File

@ -0,0 +1,28 @@
<filelist id="buildfiles" dir="."
files="object/build.xml
operators/build.xml
control/build.xml
initialization/build.xml
access/build.xml
net/build.xml
reusing/build.xml
polymorphism/build.xml
interfaces/build.xml
innerclasses/build.xml
holding/build.xml
exceptions/build.xml
strings/build.xml
typeinfo/build.xml
generics/build.xml
arrays/build.xml
containers/build.xml
io/build.xml
xml/build.xml
enumerated/build.xml
annotations/build.xml
concurrency/build.xml
gui/build.xml
frogbean/build.xml
bangbean/build.xml
swt/build.xml
"/>

View File

@ -0,0 +1,90 @@
//: concurrency/ActiveObjectDemo.java
package concurrency; /* Added by Eclipse.py */
// Can only pass constants, immutables, "disconnected
// objects," or other active objects as arguments
// to asynch methods.
import java.util.concurrent.*;
import java.util.*;
import static net.mindview.util.Print.*;
public class ActiveObjectDemo {
private ExecutorService ex =
Executors.newSingleThreadExecutor();
private Random rand = new Random(47);
// Insert a random delay to produce the effect
// of a calculation time:
private void pause(int factor) {
try {
TimeUnit.MILLISECONDS.sleep(
100 + rand.nextInt(factor));
} catch(InterruptedException e) {
print("sleep() interrupted");
}
}
public Future<Integer>
calculateInt(final int x, final int y) {
return ex.submit(new Callable<Integer>() {
public Integer call() {
print("starting " + x + " + " + y);
pause(500);
return x + y;
}
});
}
public Future<Float>
calculateFloat(final float x, final float y) {
return ex.submit(new Callable<Float>() {
public Float call() {
print("starting " + x + " + " + y);
pause(2000);
return x + y;
}
});
}
public void shutdown() { ex.shutdown(); }
public static void main(String[] args) {
ActiveObjectDemo d1 = new ActiveObjectDemo();
// Prevents ConcurrentModificationException:
List<Future<?>> results =
new CopyOnWriteArrayList<Future<?>>();
for(float f = 0.0f; f < 1.0f; f += 0.2f)
results.add(d1.calculateFloat(f, f));
for(int i = 0; i < 5; i++)
results.add(d1.calculateInt(i, i));
print("All asynch calls made");
while(results.size() > 0) {
for(Future<?> f : results)
if(f.isDone()) {
try {
print(f.get());
} catch(Exception e) {
throw new RuntimeException(e);
}
results.remove(f);
}
}
d1.shutdown();
}
} /* Output: (85% match)
All asynch calls made
starting 0.0 + 0.0
starting 0.2 + 0.2
0.0
starting 0.4 + 0.4
0.4
starting 0.6 + 0.6
0.8
starting 0.8 + 0.8
1.2
starting 0 + 0
1.6
starting 1 + 1
0
starting 2 + 2
2
starting 3 + 3
4
starting 4 + 4
6
8
*///:~

View File

@ -0,0 +1,16 @@
//: concurrency/AtomicEvenGenerator.java
package concurrency; /* Added by Eclipse.py */
// Atomic classes are occasionally useful in regular code.
// {RunByHand}
import java.util.concurrent.atomic.*;
public class AtomicEvenGenerator extends IntGenerator {
private AtomicInteger currentEvenValue =
new AtomicInteger(0);
public int next() {
return currentEvenValue.addAndGet(2);
}
public static void main(String[] args) {
EvenChecker.test(new AtomicEvenGenerator());
}
} ///:~

View File

@ -0,0 +1,33 @@
//: concurrency/AtomicIntegerTest.java
package concurrency; /* Added by Eclipse.py */
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
import java.util.*;
public class AtomicIntegerTest implements Runnable {
private AtomicInteger i = new AtomicInteger(0);
public int getValue() { return i.get(); }
private void evenIncrement() { i.addAndGet(2); }
public void run() {
while(true)
evenIncrement();
}
public static void main(String[] args) {
new Timer().schedule(new TimerTask() {
public void run() {
System.err.println("Aborting");
System.exit(0);
}
}, 5000); // Terminate after 5 seconds
ExecutorService exec = Executors.newCachedThreadPool();
AtomicIntegerTest ait = new AtomicIntegerTest();
exec.execute(ait);
while(true) {
int val = ait.getValue();
if(val % 2 != 0) {
System.out.println(val);
System.exit(0);
}
}
}
} ///:~

View File

@ -0,0 +1,30 @@
//: concurrency/Atomicity.java
package concurrency; /* Added by Eclipse.py */
// {Exec: javap -c Atomicity}
public class Atomicity {
int i;
void f1() { i++; }
void f2() { i += 3; }
} /* Output: (Sample)
...
void f1();
Code:
0: aload_0
1: dup
2: getfield #2; //Field i:I
5: iconst_1
6: iadd
7: putfield #2; //Field i:I
10: return
void f2();
Code:
0: aload_0
1: dup
2: getfield #2; //Field i:I
5: iconst_3
6: iadd
7: putfield #2; //Field i:I
10: return
*///:~

View File

@ -0,0 +1,27 @@
//: concurrency/AtomicityTest.java
package concurrency; /* Added by Eclipse.py */
import java.util.concurrent.*;
public class AtomicityTest implements Runnable {
private int i = 0;
public int getValue() { return i; }
private synchronized void evenIncrement() { i++; i++; }
public void run() {
while(true)
evenIncrement();
}
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
AtomicityTest at = new AtomicityTest();
exec.execute(at);
while(true) {
int val = at.getValue();
if(val % 2 != 0) {
System.out.println(val);
System.exit(0);
}
}
}
} /* Output: (Sample)
191583767
*///:~

View File

@ -0,0 +1,56 @@
//: concurrency/AttemptLocking.java
package concurrency; /* Added by Eclipse.py */
// Locks in the concurrent library allow you
// to give up on trying to acquire a lock.
import java.util.concurrent.*;
import java.util.concurrent.locks.*;
public class AttemptLocking {
private ReentrantLock lock = new ReentrantLock();
public void untimed() {
boolean captured = lock.tryLock();
try {
System.out.println("tryLock(): " + captured);
} finally {
if(captured)
lock.unlock();
}
}
public void timed() {
boolean captured = false;
try {
captured = lock.tryLock(2, TimeUnit.SECONDS);
} catch(InterruptedException e) {
throw new RuntimeException(e);
}
try {
System.out.println("tryLock(2, TimeUnit.SECONDS): " +
captured);
} finally {
if(captured)
lock.unlock();
}
}
public static void main(String[] args) {
final AttemptLocking al = new AttemptLocking();
al.untimed(); // True -- lock is available
al.timed(); // True -- lock is available
// Now create a separate task to grab the lock:
new Thread() {
{ setDaemon(true); }
public void run() {
al.lock.lock();
System.out.println("acquired");
}
}.start();
Thread.yield(); // Give the 2nd task a chance
al.untimed(); // False -- lock grabbed by task
al.timed(); // False -- lock grabbed by task
}
} /* Output:
tryLock(): true
tryLock(2, TimeUnit.SECONDS): true
acquired
tryLock(): false
tryLock(2, TimeUnit.SECONDS): false
*///:~

View File

@ -0,0 +1,205 @@
//: concurrency/BankTellerSimulation.java
package concurrency; /* Added by Eclipse.py */
// Using queues and multithreading.
// {Args: 5}
import java.util.concurrent.*;
import java.util.*;
// Read-only objects don't require synchronization:
class Customer {
private final int serviceTime;
public Customer(int tm) { serviceTime = tm; }
public int getServiceTime() { return serviceTime; }
public String toString() {
return "[" + serviceTime + "]";
}
}
// Teach the customer line to display itself:
class CustomerLine extends ArrayBlockingQueue<Customer> {
public CustomerLine(int maxLineSize) {
super(maxLineSize);
}
public String toString() {
if(this.size() == 0)
return "[Empty]";
StringBuilder result = new StringBuilder();
for(Customer customer : this)
result.append(customer);
return result.toString();
}
}
// Randomly add customers to a queue:
class CustomerGenerator implements Runnable {
private CustomerLine customers;
private static Random rand = new Random(47);
public CustomerGenerator(CustomerLine cq) {
customers = cq;
}
public void run() {
try {
while(!Thread.interrupted()) {
TimeUnit.MILLISECONDS.sleep(rand.nextInt(300));
customers.put(new Customer(rand.nextInt(1000)));
}
} catch(InterruptedException e) {
System.out.println("CustomerGenerator interrupted");
}
System.out.println("CustomerGenerator terminating");
}
}
class Teller implements Runnable, Comparable<Teller> {
private static int counter = 0;
private final int id = counter++;
// Customers served during this shift:
private int customersServed = 0;
private CustomerLine customers;
private boolean servingCustomerLine = true;
public Teller(CustomerLine cq) { customers = cq; }
public void run() {
try {
while(!Thread.interrupted()) {
Customer customer = customers.take();
TimeUnit.MILLISECONDS.sleep(
customer.getServiceTime());
synchronized(this) {
customersServed++;
while(!servingCustomerLine)
wait();
}
}
} catch(InterruptedException e) {
System.out.println(this + "interrupted");
}
System.out.println(this + "terminating");
}
public synchronized void doSomethingElse() {
customersServed = 0;
servingCustomerLine = false;
}
public synchronized void serveCustomerLine() {
assert !servingCustomerLine:"already serving: " + this;
servingCustomerLine = true;
notifyAll();
}
public String toString() { return "Teller " + id + " "; }
public String shortString() { return "T" + id; }
// Used by priority queue:
public synchronized int compareTo(Teller other) {
return customersServed < other.customersServed ? -1 :
(customersServed == other.customersServed ? 0 : 1);
}
}
class TellerManager implements Runnable {
private ExecutorService exec;
private CustomerLine customers;
private PriorityQueue<Teller> workingTellers =
new PriorityQueue<Teller>();
private Queue<Teller> tellersDoingOtherThings =
new LinkedList<Teller>();
private int adjustmentPeriod;
private static Random rand = new Random(47);
public TellerManager(ExecutorService e,
CustomerLine customers, int adjustmentPeriod) {
exec = e;
this.customers = customers;
this.adjustmentPeriod = adjustmentPeriod;
// Start with a single teller:
Teller teller = new Teller(customers);
exec.execute(teller);
workingTellers.add(teller);
}
public void adjustTellerNumber() {
// This is actually a control system. By adjusting
// the numbers, you can reveal stability issues in
// the control mechanism.
// If line is too long, add another teller:
if(customers.size() / workingTellers.size() > 2) {
// If tellers are on break or doing
// another job, bring one back:
if(tellersDoingOtherThings.size() > 0) {
Teller teller = tellersDoingOtherThings.remove();
teller.serveCustomerLine();
workingTellers.offer(teller);
return;
}
// Else create (hire) a new teller
Teller teller = new Teller(customers);
exec.execute(teller);
workingTellers.add(teller);
return;
}
// If line is short enough, remove a teller:
if(workingTellers.size() > 1 &&
customers.size() / workingTellers.size() < 2)
reassignOneTeller();
// If there is no line, we only need one teller:
if(customers.size() == 0)
while(workingTellers.size() > 1)
reassignOneTeller();
}
// Give a teller a different job or a break:
private void reassignOneTeller() {
Teller teller = workingTellers.poll();
teller.doSomethingElse();
tellersDoingOtherThings.offer(teller);
}
public void run() {
try {
while(!Thread.interrupted()) {
TimeUnit.MILLISECONDS.sleep(adjustmentPeriod);
adjustTellerNumber();
System.out.print(customers + " { ");
for(Teller teller : workingTellers)
System.out.print(teller.shortString() + " ");
System.out.println("}");
}
} catch(InterruptedException e) {
System.out.println(this + "interrupted");
}
System.out.println(this + "terminating");
}
public String toString() { return "TellerManager "; }
}
public class BankTellerSimulation {
static final int MAX_LINE_SIZE = 50;
static final int ADJUSTMENT_PERIOD = 1000;
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool();
// If line is too long, customers will leave:
CustomerLine customers =
new CustomerLine(MAX_LINE_SIZE);
exec.execute(new CustomerGenerator(customers));
// Manager will add and remove tellers as necessary:
exec.execute(new TellerManager(
exec, customers, ADJUSTMENT_PERIOD));
if(args.length > 0) // Optional argument
TimeUnit.SECONDS.sleep(new Integer(args[0]));
else {
System.out.println("Press 'Enter' to quit");
System.in.read();
}
exec.shutdownNow();
}
} /* Output: (Sample)
[429][200][207] { T0 T1 }
[861][258][140][322] { T0 T1 }
[575][342][804][826][896][984] { T0 T1 T2 }
[984][810][141][12][689][992][976][368][395][354] { T0 T1 T2 T3 }
Teller 2 interrupted
Teller 2 terminating
Teller 1 interrupted
Teller 1 terminating
TellerManager interrupted
TellerManager terminating
Teller 3 interrupted
Teller 3 terminating
Teller 0 interrupted
Teller 0 terminating
CustomerGenerator interrupted
CustomerGenerator terminating
*///:~

View File

@ -0,0 +1,14 @@
//: concurrency/BasicThreads.java
package concurrency; /* Added by Eclipse.py */
// The most basic use of the Thread class.
public class BasicThreads {
public static void main(String[] args) {
Thread t = new Thread(new LiftOff());
t.start();
System.out.println("Waiting for LiftOff");
}
} /* Output: (90% match)
Waiting for LiftOff
#0(9), #0(8), #0(7), #0(6), #0(5), #0(4), #0(3), #0(2), #0(1), #0(Liftoff!),
*///:~

View File

@ -0,0 +1,14 @@
//: concurrency/CachedThreadPool.java
package concurrency; /* Added by Eclipse.py */
import java.util.concurrent.*;
public class CachedThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
for(int i = 0; i < 5; i++)
exec.execute(new LiftOff());
exec.shutdown();
}
} /* Output: (Sample)
#0(9), #0(8), #1(9), #2(9), #3(9), #4(9), #0(7), #1(8), #2(8), #3(8), #4(8), #0(6), #1(7), #2(7), #3(7), #4(7), #0(5), #1(6), #2(6), #3(6), #4(6), #0(4), #1(5), #2(5), #3(5), #4(5), #0(3), #1(4), #2(4), #3(4), #4(4), #0(2), #1(3), #2(3), #3(3), #4(3), #0(1), #1(2), #2(2), #3(2), #4(2), #0(Liftoff!), #1(1), #2(1), #3(1), #4(1), #1(Liftoff!), #2(Liftoff!), #3(Liftoff!), #4(Liftoff!),
*///:~

View File

@ -0,0 +1,47 @@
//: concurrency/CallableDemo.java
package concurrency; /* Added by Eclipse.py */
import java.util.concurrent.*;
import java.util.*;
class TaskWithResult implements Callable<String> {
private int id;
public TaskWithResult(int id) {
this.id = id;
}
public String call() {
return "result of TaskWithResult " + id;
}
}
public class CallableDemo {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results =
new ArrayList<Future<String>>();
for(int i = 0; i < 10; i++)
results.add(exec.submit(new TaskWithResult(i)));
for(Future<String> fs : results)
try {
// get() blocks until completion:
System.out.println(fs.get());
} catch(InterruptedException e) {
System.out.println(e);
return;
} catch(ExecutionException e) {
System.out.println(e);
} finally {
exec.shutdown();
}
}
} /* Output:
result of TaskWithResult 0
result of TaskWithResult 1
result of TaskWithResult 2
result of TaskWithResult 3
result of TaskWithResult 4
result of TaskWithResult 5
result of TaskWithResult 6
result of TaskWithResult 7
result of TaskWithResult 8
result of TaskWithResult 9
*///:~

View File

@ -0,0 +1,48 @@
//: concurrency/CaptureUncaughtException.java
package concurrency; /* Added by Eclipse.py */
import java.util.concurrent.*;
class ExceptionThread2 implements Runnable {
public void run() {
Thread t = Thread.currentThread();
System.out.println("run() by " + t);
System.out.println(
"eh = " + t.getUncaughtExceptionHandler());
throw new RuntimeException();
}
}
class MyUncaughtExceptionHandler implements
Thread.UncaughtExceptionHandler {
public void uncaughtException(Thread t, Throwable e) {
System.out.println("caught " + e);
}
}
class HandlerThreadFactory implements ThreadFactory {
public Thread newThread(Runnable r) {
System.out.println(this + " creating new Thread");
Thread t = new Thread(r);
System.out.println("created " + t);
t.setUncaughtExceptionHandler(
new MyUncaughtExceptionHandler());
System.out.println(
"eh = " + t.getUncaughtExceptionHandler());
return t;
}
}
public class CaptureUncaughtException {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool(
new HandlerThreadFactory());
exec.execute(new ExceptionThread2());
}
} /* Output: (90% match)
HandlerThreadFactory@de6ced creating new Thread
created Thread[Thread-0,5,main]
eh = MyUncaughtExceptionHandler@1fb8ee3
run() by Thread[Thread-0,5,main]
eh = MyUncaughtExceptionHandler@1fb8ee3
caught java.lang.RuntimeException
*///:~

Some files were not shown because too many files have changed in this diff Show More