diff options
author | Stephan Herrmann | 2010-04-21 16:18:00 +0000 |
---|---|---|
committer | Stephan Herrmann | 2010-04-21 16:18:00 +0000 |
commit | 3605c8228f8610fcd3ab135dccf7a9e963766137 (patch) | |
tree | baaad39732000f6f98038eb3c2c254cb91850e14 /othersrc/otdt-examples | |
parent | d5ab1505dee109bbb1aac3d6e5312d3560a876ea (diff) | |
download | org.eclipse.objectteams-3605c8228f8610fcd3ab135dccf7a9e963766137.tar.gz org.eclipse.objectteams-3605c8228f8610fcd3ab135dccf7a9e963766137.tar.xz org.eclipse.objectteams-3605c8228f8610fcd3ab135dccf7a9e963766137.zip |
initial contribution "Object Teams Examples" as approved in CQ 3793
Diffstat (limited to 'othersrc/otdt-examples')
90 files changed, 8029 insertions, 0 deletions
diff --git a/othersrc/otdt-examples/OTSample-ATM-src/.classpath b/othersrc/otdt-examples/OTSample-ATM-src/.classpath new file mode 100644 index 000000000..bcc3bc2b8 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="OTRE"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/othersrc/otdt-examples/OTSample-ATM-src/.project b/othersrc/otdt-examples/OTSample-ATM-src/.project new file mode 100644 index 000000000..0bd56e57c --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>OTSample-ATM-src</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.objectteams.otdt.builder.OTJBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.objectteams.otdt.OTJavaNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/othersrc/otdt-examples/OTSample-ATM-src/.settings/org.eclipse.jdt.core.prefs b/othersrc/otdt-examples/OTSample-ATM-src/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..3ea64814e --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,64 @@ +#Sat Jul 18 22:09:19 CEST 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning diff --git a/othersrc/otdt-examples/OTSample-ATM-src/atm-zip.jardesc b/othersrc/otdt-examples/OTSample-ATM-src/atm-zip.jardesc new file mode 100644 index 000000000..100efff54 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/atm-zip.jardesc @@ -0,0 +1,12 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<jardesc> + <jar path="org.eclipse.objectteams.otdt.samples/samples/atm.zip"/> + <options buildIfNeeded="true" compress="true" descriptionLocation="/OTSample-ATM-src/atm-zip.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="true"/> + <storedRefactorings deprecationInfo="true" structuralOnly="false"/> + <selectedProjects/> + <selectedElements exportClassFiles="false" exportJavaFiles="true" exportOutputFolder="false"> + <file path="/OTSample-ATM-src/.classpath"/> + <file path="/OTSample-ATM-src/.project"/> + <javaElement handleIdentifier="=OTSample-ATM-src/src"/> + </selectedElements> +</jardesc> diff --git a/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/ATM.java b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/ATM.java new file mode 100644 index 000000000..e873b3a89 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/ATM.java @@ -0,0 +1,116 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.atm; +import org.objectteams.ImplicitTeamActivation; + +/** + * This team realizes the ATM. + * An ATM belongs to a certain bank and only for withdrawal from a foreign account + * an additional fee is debited. Furthermore it is not possible to query the balance + * of a foreign account. + */ +@ImplicitTeamActivation +public team class ATM { + private Bank myBank; + private Account feeAccount; + + public ATM(Bank bank) { + myBank = bank; + feeAccount = new Account(bank); + } + + /** + * Returns the balance of the fee account. + */ + int getFeeAccountBalance() { + return feeAccount.getBalance(); + } + + /** + * Pays the given amount of cash from the given account, if it contains enough money. + */ + public int payCash(Account account, int amount) { + boolean ok = account.debit(amount); + if (ok) + return amount; + else + return 0; + } + + /** + * Returns the balance of the given Account object. If an exception is thrown while accessing the + * balance of the account this method throws an AccessDeniedException. + */ + public int getBalance(Account account) throws AccessDeniedException { + try { + return account.getBalance(); + } catch (Exception e) { + throw new AccessDeniedException(); + } + } + + /** + * This role is responsible for the different handling of accounts belonging to a different bank + * than the ATM does (foreign accounts). + * + * The guard predicate attached to the ForeignAccount role ensures that this role and therefore + * all its callin bindings are only effective for foreign accounts. It checks, if the bank of the base + * object to be lifted is different from the bank of the ATM. + */ + public class ForeignAccount playedBy Account + base when (!(ATM.this.myBank.equals(base.getBank()))) + { + /** + * This callin method calls its base method with the given amount plus an additional fee. + */ + callin boolean debitWithFee(int amount) { + int fee = calculateFee(amount); + if (base.debitWithFee(fee+amount)) { + System.out.println("Debiting from a foreign account: Additional fee of "+fee+" Euro will be debited!"); + feeAccount.credit(fee); + return true; + } + return false; + } + /** + * Binds the role method debitWithFee to the base method debit of the base class Account. + */ + debitWithFee <- replace debit; + + /** + * Restricting the query of balance, is realized as another callin method denying the call to + * getBalance for foreign accounts. Because of the role predicate, this callin method is not called for own accounts. + */ + callin int checkedGetBalance() { + throw new RuntimeException("Access to balance of foreign account not allowed!"); + } + + /** + * Binds the role method checkedGetBalance to the base method getBalance of the base class Account. + */ + checkedGetBalance <- replace getBalance; + + /** + * Returns the fee for debiting the given amount from a foreign account. + * Here this is a fixed fee of 5%. + */ + public int calculateFee(int amount) { + int feePercent = 5; + return (amount/100)*feePercent; + } + } +} diff --git a/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/AccessDeniedException.java b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/AccessDeniedException.java new file mode 100644 index 000000000..d39df0c1e --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/AccessDeniedException.java @@ -0,0 +1,24 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.atm; +/** + * This exception is thrown if an unauthorized access to an account is tried. + * + */ +public class AccessDeniedException extends Throwable { + +} diff --git a/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Account.java b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Account.java new file mode 100644 index 000000000..54f1e1499 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Account.java @@ -0,0 +1,68 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.atm; +/** + * This class represents an account. + * In this application it is the base class of the ATM.ForeignAccount role + * and the SpecialConditions.BonusAccount role. + */ +public class Account { + + private int balance; + private Bank bank; + + /** + * Constructor of an account object. Gets the owning bank as parameter. + */ + public Account(Bank _bank) { + bank = _bank; + } + + /** + * Get the balance of the account. + */ + public int getBalance() { + return balance; + } + + /** + * Get the bank of the account. + */ + public Bank getBank() { + return bank; + } + + /** + * Debit an amount from the account. + */ + public boolean debit(int amount) { + + if (!(amount>balance)) { + balance -= amount; + return true; + } + return false; + } + + /** + * Credit an amount to the account. + */ + public void credit(int amount) { + balance += amount; + } + +} diff --git a/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Bank.java b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Bank.java new file mode 100644 index 000000000..00a8fbb32 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Bank.java @@ -0,0 +1,33 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.atm; +/** + * This class represents a very simple bank, only characterized by its name. + * + */ +public class Bank { + private String name; + + public Bank(String _name) { + name = _name; + } + + public String getName() { + return name; + } + +} diff --git a/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Main.java b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Main.java new file mode 100644 index 000000000..ac2046682 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/Main.java @@ -0,0 +1,98 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.atm; + +/** + * Object Teams features demonstrated by this example: + * --------------------------------------------------- + * + * Guard Predicates: + * Guard predicates are used to restrict the activation of callins. + * + * Reflection: + * Reflection is used to check whether a base object already has a role in + * the context of a certain team. + * + * + * Domain description: + * ------------------- + * + * This is a simple example of an automatic teller machine (ATM). + * Using a certain account it is possible to pay cash and to check the balance. + * Accounts of foreign banks are handled differently from home bank accounts. Additionally, + * it is possible to participate in special conditions to gain bonus for certain withdrawals. + + * Launching the application: + * -------------------------- + * + * - Just run this class as you would run any regular Java program. + * (to check enablement of OT/J you may visit the JRE tab of the corres- + * ponding launch configuration and ensure that "Enable OTRE" is checked). + * + */ +public class Main { + + public static void main(String[] args) { + Bank bb = new Bank("Bust-Bank"); + + Account acc1 = new Account(bb); + + + Bank cb = new Bank("Crash-Bank"); + Account acc2 = new Account(cb); + + ATM cbATM = new ATM(cb); + System.out.println("Both accounts get 1000 Euro seed capital."); + acc1.credit(1000); + acc2.credit(1000); + + System.out.println("Withdrawing 200 Euro from both accounts:"); + cbATM.payCash(acc1, 200); + System.out.println("Balance of foreign account: "+ acc1.getBalance()+ " Euro"); + cbATM.payCash(acc2, 200); + System.out.println("Balance of home account: "+ acc2.getBalance()+ " Euro"); + System.out.println("ATMs fee account balance: " + cbATM.getFeeAccountBalance()+ " Euro"); + + System.out.println("---------------------------------------------------"); + try { + System.out.println("Get balance of foreign account via atm: "); + System.out.println(cbATM.getBalance(acc1)+ " Euro"); + } catch (AccessDeniedException ade) { + System.out.println("Sorry: Can not read the balance of a foreign account!"); + } + try { + System.out.println("Get balance of home account via atm: "); + System.out.println(cbATM.getBalance(acc2)+ " Euro"); + } catch (AccessDeniedException ade) { + System.out.println("Sorry: Can not read the balance of a foreign account!"); + } + System.out.println("---------------------------------------------------"); + SpecialConditions sc = new SpecialConditions(); + sc.activate(); + sc.participate(acc2); + + System.out.println("Crediting 2000 Euro to both accounts:"); + int acc1_before = acc1.getBalance(); + int acc2_before = acc2.getBalance(); + acc1.credit(2000); // -> balance += 2020 + + System.out.println("Not participating account gets: " + (acc1.getBalance() - acc1_before)+" Euro."); + acc2.credit(2000); // -> balance += 2000 + System.out.println("Special condition participating account gets: " + (acc2.getBalance() - acc2_before)+" Euro."); + + } +} diff --git a/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/SpecialConditions.java b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/SpecialConditions.java new file mode 100644 index 000000000..68b033458 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ATM-src/src/org/eclipse/objectteams/example/atm/SpecialConditions.java @@ -0,0 +1,64 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.atm; + +/** + * This team realizes special conditions for selected accounts. + * If an account is registered to collect a special bonus, every time + * an amount of more than 1000 is deposited, additionaly, 1% of the amount + * is credited. + */ +public team class SpecialConditions { + + /** + * This team provides a registration method participate which + * is used to register an Account for the special conditions. + * Here, the explicit role creation mechanism is used. + */ + public void participate(Account as BonusAccount ba) {} + + + /** + * The base guard predicate at the BonusAccount role checks, if the base + * object already has a role in this team. If this is not the case it prevents + * lifting (and thus role creation). In combination with the registration method + * this means that BonusAccountroles are never created automatically via lifting but + * have to be explicitly registered first. + */ + public class BonusAccount playedBy Account + base when(SpecialConditions.this.hasRole(base, BonusAccount.class)) + { + /** + * This callin method implements the collection of the bonus. + * It replaces the original Account.credit method and performs a base call with the + * increased amount of money. + */ + callin void creditBonus(int amount) + { + int bonus = amount/100; + base.creditBonus(amount+bonus); + System.out.println("You will gain a bonus of "+ bonus + " Euro!"); + } + + /** + * In the method binding we use an additional predicate to ensure that + * bonus is only credited for amounts greater than 1000. + */ + void creditBonus(int amount) <- replace void credit(int i) + base when (i > 1000); + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/.classpath b/othersrc/otdt-examples/OTSample-Flightbonus-src/.classpath new file mode 100644 index 000000000..dae5e9fe1 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/.classpath @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src/src"/> + <classpathentry kind="src" path="src/booking"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/J2SE-1.5"/> + <classpathentry kind="con" path="OTRE"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/.project b/othersrc/otdt-examples/OTSample-Flightbonus-src/.project new file mode 100644 index 000000000..8d99dca0f --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>OTSample-Flightbonus-src</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.objectteams.otdt.builder.OTJBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.objectteams.otdt.OTJavaNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/.settings/org.eclipse.jdt.core.prefs b/othersrc/otdt-examples/OTSample-Flightbonus-src/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..004aee8b9 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,70 @@ +#Fri Mar 13 22:53:55 CET 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=warning +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=warning +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/booking.jardesc b/othersrc/otdt-examples/OTSample-Flightbonus-src/booking.jardesc new file mode 100644 index 000000000..f9e66bc71 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/booking.jardesc @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<jardesc> + <jar path="OTSample-Flightbonus-src/src/lib/booking.jar"/> + <options buildIfNeeded="true" compress="true" descriptionLocation="/OTSample-Flightbonus-src/booking.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="false" saveDescription="true" storeRefactorings="false" useSourceFolders="false"/> + <storedRefactorings deprecationInfo="true" structuralOnly="false"/> + <selectedProjects/> + <manifest generateManifest="true" mainClassHandleIdentifier="=OTSample-Flightbonus-src/src\/booking<org.eclipse.objectteams.example.flightbooking{Main.java[Main" manifestLocation="" manifestVersion="1.0" reuseManifest="false" saveManifest="false" usesManifest="true"> + <sealing sealJar="false"> + <packagesToSeal/> + <packagesToUnSeal/> + </sealing> + </manifest> + <selectedElements exportClassFiles="true" exportJavaFiles="true" exportOutputFolder="false"> + <javaElement handleIdentifier="=OTSample-Flightbonus-src/src\/booking"/> + </selectedElements> + <fatjar builder="org.eclipse.jdt.ui.plain_jar_builder" launchConfig=""/> +</jardesc> diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/build.xml b/othersrc/otdt-examples/OTSample-Flightbonus-src/build.xml new file mode 100644 index 000000000..1764bfdeb --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/build.xml @@ -0,0 +1,11 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project name="flightbonus" default="zip"> + <property name="zipfile" value="org.eclipse.objectteams.otdt.samples/samples/flightbonus.zip"/> + <target name="zip"> + <delete file="${zipfile}"/> + <zip + destfile="${zipfile}" + basedir="OTSample-Flightbonus-src/src" + includes="Intro0.html,FlightbookingWithBonus.launch,.classpath,.project,sample.properties,src/**,lib/**,.settings/**"/> + </target> +</project>
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.classpath b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.classpath new file mode 100644 index 000000000..accdde381 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.classpath @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="OTRE"/> + <classpathentry kind="lib" path="lib/booking.jar"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.project b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.project new file mode 100644 index 000000000..f51313f74 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>OTSample-Flightbonus</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.eclipse.objectteams.example.otdt.builder.OTJBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.eclipse.jdt.core.javanature</nature> + <nature>org.eclipse.objectteams.example.otdt.OTJavaNature</nature> + </natures> +</projectDescription> diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.settings/org.eclipse.jdt.core.prefs b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..7d74eb02a --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +#Thu Mar 01 00:59:03 CET 2007 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.5 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.5 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.5 diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/FlightbookingWithBonus.launch b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/FlightbookingWithBonus.launch new file mode 100644 index 000000000..06123982a --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/FlightbookingWithBonus.launch @@ -0,0 +1,17 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.jdt.launching.localJavaApplication"> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/OTSample-Flightbonus/lib/booking.jar"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="1"/> +</listAttribute> +<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.objectteams.example.flightbooking.Main"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="OTSample-Flightbonus"/> +<booleanAttribute key="org.eclipse.objectteams.launch" value="true"/> +<booleanAttribute key="org.eclipse.objectteams.otdt.debug.TEAMCONFIG_ACTIVE_ATTR" value="true"/> +<listAttribute key="org.eclipse.objectteams.otdt.debug.TEAMCONFIG_ATTR"> +<listEntry value="=OTSample-Flightbonus/src<org.eclipse.objectteams.example.fbapplication{GUIConnector.java[GUIConnector"/> +</listAttribute> +<booleanAttribute key="org.eclipse.objectteams.otdt.debug.USE_JPLIS" value="true"/> +</launchConfiguration>
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/Intro0.html b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/Intro0.html new file mode 100644 index 000000000..5b5f0c943 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/Intro0.html @@ -0,0 +1,127 @@ +<title>OTSample-FlightBonus Intro</title> +<style type="text/css"> +code { background-color:lightgray; } +img { border:0px; } +</style> +<body> +<h1>Overview of the Flight Bonus example</h1> +This is a simple flight booking program, which exists in different versions. + +<h2>Flight booking - bare application</h2> +Package <img src="images/package.gif" /><code>flightbooking</code> +is available only as jar file (<img src="images/jar_src_obj.gif"/><code>Referenced Libraries/booking.jar</code>).<br /> +<img src="images/run_exc.gif" /><strong>Running:</strong> +This regular Java application can be invoked like a regular Java program +(e.g., by click the link <u><font color="blue">run the sample</font></u> on the welcome sheet at the right). +The main method is in <img src="images/class_public.gif" /><code>flightbooking.Main</code>. +It has a simple GUI which will direct you through the relevant transactions. +Note that this variant does not include collecting bonus points. + +<h2>Bonus and FlightBonus</h2> +The first scenario of adaptation concerns the definition of a bonus +programme for frequent flyers. Two team classes are involved. + +The purpose of each team class is: + +<dl> +<dt><img src="images/team_obj.gif" /><code>bonussystem/Bonus</code>:</dt> +<dd>Define an abstract, re-usable concept of + <img src="images/role_obj.gif"/>Subscriber</code>s that may collect credits, + and <img src="images/role_obj.gif"/>BonusItems</code> that are acquired by a Subscriber + and give a specific amount of credits.</dd> +<dt><img src="images/team_obj.gif" /><code>fbappication/FlightBonus</code>:</dt> +<dd>Bind the abstract team Bonus to the flightbooking package. Other + than class and method bindings, this team only adds one method + implementation for calculating the credit for booking a flight segment.</dd> +</dl> + +<h2>Integrating the application</h2> +In order to integrate the new functionality into the GUI, even another +team class exists: <img src="images/team_obj.gif" /><code>GUIConnector</code>. +It adapts the original GUI in <code>booking.jar</code>.<br /> + +<img src="images/run_exc.gif" /><strong>Running:</strong> +To invoke the variant with bonus apply the supplied launch configuration <img src="images/file_obj.gif" /><code>FlightbookingWithBonus.launch</code>. +Looking at this launch configuration you will find these relevant settings: +<ul> + <li>On tab "JRE" two options are checked: <code>Enable OTRE</code> and <code>Java 5 JPLIS Launching</code></li> + <li>On the tab "<img src="images/team_obj.gif"> Team Activation" the team <code>GUIConnector</code> is selected for instantiation and activation.<br> + <strong>Optional:</strong><br> + <ol type="a"> + <li>You may additionally select the team <code>WindowPlacer</code> which ensures that + new windows are always centered with respect to the desktop/their parent.<br> + <i>Note,</i> that this team requires the "Java 5 JPLIS Launching" option (see above), + because it adapts class <code>java.awt.Window</code> + which is not adaptable using the old launch mode. + </ol></li> +</ul> + +The most important step is to add a method binding to <code>flightbooking.PassengerList.add()</code>.<br /> +The following line in +<code><img src="images/role_obj.gif"/> fbapplication.GUIConnector.Controller</code> +is responsible for this (it's a callin binding):<br /> +<img src="images/callinbinding_obj.gif" /> <code> queryRegisterForBonus <- <strong>after</strong> add;</code><br /> + +<p> +Whenever a passenger is added to that list (an internal "repository"), +the user is asked, whether the passenger wants to participate in the bonus programme. +If so, a new <img src="images/team_obj.gif" /><code>FlightBonus</code> instance is created +and the passenger is implicitly registered +(cf. the implementation of <code>fbapplication.BonusGUI.Controller.queryRegisterForBonus</code>). +After that all bookings for this passenger will also give bonus credits +to the passenger. +</p> +<p> +Collecting credits will be reported by a new dialog box — the nested team +<code><img src="images/team_role_obj.gif" /> fbapplication.GUIConnector.FlightBonusDialog</code>. +This team defines another layer over the team FlightBonus, observing the behaviour of its roles. +</p> + +<h2>OT/J concepts used</h2> +The following concepts are demonstrated and documented in the source code (<a href="guide/otjld/def/index.html"><img src="images/ot_paragraph.gif" /> numbers refer to paragraphs in the language definition</a>): +<dl> +<dt><strong>team inheritance and implicit inheritance of roles</strong> (<a href="guide/otjld/def/team.html"><img src="images/ot_paragraph.gif" /> 1</a>)</dt> +<dd>There are two team inheritance relations: <code>FlightBonus extends Bonus</code> + and <code>GUIConnector extends BonusGUI</code>. + In both cases the contained roles are further specialized in the sub-team.<br /> + Implicit inheritance works accross levels (<a href="guide/otjld/def/team.html#s1.5"><img src="images/ot_paragraph.gif" /> 1.5</a>): + the nested team <code>FlightBonusDialog</code> + implicitly inherits all roles from its implicit super team of the same name. + The inner most roles recursively inherit from their implicit super roles.<br /> + You may want to try the special hierarchy view (F4) for exploring this implicit inheritance. + </dd> +<dt><strong>callin method bindinds</strong> (<a href="guide/otjld/def/callin.html"><img src="images/ot_paragraph.gif" /> 4</a>)</dt> +<dd>The <code>FlightBonus</code> and the <code>GUIConnector</code> teams are both triggered + via callin bindings, by which they hook into the underlying system. + In the case of the <code>FlightBonusDialog</code> the base classes are roles, too. + This means roles are used to intercept events at some other roles.</dd> +<dt><strong>callout method bindinds</strong> (<a href="guide/otjld/def/callout.html"><img src="images/ot_paragraph.gif" /> 3</a>)</dt> +<dd>Most roles access features of their base class using callout bindings.</dd> +<dt><strong>role files</strong> (<a href="guide/otjld/def/team.html#s1.2.5"><img src="images/ot_paragraph.gif" /> 1.2.5</a>)</dt> +<dd><code>fbapplication.BonusGUI.FlightBonusDialog</code> and + <code>fbapplication.GUIConnector.FlightBonusDialog</code>. + Each role file resides in a <strong><code>team package</code></strong> + that has the same name as the enclosing team (i.e., a team is a class and a package).</dd> +<dt><strong>team activation</strong> (<a href="guide/otjld/def/activation.html"><img src="images/ot_paragraph.gif" /> 5</a>)</dt> +<dd>The 'bootstrap' team <code>GUIConnector</code> is activated via the <strong>launch configuration</strong> + (<a href="guide/otjld/def/activation.html#s5.5"><img src="images/ot_paragraph.gif" /> 5.5</a>). + By this technique it is possible to adapt the flight booking application without changing + a single line of source code. + In the sequel the <code>GUIConnector</code> creates instances of <code>FlightBonus</code> + and <code>FlightBonusDialog</code>, both of which invoke <strong><code>activate()</code></strong> + (<a href="guide/otjld/def/activation.html#s5.2.b"><img src="images/ot_paragraph.gif" /> 5.2(b)</a>) from their constructor in order to enable all callins of contained roles.<br /> + Roles <code>FlightBonus.Subscriber</code> and <code>BonusGUI.Collector</code> restrict + activation to specific instances using a <strong>guard predicate</strong> (<a href="guide/otjld/def/activation.html#s5.4"><img src="images/ot_paragraph.gif" /> 5.4</a>). +<dt><strong>lifting</strong> (<a href="guide/otjld/def/rolebinding.html#s2.3"><img src="images/ot_paragraph.gif" /> 2.3</a>)</dt> +<dd>The constructor <code>FlightBonus(Passenger as Subscriber s)</code> uses declared lifting + (<a href="guide/otjld/def/rolebinding.html#s2.3.2"><img src="images/ot_paragraph.gif" /> 2.3.2</a>) + to force creation of a subscriber role for each passenger to be registered.<br /> + The constructor <code>FlightBonusDialog(FlightBonus fb)</code> is a lifting constructor, + which means it will implicitly be used by the lifting operation, but it can also be + invoked explicitly, to create a new role for a given base instance + (cf. method <code>queryRegisterForBonus</code>). + </dd> +</dl> + +</body> +</html> diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/FlightBookingSystem.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/FlightBookingSystem.java new file mode 100644 index 000000000..503fa03e6 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/FlightBookingSystem.java @@ -0,0 +1,188 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: FlightBookingSystem.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking; + +import org.eclipse.objectteams.example.flightbooking.model.BookingException; +import org.eclipse.objectteams.example.flightbooking.model.Flight; +import org.eclipse.objectteams.example.flightbooking.model.Passenger; +import org.eclipse.objectteams.example.flightbooking.model.PassengerDB; +import org.eclipse.objectteams.example.flightbooking.util.FlightIterator; +import org.eclipse.objectteams.example.flightbooking.util.FlightList; + +/** + * This class represents a flight booking system. + */ +public class FlightBookingSystem { + /** + * The list of bookable <code>Flight</code>s. + */ + private FlightList _flights = new FlightList(); + + /** + * The list of registered <code>Passenger</code>s. + */ + private PassengerDB _passengers = new PassengerDB(); + + /** + * This is the <code>Passenger</code> who is currently active. + */ + private Passenger _currentPassenger; + + public FlightBookingSystem() { + super(); + } + + /** + * This method registers a new <code>Passenger</code>. + * + * @param name + * The <code>Passenger</code>'s name. + * @param budget + * The <code>Passenger</code>'s budget. + * @return <code>true</code> if the <code>Passenger</code> is already + * known to the booking system, <code>false</code> otherwise. + */ + public boolean registerPassenger(String name, int budget) { + if (_passengers.contains(name)) { + return false; + } + _passengers.add(new Passenger(name, budget)); + + return true; + } + + /** + * This method adds a <code>Flight</code> to the booking system. + * + * @param flight + * The <code>Flight</code> to add. + */ + public void addFlight(Flight flight) { + _flights.add(flight); + } + + /** + * This method removes a <code>Flight</code> from the booking system. + * + * @param flight + * The <code>Flight</code> to remove. + */ + public void removeFlight(Flight flight) { + _flights.remove(flight); + } + + /** + * This method returns a <code>FlightIterator</code> of all offered + * <code>Flight</code>s. + * + * @return The flights. + */ + public FlightIterator getOfferedFlights() { + return _flights.getIterator(); + } + + /** + * This method books a certain <code>Flight</code> for the active + * <code>Passenger</code>. + * + * @param idx + * The number of the flight to book. + */ + public void bookFlight(int idx) throws BookingException { + if (_currentPassenger == null) { + throw new BookingException("No current passenger"); + } + _currentPassenger.book(_flights.get(idx)); + } + + /** + * This method activates a <code>Passenger</code>. + * + * @param name + * The name of the <code>Passenger</code> to activate. + * @return <code>true</code> if the <code>Passenger</code> was found in + * the booking system and there is currently no other active + * <code>Passenger</code>,<code>false</code> otherwise. + */ + public boolean setCurrentPassenger(String name) { + if (_passengers.contains(name) && (_currentPassenger == null)) { + _currentPassenger = _passengers.get(name); + return true; + } + return false; + } + + /** + * This method deactivates a <code>Passenger</code>. + * + * @param name + * The name of the <code>Passenger</code> to deactivate. + * @return <code>true</code> if the <code>Passenger</code> was found in + * the booking system and he really is the active + * <code>Passenger</code>,<code>false</code> otherwise. + */ + public boolean disableCurrentPassenger(String name) { + if (_passengers.contains(name) + && (_currentPassenger.getName().equals(name))) { + _currentPassenger = null; + return true; + } + return false; + } + + /** + * This method returns the current <code>Passenger</code>. + * + * @return The current <code>Passenger</code>. + */ + public Passenger getCurrentPassenger() { + return _currentPassenger; + } + + /** + * This method searches for a <code>Passenger</code> in the booking + * system. + * + * @return <code>true</code> if the <code>Passenger</code> was found, + * <code>false</code> otherwise. + */ + public boolean containsPassenger(String name) { + return _passengers.contains(name); + } + + /** + * Get the passengers list for iteration. + * + * @return + */ + public PassengerDB getRegisteredPassengers() { + _passengers.reset(); + return _passengers; + } + + /** + * This method ends the program. + */ + public void exit() { + System.exit(1); + } + +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/Main.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/Main.java new file mode 100644 index 000000000..4ffb2b594 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/Main.java @@ -0,0 +1,108 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Main.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking; + +import org.eclipse.objectteams.example.flightbooking.gui.FlightBookingGUI; +import org.eclipse.objectteams.example.flightbooking.model.Flight; +import org.eclipse.objectteams.example.flightbooking.model.Segment; + +// ## Attention: the current version has a few publics which should +// not be needed, but callout still requires regular visibility. +/** + * This class contains the main method. + */ +public class Main { + final private FlightBookingSystem _system; + + // ## added to give access to _system + /** + * This method returns the associated <code>FlightBookingSystem</code>. + * + * @return The code>FlightBookingSystem</code>. + */ + public FlightBookingSystem getSystem() { + return _system; + } + + /** + * Contructs a new <code>Main</code> object. + */ + public Main() { + _system = new FlightBookingSystem(); + } + + public void start() { + initFlights(); + providePassengers(); + + + java.awt.EventQueue.invokeLater(new Runnable() { + public void run() { + FlightBookingGUI fbgui = new FlightBookingGUI(_system); + fbgui.setVisible(true); + } + }); + } + + /** + * This is the main method that is used to start the flight booking example. + * + * @param args + * No args. + */ + public static void main(String[] args) { + final Main main = new Main(); + main.start(); + } + + private void initFlights() { + Flight berlinNY = new Flight(); + berlinNY.addSegment(new Segment("Berlin", "Frankfurt", 903, 150, 400)); + berlinNY.addSegment(new Segment("Frankfurt", "New York", 903, 350, 1400)); + + Flight berlinHH = new Flight(); + berlinHH.addSegment(new Segment("Berlin", "Hamburg", 1105, 100, 99)); + + Flight berlinLDN = new Flight(); + berlinLDN.addSegment(new Segment("Berlin", "London", 937, 120, 125)); + berlinLDN.addSegment(new Segment("London", "Berlin", 938, 120, 135)); + + Flight chicago1 = new Flight(); + chicago1.addSegment(new Segment("Berlin", "Amsterdam", 342, 60, 213)); + chicago1.addSegment(new Segment("Amsterdam", "Chicago", 342, 260, 313)); + + Flight chicago2 = new Flight(); + chicago2.addSegment(new Segment("Berlin", "Frankfurt", 342, 60, 113)); + chicago2.addSegment(new Segment("Frankfurt", "Chicago", 342, 260, 316)); + + _system.addFlight(berlinNY); + _system.addFlight(berlinHH); + _system.addFlight(berlinLDN); + _system.addFlight(chicago1); + _system.addFlight(chicago2); + } + + private void providePassengers() { + _system.registerPassenger("Carsten", 16000); + _system.registerPassenger("Jan", 100); + _system.registerPassenger("Stephan", 16000); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/data/DistanceManager.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/data/DistanceManager.java new file mode 100644 index 000000000..54533157a --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/data/DistanceManager.java @@ -0,0 +1,79 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: DistanceManager.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.data; + + +/** + * The distance manager is used to manage the distances between + * different cities. It implements the Singleton pattern. + */ +public class DistanceManager +{ + private DistanceTable _distanceTable = new DistanceTable(); + + /** + * Some exemplary distances are stored in the distance table. + */ + private DistanceManager() + { + _distanceTable.addPlace("Berlin"); + _distanceTable.getPlaceDistances("Berlin").addDistance("Frankfurt", 424); + _distanceTable.getPlaceDistances("Berlin").addDistance("Hamburg", 252); + _distanceTable.getPlaceDistances("Berlin").addDistance("Brussels", 653); + _distanceTable.getPlaceDistances("Berlin").addDistance("London", 934); + _distanceTable.getPlaceDistances("Berlin").addDistance("Amsterdam", 576); + + _distanceTable.addPlace("Frankfurt"); + _distanceTable.getPlaceDistances("Frankfurt").addDistance("New York", 6194); + _distanceTable.getPlaceDistances("Frankfurt").addDistance("Atlanta", 7396); + _distanceTable.getPlaceDistances("Frankfurt").addDistance("Chicago", 6960); + + _distanceTable.addPlace("Brussels"); + _distanceTable.getPlaceDistances("Brussels").addDistance("Chicago", 6657); + _distanceTable.addPlace("London"); + _distanceTable.getPlaceDistances("London").addDistance("Chicago", 6347); + _distanceTable.getPlaceDistances("London").addDistance("Berlin", 934); + _distanceTable.addPlace("Amsterdam"); + _distanceTable.getPlaceDistances("Amsterdam").addDistance("Chicago", 6605); + } + +// TODO(mkr): add javadoc + public int getDistance(String place1, String place2) + { + if (_distanceTable.containsPlace(place1)) + { + return _distanceTable.getPlaceDistances(place1).getDistance(place2); + } + if (_distanceTable.containsPlace(place2)) + { + return _distanceTable.getPlaceDistances(place2).getDistance(place1); + } + return DistanceTable.NO_DISTANCE; + } + + /** + * This method returns the singleton object. + * @return The <code>DistanceManager</code>. + */ + public static DistanceManager getSingleton() { + return new DistanceManager(); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/data/DistanceTable.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/data/DistanceTable.java new file mode 100644 index 000000000..e609fe9c3 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/data/DistanceTable.java @@ -0,0 +1,66 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: DistanceTable.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.data; + +import java.util.Hashtable; + +/** + * This class represents a table of distances between different cities. + * It is used by the <code>DistanceManager</code> + * to store and retrieve those distances. + */ +public class DistanceTable { + public final static int NO_DISTANCE = 0; + + private Hashtable<String, DistanceList> _data = new Hashtable<String, DistanceList>(); + + /** + * A list of distances. + */ + public class DistanceList { + private Hashtable<String, Integer> _distances = new Hashtable<String, Integer>(); + + public void addDistance(String placeName, int distance) { + _distances.put(placeName, new Integer(distance)); + } + + public int getDistance(String placeName) { + return _distances.containsKey(placeName) ? _distances + .get(placeName).intValue() : NO_DISTANCE; + } + } + + public DistanceTable() { + super(); + } + + public void addPlace(String name) { + _data.put(name, new DistanceList()); + } + + public DistanceList getPlaceDistances(String name) { + return _data.get(name); + } + + public boolean containsPlace(String name) { + return _data.containsKey(name); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/gui/EnterPassengerDialog.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/gui/EnterPassengerDialog.java new file mode 100644 index 000000000..d68e2ad90 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/gui/EnterPassengerDialog.java @@ -0,0 +1,227 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: EnterPassengerDialog.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.gui; + +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JLabel; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.WindowConstants; + +import org.eclipse.objectteams.example.flightbooking.FlightBookingSystem; +import org.eclipse.objectteams.example.flightbooking.model.Passenger; + + +@SuppressWarnings("serial") +public class EnterPassengerDialog extends JDialog { + + private FlightBookingSystem _system; + private FlightBookingGUI _parentFrame; + private String _customerName = ""; + private int _customerBudget = 0; + + private JTextField _nameTextField; + private JTextField _budgetTextField; + + public EnterPassengerDialog( + FlightBookingGUI parent, + boolean modal, + FlightBookingSystem system) { + super(parent, modal); + _system = system; + _parentFrame = parent; + initComponents(); + setResizable(false); + setVisible(true); + } + + public void clearButtonClicked() { + _nameTextField.setText(""); + _budgetTextField.setText(""); + } + + public void okButtonClicked() { + _customerName = _nameTextField.getText(); + + if (_customerName.equals("")) { + showErrDialog("Please enter the passenger's name"); + return; + } + + try { + _customerBudget = Integer.parseInt(_budgetTextField.getText()); + } + catch (NumberFormatException ex) { + showErrDialog("The characters in the budget string must be decimal digits"); + + return; + } + + Passenger prev = _system.getCurrentPassenger(); + if (prev != null) { + _system.disableCurrentPassenger(prev.getName()); + } + + if (!_system.containsPassenger(_customerName)) { + _system.registerPassenger(_customerName, _customerBudget); + _system.setCurrentPassenger(_customerName); + _parentFrame.getCustomerModel().addElement(_system.getCurrentPassenger()); + } else { + _system.setCurrentPassenger(_customerName); + showInfoDialog("Passenger exists already"); + } + + _parentFrame.setEnabled(true); + setVisible(false); + } + + + private void showErrDialog(final String message) { + JOptionPane.showMessageDialog( + this, + message, + "Error", + JOptionPane.ERROR_MESSAGE); + } + + private void showInfoDialog (final String message) { + JOptionPane.showMessageDialog( + this, + message, + "Message", + JOptionPane.INFORMATION_MESSAGE); + } + + /** + * This method is called from within the constructor to + * initialize the form. + */ + private void initComponents( ) { + GridBagConstraints gridBagConstraints = null; + + this.setTitle("New Passenger Dialog"); + JPanel jPanel1 = new JPanel(); + JLabel nameLabel = new JLabel(); + _nameTextField = new JTextField(); + JLabel budgetLabel = new JLabel(); + _budgetTextField = new JTextField(); + JPanel jPanel2 = new JPanel(); + JButton okButton = new JButton(); + JButton clearButton = new JButton(); + JButton cancelButton = new JButton(); + + getContentPane().setLayout(new GridBagLayout()); + + setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); + jPanel1.setLayout(new GridBagLayout()); + + nameLabel.setText("Passenger's Name: "); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = GridBagConstraints.WEST; + gridBagConstraints.insets = new Insets(5, 0, 6, 0); + jPanel1.add(nameLabel, gridBagConstraints); + + _nameTextField.setColumns(12); + _nameTextField.setText(""); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.ipadx = 2; + gridBagConstraints.insets = new Insets(0, 6, 4, 0); + jPanel1.add(_nameTextField, gridBagConstraints); + + budgetLabel.setText("Passenger's Budget: "); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.anchor = GridBagConstraints.WEST; + jPanel1.add(budgetLabel, gridBagConstraints); + + _budgetTextField.setText(""); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.insets = new Insets(0, 6, 0, 0); + jPanel1.add(_budgetTextField, gridBagConstraints); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(10, 10, 10, 10); + getContentPane().add(jPanel1, gridBagConstraints); + + jPanel2.setLayout(new java.awt.GridBagLayout()); + + clearButton.setText("Clear"); + clearButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + clearButtonClicked(); + } + }); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + jPanel2.add(clearButton, gridBagConstraints); + + okButton.setText("OK"); + okButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + okButtonClicked(); + } + }); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(0, 30, 0, 0); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 0; + jPanel2.add(okButton, gridBagConstraints); + + cancelButton.setText("Cancel"); + cancelButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + _parentFrame.setEnabled(true); + setVisible(false); + } + }); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 0; + jPanel2.add(cancelButton, gridBagConstraints); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = GridBagConstraints.EAST; + gridBagConstraints.insets = new Insets(10, 10, 10, 10); + getContentPane().add(jPanel2, gridBagConstraints); + + pack(); + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/gui/FlightBookingGUI.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/gui/FlightBookingGUI.java new file mode 100644 index 000000000..f3c9cff98 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/gui/FlightBookingGUI.java @@ -0,0 +1,316 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: FlightBookingGUI.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.gui; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.SwingConstants; +import javax.swing.WindowConstants; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import org.eclipse.objectteams.example.flightbooking.FlightBookingSystem; +import org.eclipse.objectteams.example.flightbooking.model.BookingException; +import org.eclipse.objectteams.example.flightbooking.model.Flight; +import org.eclipse.objectteams.example.flightbooking.model.Passenger; +import org.eclipse.objectteams.example.flightbooking.model.PassengerDB; +import org.eclipse.objectteams.example.flightbooking.util.FlightIterator; + + + +/** +* This class implements a simple graphical user interface for the flight booking system. +*/ +@SuppressWarnings("serial") +public class FlightBookingGUI extends JFrame { + + private JList _flightList; + private JList _passengerList; + + private FlightBookingSystem _system; + private FlightBookingGUI _frame = this; + private DefaultListModel _flightModel; + private DefaultListModel _customerModel; + private Flight _selectedFlight; + private Passenger _selectedCustomer; + + /** + * Creates new <code>FlightBookingGUI</code> object + */ + public FlightBookingGUI(FlightBookingSystem system) { + _system = system; + _customerModel = new DefaultListModel(); + _flightModel = new DefaultListModel(); + initFlightModel(); + initCustomerModel(); + initComponents(); + this.setResizable(false); + } + + /** + * Initializes the <code>FlightModel</code> with data contained + * in the flight booking system, + */ + private void initFlightModel() { + for (FlightIterator iter = _system.getOfferedFlights(); iter.hasNext();) { + _flightModel.addElement(iter.getNext()); + } + } + + /** + * Initializes the <code>PassengerModel</code> with data contained + * in the flight booking system, + */ + private void initCustomerModel() { + for (PassengerDB passengers = _system.getRegisteredPassengers(); passengers.hasNext();) { + _customerModel.addElement(passengers.getNext()); + } + } + /** + * Returns the customer + */ + public DefaultListModel getCustomerModel() { + return _customerModel; + } + + /** + * Returns the flight model + */ + public DefaultListModel getFlightModel() { + return _flightModel; + } + + /** + * Invoked when the bookButton is pressed + */ + public void bookButtonClicked() { + + if(_selectedFlight == null) { + showErrDialog("Please select a flight!"); + return; + } + + if(_selectedCustomer == null) { + showErrDialog("Please select a passenger!"); + return; + } + + Passenger prev = _system.getCurrentPassenger(); + if (prev != null) { + _system.disableCurrentPassenger(prev.getName()); + } + + _system.setCurrentPassenger(_selectedCustomer.getName()); + + try { + _system.bookFlight(_flightList.getSelectedIndex()); + } catch (BookingException ex) { + showErrDialog("Booking transaction failed: " + ex.getMessage()); + return; + } + + showInfoDialog("Passenger " + _selectedCustomer.getName() + ": " + + _selectedFlight + "\n" + + _selectedCustomer.getName() + "'s balance : " + + _selectedCustomer.getBudget()); + } + + + /** + * This method is called from within the constructor to + * initialize the form. + */ + private void initComponents() { + GridBagConstraints gridBagConstraints = null; + + JButton bookButton = new JButton(); + JButton customerButton = new JButton(); + JButton exitButton = new JButton(); + JScrollPane flightPane = new JScrollPane(); + JScrollPane passPane = new JScrollPane(); + _flightList = new JList(_flightModel); + _passengerList = new JList(_customerModel); + + getContentPane().setLayout(new GridBagLayout()); + + setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + setTitle("Flight Booking System"); + + JLabel flightsLabel = new JLabel(); + flightsLabel.setText("Offered Flights: "); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = GridBagConstraints.WEST; + gridBagConstraints.insets = new Insets(5, 19, 5, 17); + getContentPane().add(flightsLabel, gridBagConstraints); + + JLabel passLabel = new JLabel(); + passLabel.setText("Passengers: "); + passLabel.setHorizontalAlignment(SwingConstants.RIGHT); + gridBagConstraints = new java.awt.GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 0; + gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 43); + getContentPane().add(passLabel, gridBagConstraints); + + _flightList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + flightPane.setPreferredSize(new Dimension(250, 250)); + flightPane.setViewportView(_flightList); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridheight = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.insets = new java.awt.Insets(0, 20, 0, 10); + getContentPane().add(flightPane, gridBagConstraints); + + _passengerList.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION); + passPane.setPreferredSize(new Dimension(100, 250)); + passPane.setViewportView(_passengerList); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridheight = 5; + gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH; + gridBagConstraints.insets = new java.awt.Insets(0, 10, 0, 0); + getContentPane().add(passPane, gridBagConstraints); + + + customerButton.setText("New Passenger"); + customerButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + showEnterCustomerDialog(); + } + }); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 1; +// gridBagConstraints.insets = new Insets(0, 20, 0, 0); + getContentPane().add(customerButton, gridBagConstraints); + + bookButton.setText("Book"); + bookButton.setPreferredSize(customerButton.getPreferredSize()); + bookButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + bookButtonClicked(); + } + }); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 2; + gridBagConstraints.gridy = 2; + getContentPane().add(bookButton, gridBagConstraints); + + + JPanel btnPanel = new JPanel(); + btnPanel.setLayout(new GridBagLayout()); + + exitButton.setText("Exit"); + exitButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + System.exit(0); + } + }); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 5; + gridBagConstraints.gridy = 0; + btnPanel.add(exitButton, gridBagConstraints); + + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 6; + gridBagConstraints.gridwidth = 3; + gridBagConstraints.anchor = java.awt.GridBagConstraints.EAST; + gridBagConstraints.insets = new java.awt.Insets(20, 10, 10, 10); + getContentPane().add(btnPanel, gridBagConstraints); + + + _flightList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(javax.swing.event.ListSelectionEvent evt) { + flightListValueChanged(evt); + } + }); + + _passengerList.addListSelectionListener(new ListSelectionListener() { + public void valueChanged(ListSelectionEvent evt) { + customerListValueChanged(evt); + } + }); + + pack(); + } + + /** + * Updates the selected flight reference when the flight list value is changed + */ + public void flightListValueChanged(ListSelectionEvent evt) { + _selectedFlight = (Flight)_flightList.getSelectedValue(); + } + + /** + * Updates the selected customer reference when the passenger list value is changed + */ + public void customerListValueChanged(ListSelectionEvent evt) { + if(!_passengerList.isSelectionEmpty()) { + _selectedCustomer = (Passenger)_passengerList.getSelectedValue(); + } + } + + /** + * Shows the given message in a message dialog box + */ + private void showInfoDialog(final String message){ + JOptionPane.showMessageDialog(_frame, message, "Message", JOptionPane.INFORMATION_MESSAGE); + } + + /** + * Shows the given message in a error dialog box + */ + private void showErrDialog(final String message){ + JOptionPane.showMessageDialog(_frame, message, "Error", JOptionPane.ERROR_MESSAGE); + } + + /** + * Shows the <code>EnterPassengerDialog</code> for entering of new passenger data + */ + private void showEnterCustomerDialog() { + this.setEnabled(false); + new EnterPassengerDialog(_frame,false,_system); + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/BookingException.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/BookingException.java new file mode 100644 index 000000000..f4ff68106 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/BookingException.java @@ -0,0 +1,36 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: BookingException.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.model; + +// TODO(mkr): add javadoc +@SuppressWarnings("serial") +public class BookingException extends Exception +{ + public BookingException() + { + super(); + } + + public BookingException(String msg) + { + super(msg); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Flight.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Flight.java new file mode 100644 index 000000000..707959cc4 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Flight.java @@ -0,0 +1,95 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Flight.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.model; + +import org.eclipse.objectteams.example.flightbooking.util.SegmentIterator; +import org.eclipse.objectteams.example.flightbooking.util.SegmentList; + +/** + * A flight which consists of a number of segments. + */ +public class Flight { + /** + * The list of <code>Segment</code>s, this Flight consists of. + */ + private SegmentList _segments; + + /** + * Constructs a new <code>Flight</code>. + */ + public Flight() { + _segments = new SegmentList(); + } + + /** + * This method adds a <code>Segment</code> to this <code>Flight</code>. + * + * @param seg + * The <code>Segment</code> to add. + */ + public void addSegment(Segment seg) { + _segments.add(seg); + } + + /** + * This method returns the price of this <code>Flight</code>, which + * equals the sum of all its <code>Segment</code>s' prices. + * + * @return The price. + */ + public int getPrice() { + int price = 0; + for (SegmentIterator iter = _segments.getIterator(); iter.hasNext();) { + price += iter.getNext().getPrice(); + } + + return price; + } + + /** + * This method books a <code>Flight</code>. + * + * @param pass + * The <code>Passenger</code> who is booking. + */ + public void book(Passenger pass) throws BookingException { + for (SegmentIterator iter = _segments.getIterator(); iter.hasNext();) { + iter.getNext().book(pass); + } + } + + /** + * This method returns a String representation of this <code>Flight</code>. + * + * @return The String. + */ + public String toString() { + StringBuffer result = new StringBuffer(); + result.append(_segments.get(0).getStart()); + + for (SegmentIterator iter = _segments.getIterator(); iter.hasNext();) { + result.append(" --> "); + result.append(iter.getNext().getDestination()); + } + + return result.toString(); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Passenger.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Passenger.java new file mode 100644 index 000000000..ef6c76c39 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Passenger.java @@ -0,0 +1,124 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Passenger.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.model; + +/** + * This class represents a passenger who has a name, a budget and who is able to + * book flights. + */ +public class Passenger { + private String _name; + + private int _budget; + + /** + * Constructs a new <code>Passenger</code>. + * + * @param name + * The <code>Passenger</code>'s name. + */ + public Passenger(String name) { + _name = name; + _budget = 0; + } + + /** + * Constructs a new <code>Passenger</code>. + * + * @param name + * The <code>Passenger</code>'s name. + * @param budget + * The <code>Passenger</code>'s budget. + */ + public Passenger(String name, int budget) { + _name = name; + _budget = budget; + } + + /** + * This method implements the booking of a <code>Flight</code>. + * + * @param flight + * The <code>Flight</code> to book. + * @throws BookingException + * Thrown if the <code>Passenger</code> has not enough money + * to book the given <code>Flight</code>. + */ + public void book(Flight flight) throws BookingException { + int price = flight.getPrice(); + + if (_budget < price) { + throw new BookingException("Passenger " + getName() + + " hasn't enough money!"); + } + + _budget -= price; + + flight.book(this); + } + + /** + * This method returns the <code>Passenger</code>'s budget. + * + * @return The budget. + */ + public int getBudget() { + return _budget; + } + + /** + * This method increases the <code>Passenger</code>'s budget by a given + * amount. + * + * @param amount + * The amount to increase the budget by. + */ + public void earn(int amount) { + _budget += amount; + } + + /** + * This is a setter for the <code>Passenger</code>'s budget. + * + * @param bud + * The budget. + */ + public void setBudget(int bud) { + _budget = bud; + } + + /** + * This method returns a String representation of this + * <code>Passenger</code>. + */ + public String toString() { + return _name; + } + + /** + * This method returns the <code>Passenger</code>'s name. + * + * @return The name. + */ + public String getName() { + return _name; + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/PassengerDB.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/PassengerDB.java new file mode 100644 index 000000000..fb47fb5e8 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/PassengerDB.java @@ -0,0 +1,71 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: PassengerDB.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.model; + +import java.util.Enumeration; +import java.util.Hashtable; + +import org.eclipse.objectteams.example.flightbooking.model.Passenger; + + +/** + * This class implements a list of <code>Passenger</code>s. + */ +public class PassengerDB { + + private Hashtable<String, Passenger> _data; + private Enumeration<Passenger> _valueEnumeration; + + public PassengerDB() { + _data = new Hashtable<String, Passenger>(); + } + + public void add(Passenger pass) { + if (!_data.containsKey(pass.getName())) { + _data.put(pass.getName(), pass); + } + } + + public void remove(Passenger pass) { + _data.remove(pass.getName()); + } + + public Passenger get(String name) { + return _data.get(name); + } + + public boolean contains(String name) { + return _data.containsKey(name); + } + + + public void reset() { + _valueEnumeration = _data.elements(); + } + + public boolean hasNext() { + return _valueEnumeration != null && _valueEnumeration.hasMoreElements(); + } + + public Passenger getNext() { + return _valueEnumeration.nextElement(); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Segment.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Segment.java new file mode 100644 index 000000000..99261ac5c --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/model/Segment.java @@ -0,0 +1,123 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Segment.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.model; + +import org.eclipse.objectteams.example.flightbooking.data.DistanceManager; + +/** + * A <code>Segment</code> is part of a <code>Flight</code>. Different + * <code>Flight</code>s may share common <code>Segment</code>s. + */ +public class Segment { + /** + * This <code>Segment</code>'s start. + */ + private String _start; + + /** + * This <code>Segment</code>'s destination. + */ + private String _destination; + + /** + * This <code>Segment</code>'s date. + */ + private int _date; + + /** + * The number of available seats for this <code>Segment</code>. + */ + private int _seatsAvail; + + /** + * This <code>Segment</code>'s price. + */ + private int _price; + + /** + * Constructs a new <code>Segment</code>. + */ + public Segment(String start, String dest, int date, int seats, int price) { + _start = start; + _destination = dest; + _date = date; + _seatsAvail = seats; + _price = price; + } + + /** + * This method returns this <code>Segment</code>'s start. + */ + public String getStart() { + return _start; + } + + /** + * This method returns this <code>Segment</code>'s destination. + */ + public String getDestination() { + return _destination; + } + + /** + * This method returns this <code>Segment</code>'s date. + */ + public int getDate() { + return _date; + } + + /** + * This method returns the number of this <code>Segment</code>'s + * available seats. + */ + public int getAvailableSeats() { + return _seatsAvail; + } + + /** + * This method returns this <code>Segment</code>'s price. + */ + public int getPrice() { + return _price; + } + + public void book(Passenger pass) throws BookingException { + if (_seatsAvail <= 0) { + throw new BookingException("Segment overbooked!"); + } + reserveSeat(pass); + } + + private void reserveSeat(Passenger pass) { + // reserve a seat for the passenger + _seatsAvail--; + } + + /** + * This method returns the distance between this <code>Segment</code>'s + * start and its destination. + * + * @return The distance. + */ + public int getDistance() { + return DistanceManager.getSingleton().getDistance(_start, _destination); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/FlightIterator.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/FlightIterator.java new file mode 100644 index 000000000..b25e38b05 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/FlightIterator.java @@ -0,0 +1,37 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: FlightIterator.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.util; + +import org.eclipse.objectteams.example.flightbooking.model.Flight; + +/** + * This interface is used to make the <code>FlightIterator</code>, + * implemented as an inner class in <code>FlightList</code>, usable outside + * of that class. + */ +public interface FlightIterator +{ + public boolean hasNext(); + + public Flight getNext(); + + public int getLength(); +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/FlightList.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/FlightList.java new file mode 100644 index 000000000..f5a24afd9 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/FlightList.java @@ -0,0 +1,72 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: FlightList.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.util; + +import java.util.Vector; +import java.util.Enumeration; + +import org.eclipse.objectteams.example.flightbooking.model.Flight; +import org.eclipse.objectteams.example.flightbooking.util.FlightIterator; + + +/** + * This class implements a list of <code>Flight</code>s. + */ +public class FlightList { + private Vector<Flight> _data; + + public FlightList() { + _data = new Vector<Flight>(); + } + + public void add(Flight flight) { + if (!_data.contains(flight)) { + _data.add(flight); + } + } + + public void remove(Flight flight) { + _data.remove(flight); + } + + public Flight get(int idx) { + return _data.get(idx); + } + + public FlightIterator getIterator() { + final Enumeration<Flight> rawIter = _data.elements(); + + return new FlightIterator() { + + public boolean hasNext() { + return rawIter.hasMoreElements(); + } + + public Flight getNext() { + return rawIter.nextElement(); + } + + public int getLength() { + return _data.size(); + } + }; + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/SegmentIterator.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/SegmentIterator.java new file mode 100644 index 000000000..6c5b690b1 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/SegmentIterator.java @@ -0,0 +1,35 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: SegmentIterator.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.util; + +import org.eclipse.objectteams.example.flightbooking.model.Segment; + +/** + * This interface is used to make the <code>SegmentIterator</code>, + * implemented as an inner class in <code>SegmentList</code>, usable outside + * of that class. + */ +public interface SegmentIterator +{ + public boolean hasNext(); + + public Segment getNext(); +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/SegmentList.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/SegmentList.java new file mode 100644 index 000000000..3b2271bb2 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/booking/org/eclipse/objectteams/example/flightbooking/util/SegmentList.java @@ -0,0 +1,82 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: SegmentList.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.flightbooking.util; + +import java.util.Vector; +import java.util.Iterator; + +import org.eclipse.objectteams.example.flightbooking.model.Segment; + + +/** + * This class implements a list of <code>Segment</code>s. + */ +public class SegmentList +{ + private Vector<Segment> _data; + + public SegmentList() + { + _data = new Vector<Segment>(); + } + + public void add(Segment seg) + { + if (!_data.contains(seg)) + { + _data.add(seg); + } + } + + public void remove(Segment seg) + { + _data.remove(seg); + } + + public Segment get(int idx) + { + return _data.elementAt(idx); + } + + /** How many segments does this list contain? */ + public int getSegmentCount() { + return _data.size(); + } + + public SegmentIterator getIterator() + { + final Iterator<Segment> rawIter = _data.iterator(); + + return new SegmentIterator() + { + + public boolean hasNext() + { + return rawIter.hasNext(); + } + + public Segment getNext() + { + return rawIter.next(); + } + }; + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/sample.properties b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/sample.properties new file mode 100644 index 000000000..cb47bebba --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/sample.properties @@ -0,0 +1,8 @@ +# +#Wed Mar 11 12:22:47 CET 2009 +projectName=OTSample-Flightbonus +name=Object Teams Sample - Flightbonus +launchTarget=org.eclipse.objectteams.example.flightbooking.Main +description=This example demonstrates, how a reusable collaboration for collecting bonus points can be integrated into an existing application for flight booking. +launcher=org.eclipse.jdt.debug.ui.launchConfigurations.JavaApplicationLaunchShortcut +id=org.eclipse.objectteams.otdt.samples.flightbooking diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/bonussystem/Bonus.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/bonussystem/Bonus.java new file mode 100644 index 000000000..cc2d8f481 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/bonussystem/Bonus.java @@ -0,0 +1,92 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Bonus.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.bonussystem; + +/** + * Abstract team defining the collaboration between a subscriber and some bonus + * items by which the subscriber earns some credits. + */ +public abstract team class Bonus { + + /** + * By this attribute a bonus item can access the currently active subscriber + * (relative to the team instance). + */ + protected Subscriber subscriber = null; + + /** + * While a subscriber is buying something, all acquired + * bonus items will contribute to his/her credits. + */ + public abstract class Subscriber { + + int collectedCredits = 0; + + protected int getCollectedCredits() { + return collectedCredits; + } + + /** Add new credit points to our balance. */ + protected void collectCredit (int credit) { + collectedCredits += credit; + } + + /** + * When buying something, tell the enclosing team + * who we are, so that we will get the credits. + */ + callin void buy () + { + Bonus.this.subscriber = this; + base.buy(); + Bonus.this.subscriber = null; + + log("Subscriber has collected a total of "+getCollectedCredits()+" credit points."); + } + } + + /** + * An item that is associated with some bonus points (credits). + */ + public abstract class Item { + + /** Expected method: calculate the number of points to be earned. */ + protected abstract int calculateCredit (); + + /** + * The item is about to be acquired: give the associated + * credit points to the subscriber. + */ + protected void earnCredit () { + Subscriber subscriber = Bonus.this.subscriber; + if (subscriber == null) + return; + + int tmpCredits = calculateCredit(); + log("buying an item that yields "+tmpCredits+" credit points."); + subscriber.collectCredit(tmpCredits); + } + } + + protected void log (String msg) { + System.out.println(">>Bonus>> "+msg); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/BonusGUI.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/BonusGUI.java new file mode 100644 index 000000000..ee823ae41 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/BonusGUI.java @@ -0,0 +1,84 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: BonusGUI.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.fbapplication; + +import java.awt.Component; + +import javax.swing.JOptionPane; + +import org.eclipse.objectteams.example.flightbooking.model.Passenger; + +/** + * This team gives an unspecific, partially abstract implementation of a GUI + * for a bonus programme. + * Please also see its nested team FlightBonusDialog + * (since FlightBonusDialog is a role file, you may try pressing ctrl-o twice for navigation). + * FlightBonusDialog already connects to FlightBonus. + * However, no bindings to the flight booking system are given at this level. + */ +public team class BonusGUI { + + /** This is a reference to the active GUI. */ + View view = null; + + /** + * Make the GUI accessible and extend it by a registration question. + */ + abstract protected class View { + + void registerView() { + BonusGUI.this.view = this; + } + + protected boolean queryRegisterDialog() { + int choice = JOptionPane.showConfirmDialog( + getComponent(), + "Register for Flight Bonus?", + "OT Bonus System", + JOptionPane.YES_NO_OPTION); + + return choice == JOptionPane.YES_OPTION; + } + + /** + * Expected method: get an AWT component as parent for new windows. + */ + protected abstract Component getComponent(); + } + + + /** + * This role is used as a hook into PassengerList. + */ + protected class Controller + when (BonusGUI.this.view != null) // don't receive callin triggers before proper initialization + { + /** + * Given a passenger, ask if he/she should participate in the + * bonus programme. + */ + void queryRegisterForBonus (Passenger p) { + if (BonusGUI.this.view.queryRegisterDialog()) + new FlightBonusDialog(new FlightBonus(p)); + }; + } +} + diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/BonusGUI/FlightBonusDialog.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/BonusGUI/FlightBonusDialog.java new file mode 100644 index 000000000..437991417 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/BonusGUI/FlightBonusDialog.java @@ -0,0 +1,91 @@ +team package org.eclipse.objectteams.example.fbapplication.BonusGUI; + +/** + * A dialog for presenting information about collected bonus credits. + * + * This class is a nested team, i.e., it is a role of its enclosing team BonusGUI + * and at the same time it is the team for the contained roles Collector and Message. + * As a role it uses the option of role files, i.e., roles stored in their own file. + * You may use the package declaration to navigate (F3) to the enclosing team BonusGUI. + */ +protected team class FlightBonusDialog playedBy FlightBonus { + + /** + * Message string to be placed in the dialog box + */ + String message; + + /** + * Team/role constructor: Creates a new <code>FlightBonusDialog</code> object for the given + * <code>FlightBonus</code> object + */ + public FlightBonusDialog(FlightBonus fb) { + this.initializeMessage(0); + this.activate(); + System.out.println("FBDialog "); + } + + /** + * Store old number of credits for the next message. + * @param credits + */ + void initializeMessage(int credits) { + this.message = new String("Collected credits in the past: "+credits+"\n"); + } + + /** + * When a subscriber is earning credits, the message string has to be updated. + */ + protected abstract class Collector { + + /** + * Expected method: Returns the start string + */ + public abstract String getStart(); + + /** + * Expected method: Returns the destination string + */ + public abstract String getDestination(); + + /** + * Updates the message string when credits are calculated + */ + callin int recordCredits() { + int credits = base.recordCredits(); + FlightBonusDialog.this.message += "FlightSegment: \n"; + FlightBonusDialog.this.message += " "+this.getStart()+"-->"+this.getDestination()+"\n"; + FlightBonusDialog.this.message += " earning credit: "+credits+"\n"; + return credits; + } + + } + + /** + * When a subscriber is buying something, the earned credits are shown in a dialog box. + */ + protected abstract class Message { + + abstract int getTotalCollectedCredits(); + abstract String getName(); + + /** + * Shows a dialog box with the bonus message + */ + public void showBonusDialog() { + int currentCredits = this.getTotalCollectedCredits(); + + String title = "Bonus message for Passenger "+this.getName(); + FlightBonusDialog.this.message += new String ("Collected credits now: "+currentCredits); + + JOptionPane.showMessageDialog( + BonusGUI.this.view.getComponent(), + FlightBonusDialog.this.message, + title, + JOptionPane.INFORMATION_MESSAGE); + + // reinitialize for the next message: + FlightBonusDialog.this.initializeMessage(currentCredits); + } + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/FlightBonus.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/FlightBonus.java new file mode 100644 index 000000000..e128b29cc --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/FlightBonus.java @@ -0,0 +1,84 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: FlightBonus.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.fbapplication; + +import org.eclipse.objectteams.example.bonussystem.Bonus; + +import base org.eclipse.objectteams.example.flightbooking.model.Passenger; +import base org.eclipse.objectteams.example.flightbooking.model.Segment; + +/** + * This team is a specialization of the generic Bonus programme. + * It inherits all roles from its super-team, which are adapted + * to the flightbooking domain in this team. + */ +public team class FlightBonus extends Bonus { + + /** + * Register a passenger as subscriber of this bonus programme. This creates + * a Subscriber role for the given Passenger object and makes the declared + * callin method binding effective for it. + */ + public FlightBonus(Passenger as Subscriber s) { + activate(); + } + + /** + * In flight booking our subscribers are passengers. + */ + public class Subscriber playedBy Passenger + // adapt only registered passengers (guard predicate): + base when (FlightBonus.this.hasRole(base)) + { + // Callin method binding: + buy <- replace book; + + // Callout method binding + String getName() -> String getName(); + }; + + /** + * Credits are associated with each segment of a flight. + */ + public class Item playedBy Segment { + + /** + * Implement the air line's strategy: For each started 1000 miles give + * 1000 points. + */ + public int calculateCredit () { + int miles = getDistance(); + int credit = ((miles+999)/1000) * 1000; // round up + return credit; + }; + + + // Callin method binding: + earnCredit <- after book; + + // Callout method binding: forwarding to base method + String getDestination() -> String getDestination(); + + int getDistance() -> int getDistance(); + + String getStart() -> String getStart(); + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/GUIConnector.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/GUIConnector.java new file mode 100644 index 000000000..5a032945b --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/GUIConnector.java @@ -0,0 +1,48 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: GUIConnector.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.fbapplication; + +import java.awt.Component; + +import base org.eclipse.objectteams.example.flightbooking.gui.FlightBookingGUI; +import base org.eclipse.objectteams.example.flightbooking.model.PassengerDB; + +/** + * This team class (connector) connects the + */ +public team class GUIConnector extends BonusGUI { + + + protected class View playedBy FlightBookingGUI { + protected Component getComponent () { + return this; // implicit lowering, the base object conforms to Component. + } + + registerView <- after initComponents; + } + + protected class Controller playedBy PassengerDB { + //------------------------------------------------------ + // Bootstrap callin method binding: + queryRegisterForBonus <- after add; + //------------------------------------------------------- + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/GUIConnector/FlightBonusDialog.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/GUIConnector/FlightBonusDialog.java new file mode 100644 index 000000000..c006e57ec --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/fbapplication/GUIConnector/FlightBonusDialog.java @@ -0,0 +1,40 @@ +/* + * Created on Mar 6, 2005 + */ +team package org.eclipse.objectteams.example.fbapplication.GUIConnector; + + +/** + * This team is nested within GUIConnector (see the package statement above). + * It is responsible for recording acquired credits and displaying this + * information after a passenger has booked his or her flight. + * + * Note, that this class implicitly inherits from GUIConnector.FlightBonusDialog + * and so do its roles recursively. + */ +protected team class FlightBonusDialog playedBy FlightBonus { + + protected class Collector playedBy Item<@FlightBonusDialog.base> { + + //------------------------------------------------------- + //Callin bindings + recordCredits <- replace calculateCredit; + //------------------------------------------------------- + //Callout bindings + getDestination -> getDestination; + getStart -> getStart; + //------------------------------------------------------- + } + + protected class Message playedBy Subscriber<@FlightBonusDialog.base> { + + //------------------------------------------------------- + // Callout bindings + getTotalCollectedCredits -> getCollectedCredits; + getName -> getName; + //------------------------------------------------------- + // Callin binding + showBonusDialog <- after buy; + //------------------------------------------------------- + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/ui/WindowPlacer.java b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/ui/WindowPlacer.java new file mode 100644 index 000000000..8f7bb440a --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/src/src/org/eclipse/objectteams/example/ui/WindowPlacer.java @@ -0,0 +1,49 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: WindowPlacer.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.ui; + +import java.awt.Component; +import java.awt.Container; + +import base java.awt.Window; + + +/** + * This aspect ensures that each window will appear in the middle + * of the screen. + */ +public team class WindowPlacer { + + @SuppressWarnings("bindingtosystemclass") + protected class WindowAdaptor playedBy Window { + // callouts: + Container getParent() -> Container getParent(); + void setCentered(Container parent) -> void setLocationRelativeTo(Component parent); + + // callin: + void centerRelativeToParent() <- after void pack(); + + // the action: + protected void centerRelativeToParent() { + setCentered(getParent()); + } + } +} diff --git a/othersrc/otdt-examples/OTSample-Flightbonus-src/zipFlightbonus.launch b/othersrc/otdt-examples/OTSample-Flightbonus-src/zipFlightbonus.launch new file mode 100644 index 000000000..b57106526 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Flightbonus-src/zipFlightbonus.launch @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<launchConfiguration type="org.eclipse.ant.AntLaunchConfigurationType"> +<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="true"/> +<stringAttribute key="org.eclipse.debug.core.ATTR_REFRESH_SCOPE" value="${working_set:<?xml version="1.0" encoding="UTF-8"?> <launchConfigurationWorkingSet factoryID="org.eclipse.ui.internal.WorkingSetFactory" label="working set" name="working set"> <item factoryID="org.eclipse.ui.internal.model.ResourceFactory" path="/org.eclipse.objectteams.otdt.samples/samples" type="2"/> </launchConfigurationWorkingSet>}"/> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_PATHS"> +<listEntry value="/OTSample-Flightbonus-src/build.xml"/> +</listAttribute> +<listAttribute key="org.eclipse.debug.core.MAPPED_RESOURCE_TYPES"> +<listEntry value="1"/> +</listAttribute> +<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> +<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.eclipse.ant.internal.ui.antsupport.InternalAntRunner"/> +<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="OTSample-Flightbonus-src"/> +<stringAttribute key="org.eclipse.jdt.launching.SOURCE_PATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_INSTALL_NAME" value="jdk1.5.0_17"/> +<stringAttribute key="org.eclipse.jdt.launching.VM_INSTALL_TYPE_ID" value="org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType"/> +<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="${workspace_loc}"/> +<mapAttribute key="org.eclipse.jdt.launchingVM_INSTALL_TYPE_SPECIFIC_ATTRS_MAP"> +<mapEntry key="org.eclipse.jdt.launching.JAVA_COMMAND" value="java"/> +</mapAttribute> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LAUNCH_CONFIGURATION_BUILD_SCOPE" value="${none}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/OTSample-Flightbonus-src/build.xml}"/> +<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc}"/> +<booleanAttribute key="org.eclipse.objectteams.launch" value="false"/> +<booleanAttribute key="org.eclipse.objectteams.otdt.debug.USE_JPLIS" value="false"/> +<stringAttribute key="process_factory_id" value="org.eclipse.ant.ui.remoteAntProcessFactory"/> +</launchConfiguration> diff --git a/othersrc/otdt-examples/OTSample-Observer-src/.classpath b/othersrc/otdt-examples/OTSample-Observer-src/.classpath new file mode 100644 index 000000000..bcc3bc2b8 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="OTRE"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/othersrc/otdt-examples/OTSample-Observer-src/.project b/othersrc/otdt-examples/OTSample-Observer-src/.project new file mode 100644 index 000000000..37d4665f8 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>OTSample-Observer-src</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.objectteams.otdt.builder.OTJBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.objectteams.otdt.OTJavaNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/othersrc/otdt-examples/OTSample-Observer-src/observer-zip.jardesc b/othersrc/otdt-examples/OTSample-Observer-src/observer-zip.jardesc new file mode 100644 index 000000000..2fc91c671 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/observer-zip.jardesc @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<jardesc> + <jar path="org.eclipse.objectteams.otdt.samples/samples/observer.zip"/> + <options buildIfNeeded="true" compress="true" descriptionLocation="/OTSample-Observer-src/observer-zip.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="true"/> + <storedRefactorings deprecationInfo="true" structuralOnly="false"/> + <selectedProjects/> + <selectedElements exportClassFiles="false" exportJavaFiles="true" exportOutputFolder="false"> + <javaElement handleIdentifier="=OTSample-Observer-src"/> + </selectedElements> +</jardesc> diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/Main.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/Main.java new file mode 100644 index 000000000..777735124 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/Main.java @@ -0,0 +1,97 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.application; + +import java.util.Arrays; +import java.util.List; + +import org.eclipse.objectteams.example.observer.library.*; +import org.eclipse.objectteams.example.observer.point_n_line.*; + + +/** + * Simple main program: create some objects, invoke modifications and watch the result. + */ +public class Main { + + public static void main (String[] args) { + // --- Testing ObserveLibrary: --- + ObserveLibrary ol = new ObserveLibrary(); + ol.activate(); + + Person jack = new Person("Jack"); + Book gof = new Book("Design Patterns", "GoF", "1234"); + Book etl = new Book("Eiffel The Language", "BM", "345"); + BookCopy gof1 = new BookCopy(gof); + BookCopy gof2 = new BookCopy(gof); + BookCopy etl1 = new BookCopy(etl); + BookCopy etl2 = new BookCopy(etl); + + printBorrow(gof1, jack); + printBorrow(etl2, jack); + + BookManager manager = new BookManager(); + manager.printView(); + + manager.buy(gof1); + manager.buy(gof2); + manager.buy(etl1); + manager.buy(etl2); + + manager.printView(); + + System.out.println("===> return gof1, borrow etl1"); + gof1.returnIt(); + printBorrow(etl1, jack); + manager.printView(); + + System.out.println("===> test unregistering:"); + manager.drop(etl2); + etl2.returnIt(); + manager.printView(); + manager.buy(etl2); + manager.printView(); + + // --- Testing ObserveLine: --- + testPointNLine(); + } + + static void printBorrow(BookCopy bc, Person p) { + System.out.println(bc+" is borrowed by "+bc.borrow(p)); + } + + /** + * Perform some tests: create an Area and a Polyline. + * After drawing the line, perform some changes + * + */ + static void testPointNLine() { + ObserveLine observing = new ObserveLine(); + observing.activate(); // needed to make callin bindings effective. + Area area = new Area(); + Polyline line = new Polyline(); + area.draw(line); + // single point: + line.addPoint(new Point(0,0)); + // list of points: + List<Point> points = Arrays.asList( new Point[] { + new Point(1,0), new Point(1,1), new Point(2,2) + }); + // bulk-operation: + line.addPoints(points); // causes re-entrance (but not of observer! ;) + } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/ObserveLibrary.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/ObserveLibrary.java new file mode 100644 index 000000000..390c9d69a --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/ObserveLibrary.java @@ -0,0 +1,49 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.application; + +import org.eclipse.objectteams.example.observer.pattern.ObserverPattern; + +import base org.eclipse.objectteams.example.observer.library.BookManager; +import base org.eclipse.objectteams.example.observer.library.BookCopy; + +/** + * This is a team class which is used as a connector, meaning, it contains + * just bindings, no implementation. + * The abstract modifier of superclass is dropped, + * because abstract methods are defined by deployment (using callout-bindings). + */ +public team class ObserveLibrary extends ObserverPattern { + + public class Observer playedBy BookManager { + + // Callout method binding: bind an action to the update event. + update -> updateView; + + /* -------------------------------------------------------------- */ + + // Callin method bindings: bind events to trigger the start/stop operations. + start <- after buy; + stop <- before drop; + } + + public class Subject playedBy BookCopy { + + // Callin method binding: bind events to trigger the notification mechanism. + changeOp <- after returnIt, borrow; + } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/ObserveLine.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/ObserveLine.java new file mode 100644 index 000000000..234653baa --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/application/ObserveLine.java @@ -0,0 +1,57 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.application; + +import org.eclipse.objectteams.example.observer.pattern.ObserverPattern; + +import base org.eclipse.objectteams.example.observer.point_n_line.Polyline; +import base org.eclipse.objectteams.example.observer.point_n_line.Area; + +/** + * This class applies the observer pattern to a set of drawing elements. + * One could easily think of a canvas that should react to changes of + * its figures. + */ +public team class ObserveLine extends ObserverPattern { + + /** + * Elements to be observed are simple poly-lines. + */ + protected class Subject playedBy Polyline { + // bindings only: + changeOp <- after addPoint; + changeOpMany <- replace addPoints; + toString => toString; // callout overrides existing method + } + protected class Observer playedBy Area { + /** + * Only print out that a change happend and some action should be taken. + * (this method implements the inherited abstract method, instead of + * binding it to a base method). + * + * @param s the element that has changed. + */ + protected void update(Subject s) { + System.out.println("Observing: "+s); + } + /** + * Bind the trigger to start the protocol: + * only elements that are drawn need to participate in the observer pattern. + */ + start <- after draw; + } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/Book.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/Book.java new file mode 100644 index 000000000..d65c0696f --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/Book.java @@ -0,0 +1,50 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.library; + +import java.util.LinkedList; + +/** + * A title listed in the catalogue. + */ +public class Book { + + private String name; + private String author; + private String isbn; + private LinkedList<BookCopy> copies = new LinkedList<BookCopy>(); + + public Book (String name, String author, String isbn) { + this.name = name; + this.author = name; + this.isbn = isbn; + } + + public String getName () { return name ; } + public String getAuthor () { return author; } + public String getISBN () { return isbn; } + + /** + * When a new copy of this book is acquired, use this method to register. + * @param bc + * @return number of registered copies after the operation. + */ + public int registerCopy (BookCopy bc) { + copies.add(bc); + return copies.size(); + } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/BookCopy.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/BookCopy.java new file mode 100644 index 000000000..59d4965f5 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/BookCopy.java @@ -0,0 +1,68 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.library; + +/** + * Instances represent physical books in the shelf. + */ +public class BookCopy { + + private Book theBook; // the title of which this is a copy + private Person borrower = null; + private int nr; + + public BookCopy (Book ofBook) { + theBook = ofBook; + nr = ofBook.registerCopy(this); + } + + /** + * When a person borrows a book, record who is the borrower. + * @param who + * @return the borrower + */ + public Person borrow (Person who) { + borrower = who; + return borrower; + } + + /** + * (Unfortunately cannot name a method "return" ;-) + * A book copy that was out is returned. + */ + public void returnIt () { + borrower = null; + } + + /** + * Is it available for borrowing? + */ + public boolean isAvail () { + return borrower == null; + } + + /** + * The ID of a book copy gives the title and a serial number. + */ + public String getID () { + return "'"+theBook.getName() + "'#" + nr; + } + + public String toString () { + return getID(); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/BookManager.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/BookManager.java new file mode 100644 index 000000000..71139106f --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/BookManager.java @@ -0,0 +1,69 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.library; + +import java.util.Arrays; +import java.util.HashMap; + +/** + * Central class of a simplistic library-system. + * The book manager keeps a set of books. + */ +public class BookManager { + + private HashMap<String, String> view = new HashMap<String, String>(); // ID -> status + + /** + * A new copy of a book is bought and stored in the book manager. + * @param bc the new book copy. + */ + public void buy (BookCopy bc) { + updateView (bc); + } + + /** + * Remove a book copy, e.g., after it was lost. + * @param bc + */ + public void drop (BookCopy bc) { + view.remove(bc.getID()); + } + + /** + * Print some information on each book managed by us. + */ + public void printView () { + System.out.println("Copy\t\t\tStatus"); + System.out.println("--------------------------------"); + String[] keys = view.keySet().toArray(new String[view.size()]); + Arrays.sort(keys); // sorting is for testability. + for (int i=0; i<keys.length; i++) { + String key = keys[i]; + String status = view.get(key); + System.out.println(key + "\t" + status); + } + } + + /** + * Update the status (available/out) of a given book copy. + * @param bc + */ + public void updateView(BookCopy bc) { + String status = bc.isAvail() ? "available" : "out"; + view.put(bc.getID(), status); + } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/Person.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/Person.java new file mode 100644 index 000000000..8c7ea806c --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/library/Person.java @@ -0,0 +1,34 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.library; + +/** + * While Persons are actually quite complex, this class models only + * what is needed to identify a Person when borrowing a book copy. + */ +public class Person { + + private String name; + + public Person (String n) { + name = n; + } + + public String getName () { return name; } + + public String toString() { return name; } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/pattern/ObserverPattern.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/pattern/ObserverPattern.java new file mode 100644 index 000000000..e52d260e1 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/pattern/ObserverPattern.java @@ -0,0 +1,106 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.pattern; + +import java.util.LinkedList; + +/** + * This team gives a reusable implementation of the Observer Pattern. + * Only application-specific parts are left abstract. + * + * Two applications of this pattern and a simple Main can be found in package org.eclipse.objectteams.example.observer.application. + * + * To run the application, select org.eclipse.objectteams.example.observer.application/Main.java in the package explorer + * and select "Run as" -> "Java Application". + * (to check enablement of OT/J you may visit the JRE tab of the corres- + * ponding launch configuration and ensure that "Enable OTRE" is checked). + */ +public abstract team class ObserverPattern { + + /** + * The Subject role of the observer pattern. + * Abstractness is not strictly needed, but it signals that applications + * of the pattern should refine this role. + */ + protected abstract class Subject { + + // ========== Registry of known Observers: ========== + private LinkedList<Observer> observers = new LinkedList<Observer>(); + + protected void addObserver (Observer o) { + observers.add(o); + } + + protected void removeObserver (Observer o) { + observers.remove(o); + } + + /** + * All edit operations of the concrete Subject should call into this method. + */ + public void changeOp() { + for (Observer observer : observers) + observer.update(this); + } + + /** + * Variant for multiple changes in one method call. + * Because we suspect reentrance at the base side, we temporarily deactivate this Team. + * (This solves the problem known as "jumping aspects" + * where more notifications would be sent than needed). + * By declaring the method as "callin" it is designed to be bound using "replace". + */ + callin void changeOpMany () { + boolean wasActive = isActive(); + deactivate(); // no notification during the base call. + base.changeOpMany(); // call original version (requires "callin" modifier). + if (wasActive) + activate(); // restore state + + changeOp(); + } + } + + /** + * Observer role of the design pattern. + */ + protected abstract class Observer { + + /** + * This method needs to be realized to do something usefull + * on the actual observer instance. + */ + protected abstract void update(Subject s); + + /** + * To be called, when a concrete observer starts to participate in the pattern. + * @param s the subject to connect to. + */ + public void start (Subject s) { + s.addObserver(this); + } + + /** + * To be called, when a concrete observer stops to participate in the pattern. + * @param s the subject to disconnect from. + */ + public void stop (Subject s) { + s.removeObserver(this); + } + } +} + diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Area.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Area.java new file mode 100644 index 000000000..66fd5347a --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Area.java @@ -0,0 +1,24 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.point_n_line; + +public class Area { + + public void draw (Polyline l) { + System.out.println("Area drawing line "+l); + } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Point.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Point.java new file mode 100644 index 000000000..9aae5da9f --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Point.java @@ -0,0 +1,28 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.point_n_line; + +public class Point { + private int x,y; + public Point (int x, int y) { + this.x = x; + this.y = y; + } + public String toString () { + return "("+x+", "+y+")"; + } +} diff --git a/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Polyline.java b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Polyline.java new file mode 100644 index 000000000..55cb648b2 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Observer-src/src/org/eclipse/objectteams/example/observer/point_n_line/Polyline.java @@ -0,0 +1,44 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id$ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.observer.point_n_line; + +import java.util.*; + +public class Polyline { + private LinkedList<Point> points = new LinkedList<Point>(); + + public void addPoint (Point p) { + points.add(p); + } + + public void addPoints (List<Point> pList) { + for (Point p : pList) + addPoint(p); + } + + public String toString () { + StringBuffer buf = new StringBuffer("Line ["); + String sep = ""; + for (Point p : points) { + buf.append(sep+p.toString()); + sep = ", "; + } + buf.append("]"); + return buf.toString(); + } + +} diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/.classpath b/othersrc/otdt-examples/OTSample-Stopwatch-src/.classpath new file mode 100644 index 000000000..bcc3bc2b8 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="OTRE"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/.project b/othersrc/otdt-examples/OTSample-Stopwatch-src/.project new file mode 100644 index 000000000..7ce28463d --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>OTSample-Stopwatch-src</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.objectteams.otdt.builder.OTJBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.objectteams.otdt.OTJavaNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/.settings/org.eclipse.jdt.core.prefs b/othersrc/otdt-examples/OTSample-Stopwatch-src/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 000000000..87e37e0d9 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,64 @@ +#Sat Jul 18 21:53:34 CEST 2009 +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning +org.eclipse.jdt.core.compiler.problem.autoboxing=ignore +org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning +org.eclipse.jdt.core.compiler.problem.deadCode=warning +org.eclipse.jdt.core.compiler.problem.deprecation=warning +org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled +org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled +org.eclipse.jdt.core.compiler.problem.discouragedReference=warning +org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore +org.eclipse.jdt.core.compiler.problem.fallthroughCase=warning +org.eclipse.jdt.core.compiler.problem.fatalOptionalError=enabled +org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore +org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning +org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning +org.eclipse.jdt.core.compiler.problem.forbiddenReference=error +org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning +org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning +org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore +org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore +org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore +org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning +org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore +org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore +org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore +org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore +org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning +org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning +org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore +org.eclipse.jdt.core.compiler.problem.nullReference=warning +org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning +org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore +org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore +org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore +org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning +org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore +org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore +org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled +org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning +org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled +org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore +org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning +org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning +org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore +org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning +org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore +org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=ignore +org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled +org.eclipse.jdt.core.compiler.problem.unusedImport=warning +org.eclipse.jdt.core.compiler.problem.unusedLabel=warning +org.eclipse.jdt.core.compiler.problem.unusedLocal=warning +org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore +org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled +org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled +org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning +org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning +org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/img/watch.jpg b/othersrc/otdt-examples/OTSample-Stopwatch-src/img/watch.jpg Binary files differnew file mode 100644 index 000000000..2e293fe07 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/img/watch.jpg diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/AnalogClock.java b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/AnalogClock.java new file mode 100644 index 000000000..579ffc859 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/AnalogClock.java @@ -0,0 +1,123 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: AnalogClock.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.stopwatch; + +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; + +import javax.imageio.ImageIO; +import javax.swing.JPanel; + +public class AnalogClock extends JPanel { + private int seconds = 0; + + private static final int spacing = 10; + private static final float threePi = (float)(3.0 * Math.PI); + // Angles for the trigonometric functions are measured in radians. + // The following in the number of radians per sec or min. + private static final float radPerSecMin = (float)(Math.PI / 30.0); + + private int size; // height and width of clock face + private int centerX; // x coord of middle of clock + private int centerY; // y coord of middle of clock + private BufferedImage clockImage; + + //==================================================== Clock constructor + public AnalogClock() { + this.setBackground(Color.white); + this.setForeground(Color.black); + }//end constructor + + //=============================================================== update + // Replace the default update so that the plain background + // doesn't get drawn. + public void update(int value) { + seconds = value; + this.repaint(); + }//end update + + //======================================================= paintComponent + + public void paintComponent(Graphics g) { + super.paintComponent(g); // paint background, borders + Graphics2D g2 = (Graphics2D)g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + + int w = getWidth(); + int h = getHeight(); + size = ((w < h) ? w : h) - 2 * spacing; + centerX = size / 2 + spacing; + centerY = size / 2 + spacing + 35; + + // Create the clock face background image if this is the first time + if (clockImage == null + || clockImage.getWidth() != w + || clockImage.getHeight() != h) { + + try { + clockImage = ImageIO.read(new File("img/watch.jpg")); + } catch (IOException e) { + // File not found :-/ + } + // now get a graphics context from this image + Graphics2D gc = clockImage.createGraphics(); + gc.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + } + + // Draw the clock face from the precomputed image + g2.drawImage(clockImage, null, 0, 0); + + // Draw the clock hands + drawClockHand(g); + }//end paintComponent + + //======================================================= drawClockHand + private void drawClockHand(Graphics g) { + int secondRadius = size / 2 - 55; + + // second hand + float fseconds = seconds; + float secondAngle = threePi - (radPerSecMin * fseconds); + drawRadius(g, centerX, centerY, secondAngle, 0, secondRadius); + + }//end drawClockHands + + // =========================================================== drawRadius + private void drawRadius(Graphics g, int x, int y, double angle, + int minRadius, int maxRadius) { + float sine = (float)Math.sin(angle); + float cosine = (float)Math.cos(angle); + + int dxmin = (int)(minRadius * sine); + int dymin = (int)(minRadius * cosine); + + int dxmax = (int)(maxRadius * sine); + int dymax = (int)(maxRadius * cosine); + Graphics2D g2d = (Graphics2D)g; + g2d.setStroke(new BasicStroke(4)); + g2d.drawLine(x + dxmin, y + dymin, x + dxmax, y + dymax); + }//end drawRadius + +} diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/Main.java b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/Main.java new file mode 100644 index 000000000..9b65979b5 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/Main.java @@ -0,0 +1,59 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Main.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.stopwatch; + +/** + * Object Teams features demonstrated by this example: + * --------------------------------------------------- + * + * Callin and callout method binding: Callin bindings are used to inform the GUI + * about changes in the base class. The callout method bindings allow us to + * propagate commands from the GUI to the base class. + * + * Role class binding: The role WatchDisplay is bound to the base class StopWatch. + * + * + * Domain description: + * ------------------- + * + * This is a simple example for an implementation of the Model-View-Controller + * pattern. A StopWatch with the basic functions start, stop, and clear is + * created and passed to two WatchDisplays. Any changes in the model (StopWatch) + * are made visible in both views (WatchDisplay). + * + * Launching the application: + * -------------------------- + * Just run this main class as a Java Application, e.g., like this: + * - Choose "Run", "Run..." in the Eclipse menu bar + * - Select "Java Application" + * - Create a new run configuration by clicking "New" + * - Click "Run" + * (to check enablement of OT/J you may visit the JRE tab of the corres- + * ponding launch configuration and ensure that "Enable OTRE" is checked). + */ +public class Main { + + public static void main(String[] args) { + StopWatch w = new StopWatch(); + new WatchUIAnalog(w); + new WatchUI(w); + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/StopWatch.java b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/StopWatch.java new file mode 100644 index 000000000..e3b0ff029 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/StopWatch.java @@ -0,0 +1,127 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: StopWatch.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.stopwatch; + +/** + * This class acts as base class for this example. It is bound to the + * WatchDisplay role of the WatchUI team. StopWatch implemets a simple watch as + * a thread. The watch can be controlled via three methods: start(), stop() and + * clear(). getValue() returns the current time value. Note, that the StopWatch + * is not aware of the GUI. + */ +public class StopWatch implements Runnable { + + /** + * Current time value + */ + private int time = 0; + + /** + * Flag that indicates if the watch is running + */ + private boolean running; + + /** + * Flag that indicates if there is a stop request + */ + private boolean stopRequest; + + /** + * Increases the time value. + */ + private synchronized void advance() { + time++; + } + + /** + * Starts the watch thread. + */ + public synchronized void start() { + if (!running) { + setRunning(true); + setStopped(false); + (new Thread(this)).start(); + } + } + + /** + * Stops the watch thread. + * + */ + public synchronized void stop() { + setStopped(true); + } + + /** + * Resets the time value. + */ + public synchronized void reset() { + time = 0; + } + + /** + * Returns the current time value. + */ + public synchronized int getValue() { + return time; + } + + /** + * Sets the running flag value. + */ + private synchronized void setRunning(boolean value) { + running = value; + } + + /** + * Returns the stop flag value + */ + private synchronized boolean isStopped() { + return stopRequest; + } + + /** + * Sets the stop flag value + */ + private synchronized void setStopped(boolean value) { + stopRequest = value; + } + + /** + * This method contains the main loop that is executed while the watch is + * running. + */ + public void run() { + while (true) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + setRunning(false); + return; + } + if (isStopped()) { + setRunning(false); + return; + } + advance(); + } + } +}
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/WatchUI.java b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/WatchUI.java new file mode 100644 index 000000000..b788f21dd --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/WatchUI.java @@ -0,0 +1,135 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: WatchUI.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.stopwatch; + +import java.awt.Container; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JTextField; + +/** + * This team implements the UI for a StopWatch and contains the role class + * WatchDisplay. + */ +public team class WatchUI { + static int ypos = 150; + + /** + * Role class WatchDisplay is played by the base class StopWatch. The role + * class WatchDisplay is bound to the base class StopWatch with the keyowrd + * 'playedBy'. + */ + protected class WatchDisplay extends JFrame playedBy StopWatch + { + private JTextField display; + private JButton startButton; + private JButton stopButton; + private JButton clearButton; + + /** + * This constructor is used for automatic role creation. E.g. via + * declared lifting. Role class constructor takes an object of the type + * of the declared base class. Setup the window, create a textfield for + * time display and three buttons "start", "stop", and "clear". + */ + public WatchDisplay(StopWatch w) { + setTitle("Digital Stop Watch"); + setSize(new Dimension(300, 100)); + setLocation(410, ypos+=110); + Container pane = getContentPane(); + pane.setLayout(new GridLayout(2,3)); + + pane.add(new JLabel("")); + display = new JTextField("0", 8); + display.setHorizontalAlignment(JTextField.RIGHT); + pane.add(display); + pane.add(new JLabel("")); + + startButton = new JButton("start"); + startButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + start(); + }}); + pane.add(startButton); + + stopButton = new JButton("stop"); + stopButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + stop(); + }}); + pane.add(stopButton); + + clearButton = new JButton("clear"); + clearButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + clear(); + }}); + pane.add(clearButton); + setVisible(true); + } + + /** + * Shows the new time value on the watch display. + */ + void update() { + String val = getStringValue(); + display.setText(val); + } + + // Abstract methods for mapping to the concrete base methods: + abstract void start(); + abstract void stop(); + abstract void clear(); + abstract String getStringValue(); + + // callout method bindings: any call of the abstract WatchDisplay + // method will be forwarded to the concrete StopWatch method + start -> start; + stop -> stop; + clear -> reset; + String getStringValue() -> int getValue() + with { + // result is a predefined name. + result <- Integer.toString(result) + } + + /* -------------------------------------------------------------- */ + + // Callin method bindings: WatchDisplay (role object) is updated + // after the StopWatch (base object) advanced or was reset. + void update() <- after void advance(); + void update() <- after void reset(); + } + + /** + * The team constructor uses declared lifting. A WatchDisplay role is + * created for the given StopWatch object. + */ + public WatchUI (StopWatch as WatchDisplay w) { + activate(ALL_THREADS); // Without this, the callin bindings have no effect. + } +} diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/WatchUIAnalog.java b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/WatchUIAnalog.java new file mode 100644 index 000000000..814e1c846 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/src/org/eclipse/objectteams/example/stopwatch/WatchUIAnalog.java @@ -0,0 +1,117 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Fraunhofer Gesellschaft, Munich, Germany, + * for its Fraunhofer Institute and Computer Architecture and Software + * Technology (FIRST), Berlin, Germany and Technical University Berlin, + * Germany. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: WatchUIAnalog.java 23501 2010-02-08 18:27:55Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Fraunhofer FIRST - Initial API and implementation + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.eclipse.objectteams.example.stopwatch; + +import java.awt.BorderLayout; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; + +/** + * This team implements the UI for a StopWatch and contains the role class + * WatchDisplay. + */ +public team class WatchUIAnalog { + public class WatchDisplay extends JFrame playedBy StopWatch { + + AnalogClock clockFace; + private JButton startButton; + private JButton stopButton; + private JButton clearButton; + + //========================================================== constructor + public WatchDisplay(StopWatch sw) { + Container content = this.getContentPane(); + content.setLayout(new BorderLayout()); + clockFace = new AnalogClock(); + this.setLocation(90, 110); + this.setResizable(false); + + content.add(clockFace, BorderLayout.CENTER); + JPanel buttons = new JPanel(); + buttons.setLayout(new FlowLayout()); + + startButton = new JButton("start"); + startButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + start(); + }}); + buttons.add(startButton); + + stopButton = new JButton("stop"); + stopButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + stop(); + }}); + buttons.add(stopButton); + + clearButton = new JButton("clear"); + clearButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + clear(); + }}); + buttons.add(clearButton); + + content.add(buttons, BorderLayout.SOUTH); + + this.setTitle("Analog Stop Watch"); + this.setSize(new Dimension(298, 440)); + + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setVisible(true); + }//end constructor + + void update() { + clockFace.update(getValue()); + } +// Abstract methods for mapping to the concrete base methods: + abstract void stop(); + abstract void clear(); + abstract int getValue(); + + // callout method bindings: any call of the abstract WatchDisplay + // method will be forwarded to the concrete StopWatch method + void start() -> void start(); + stop -> stop; + clear -> reset; + getValue -> getValue; + +// Callin method bindings: WatchDisplay (role object) is updated + // after the StopWatch (base object) advanced or was reset. + void update() <- after void advance(); + void update() <- after void reset(); + }//end class ClockAnalogBuf + + + /** + * The team constructor uses declared lifting. A WatchDisplay role is + * created for the given StopWatch object. + */ + public WatchUIAnalog (StopWatch as WatchDisplay w) { + activate(ALL_THREADS); // Without this, the callin bindings have no effect. + } +} diff --git a/othersrc/otdt-examples/OTSample-Stopwatch-src/stopwatch-zip.jardesc b/othersrc/otdt-examples/OTSample-Stopwatch-src/stopwatch-zip.jardesc new file mode 100644 index 000000000..1e6e12545 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-Stopwatch-src/stopwatch-zip.jardesc @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<jardesc> + <jar path="org.eclipse.objectteams.otdt.samples/samples/stopwatch.zip"/> + <options buildIfNeeded="true" compress="true" descriptionLocation="/OTSample-Stopwatch-src/stopwatch-zip.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="true"/> + <storedRefactorings deprecationInfo="true" structuralOnly="false"/> + <selectedProjects/> + <selectedElements exportClassFiles="false" exportJavaFiles="true" exportOutputFolder="false"> + <javaElement handleIdentifier="=OTSample-Stopwatch-src"/> + </selectedElements> +</jardesc> diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/.classpath b/othersrc/otdt-examples/OTSample-ordersystem-src/.classpath new file mode 100644 index 000000000..bcc3bc2b8 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/.classpath @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<classpath> + <classpathentry kind="src" path="src"/> + <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> + <classpathentry kind="con" path="OTRE"/> + <classpathentry kind="output" path="bin"/> +</classpath> diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/.project b/othersrc/otdt-examples/OTSample-ordersystem-src/.project new file mode 100644 index 000000000..76279e97e --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/.project @@ -0,0 +1,18 @@ +<?xml version="1.0" encoding="UTF-8"?> +<projectDescription> + <name>OTSample-ordersystem-src</name> + <comment></comment> + <projects> + </projects> + <buildSpec> + <buildCommand> + <name>org.objectteams.otdt.builder.OTJBuilder</name> + <arguments> + </arguments> + </buildCommand> + </buildSpec> + <natures> + <nature>org.objectteams.otdt.OTJavaNature</nature> + <nature>org.eclipse.jdt.core.javanature</nature> + </natures> +</projectDescription> diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/Intro0.html b/othersrc/otdt-examples/OTSample-ordersystem-src/Intro0.html new file mode 100644 index 000000000..f37851b6e --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/Intro0.html @@ -0,0 +1,75 @@ +<title>Intro to the Order System Sample</title> +<style type="text/css"> +code { background-color:lightgray; } +img { border:0px; } +</style> +<body> +<h1>A Simple Order System</h1> + +<h2>Package Overview</h2> +See the individual class comments for details. + +<dl> +<dt><img src="images/package.gif"> <b><code>package org.objectteams.sample.ordersystem</code></b> +<dd>A simple main class triggering some actions in batch mode. + +<dt><img src="images/package.gif"> <b><code>package org.objectteams.sample.ordersystem.data</code></b> +<dd>Plain data classes <code>Customer</code> and <code>Address</code> + +<dt><img src="images/package.gif"> <b><code>package org.objectteams.sample.ordersystem.store</code></b> +<dd>This package models a <code>Storage</code> and its <code>StockItems</code>.<br /> + These are normal data objects with the usual access methods.<br /> + Throughout the class <code>StockItem</code> you will find "callin markers" + (<img src="images/callinbinding_obj.gif">) in the gutter, + indicating that the corresponding methods are adapted by one or more aspects in the system. + +<dt><img src="images/package.gif"> <b><code>package org.objectteams.sample.ordersystem.reservation</code></b> +<dl> +<dt><img src="images/team_obj.gif"> <code>team class Reservations</code> +<dd>A simple reservation component; abstract at this level because it is + completely undefined what kinds of <img src="images/role_obj.gif"> <code>Reservable</code> items are + being managed. +<dt><img src="images/team_obj.gif"> <code>team class StockReservations</code> +<dd>Binding the reservation component in order to manage <code>StockItems</code>. +</dl> + +<dt><img src="images/package.gif"> <b><code>package org.objectteams.sample.ordersystem.order</code></b> +<dl> +<dt><img src="images/team_obj.gif"> <code>team class Order</code> +<dd>A simple ordering component; abstract at this level because it is + completely undefined what kinds of <img src="images/role_obj.gif"> <code>Items</code> items are + being managed. <br /> + However, each order is associated to a <img src="images/role_obj.gif"> <code>Customer</code> + and his or her <img src="images/role_obj.gif"> <code>Address</code>. Please note, that these + role classes are not related to those classes defined in <code>org.objectteams.samples.data</code>. +<dt><img src="images/team_obj.gif"> <code>team class StockOrder</code> +<dd>Binding the order component in order to manage <code>StockItems</code>. +</dl> +<dt><img src="images/package.gif"> <b><code>package org.objectteams.sample.ordersystem.gui</code></b> +<dl><img src="images/class_public.gif"> <code>class OrderSystemMainFrame</code> +<dd>Definition of the GUI of this system. Most of this class might have been generated by + a Form Designer. +<dt><img src="images/team_obj.gif"> <code>team class ModelAdapterTeam</code> +<dd>This aspect binds classes from the packages <code>data</code> and <code>store</code> to + the GUI. +<dt><img src="images/team_obj.gif"> <code>team class ControllerAdapterTeam</code> +<dd>This aspect contains all listeners and attaches them to the GUI. +<dt><img src="images/team_obj.gif"> <code>team class GUIAdapterTeam</code> +<dd>This aspect ensures that each window will appear in the middle of the screen. +<dt> +<dd> +</dl> +</dl> + +<h2>Running the application</h2> +In order to see the full functionality enter the following information to the launch configuration: +<table padding=3 border=1> +<tr><td colspan=2><b>Tab <img src="images/class_public.gif"> Main</b> +<tr><td>Main class<td><code>org.objectteams.samples.ordersystem.gui.GUITest</code> +<tr><td colspan=2><b>Tab <img src="images/team_obj.gif"> Team Activation</b> +<tr><td>Add: <td><code>ModelAdapterTeam</code><br /> + <code>ControllerAdapterTeam</code><br /> + <code>GUIAdapterTeam</code> +</table> +</body> +</html>
\ No newline at end of file diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/ordersystem-zip.jardesc b/othersrc/otdt-examples/OTSample-ordersystem-src/ordersystem-zip.jardesc new file mode 100644 index 000000000..3ecf58adb --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/ordersystem-zip.jardesc @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<jardesc> + <jar path="org.objectteams.otdt.samples/samples/ordersystem.zip"/> + <options buildIfNeeded="true" compress="true" descriptionLocation="/OTSample-ordersystem-src/ordersystem-zip.jardesc" exportErrors="false" exportWarnings="true" includeDirectoryEntries="false" overwrite="true" saveDescription="true" storeRefactorings="false" useSourceFolders="true"/> + <storedRefactorings deprecationInfo="true" structuralOnly="false"/> + <selectedProjects/> + <selectedElements exportClassFiles="false" exportJavaFiles="true" exportOutputFolder="false"> + <javaElement handleIdentifier="=OTSample-ordersystem-src/src"/> + <file path="/OTSample-ordersystem-src/Intro0.html"/> + <file path="/OTSample-ordersystem-src/.project"/> + <file path="/OTSample-ordersystem-src/.classpath"/> + </selectedElements> +</jardesc> diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/Main.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/Main.java new file mode 100644 index 000000000..9db247fb6 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/Main.java @@ -0,0 +1,189 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Main.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem; + +import org.objectteams.samples.ordersystem.data.*; +import org.objectteams.samples.ordersystem.order.StockOrder; +import org.objectteams.samples.ordersystem.reservation.StockReservations; +import org.objectteams.samples.ordersystem.store.*; + +/** + * Object Teams features demonstrated by this example: + * --------------------------------------------------- + * Team class as design pattern Facade: The team class reservations.Reservations + * provides a simple interface which hides the system complexity and minimizes + * the communication between reservation system and main class. + * + * Role classes as Decorator: The role class Reservable decorates its base class + * StockItem by adding of reservation feature, thereby allowing to control the + * availability of items in the storage. The role class Item encloses its base class + * StockItem, forwards requests to its provided methods (callouts) and performs + * additional actions for its base class (callins), thereby allowing to regard + * the storage items as a part of an order list. So we can manage the items in + * the storage, discount them and give the alarm, if the item has been invalidated. + * + * Team and role inheritance: The team class reservation.StockReservations inherits + * the role class Reservable from its super-team reservation.Reservations, the team + * class order.StockOrder inherits the role class Item from its super-team order.Order + * + * Declared lifting: The base object StockItem is explicitly lifted to its role object + * in the team class methods (teams order.StockOrder and reservation.StockReservations). + * + * Translation polymorphism: The base class StockItem plays two different roles + * in two different teams: Item in order.StockOrder and Reservable in + * reservation.StockReservations. The both role classes are not conform to each + * other. By transfer of an object of type Item between two methods of the different + * team classes (order.StockOrder and reservation.StockReservations) the Item object + * is implicitly lowered to its base object StockOrder following by declared lifting + * to the object of type Reservable. (see the data flow between Item.doReserve(int) and + * StockReservations.reserve(StockItem as Reservable,int)) + * + * Separation of team implementaion and role binding: The role classes Item and Reservable + * are implemented in their enclosing teams order.Order and reservation.Reservations + * and bound to their base classes in the sub-teams order.StockOrder and + * reservation.StockReservations. + * + * Callin and callout method binding: The essential adaptations are integrated using + * callin bindings. Note, that the roles also employ the style of callout bindings + * in order to access features of their base class. + * + * + * Domain description: + * ------------------- + * + * A generic storage functionality is implemented in the classes Storage and StockItem. + * The order system is introduced in the team class order.Order, where the role Item is + * unbound. The team class reservation.Reservatoins realizes the storage management in + * connection with the reservation of contained items. The base class storage.StockItem + * plays a role of an order entry in the team order.StockOrder (Item) and the role of + * a reservable item in the team reservation.StockReservations (Reservable). + */ +public class Main { + static StockItem[] items = new StockItem[] { + new StockItem("screw driver", 1500), + new StockItem("tool box pro", 5000), + new StockItem("stepladder", 7999), + new StockItem("philips screw", 155), + new StockItem("wall paint", 1680), + new StockItem("paint brush", 800) + }; + + static Address[] addresses = new Address[] { + new Address("22, october avenue", "2345", "Chicago", "Il,USA"), + new Address("Blaumeisenweg 5", "12345", "Berlin", "Germany"), + new Address("10, Lundy Avenue", "513648", "Paris", "France"), + new Address("Venus/Mars", "135754", "Io", "Jupiter"), + }; + + static Customer[] customers = new Customer[] { + new Customer("Joe", "Jojo", addresses[0]), + new Customer("Jim", "Beann", addresses[1]), + new Customer("Jan", "Tatam", addresses[2]) + }; + + static StockReservations res = (StockReservations)StockReservations.theInstance(); + + public static void main (String[] args) { + + + print("================StoreTest================\n"); + +// print("----------------Init Tests---------------\n"); +// InitTests.initTests(); + + print("----------------Fill storage-------------"); + fillStorage(); + Storage storage = Storage.theInstance(); + storage.print(System.out); + + print("----------------Remove item--------------"); + storage.delete(items[2]); + storage.print(System.out); + + + print("----------------Change item counts-------"); + storage.changeCount(items[4], 40); + storage.changeCount(items[0], 25); + storage.changeCount(items[5], 99); + storage.print(System.out); + + reserve(items[0], 24); + reserve(items[3], 100); + Storage.theInstance().print(System.out); + printStore(); + print("--- Deliver 20 of "+items[0]); + res.deliver(items[0], 20); + printStore(); + + print("--- Record that we lost 5 screw driver by theft."); + items[0].take(5); // they were stolen!! + printStore(); + + //create a new stock order and try to order some items and deliver these + StockOrder o1 = new StockOrder(customers[0]); + o1.order(items[4], 100); + o1.order(items[5], 2); + o1.print(); + o1.deliver(); + o1.print(); + + //create a new stock order and try to order an item + StockOrder o2 = new StockOrder(customers[1]); + o2.order(items[4], 200); + o2.print(); + + items[4].put(400); + + //discounting + StockOrder o3 = new StockOrder(customers[2], addresses[3]); + o3.setDiscount(items[4], 0.10); + o3.order(items[4], 200); + o3.order(items[5], 2); + o3.print(); + items[4].take(200); + } + + public static void fillStorage() { + Storage storage = Storage.theInstance(); + storage .add(items[0]); + storage .add(items[1]); + items[1].put(20); + storage .add(items[2]); + storage .add(items[3]); + items[3].put(1); + storage .add(items[4]); + items[4].put(200); + storage .add(items[5]); + } + + public static void print(String str) { + System.out.println(str); + } + + static void reserve(StockItem item, int count) { + int actual = res.reserve(item, count); + print("--- Reserved "+actual+"("+count+") of "+item); + } + + /** + * Printing of inventory list + */ + static void printStore() { + for (int i=0;i<items.length; i++) + print("available: "+res.numAvail(items[i])+"\t of "+items[i]); + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/data/Address.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/data/Address.java new file mode 100644 index 000000000..5ee64712a --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/data/Address.java @@ -0,0 +1,94 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Address.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.data; + +/** + * @author Dehla + * + */ +public class Address { + + @SuppressWarnings("unused") private int id; + + private String street; + private String postalcode; + private String city; + private String country; + + public Address(String street, String postalcode, String city, String country) { + this.street = street; + this.postalcode = postalcode; + this.city = city; + this.country = country; + } + + Address() {} + + + /** + * @return Returns the city. + */ + public String getCity() { + return city; + } + /** + * @param city The city to set. + */ + public void setCity(String city) { + this.city = city; + } + /** + * @return Returns the country. + */ + public String getCountry() { + return country; + } + /** + * @param country The country to set. + */ + public void setCountry(String country) { + this.country = country; + } + /** + * @return Returns the postalcode. + */ + public String getPostalcode() { + return postalcode; + } + /** + * @param postalcode The postalcode to set. + */ + public void setPostalcode(String postalcode) { + this.postalcode = postalcode; + } + /** + * @return Returns the street. + */ + public String getStreet() { + return street; + } + /** + * @param street The street to set. + */ + public void setStreet(String street) { + this.street = street; + } + + public String toString() { + return street + ", " + postalcode + " " + city + ", " + country; + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/data/Customer.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/data/Customer.java new file mode 100644 index 000000000..2f3c0a7d3 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/data/Customer.java @@ -0,0 +1,85 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Customer.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.data; + +/** + * @author Dehla + * + */ +public class Customer { + + @SuppressWarnings("unused") private int id; + + private String lastname; + private String firstname; + private Address address; + + public Customer(String lastname, String firstname, Address address) { + this.lastname = lastname; + this.firstname = firstname; + this.address = address; + } + + Customer() { } + + + /** + * @return Returns the address. + */ + public Address getAddress() { + return address; + } + + /** + * @param address The address to set. + */ + public void setAddress(Address address) { + this.address = address; + } + + /** + * @return Returns the firstname. + */ + public String getFirstname() { + return firstname; + } + + /** + * @param firstname The firstname to set. + */ + public void setFirstname(String firstname) { + this.firstname = firstname; + } + + /** + * @return Returns the lastname. + */ + public String getLastname() { + return lastname; + } + + /** + * @param lastname The lastname to set. + */ + public void setLastname(String lastname) { + this.lastname = lastname; + } + + public String toString() { + return firstname + " " + lastname + "\n" + "private address: " + address.toString(); + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/AbstractTableModelTemplate.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/AbstractTableModelTemplate.java new file mode 100644 index 000000000..36e027949 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/AbstractTableModelTemplate.java @@ -0,0 +1,68 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: AbstractTableModelTemplate.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +import java.util.Vector; + +import javax.swing.table.AbstractTableModel; + + +@SuppressWarnings("serial") +public abstract class AbstractTableModelTemplate<T> extends AbstractTableModel { + + protected abstract String[] getColumnNames(); + + public abstract Vector<T> getElements(); + + public abstract Object getValueAt(int aRowIndex, int aColumnIndex); + + /** + * @param aRowIndex an index + * @return the element (row) at given index + */ + public Object getElementAt(int aRowIndex) { + if (aRowIndex >= 0) { + return getElements().elementAt(aRowIndex); + } + else { + return null; + } + } + + /** + * @see javax.swing.table.TableModel#getRowCount() + */ + public int getRowCount() { + return getElements().size(); + } + + /** + * @see javax.swing.table.TableModel#getColumnCount() + */ + public int getColumnCount() { + return getColumnNames().length; + } + + /** + * @see javax.swing.table.AbstractTableModel#getColumnName(int) + */ + public String getColumnName(int aColumn) { + return getColumnNames()[aColumn]; + } + + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ButtonListLayout.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ButtonListLayout.java new file mode 100644 index 000000000..3fc5492df --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ButtonListLayout.java @@ -0,0 +1,390 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: ButtonListLayout.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.LayoutManager2; +import java.util.ArrayList; + +/** + * + * @author Dehla Sokenou + * + * Class for laying out are typical constellation: a button panel and a list (or a similar + * e.g. table) panel. + * <p> + * + * Buttons can be placed on top or below (vertical orientation) or on the left or right side + * (horizontal orientation) of the list. + * Standard orientation is horizontal. + * Standard placement of buttons is -depending on orientation- below or on the right side + * of the list panel (buttons after list). + * + */ +public class ButtonListLayout implements LayoutManager2 { + + /** + * Enum for the orientation. + * Possibly values are + * <ul> + * <li> HORIZONTAL: button panel ist displayed at the left or the right side of list panel. + * <li> VERTICAL: button panel is dispayed on top or below list panel. + * </ul> + * + * Orientation and placement cannot be changed during lifecycle of this class' objects. + */ + public enum Orientation { + VERTICAL, HORIZONTAL; + } + + public enum Placement { + BUTTONS_AFTER_LIST, BUTTONS_BEFORE_LIST; + } + + public enum ComponentType { + BUTTON_PANEL, LIST_OR_TABLE_PANEL; + } + + /** + * Orientation of the actual layout manager. Default is horizontal. + */ + protected final Orientation orientation; + + /** + * Placement of the actual layout manager. Default is the placement of buttons after list. + */ + protected final Placement placement; + + /** + * Reference to button panel that is managed by this layout manager. + */ + protected ArrayList<Component> buttons = new ArrayList<Component>(); + + /** + * Reference to list panel that is managed by this layout manager. + */ + protected Component listOrTablePanel = null; + + /** + * The spacing between buttons. Default is 5. + */ + protected int buttonSpacing = 5; + + /** + * The spacing between panels and panel to frame. Default is . + */ + protected int panelSpacing = 0; + + /** + * Size of button panel depending from button panel's orientation. + * If orientation is horizontal, size means width. + * If orientation is vertical, size means height. + * Default is preferred size of included buttons (null). + */ + protected Dimension fixedButtonSize = null; + + + public ButtonListLayout() { + this(null, null); + } + + public ButtonListLayout(Orientation anOrientation) { + this(anOrientation, null); + } + + public ButtonListLayout(Placement aPlacement) { + this(null, aPlacement); + } + + public ButtonListLayout(Orientation anOrientation, Placement aPlacement) { + orientation = anOrientation != null ? anOrientation : Orientation.HORIZONTAL; + placement = aPlacement != null ? aPlacement : Placement.BUTTONS_AFTER_LIST; + } + + /** + * @param aPanelSpacing the panelSpacing to set + */ + public void setPanelSpacing(int aPanelSpacing) { + panelSpacing = aPanelSpacing; + } + + /** + * @param aButtonSpacing the buttonSpacing to set + */ + public void setButtonSpacing(int aButtonSpacing) { + if (aButtonSpacing >= 0) { + buttonSpacing = aButtonSpacing; + } + } + + /** + * @param aFixedButtonPanelSize the fixedButtonPanelSize to set + */ + public void setFixedButtonSize(Dimension aFixedButtonPanelSize) { + fixedButtonSize = aFixedButtonPanelSize; + } + + /** + * @see LayoutManager2#addLayoutComponent(Component, Object) + */ + public void addLayoutComponent(Component aComponent, Object aConstraints) { + if (aConstraints instanceof ComponentType) { + switch ((ComponentType) aConstraints) { + case BUTTON_PANEL: + buttons.add(aComponent); break; + case LIST_OR_TABLE_PANEL: + listOrTablePanel = aComponent; break; + default: + throw new IllegalArgumentException("Unsupported layout constraint: " + aConstraints.toString()); + } + } + else { + throw new IllegalArgumentException("Unsupported layout constraint: " + aConstraints.toString()); + } + } + + /** + * @see LayoutManager2#maximumLayoutSize(Container) + */ + public Dimension maximumLayoutSize(Container aTarget) { + return new Dimension(Integer.MAX_VALUE, Integer.MAX_VALUE); + } + + /** + * @see LayoutManager2#getLayoutAlignmentX(Container) + */ + public float getLayoutAlignmentX(Container aTarget) { + // do nothing + return 0; + } + + /** + * @see LayoutManager2#getLayoutAlignmentY(Container) + */ + public float getLayoutAlignmentY(Container aTarget) { + // do nothing + return 0; + } + + /** + * @see LayoutManager2#invalidateLayout(Container) + */ + public void invalidateLayout(Container aTarget) { + // do nothing + } + + /** + * @see LayoutManager#addLayoutComponent(String, Component) + */ + public void addLayoutComponent(String aName, Component aComponent) { + throw new UnsupportedOperationException("Sdding layout components based on String constraints is not supported." + + "Use add(Component, Object) instead."); + } + + /** + * @see LayoutManager#removeLayoutComponent(Component) + */ + public void removeLayoutComponent(Component aComponent) { + if (listOrTablePanel == aComponent) { + listOrTablePanel = null; + } + else if (buttons.contains(aComponent)) { + buttons.remove(aComponent); + } + // else do nothing + } + + /** + * @see LayoutManager#preferredLayoutSize(Container) + */ + public Dimension preferredLayoutSize(Container aParent) { + return getLayoutSize(aParent, false); + } + + /** + * @see LayoutManager#minimumLayoutSize(Container) + */ + public Dimension minimumLayoutSize(Container aParent) { + return getLayoutSize(aParent, true); + } + + /** + * @see LayoutManager#layoutContainer(Container) + */ + public void layoutContainer(Container aParent) { + // beachten: insets, orientation, fixedbuttonsize, placement + // Note: we don't care about to small panel... if it doesn't fit, only a part is visible + + // firstly, calculate button panel size + Insets tempInsets = aParent.getInsets(); + int tempMaxWidth = aParent.getWidth() - (tempInsets.left + tempInsets.right) + - 2 * panelSpacing; + int tempMaxHeight = aParent.getHeight() - (tempInsets.top + tempInsets.bottom) + - 2 * panelSpacing; + + Dimension tempPreferredButtonPanelSize = getButtonPanelLayoutSize(false); + double tempPreferredButtonPanelWidth = tempPreferredButtonPanelSize.getWidth(); + double tempPreferredButtonPanelHeight = tempPreferredButtonPanelSize.getHeight(); + + // secondly, give remaining space to list + int tempListPanelX = tempInsets.left + panelSpacing; + if (orientation == Orientation.VERTICAL && placement == Placement.BUTTONS_BEFORE_LIST) { + tempListPanelX += panelSpacing + tempPreferredButtonPanelWidth; + } + int tempListPanelY = tempInsets.top + panelSpacing; + if (orientation == Orientation.HORIZONTAL && placement == Placement.BUTTONS_BEFORE_LIST) { + tempListPanelY += panelSpacing + tempPreferredButtonPanelHeight; + } + int tempListPanelWidth = tempMaxWidth; + if (orientation == Orientation.VERTICAL) { + tempListPanelWidth -= (int) tempPreferredButtonPanelWidth + panelSpacing; + } + int tempListPanelHeight = tempMaxHeight; + if (orientation == Orientation.HORIZONTAL) { + tempListPanelHeight -= (int) tempPreferredButtonPanelHeight + panelSpacing; + } + // check, if panel is unvisible + if (tempListPanelWidth < 0) { + tempListPanelWidth = 0; + } + if (tempListPanelHeight < 0) { + tempListPanelHeight = 0; + } + listOrTablePanel.setBounds(tempListPanelX, tempListPanelY, tempListPanelWidth, tempListPanelHeight); + + // thirdly, layout buttons in button panel based on preferred size + int tempButtonX = tempInsets.left + panelSpacing; + if (orientation == Orientation.VERTICAL && placement == Placement.BUTTONS_AFTER_LIST) { + tempButtonX += panelSpacing + tempListPanelWidth; + } + int tempButtonY = tempInsets.top + panelSpacing; + if (orientation == Orientation.HORIZONTAL && placement == Placement.BUTTONS_AFTER_LIST) { + tempButtonY += panelSpacing + tempListPanelHeight; + } + for (Component tempButton : buttons) { + Dimension tempButtonSize = fixedButtonSize != null ? fixedButtonSize : tempButton.getPreferredSize(); + int tempButtonWidth = tempButtonSize.width; + int tempButtonHeight = tempButtonSize.height; + tempButton.setBounds(tempButtonX, tempButtonY, tempButtonWidth, tempButtonHeight); + // calculate next button position + switch (orientation) { + case VERTICAL: + tempButtonY += tempButtonHeight + buttonSpacing; + break; + case HORIZONTAL: + tempButtonX += tempButtonWidth + buttonSpacing; + break; + } + } + + } + + /** + * + * @param aParent the container to manage + * @param minimum indicates whether minimum (true) or preferred (false) layout + * will be returned + * @return the preferred or (if minimum) minimum layout size + */ + protected Dimension getLayoutSize(Container aParent, boolean minimum) { + Dimension tempButtonPanelDimension = getButtonPanelLayoutSize(minimum); + + Insets tempInsets = aParent.getInsets(); + double tempLayoutWidth = 2 * panelSpacing + tempInsets.left + tempInsets.right; + double tempLayoutHeight = 2 * panelSpacing + tempInsets.top + tempInsets.bottom; + Dimension tempListDimension = minimum ? listOrTablePanel.getMinimumSize() + : listOrTablePanel.getPreferredSize(); + switch (orientation) { + case HORIZONTAL: + tempLayoutWidth += tempListDimension.getWidth() + panelSpacing + + tempButtonPanelDimension.getWidth(); + tempLayoutHeight += Math.max(tempListDimension.getHeight(), + tempButtonPanelDimension.getHeight()); + break; + case VERTICAL: + tempLayoutHeight += tempListDimension.getHeight() + panelSpacing + + tempButtonPanelDimension.getHeight(); + tempLayoutWidth += Math.max(tempListDimension.getWidth(), + tempButtonPanelDimension.getWidth()); + break; + } + + Dimension tempLayoutDimension = new Dimension(); + tempLayoutDimension.setSize(tempLayoutWidth, tempLayoutHeight); + return tempLayoutDimension; + } + + /** + * Returns the layout size of button panel. + * + * @param minimum indicates whether minimum (true) or preferred (false) layout + * will be returned + * @return the preferred or (if minimum) minimum layout size + */ + protected Dimension getButtonPanelLayoutSize(boolean minimum) { + // calculate sum of space between buttons dependent from orientation + double tempButtonsLayoutWidth = ((orientation == Orientation.HORIZONTAL) ? + (buttons.size() - 1) * buttonSpacing : + 0); + double tempButtonsLayoutHeight = ((orientation == Orientation.VERTICAL) ? + (buttons.size() - 1) * buttonSpacing : + 0); + if (fixedButtonSize != null) { + // if fixed button size, use fixed size instead of preferred or minimum size + switch (orientation) { + case VERTICAL: + tempButtonsLayoutWidth += fixedButtonSize.getWidth(); + tempButtonsLayoutHeight += buttons.size() * fixedButtonSize.getHeight(); + break; + case HORIZONTAL: + tempButtonsLayoutWidth += buttons.size() * fixedButtonSize.getWidth(); + tempButtonsLayoutHeight += fixedButtonSize.getHeight(); + break; + } + } + else { + // if not fixed size, use each buttons preferred resp. minimum size + for (Component tempComponent : buttons) { + Dimension tempButtonDimension = minimum ? tempComponent.getMinimumSize() + : tempComponent.getPreferredSize(); + switch (orientation) { + case VERTICAL: + if (tempButtonsLayoutWidth < tempButtonDimension.getWidth()) { + tempButtonsLayoutWidth = tempButtonDimension.getWidth(); + } + tempButtonsLayoutHeight += tempButtonDimension.getHeight(); + break; + case HORIZONTAL: + tempButtonsLayoutWidth += tempButtonDimension.getWidth(); + if (tempButtonsLayoutHeight < tempButtonDimension.getHeight()) { + tempButtonsLayoutHeight = tempButtonDimension.getHeight(); + } + break; + } + } + } + + Dimension tempButtonPanelDimension = new Dimension(); + tempButtonPanelDimension.setSize(tempButtonsLayoutWidth, tempButtonsLayoutHeight); + return tempButtonPanelDimension; + } + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ControllerAdapterTeam.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ControllerAdapterTeam.java new file mode 100644 index 000000000..c3b908486 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ControllerAdapterTeam.java @@ -0,0 +1,259 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: ControllerAdapterTeam.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.Vector; + +import javax.swing.JButton; +import javax.swing.JTable; + +import org.objectteams.Team; +import org.objectteams.samples.ordersystem.data.Customer; +import org.objectteams.samples.ordersystem.order.StockOrder; +import org.objectteams.samples.ordersystem.store.StockItem; +import org.objectteams.samples.ordersystem.store.Storage; + +/** + * @author Dehla Sokenou + * + * Team implementing controller of order system. + * + */ +public team class ControllerAdapterTeam { + + + public ControllerAdapterTeam() { + this.activate(Team.ALL_THREADS); + } + + /** + * Role that implements a controller logic for each button. + */ + public class ButtonController implements ILowerable playedBy OrderSystemMainFrame { + + // by this hook all elementary controllers are registered at startup: + void setButtonControllers() <- after void setVisible(boolean aVisibility); + + // store buttons (callout to field): + @SuppressWarnings("decapsulation") + JButton getAddItemButton() -> get JButton addItemButton; + JButton getRemoveItemButton() -> get JButton removeItemButton; + JButton getIncreaseStockButton() -> get JButton increaseStockButton; + JButton getDecreaseStockButton() -> get JButton decreaseStockButton; + + // customer management buttons + JButton getAddCustomerButton() -> get JButton addCustomerButton; + JButton getRemoveCustomerButton() -> get JButton removeCustomerButton; + + // reservation management buttons + // none + + // order management buttons + JButton getNewOrderButton() -> get JButton newOrderButton; + JButton getRemoveOrderButton() -> get JButton removeOrderButton; + JButton getChangeOrderButton() -> get JButton changeOrderButton; + + // tables + JTable getStoreTable() -> get JTable storeTable; + JTable getCustomerTable() -> get JTable customerTable; + JTable getReservationTable() -> get JTable reservationTable; + JTable getOrderTable() -> get JTable orderTable; + + /** + * Assign controllers for all buttons + */ + protected void setButtonControllers() { + final OrderSystemMainFrame tempOrderFrame = (OrderSystemMainFrame) this.lower(); + + // store buttons + getAddItemButton().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + StockItem tempItem = InputDialog.showAddItemDialog(tempOrderFrame); + if (tempItem != null) { + Storage.theInstance().add(tempItem); + } + updateModel(Tab.STORE); + updateModel(Tab.RESERVATION); + } + }); + + getRemoveItemButton().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + try { + StockItem tempItem = (StockItem) getSelectedIndex(Tab.STORE); + if (tempItem != null) { + Storage.theInstance().delete(tempItem); + updateModel(Tab.STORE); + updateModel(Tab.RESERVATION); + updateModel(Tab.ORDER); + } + } + catch (Exception e) { + // debug output + e.printStackTrace(); + } + } + }); + + getIncreaseStockButton().addActionListener( + getChangeItemCountActionListener(tempOrderFrame, true)); + + getDecreaseStockButton().addActionListener( + getChangeItemCountActionListener(tempOrderFrame, false)); + + // reservation management buttons + // none + + // customer management buttons + getAddCustomerButton().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + try { + Customer tempCustomer = InputDialog.showAddCustomerDialog(tempOrderFrame); + if (tempCustomer != null) { + // TODO: better use callin from constructor in ModelAdapterTeam as soon as it is available + ModelAdapterTeam.getModelAdapterTeam().getCustomerAdapter().addElement(tempCustomer); + updateModel(Tab.CUSTOMER); + } + } + catch (Exception e) { + // debug output + e.printStackTrace(); + } + } + }); + + getRemoveCustomerButton().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + try { + Customer tempCustomer = (Customer) getSelectedIndex(Tab.CUSTOMER); + ModelAdapterTeam.getModelAdapterTeam().getCustomerAdapter().removeElement(tempCustomer); + updateModel(Tab.CUSTOMER); + } + catch (Exception e) { + // debug output + e.printStackTrace(); + } + } + }); + + // order management buttons + getNewOrderButton().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + Vector<Customer> tempCustomerElements = + ModelAdapterTeam.getModelAdapterTeam().getCustomerAdapter().getElements(); + Customer[] tempCustomers = new Customer[tempCustomerElements.size()]; + for (int i = 0; i < tempCustomers.length; i++) { + tempCustomers[i] = tempCustomerElements.elementAt(i); + } + Vector<StockItem> tempItemElements = + ModelAdapterTeam.getModelAdapterTeam().getStorageAdapter().getElements(); + StockItem[] tempItems = new StockItem[tempItemElements.size()]; + for (int i = 0; i < tempItems.length; i++) { + tempItems[i] = (StockItem) tempItemElements.elementAt(i); + } + StockOrder tempOrder = InputDialog.showAddOrderDialog( + tempOrderFrame, tempCustomers, tempItems); + if (tempOrder != null) { + // TODO: better use callin from constructor in ModelAdapterTeam as soon as it is available + ModelAdapterTeam.getModelAdapterTeam().getOrderAdapter().addElement(tempOrder); + updateModel(Tab.ORDER); + } + } + }); + + getRemoveOrderButton().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + // TODO: + } + }); + + getChangeOrderButton().addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + // TODO: + } + }); + + } + + /** + * Updates model after changes. + */ + protected void updateModel(Tab aTab) { + ModelAdapterTeam.getModelAdapterTeam().update(aTab); + } + + /** + * + */ + protected Object getSelectedIndex(Tab aTab) { + JTable tempTable; + switch (aTab) { + case STORE : tempTable = getStoreTable(); break; + case CUSTOMER : tempTable = getCustomerTable(); break; + case RESERVATION: tempTable = getReservationTable(); break; + case ORDER : tempTable = getOrderTable(); break; + default: + throw new IllegalArgumentException("Method not defined for argument " + aTab); + } + int tempSelectedIndex = tempTable.getSelectedRow(); + if (tempSelectedIndex >= 0) { + //FIXME: remove if-statement later, workaround + if (aTab == Tab.STORE) { + final ModelAdapterTeam tempModelAdapterTeam = ModelAdapterTeam.getModelAdapterTeam(); + return ((StorageAdapter<@tempModelAdapterTeam>) tempTable.getModel()).getElementAt(tempSelectedIndex); + } + AbstractTableModelTemplate<?> tempModel = (AbstractTableModelTemplate<?>) tempTable.getModel(); + return tempModel.getElementAt(tempSelectedIndex); + } + else { + return null; + } + } + + /** + * @param tempOrderFrame the main frame + * @param anInc indicates whether the count is increased (decreased otherwise) + * @return + */ + private ActionListener getChangeItemCountActionListener( + final OrderSystemMainFrame tempOrderFrame, final boolean anInc) { + return new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + try { + StockItem tempItem = (StockItem) getSelectedIndex(Tab.STORE); + Integer tempCount = InputDialog.showChangeStockDialog(tempOrderFrame, anInc); + if (tempItem != null && tempCount != null && tempCount.intValue() > 0) { + if (! anInc) { + tempCount = -tempCount; + } + Storage.theInstance().changeCount(tempItem, tempCount); + updateModel(Tab.STORE); + updateModel(Tab.RESERVATION); + updateModel(Tab.ORDER); + } + } + catch (Exception e) { + // debug output + e.printStackTrace(); + } + } + }; + } + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/GUIAdapterTeam.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/GUIAdapterTeam.java new file mode 100644 index 000000000..50098d739 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/GUIAdapterTeam.java @@ -0,0 +1,77 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: GUIAdapterTeam.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +import java.awt.Container; +import java.awt.Dimension; + +import org.objectteams.Team; + + +/** + * This aspect ensures that each window will appear in the middle + * of the screen. + * + * @author Dehla Sokenou + */ +public team class GUIAdapterTeam { + + public GUIAdapterTeam() { + activate(Team.ALL_THREADS); + } + + // note: we need to individually adapt two GUI-classes + // as long as class java.awt.Window cannot be adapted + // (restriction to be removed in the future). + + public class MainFrameAdapter playedBy OrderSystemMainFrame { + + // callouts + public abstract Container getParent(); + getParent -> getParent; + + public abstract void setCentered(Container parent); + setCentered -> setLocationRelativeTo; + + // callins + protected void centerRelativeToParent() { + setCentered(getParent()); + } + centercallin: + void centerRelativeToParent() <- after void setSize(Dimension aDimension), + void setSize(int aWidth, int aHeight); + + } + + public class DialogAdapter playedBy InputDialog { + + // callouts + public abstract Container getParent(); + getParent -> getParent; + + public abstract void setCentered(Container parent); + setCentered -> setLocationRelativeTo; + + // callins + protected void centerRelativeToParent() { + setCentered(getParent()); + } + centercallin: + void centerRelativeToParent() <- after void setSize(Dimension aDimension), + void setSize(int aWidth, int aHeight); + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/GUITest.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/GUITest.java new file mode 100644 index 000000000..fade166fd --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/GUITest.java @@ -0,0 +1,33 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: GUITest.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + + +public class GUITest { + + public static void main(String[] args) { + GUITest tempGUITest = new GUITest(); + tempGUITest.init(); + } + + private void init() { + // hook for security application + // TODO: remove this when OT can adapt constructors + new OrderSystemMainFrame(); + } + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/InputDialog.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/InputDialog.java new file mode 100644 index 000000000..0287391ee --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/InputDialog.java @@ -0,0 +1,566 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: InputDialog.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.Box; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JButton; +import javax.swing.JComboBox; +import javax.swing.JDialog; +import javax.swing.JFrame; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTextField; + +import org.objectteams.samples.ordersystem.data.Address; +import org.objectteams.samples.ordersystem.data.Customer; +import org.objectteams.samples.ordersystem.order.StockOrder; +import org.objectteams.samples.ordersystem.store.StockItem; + + + +@SuppressWarnings("serial") +public class InputDialog extends JDialog { + + /** + * Options that can be selected by user: <br> + * OK - proceed <br> + * CANCEL - cancel actual dialog + */ + protected static enum InputOption { + OK, CANCEL + } + + /** + * The textfields for user input. + */ + protected JTextField[] inputFields; + + /** + * Option that the user selected (InputOption.OK or InputOption.CANCEL). + */ + protected InputOption selectedOption = InputOption.CANCEL; + + + /** + * Creates a new input dialog. Constructor is protected because only static methods of this + * class should be used to create an input dialog. + * + * @param aParent the dialog's parent + * @param aTitle the dialog's title + * @param aInputNames the names of input fields + */ + protected InputDialog(JFrame aParent, String aTitle, String[] aInputNames) { + this(aParent, aTitle); + + int tempInputCount = aInputNames.length; + JPanel tempInputPanel = new JPanel(); + tempInputPanel.setLayout(new GridLayout(tempInputCount, 2)); + inputFields = new JTextField[tempInputCount]; + for (int i = 0; i < aInputNames.length; i++) { + String tempInput = aInputNames[i]; + tempInputPanel.add(new JLabel(tempInput + ": ")); + inputFields[i] = new JTextField(100); + tempInputPanel.add(inputFields[i]); + } + add("Center", tempInputPanel); + + setSize(); + setVisible(true); + } + + /** + * Creates a new input dialog based on the given components. + * Components are simply layout using a vertical Box. + * + * @param aParent the dialog's parent + * @param aTitle the dialog's title + * @param aDisplayedComponents + */ + protected InputDialog(JFrame aParent, String aTitle, Component[] aDisplayedComponents) { + this(aParent, aTitle); + + Box tempInputPanel = Box.createVerticalBox(); + for (Component tempComponent : aDisplayedComponents) { + tempInputPanel.add(tempComponent); + } + add("Center", tempInputPanel); + + setSize(); + setVisible(true); + } + + /** + * Creates an empty unvisible input dialog (only buttons visible). + * + * @param aParent the dialog's parent + * @param aTitle the dialog's title + */ + protected InputDialog(JFrame aParent, String aTitle) { + super(aParent, aTitle, true); + setLayout(new BorderLayout()); + + Box tempButtonPanel = Box.createHorizontalBox(); + JButton tempOkayButton = new JButton("Okay"); + tempOkayButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + selectedOption = InputOption.OK; + setVisible(false); + } + }); + tempButtonPanel.add(tempOkayButton); + tempButtonPanel.add(Box.createHorizontalGlue()); + JButton tempCancelButton = new JButton("Cancel"); + tempCancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + selectedOption = InputOption.CANCEL; + setVisible(false); + } + }); + tempButtonPanel.add(tempCancelButton); + add("South", tempButtonPanel); + } + + protected InputDialog(final JFrame aParent, + final JComboBox aCustomerComboBox, final JComboBox anAddressComboBox, + final JList aSelectItemList, final JList anOrderItemList) { + this(aParent, "New Order"); + addWindowListener(new WindowAdapter() { + public void windowOpened(WindowEvent aE) { + super.windowOpened(aE); + setSize(); + repaint(); + } + }); + + // create customer combobox + JPanel tempCustomerPanel = new JPanel(); + tempCustomerPanel.setLayout(new GridLayout(3,2)); + tempCustomerPanel.add(new JLabel("Select Customer: ")); + aCustomerComboBox.setRenderer(new CustomerRenderer()); + tempCustomerPanel.add(aCustomerComboBox); + // TODO: order address + tempCustomerPanel.add(new JLabel("Order Address: ")); + anAddressComboBox.addItem("NONE"); + anAddressComboBox.addItem("New Order Address"); + anAddressComboBox.setRenderer(new AddressRenderer()); + anAddressComboBox.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent aE) { + if (anAddressComboBox.getSelectedItem().equals("New Order Address")) { + Address tempAddress = showAddAddressDialog(aParent); + if (tempAddress != null) { + anAddressComboBox.removeAllItems(); + anAddressComboBox.addItem(tempAddress); + anAddressComboBox.addItem("NONE"); + anAddressComboBox.addItem("New Order Address"); + } + anAddressComboBox.setSelectedIndex(0); + } + } + }); + tempCustomerPanel.add(anAddressComboBox); + // fill with empty components + tempCustomerPanel.add(new JPanel()); + tempCustomerPanel.add(new JPanel()); + add("North", tempCustomerPanel); + + // create item lists + anOrderItemList.setCellRenderer(new OrderItemCellRenderer()); + anOrderItemList.setModel(new DefaultListModel()); + + aSelectItemList.setCellRenderer(new ItemCellRenderer()); + + JButton tempButton = new JButton("->"); + tempButton.setBackground(new Color(238, 238, 238)); + tempButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent anEvent) { + try { + StockItem tempSelectedItem = (StockItem) aSelectItemList.getSelectedValue(); + Integer tempAmount = InputDialog.showChangeAmountDialog(aParent, "Item Amount in Order"); + if (tempSelectedItem != null && tempAmount != null) { + DefaultListModel tempModel = (DefaultListModel) anOrderItemList.getModel(); + OrderItem tempOrderItem = new OrderItem(tempSelectedItem, tempAmount); + if (! tempModel.contains(tempOrderItem)) { + tempModel.addElement(tempOrderItem); + } + } + } + catch (Exception ex) { + // error message output + ex.printStackTrace(); + } + } + }); + + JPanel tempListPanel = new JPanel(); + tempListPanel.setLayout(new GridLayout(1,3)); + JScrollPane tempSelectItemScrollPane = new JScrollPane(aSelectItemList); + JScrollPane tempOrderItemScrollPane = new JScrollPane(anOrderItemList); + tempListPanel.add(tempSelectItemScrollPane); + tempListPanel.add(tempButton); + tempListPanel.add(tempOrderItemScrollPane); + + add("Center", tempListPanel); + + setSize(); + setVisible(true); + } + + + /** + * Shows dialog that requests stock item data. + * + * @param aParent the dialogs parents or null, if no parent should be set. + * @return the stock item that is created from user data or null if any error occured or the + * user has canceled dialog + */ + public static StockItem showAddItemDialog(JFrame aParent) { + String[] data = createInputDialog(aParent, "New StockItem", new String[] {"Name", "Price (in Cent)"}); + try{ + if (data != null) { + return new StockItem(data[0], Integer.valueOf(data[1])); + } + else { + return null; + } + } + catch (NumberFormatException e) { + // can't convert to integer, don't create item (not a user-friendly way ;-) + return null; + } + } + + /** + * Shows dialog that requests stock item data. + * + * @param aParent the dialog's parents or null, if no parent should be set. + * @return the stock item that is created from user data or null if any error occured or the + * user has canceled dialog + */ + public static Customer showAddCustomerDialog(JFrame aParent) { + String[] data = createInputDialog(aParent, "New Customer", + new String[] {"First Name", "Last Name", "Street", "Postal Code", "City", "Country"}); + if (data != null) { + Address tempAddress = new Address(data[2], data[3], data[4], data[5]); + return new Customer(data[0], data[1], tempAddress); + } + else { + return null; + } + } + + /** + * Shows dialog that requests stock item data. + * + * @param aParent the dialog's parents or null, if no parent should be set. + * @return the stock item that is created from user data or null if any error occured or the + * user has canceled dialog + */ + public static Address showAddAddressDialog(JFrame aParent) { + String[] data = createInputDialog(aParent, "New Address", + new String[] {"Street", "Postal Code", "City", "Country"}); + if (data != null) { + return new Address(data[0], data[1], data[2], data[3]); + } + else { + return null; + } + } + + /** + * Shows dialog that requests item change count. + * + * @param aParent the dialog's parents or null, if no parent should be set. + * @param increase indicates if stock item count will be increased, if false decreasing is selected + * @return the amount to increase resp. decrease stock, null if none + */ + public static Integer showChangeStockDialog(JFrame aParent, boolean increase) { + String tempTitle = increase ? "Increase Item Count" : "Decrease Item Count"; + return showChangeAmountDialog(aParent, tempTitle); + } + + /** + * Shows dialog that requests an amount. + * + * @param aParent the dialog's parent (null, if none) + * @param aTitle the dialog's title + * @return the user's input amount, null if none + */ + public static Integer showChangeAmountDialog(JFrame aParent, String aTitle) { + String[] data = createInputDialog(aParent, aTitle, new String[] {"Enter Amount"}); + if (data != null && ! data[0].equals("")) { + return Integer.valueOf(data[0]); + } + else { + return null; + } + } + + /** + * Creates an input dialog that requests user data based on the given input names. + * For each name, a field is provided that delivers a string. + * These strings are collected by a data array. + * + * @param aParent the dialog's parent (null, if none) + * @param aTitle the dialog's title + * @param aInputNames the names of input + * @return the data array referencing the user input as string; note, values can be null or empty strings + */ + public static String[] createInputDialog(JFrame aParent, String aTitle, String[] aInputNames) { + InputDialog tempDialog = new InputDialog(aParent, aTitle, aInputNames); + if (tempDialog.selectedOption == InputOption.OK) { + String[] tempInput = new String[aInputNames.length]; + for (int i = 0; i < tempInput.length; i++) { + tempInput[i] = tempDialog.inputFields[i].getText(); + } + for (String tempString : tempInput) { + if (tempString.equals("")) { + return null; + } + } + return tempInput; + } + else { + return null; + } + } + + /** + * Shows dialog that requests input for creating a new order. + * + * @return an order + */ + public static StockOrder showAddOrderDialog(final JFrame aParent, Customer[] aCustomers, StockItem[] aItems) { + + JComboBox tempCustomerComboBox = new JComboBox(aCustomers); + JComboBox tempAddressComboBox = new JComboBox(); + JList tempSelectItemList = new JList(aItems); + JList tempOrderItemList = new JList(); + + InputDialog tempDialog = new InputDialog(aParent, tempCustomerComboBox, tempAddressComboBox, + tempSelectItemList, tempOrderItemList); + + // collect input and return new Order + if (tempDialog.selectedOption == InputOption.OK) { + // get Customer and order address and create new order + Customer tempChoosenCustomer = (Customer) tempCustomerComboBox.getSelectedObjects()[0]; + if (tempChoosenCustomer != null) { + // TODO: distinguish between orders with and without order address + StockOrder tempOrder; + Object tempAddressElement = tempAddressComboBox.getItemAt(0); + if (tempAddressElement instanceof Address) { + if (tempAddressComboBox.getSelectedIndex() > 0) { + tempOrder = new StockOrder(tempChoosenCustomer, (Address) tempAddressElement, true); +// tempOrder = new StockOrder(tempChoosenCustomer, (Address) tempAddressElement); + } + else { + tempOrder = new StockOrder(tempChoosenCustomer, (Address) tempAddressElement); + } + } + else { + tempOrder = new StockOrder(tempChoosenCustomer); + } + // get order items and add them to order + DefaultListModel tempModel = (DefaultListModel) tempOrderItemList.getModel(); + for (int i = 0; i < tempModel.size(); i++) { + OrderItem tempItem = (OrderItem) tempModel.getElementAt(i); + tempOrder.order(tempItem.getItem(), tempItem.getAmount()); + } + return tempOrder; + } + else { + return null; + } + } + else { + return null; + } + } + + + /** + * Sets size of dialog to (nearly) preferred size. + */ + private void setSize() { + setSize(400, getPreferredSize().height+50); + } + + + /** + * + * Class implementing a cell renderer for customers + */ + private static class CustomerRenderer extends DefaultListCellRenderer { + + /** + * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean) + */ + public Component getListCellRendererComponent(JList aList, Object aValue, int anIndex, boolean aIsSelected, boolean aCellHasFocus) { + JLabel tempLabel = (JLabel) super.getListCellRendererComponent(aList, aValue, anIndex, aIsSelected, aCellHasFocus); + if (aValue instanceof Customer) { + Customer aCustomer = (Customer) aValue; + tempLabel.setText(aCustomer.getFirstname() + " " + aCustomer.getLastname()); + } + else { + tempLabel.setText(""); + } + return tempLabel; + } + + } + + + /** + * + * Class implementing a cell renderer for addresses + */ + private static class AddressRenderer extends DefaultListCellRenderer { + + /** + * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean) + */ + public Component getListCellRendererComponent(JList aList, Object aValue, int anIndex, boolean aIsSelected, boolean aCellHasFocus) { + JLabel tempLabel = (JLabel) super.getListCellRendererComponent(aList, aValue, anIndex, aIsSelected, aCellHasFocus); + if (aValue instanceof Address || aValue instanceof String) { + tempLabel.setText(aValue.toString()); + } + else { + tempLabel.setText(""); + } + return tempLabel; + } + + } + + + /** + * + * Class implementing a cell renderer for items + */ + private static class ItemCellRenderer extends DefaultListCellRenderer { + + /** + * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean) + */ + public Component getListCellRendererComponent(JList aList, Object aValue, int anIndex, boolean aIsSelected, boolean aCellHasFocus) { + JLabel tempLabel = (JLabel) super.getListCellRendererComponent(aList, aValue, anIndex, aIsSelected, aCellHasFocus); + if (aValue instanceof StockItem) { + StockItem anItem = (StockItem) aValue; + tempLabel.setText(anItem.getId() + " - " + anItem.getName()); + } + else { + tempLabel.setText(""); + } + return tempLabel; + } + + } + + /** + * + * Class implementing a cell renderer for order items + */ + private static class OrderItemCellRenderer extends DefaultListCellRenderer { + + /** + * @see javax.swing.ListCellRenderer#getListCellRendererComponent(javax.swing.JList, java.lang.Object, int, boolean, boolean) + */ + public Component getListCellRendererComponent(JList aList, Object aValue, int anIndex, boolean aIsSelected, boolean aCellHasFocus) { + JLabel tempLabel = (JLabel) super.getListCellRendererComponent(aList, aValue, anIndex, aIsSelected, aCellHasFocus); + if (aValue instanceof OrderItem) { + OrderItem anItem = (OrderItem) aValue; + tempLabel.setText(anItem.getId() + " - " + anItem.getName() + " (# " + anItem.getAmount() + ")"); + } + else { + tempLabel.setText(""); + } + return tempLabel; + } + + } + + /** + * + * Class representing order items. + */ + private static class OrderItem { + + private StockItem item; + private int amount; + + OrderItem(StockItem anItem, int anAmount) { + item = anItem; + amount = anAmount; + } + + /** + * @return the amount + */ + int getAmount() { + return amount; + } + + /** + * @return the item's id + */ + Integer getId() { + return item.getId(); + } + + /** + * @return the item's name + */ + String getName() { + return item.getName(); + } + + /** + * @return the item + */ + StockItem getItem() { + return item; + } + + /** + * @see java.lang.Object#equals(java.lang.Object) + */ + public boolean equals(Object anotherObject) { + if (anotherObject instanceof OrderItem) { + OrderItem anotherItem = (OrderItem) anotherObject; + return item.equals(anotherItem.item); + } + else { + return false; + } + } + + } + + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ModelAdapterTeam.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ModelAdapterTeam.java new file mode 100644 index 000000000..6a251d2de --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/ModelAdapterTeam.java @@ -0,0 +1,620 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: ModelAdapterTeam.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +import java.awt.Component; +import java.util.HashMap; +import java.util.Vector; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.ListSelectionModel; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableColumn; + +import org.objectteams.Team; +import org.objectteams.samples.ordersystem.data.Address; +import org.objectteams.samples.ordersystem.order.StockOrder; +import org.objectteams.samples.ordersystem.reservation.Reservations; +import org.objectteams.samples.ordersystem.store.StockItem; + +import org.objectteams.samples.ordersystem.data.Customer; +import base org.objectteams.samples.ordersystem.reservation.StockReservations; +import base org.objectteams.samples.ordersystem.store.Storage; + + + +/** + * Team providing the model of the order system. + * It does so by binding to base classes from the packages data and store. + * + * Three different kinds of roles exist: + * - CustomerRole provides a specific view to its underlying base object. + * - Different adapters present a collection of base objects as a table: + * CustomerAdapter, OrderAdapter, ReservationAdapter, StorageAdaptor + * - ModelInitializer intercepts switching between tabs in order to switch models accordingly. + * + * @author Dehla Sokenou + */ +public team class ModelAdapterTeam { + + + protected static ModelAdapterTeam theModelAdapterTeam; + + public static ModelAdapterTeam getModelAdapterTeam() { + if (theModelAdapterTeam == null) { + theModelAdapterTeam = new ModelAdapterTeam(); + } + return theModelAdapterTeam; + } + + protected ModelAdapterTeam() { + this.activate(Team.ALL_THREADS); + theModelAdapterTeam = this; + initialize(); + } + + // some things to fill storage, customer and addresses + protected StockItem[] initItems = new StockItem[] { + new StockItem("screw driver", 1500), + new StockItem("tool box pro", 5000), + new StockItem("stepladder", 7999), + new StockItem("philips screw", 155), + new StockItem("wall paint", 1680), + new StockItem("paint brush", 800) + }; + + protected Address[] initAddresses = new Address[] { + new Address("22, october avenue", "2345", "Chicago", "Il,USA"), + new Address("Blaumeisenweg 5", "12345", "Berlin", "Germany"), + new Address("10, Lundy Avenue", "513648", "Paris", "France"), + new Address("Venus/Mars", "135754", "Io", "Jupiter"), + new Address("Dan Tokpa", "14440", "Cotonou", "Benin") + }; + + protected Customer[] initCustomers = new Customer[] { + new Customer("Joe", "Jojo", initAddresses[0]), + new Customer("Jim", "Beann", initAddresses[1]), + new Customer("Jan", "Tatam", initAddresses[2]), + new Customer("Paulchen", "Panther", initAddresses[3]) + }; + + + protected void initialize() { + fillStorage(); + createCustomers(); + createOrders(); + } + + protected void fillStorage() { + StorageAdapter storage = StorageAdapter.theInstance(); + storage.add(initItems[0]); + storage.add(initItems[1]); + initItems[1].put(20); + storage.add(initItems[2]); + storage.add(initItems[3]); + initItems[3].put(1); + storage.add(initItems[4]); + initItems[4].put(200); + storage.add(initItems[5]); + initItems[5].put(3); + } + + protected void createCustomers() { + CustomerAdapter tempCustomerAdapter = getCustomerAdapter(); + // TODO: better use callin from constructor as soon as it is available + tempCustomerAdapter.addElement(initCustomers[0]); + tempCustomerAdapter.addElement(initCustomers[1]); + tempCustomerAdapter.addElement(initCustomers[2]); + tempCustomerAdapter.addElement(initCustomers[3]); + } + + protected void createOrders() { + // TODO: better use callin from constructor as soon as it is available + OrderAdapter tempOrderAdapter = getOrderAdapter(); + StockOrder tempOrder1 = new StockOrder(initCustomers[0]); + tempOrder1.order(initItems[4], 100); + tempOrder1.order(initItems[5], 2); + tempOrder1.deliver(); + tempOrderAdapter.addElement(tempOrder1); + + StockOrder tempOrder2 = new StockOrder(initCustomers[1]); + tempOrder2.order(initItems[4], 200); + tempOrderAdapter.addElement(tempOrder2); + + StockOrder tempOrder3 = new StockOrder(initCustomers[2], initAddresses[4]); + tempOrder3.setDiscount(initItems[4], 0.10); + tempOrder3.order(initItems[4], 200); + tempOrder3.order(initItems[5], 2); + tempOrderAdapter.addElement(tempOrder3); + } + + + // the adapters implementing AbstractModelTemplate + protected StorageAdapter theStorageAdapter; + protected CustomerAdapter theCustomerAdapter; + protected ReservationAdapter theReservationAdapter; + protected OrderAdapter theOrderAdapter; + + + /** + * @return the store item list model + */ + public StorageAdapter getStorageAdapter() { + if (theStorageAdapter == null) { + theStorageAdapter = StorageAdapter.theInstance(); + } + return theStorageAdapter; + } + + /** + * @return the customer list model + */ + public CustomerAdapter getCustomerAdapter() { + if (theCustomerAdapter == null) { + theCustomerAdapter = new CustomerAdapter(); + } + return theCustomerAdapter; + } + + /** + * @return the reservation list model + */ + public ReservationAdapter getReservationAdapter() { + if (theReservationAdapter == null) { + theReservationAdapter = ReservationAdapter.theInstance(); + } + return theReservationAdapter; + } + + /** + * @return the customer list model + */ + public OrderAdapter getOrderAdapter() { + if (theOrderAdapter == null) { + theOrderAdapter = new OrderAdapter(); + } + return theOrderAdapter; + } + + /** + * Updates table model in the given tab. + * @param aTab the model tab to update + */ + public void update(Tab aTab) { + switch (aTab) { + case STORE : + getStorageAdapter().fireTableDataChanged(); + break; + case CUSTOMER : + getCustomerAdapter().fireTableDataChanged(); + break; + case RESERVATION : + getReservationAdapter().fireTableDataChanged(); + break; + case ORDER : + getOrderAdapter().fireTableDataChanged(); + break; + default: + throw new IllegalArgumentException("Method not defined for argument " + aTab); + } + } + + /** + * Lifts a customer to its role in this team. + * @param aCustomer the customer to lift + */ + protected void liftCustomerToRole(Customer as CustomerRole aCustomer) { + // nop, lifting is all we want + } + + + /** + * Initializes model. + */ + protected class ModelInitializer playedBy OrderSystemMainFrame { + + // callouts to tables + JTable getStoreTable() -> get JTable storeTable; + JTable getCustomerTable() -> get JTable customerTable; + JTable getReservationTable() -> get JTable reservationTable; + JTable getOrderTable() -> get JTable orderTable; + + // callins to set models + void setModels(Tab aTab) <- after JPanel getStoreTab() with { aTab <- Tab.STORE } + void setModels(Tab aTab) <- after JPanel getCustomerTab() with { aTab <- Tab.CUSTOMER } + void setModels(Tab aTab) <- after JPanel getReservationTab() with { aTab <- Tab.RESERVATION } + setOrderModel: + void setModels(Tab aTab) <- after JPanel getOrderTab() with { aTab <- Tab.ORDER } + setOrderRenderer: + void setCellRenderer(Tab aTab) <- after JPanel getOrderTab() with { aTab <- Tab.ORDER } + + // two callins to the same base method exist, must declare precedence: + precedence setOrderModel, setOrderRenderer; + + + protected void setModels(Tab aTab) { + JTable tempTable; + AbstractTableModel tempTableModel; + switch (aTab) { + case STORE: + tempTable = getStoreTable(); + tempTableModel = getStorageAdapter(); + break; + case CUSTOMER: + tempTable = getCustomerTable(); + tempTableModel = getCustomerAdapter(); + break; + case RESERVATION: + tempTable = getReservationTable(); + tempTableModel = getReservationAdapter(); + break; + case ORDER: + tempTable = getOrderTable(); + tempTableModel = getOrderAdapter(); + break; + default: + throw new IllegalArgumentException("Method not defined for argument " + aTab); + } + if (tempTableModel != null) { + tempTable.setModel(tempTableModel); + } + tempTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + + } + + @SuppressWarnings("serial") // regarding nested anonymous class + protected void setCellRenderer(Tab aTab) { + final JTable tempTable; + switch (aTab) { + case ORDER: + tempTable = getOrderTable(); + TableColumn tempColumn = tempTable.getColumnModel().getColumn(0); + tempColumn.setCellRenderer(new DefaultTableCellRenderer() { + public Component getTableCellRendererComponent(JTable aTable, Object aValue, boolean aIsSelected, boolean aHasFocus, int aRow, int aColumn) { + JLabel tempLabel = (JLabel) super.getTableCellRendererComponent(aTable, aValue, aIsSelected, aHasFocus, aRow, aColumn); + String tempText = "<html>" + aValue.toString().replace("\n", "<br>").replace("Total", "<b>Total") + "</b></html>"; + tempLabel.setText(tempText); + tempTable.setRowHeight(aRow, tempLabel.getPreferredSize().height); + return tempLabel; + } + }); + break; + default: + // do nothing, allows overriding by subroles + break; + } + } + } + + + /** + * Manages store item via store class. + */ + @SuppressWarnings("serial") + public class StorageAdapter extends AbstractTableModelTemplate<StockItem> playedBy Storage { + + protected StorageAdapter(Storage myBase) { + ModelAdapterTeam.this.theStorageAdapter = this; + } + + protected String[] columnNames = new String[] { + "Id", "Name", "Price", "Count on Stock" + }; + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getColumnNames() + */ + protected String[] getColumnNames() { + return columnNames; + } + + /** + * @see javax.swing.table.TableModel#getValueAt(int, int) + */ + public Object getValueAt(int aRowIndex, int aColumnIndex) { + Vector<StockItem> tempElements = getElements(); + StockItem tempItem = tempElements.elementAt(aRowIndex); + switch (aColumnIndex) { + case 0 : + return tempItem.getId(); + case 1 : + return tempItem.getName(); + case 2 : + return tempItem.getPriceString(); + case 3 : + return tempItem.getCount(); + default : + return null; + } + } + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getElements() + */ + // Note: abstract method is implemented using callout binding: + @SuppressWarnings("decapsulation") + public Vector<StockItem> getElements() -> get HashMap<Integer,StockItem> items + with { + result <- new Vector<StockItem>(items.values()) + } + + StorageAdapter theInstance() -> Storage theInstance(); + + void add(StockItem item) -> void add(StockItem item); + + void delete(StockItem item) -> void delete(StockItem item); + + } + + + /** + * CustomerAdapter is not a real role class (unbound). Manages the customers (see CustomerRoles). + */ + @SuppressWarnings("serial") + public class CustomerAdapter extends AbstractTableModelTemplate<Customer> { + + protected String[] columnNames = new String[] { + "First Name", "Last Name", "Street", "Postal Code", "City", "Country"}; + + protected Vector<Customer> elements = new Vector<Customer>(); + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getColumnNames() + */ + protected String[] getColumnNames() { + return columnNames; + } + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getValueAt(int, int) + */ + public Object getValueAt(int aRowIndex, int aColumnIndex) { + Vector<Customer> tempElements = getElements(); + Customer tempCustomer = tempElements.elementAt(aRowIndex); + CustomerRole tempCustomerRole = ModelAdapterTeam.this.getRole(tempCustomer, CustomerRole.class); + switch (aColumnIndex) { + case 0 : + return tempCustomerRole.getFirstName(); + case 1 : + return tempCustomerRole.getLastName(); + case 2 : + return tempCustomerRole.getStreet(); + case 3 : + return tempCustomerRole.getPostalcode(); + case 4 : + return tempCustomerRole.getCity(); + case 5 : + return tempCustomerRole.getCountry(); + default : + return null; + } + } + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getElements() + */ + public Vector<Customer> getElements() { + return elements; + } + + /** + * Adds an element (customer) to the list of customers. + * @param aCustomer the customer to add + */ + public void addElement(Customer aCustomer) { + if (! ModelAdapterTeam.this.hasRole(aCustomer, CustomerRole.class)) { + ModelAdapterTeam.this.liftCustomerToRole(aCustomer); + } + elements.add(aCustomer); + } + + /** + * Removes an element (customer) from the list of customers. + * @param aCustomer the customer to remove + */ + public void removeElement(Customer aCustomer) { + elements.remove(aCustomer); + } + + } + + + /** + * Role played by customers in this team. + * + * This role applies the "Virtual Restructuring" pattern: + * Although at the base level, Customer and Address are distinct entities, + * this role provides a combined view as if both classes had been + * restructured into one. + */ + @SuppressWarnings("bindingconventions") // can't use base import for Customer, because it is also used directly within this team. + public class CustomerRole implements ILowerable playedBy Customer { + + // callouts to different fields in customer and address. + // fields of customer are only included to have a uniform interface to customers. + String getFirstName() -> String getFirstname(); + String getLastName() -> String getLastname(); + String getStreet() -> Address getAddress() with {result <- result.getStreet()}; + String getPostalcode() -> Address getAddress() with {result <- result.getPostalcode()}; + String getCity() -> Address getAddress() with {result <- result.getCity()}; + String getCountry() -> Address getAddress() with {result <- result.getCountry()}; + } + + + /** + * Manages the reservations via team StockReservations. + */ + @SuppressWarnings("serial") + public class ReservationAdapter extends AbstractTableModelTemplate<StockItem> playedBy StockReservations { + + protected String[] columnNames = new String[] { + "Id", "Name", "Count on Stock", "# Reserved", "# Available" + }; + + // callouts + int getNumAvail(StockItem anItem) -> int numAvail(StockItem anItem); + + ReservationAdapter theInstance() -> StockReservations theInstance(); + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getColumnNames() + */ + protected String[] getColumnNames() { + return columnNames; + } + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getElements() + */ + public Vector<StockItem> getElements() { + return getStorageAdapter().getElements(); + } + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getValueAt(int, int) + */ + public Object getValueAt(int aRowIndex, int aColumnIndex) { + Vector<StockItem> tempElements = getElements(); + StockItem tempItem = tempElements.elementAt(aRowIndex); + boolean hasRole = Reservations.theInstance().hasRole(tempItem); + switch (aColumnIndex) { + case 0 : + return tempItem.getId(); + case 1 : + return tempItem.getName(); + case 2 : + return tempItem.getCount(); + case 3 : + if (hasRole) { + return tempItem.getCount() - getNumAvail(tempItem); + } + else { + return 0; + } + case 4 : + if (hasRole) { + return getNumAvail(tempItem); + } + else { + return tempItem.getCount(); + } + default : + return null; + } + } + + } + + + /** + * Manages the reservations via team StockReservations. + */ + @SuppressWarnings("serial") + public class OrderAdapter extends AbstractTableModelTemplate<StockOrder> { + + protected Vector<StockOrder> elements = new Vector<StockOrder>(); + + protected String[] columnNames = new String[] { + "Order Information" + }; + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getColumnNames() + */ + protected String[] getColumnNames() { + return columnNames; + } + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getElements() + */ + public Vector<StockOrder> getElements() { + return elements; + } + + /** + * @see org.objectteams.samples.ordersystem.gui.AbstractTableModelTemplate#getValueAt(int, int) + */ + public Object getValueAt(int aRowIndex, int aColumnIndex) { + return getElements().elementAt(aRowIndex).toString(); + } + + /** + * Adds an element (customer) to the list of customers. + * @param aCustomer the customer to add + */ + public void addElement(StockOrder anOrder) { + elements.add(anOrder); + } + + /** + * Removes an element (customer) from the list of customers. + * @param aCustomer the customer to remove + */ + public void removeElement(StockOrder anOrder) { + elements.remove(anOrder); + } + + } + + + // don't need these roles anymore, but was not deleted because they show another kind of MVC behaviour +// /** +// * Role listening to changes that occur directly in observed model of reservations. +// */ +// protected team class ReservationListener playedBy StockReservations { +// +// protected class ReservationItemListener playedBy base.Reservable { +// +// // callins +// update <- after reserve, release, check, invalidate, remove; +// +// protected void update() { +// ModelAdapterTeam.this.update(Tab.RESERVATION); +// } +// +// } +// +// } +// +// +// /** +// * Role listening to changes that occur directly in observed model of orders. +// */ +// protected team class OrderListener playedBy StockOrder { +// +// protected class OrderItemListener playedBy base.Item { +// +// // callins +// update <- after check, alarm, doReserve, doDeliver; +// +// protected void update() { +// ModelAdapterTeam.this.update(Tab.RESERVATION); +// ModelAdapterTeam.this.update(Tab.ORDER); +// } +// +// } +// +// +// } + + + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/OrderSystemMainFrame.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/OrderSystemMainFrame.java new file mode 100644 index 000000000..9e4a43664 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/OrderSystemMainFrame.java @@ -0,0 +1,171 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: OrderSystemMainFrame.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.JScrollPane; + +import javax.swing.JButton; +import javax.swing.JTabbedPane; +import javax.swing.JTable; + + + +/** + * + * @author Dehla Sokenou + * + * Class implementing view of order system. + * + */ +@SuppressWarnings("serial") +public class OrderSystemMainFrame extends JFrame { + + // store buttons + private JButton addItemButton = new JButton("Add Item"); + protected JButton removeItemButton = new JButton("Remove Item"); + protected JButton increaseStockButton = new JButton("Increase Stock"); + protected JButton decreaseStockButton = new JButton("Decrease Stock"); + + // customer management buttons + protected JButton addCustomerButton = new JButton("Add Customer"); + protected JButton removeCustomerButton = new JButton("Remove Customer"); + + // reservation management buttons + // none + + // order management buttons + protected JButton newOrderButton = new JButton("New Order"); + protected JButton removeOrderButton = new JButton("Remove Order"); + protected JButton changeOrderButton = new JButton("Change Order"); + + // close application button + protected JButton closeButton = new JButton("Exit"); + + // table + protected JTable storeTable = new JTable(); + protected JTable customerTable = new JTable(); + protected JTable reservationTable = new JTable(); + protected JTable orderTable = new JTable(); + + // preferred size of buttons: get greatest button size + protected Dimension preferredButtonSize = round(removeCustomerButton.getPreferredSize()); + + + public OrderSystemMainFrame() { + super(); + setTitle("TOPPrax Ordersystem"); + setSize(800, 600); + setLayout(new BorderLayout()); + + initializeContents(); + + setVisible(true); + } + + /** + * Initializes components in main frame. Necessary to provide hook for adaption. + */ + private void initializeContents() { + JTabbedPane tempTabbedPane = new JTabbedPane(); + getContentPane().add("Center", tempTabbedPane); + tempTabbedPane.addTab("Store", getStoreTab()); + tempTabbedPane.addTab("Customers", getCustomerTab()); + tempTabbedPane.addTab("Reservations", getReservationTab()); + tempTabbedPane.addTab("Orders", getOrderTab()); + + closeButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent aE) { + closeApp(); + } + }); + closeButton.setAlignmentX(Component.CENTER_ALIGNMENT); + getContentPane().add("South", closeButton); + + addWindowListener(new WindowAdapter() { + public void windowClosing(WindowEvent aE) { + closeApp(); + } + }); + } + + protected JPanel getStoreTab() { + return createPanel(storeTable, new JButton[] {addItemButton, + removeItemButton, + increaseStockButton, + decreaseStockButton, + }); + } + + protected JPanel getCustomerTab() { + return createPanel(customerTable, new JButton[] {addCustomerButton, + removeCustomerButton, + }); + } + + protected JPanel getReservationTab() { + return createPanel(reservationTable, new JButton[0]); + } + + protected JPanel getOrderTab() { + return createPanel(orderTable, new JButton[] {newOrderButton, +// removeOrderButton, +// changeOrderButton, + }); + } + + protected JPanel createPanel(JTable aTable, JButton[] aButtonArray) { + JPanel tempPanel = new JPanel(); + + ButtonListLayout tempButtonListLayout = new ButtonListLayout(ButtonListLayout.Orientation.VERTICAL); + tempButtonListLayout.setFixedButtonSize(preferredButtonSize); + tempButtonListLayout.setButtonSpacing(10); + tempButtonListLayout.setPanelSpacing(10); + tempPanel.setLayout(tempButtonListLayout); + + tempPanel.add(new JScrollPane(aTable), ButtonListLayout.ComponentType.LIST_OR_TABLE_PANEL); + + for (JButton tempButton : aButtonArray) { + tempPanel.add(tempButton, ButtonListLayout.ComponentType.BUTTON_PANEL); + } + return tempPanel; + } + + protected Dimension round(Dimension aDimension) { + // round Dimension to the next whole 5 or 10 + int tempAddWidth = 5 - (aDimension.width % 5); + int tempAddHeight = 5 - (aDimension.height % 5); + aDimension.width += tempAddWidth; + aDimension.height += tempAddHeight; + return aDimension; + } + + protected void closeApp() { + System.exit(0); + } + + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/Tab.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/Tab.java new file mode 100644 index 000000000..ee585a8a1 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/gui/Tab.java @@ -0,0 +1,26 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Tab.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.gui; + +/** + * Enum representing actual foreground tab. + */ +public enum Tab { + + STORE, CUSTOMER, RESERVATION, ORDER; + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/order/Order.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/order/Order.java new file mode 100644 index 000000000..ed02175db --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/order/Order.java @@ -0,0 +1,403 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Order.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.order; + +import java.util.LinkedList; +import java.util.Iterator; +import java.util.List; + +/** +* This is a generic team definition of an order. An <code>Order</code> consists of a list of +* <code>Item</code>s, implemented as an abstract role, and several team features. +*/ +public team class Order { + + /** + * The abstract role of an address. This address is used by Customer + */ + public abstract class Address { + @SuppressWarnings("unused") private int id; + } + + /** + * The abstract role of a customer. + */ + public abstract class Customer { + + @SuppressWarnings("unused") private int id; + + private boolean usePrivateAddress = true; + private Address orderAddress; + + /** + * @return Returns the usePrivateAddress. + */ + public boolean isUsePrivateAddress() { + return usePrivateAddress; + } + + /** + * @param usePrivateAddress The usePrivateAddress to set. + */ + public void setUsePrivateAddress(boolean usePrivateAddress) { + this.usePrivateAddress = usePrivateAddress; +// this.orderAddress = null; + } + + /** + * @return Returns the orderAddress. + */ + public Address getOrderAddress() { + return orderAddress; + } + + /** + * @param orderAddress The orderAddress to set. + */ + public void setOrderAddress(Address orderAddress) { + this.orderAddress = orderAddress; + this.usePrivateAddress = false; + } + + abstract public String getRepres(); + + } + + /** + * The abstract role of an order entry. An <code>Item</code> is a part of an order list. + */ + protected abstract class Item { + + /** + * Returns the number of available items. This abstract method is implemented in a sub-role. + */ + abstract int getStockCount(); + + /** + * Returns the current price of a single piece. This abstract method is implemented in a sub-role. + */ + abstract int getSinglePrice (); + + /** + * Returns the description of the item. This abstract method is implemented in a sub-role. + */ + abstract String getDescription(); + + @SuppressWarnings("unused") private int id; + + /** + * Number of ordered pieces. + */ + private int count = 0; + + /** + * Number of missing pieces. + */ + private int numMissing = 0; + + /** + * Discounting rate for the current item. + */ + private double discount = 0.0; + + /** + * Returns the number of ordered pieces. + */ + protected int getCount() { + return count ; } + + /** + * Sets the number of ordered pieces. + * @param count + */ + protected void setCount(int count) { + this.count = count; } + + /** + * Returns the number of missing pieces. + */ + protected int getMissing () { + return numMissing; } + + /** + * Sets the number of missing pieces. + * @param count number of missing pieces + */ + protected void setMissing (int count) { + numMissing = count; } + + /** + * Sets the discounting rate for the item. + * @param discount Discounting rate to be set + */ + protected void setDiscount (double discount) { + this.discount = discount; } + + /** + * Returns the total price of the item considering the discounting rate. + */ + protected int getTotalPrice() { + return (int) ((getSinglePrice() * getCount()) * (1.0 - discount)); + } + + /** + * Reserves the missing pices again and returns the number of actually reserved pieces. + * Checks whether the complete order list can be delivered, if all missing pieces have been reserved. + */ + void check () { + int stockCount = getStockCount(); + if ((numMissing > 0) && (stockCount > 0)) { + int reserved = doReserve(numMissing); + numMissing -= reserved; + if (numMissing == 0) + Order.this.check(); // delegate up to the enclosing team instance + } + } + + /** + * Give the alarm, if the reservation became invalid. + * Completely replaces the original behavior, thus the warning about + * a missing base call. + */ + @SuppressWarnings("basecall") + callin void alarm () { + System.err.println("\nOrder of "+Order.this.customer.getRepres()+":"); + System.err.println("ATTENTION, Reservation became invalid!"); + System.err.println("Order item: "+getDescription()); + // TODO: [begin] set missing pieces to zero, try to newly reserve items + setMissing(getCount()); + check(); + // TODO: [end] + } + + /** + * Returns a report about the ordered item. + */ + public String toString() { + String comment = ""; + if (numMissing > 0) + comment = "\n !! "+numMissing+" pieces not on stock!!"; + return getDescription()+": \t" + + getCount()+"*\t= "+getEuroString(getTotalPrice()) + + comment; + } + + /** + * Reserves the missing items. Returns the number of actually reserved pieces. + * @param numMissing Number of missing pieces + * @return Number of actually reserved pieces + */ + abstract public int doReserve(int numMissing); + + /** + * Deliver the given number of pieces. + * @param count + */ + abstract public void doDeliver(int count); + + } + + @SuppressWarnings("unused") private int id; + + /** + * An Order is always associated with a customer. + */ + Customer customer; + + /** + * List of ordered items. + */ + List<Item> itemList; + + /** + * This <code>Order</code>'s status. + */ + int status; + + /** + * Status value of the order list. All ordered items are available and can be delivered. + */ + public static final int NORMAL = 0; + + /** + * Status value of the order list. There is at least one of the ordered items which is + * not available so that the complete order list cannot be delivered and has to wait for stock. + */ + public static final int WAIT = 1; + + /** + * Status value of the order list. All ordered items have been delivered. + */ + public static final int DELIVERED = 2; + + /** + * Status values of the order list. + */ + public static final String[] STATES = { + "in progress", + "wait for stock", + "delivered" + }; + + /** + * Creates a new team instance. + */ + public Order (Customer customer) { + this.customer = customer; + itemList = new LinkedList<Item>(); + status = NORMAL; + activate(ALL_THREADS); + } + + /** + * Creates a new team instance with a different order address. + */ + public Order (Customer customer, Address orderAddress) { + // this(customer); + this.customer = customer; + this.customer.setOrderAddress(orderAddress); + itemList = new LinkedList<Item>(); + status = NORMAL; + activate(ALL_THREADS); + } + + /** + * Creates a new team instance with a different order address. + */ + public Order (Customer customer, Address orderAddress, boolean isUsingPrivateAddress) { + // this(customer); + this.customer = customer; + this.customer.setOrderAddress(orderAddress); + this.customer.setUsePrivateAddress(true); + itemList = new LinkedList<Item>(); + status = NORMAL; + activate(ALL_THREADS); + } + + Order() { } + + /** + * Checks the order list and notes the missing items which cannot be delevered. The state of + * the missing items is set on <code>WAIT</code>. If all items in the order list are available, + * they will be delivered. + */ + void check () { + status = NORMAL; + Iterator<Item> it = itemList.iterator(); + while (it.hasNext()) { + Item p = it.next(); + if (p.getMissing() > 0) { + status = WAIT; + return; + } + } + System.out.println("Now deliverable!"); + print(); + deliver(); + print(); + } + + /** + * Orders a given number (count) of pieces. The local variable <code>reserved</code> holds the + * number of actually reserved pieces. + */ + public void order (Item item, int count) { + int reserved = item.doReserve(count); + item.setCount(count); + if (reserved < count) { + item.setMissing(count - reserved); + status = WAIT; + } + itemList.add(item); + } + + /** + * Checks the order status and returns true, if the order can be delivered. + */ + public boolean isDeliverable () { + return status == NORMAL; + } + + /** + * Delivers all items in the order list. After delivering the team instance should be deaktivated. + */ + public void deliver () { + Iterator<Item> it = itemList.iterator(); + while (it.hasNext()) { + Item p = it.next(); + p.doDeliver(p.getCount()); + } + status = DELIVERED; + deactivate(); + } + + /** + * Sets the discounting rate for the given item. + * @param item item which should be discounted + * @param discount discounting rate + */ + public void setDiscount (Item item, double discount) { + item.setDiscount(discount); + } + + /** + * This team method prints a string representation of this order. + */ + public void print() { + System.out.println("----------------------------------------"); + System.out.println(toString()); + System.out.println("----------------------------------------"); + } + + /** + * + */ + public String toString() { + String tempString = ""; + tempString += "Order for "+customer.getRepres()+"\n"; + if (customer.getOrderAddress() != null) { + tempString += "order address : " + customer.getOrderAddress() + "\n"; + tempString += "-> using " + + ((customer.isUsePrivateAddress()) ? "private address" : "order address") + + "\n"; + } + tempString += "("+STATES[status]+")\n"; + tempString += "========================================\n"; + Iterator<Item> it = itemList.iterator(); + int i = 1; + int total = 0; + while (it.hasNext()) { + Item p = it.next(); + tempString += ((i++)+".\t"+p) + "\n"; + total += p.getTotalPrice(); + } + tempString += "Total: "+getEuroString(total) +"\n"; + return tempString; + } + + /** + * Returns an euro string for the given price. + * @param price + * @return euro string + */ + public String getEuroString(int price) { + int euro = price / 100; + int cent = price % 100; + return euro + "," + cent + " Euro"; + } + +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/order/StockOrder.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/order/StockOrder.java new file mode 100644 index 000000000..96cb3c971 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/order/StockOrder.java @@ -0,0 +1,146 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: StockOrder.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.order; + +import org.objectteams.samples.ordersystem.reservation.StockReservations; + +import base org.objectteams.samples.ordersystem.data.Customer; +import base org.objectteams.samples.ordersystem.data.Address; +import base org.objectteams.samples.ordersystem.store.StockItem; + +/** + * The team <code>StockOrder</code> is a specialization of the <code>Order</code>. + * It inherits the <code>Item</code> role from its super-team. + */ +public team class StockOrder extends Order { + + /** + * The role class <code>Address</code> is implemented in the super-team + * <code>Order</code>. + * Here the role class is just bound to its base class. + */ + public class Address playedBy Address { + + abstract public String toString(); + toString -> toString; + + } + + /** + * The role class <code>Customer</code> is implemented in the super-team + * <code>Order</code>. + * Here the role class is just bound to its base class. + */ + public class Customer playedBy Customer { + + abstract public String toString(); + toString -> toString; + + public String getRepres() { + boolean PRINT_ADDRESS = false; + return toString() + (PRINT_ADDRESS ? "\n" + orderAddress.toString() : ""); + } + + } + + /** + * The role class <code>Item</code> is implemented in the super-team + * <code>Order</code> and realizes the ordered stock item. + * Here the role class is just bound to its base class. + */ + protected class Item playedBy StockItem { + + + // callout method bindings: forwarding to the base methods + getStockCount -> getCount; + getSinglePrice -> getPrice; + getDescription -> getName; + + // callin method bindings: + check <- after put; + alarm <- replace invalidate; + + /** + * Reserves the missing pieces of the current stock item. + */ + public int doReserve(int numMissing) { + return res.reserve(this, numMissing); + } + + /** + * Delivers the given number of pieces. + */ + public void doDeliver(int count) { + res.deliver(this, count); + } + } + + /** Reference to another team used for the reservation functionality. */ + StockReservations res; + + // ================ Facade interface: ================ + // (see the corresponding comment in StockReservations) + + /** + * Orders a given number of pieces of an item. + */ + public void order (StockItem as Item item, int count) { + super.order(item, count); + } + + /** + * Sets the given discounting rate for an item. + */ + public void setDiscount (StockItem as Item item, double discount) { + super.setDiscount(item, discount); + } + + /** + * Team constructor, uses the constructor of the super-team. + */ + public StockOrder (Customer as Customer customer) { + super(customer); + init(); + } + + /** + * Team constructor, uses the constructor of the super-team. + */ + public StockOrder (Customer as Customer customer, + Address as Address address) + { + super(customer, address); + init(); + } + + /** + * Team constructor, uses the constructor of the super-team. + */ + public StockOrder (Customer as Customer customer, + Address as Address address, + boolean isUsingPrivateAddress) + { + super(customer, address, isUsingPrivateAddress); + init(); + } + + StockOrder() {} + + public void init() { + res = (StockReservations)StockReservations.theInstance(); + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/reservation/Reservations.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/reservation/Reservations.java new file mode 100644 index 000000000..aaeb72117 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/reservation/Reservations.java @@ -0,0 +1,155 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Reservations.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.reservation; + +/** + * This is a team implementation for a simple reservation system. + * <code>Reservations</code> contains an abstract role <code>Reservable</code> + * which is bound in the sub-team <code>StockReservations</code>. + */ +public abstract team class Reservations { + + /** + * The role class <code>Reservable</code> represents a reservable item. + */ + protected abstract class Reservable { + + + abstract protected void remove(int count); + + /** + * Returns the number of pieces, which are located in the storage. + * Should be bound to the base class methods via callout in the subteam. + */ + abstract int getCount(); + + /** + * Makes the item invalid. + */ + abstract void invalidate(); + + @SuppressWarnings("unused") private int id; + + /** + * Contains the quantity of reserved pieces. + */ + private int numReserved = 0; + + /** + * Reserves the given number of pieces for the item and returns the number + * of pieces which were actually reserved. + * @param count Number of pieces that should be reserved + * @return Number of actually reserved pieces + */ + protected int reserve (int count) { + //check, how much pieces are available: + int avail = numAvail(); + //if not enough pieces are available, reserve the remaining pieces: + if (count > avail) + count = avail; + //add the newly reserved items to the reserved ones: + numReserved += count; + return count; + } + + /** + * Releases the given number of pieces by moving them to the available ones and + * returns the number of actually released pieces. + * @param count Number of pieces that should be released + * @return Number of actually released items + */ + protected int release(int count) { + //check, whether the given number of pieces can be released: + if (count > numReserved) + count = numReserved; + //put the released pieces to the available ones: + numReserved -= count; + return count; + } + + /** + * Returns the number of available pieces. This is the difference between the pieces + * which are located in the storage and the reserved ones. + * @return Number of available pieces + */ + protected int numAvail() { + return getCount() - numReserved; + } + + /** + * Checks the availability of the item. + */ + void check() { + System.out.println(">>> Checking: "+this+"("+numAvail()+")"); + //invalidate the item if some pieces are missing + if (numAvail() < 0) { + // TODO: [begin] before invalidation, remove all reservations + numReserved = 0; + // TODO: [end] + invalidate(); + } + } + + callin String toStr() { + String result = ""; + result = base.toStr(); + return result+"\t reserved="+numReserved; + } + + } + + /** + * Singleton: reference to the team instance. + */ + static Reservations instance; + + @SuppressWarnings("unused") private int id; + + /** + * Returns the singleton instance + */ + public static Reservations theInstance() { return instance; } + + /** + * Reserves the given number of pieces. Returns the number actually reserved pieces. + */ + public int reserve(Reservable item, int count) { + return item.reserve(count); + } + + /** + * Releases the given number of pieces. Returns the number actually released pieces. + */ + public int release(Reservable item, int count) { + return item.release(count); + } + + /** + * Delivers the given number of pieces and returns the number of actualy delivered pieces. + */ + public void deliver(Reservable item, int count) { + item.remove(item.release(count)); + } + + /** + * Checks whether the given item is available. + */ + public int numAvail(Reservable item) { + return item.numAvail(); + } +} + diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/reservation/StockReservations.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/reservation/StockReservations.java new file mode 100644 index 000000000..2f885abd7 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/reservation/StockReservations.java @@ -0,0 +1,103 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: StockReservations.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.reservation; + +import base org.objectteams.samples.ordersystem.store.StockItem; + +/** + * Team class <code>StockReservations</code> extends the abstract team class <code>Reservations</code> + * and realizes the role bindings. This example shows, that the role bindings may appear in a subteam. + */ +public team class StockReservations extends Reservations { + + /** + * The role class <code>Reservable</code> is implemented in the unbound super-class and realizes the + * reservable item. Here the role class is simply bound to its base class store.StockItem. + */ + protected class Reservable playedBy StockItem { + + // callout method bindings: + remove -> take; + getCount -> getCount; + invalidate -> invalidate; + toString => toString; //overriding of inherited method + + /* --------------------------------------------------------------- */ + + // callin method binding: + toStr <- replace toString; + check <- after take; + } + + /** + * Team constructor is private because Stockreservations is a Singleton. + */ + private StockReservations() { + // callins are effective only after activation + activate(ALL_THREADS); + } + + /** + * Singleton: Create the instance and store reference to it. + */ + static{ + instance = new StockReservations(); + } + + /** + * Returns the singleton instance + */ + public static StockReservations theInstance() { return (StockReservations) instance; } + + + // ================ Facade interface: ================ + // The following methods export the main functions of this team. + // The inherited methods require a role type argument, but for better + // encapsulation, clients should not refer to role types. + // To this end, the "as" signatures allow to invoke these methods + // with an argument of type StockItem. + // Before entering the method body, the argument is lifted to its Reservable role, + // which is then passed to the super-method. + + /** + * Reserves the given number of pieces. + */ + public int reserve(StockItem as Reservable item, int count) { + return super.reserve(item, count); + } + + /** + * Releases the given number of pieces. + */ + public int release(StockItem as Reservable item, int count) { + return super.release(item, count); + } + + /** + * Delivers the given number of pieces. + */ + public void deliver(StockItem as Reservable item, int count) { + super.deliver(item, count); + } + + /** + * Returns the number of available pieces in the storage. + */ + public int numAvail(StockItem as Reservable item) { + return super.numAvail(item); + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/store/StockItem.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/store/StockItem.java new file mode 100644 index 000000000..59c8edb30 --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/store/StockItem.java @@ -0,0 +1,127 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: StockItem.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.store; + +/** + * This is a simple implementation of a stock item. It contains the name of the item, + * its id, price and quantity. + */ +public class StockItem { + + /** + * Id that was assigned at last. + */ + private static int lastId = 0; + + /** + * The id of the stock item. + */ + private Integer id; + + /** + * The name of the stock item. + */ + private String name; + + /** + * The currently quantity of pieces. + */ + private int count; + + /** + * The curently price for a piece (in cents). + */ + private int price; + + /** + * Creates a new stock item initialized with the specified name and price. + */ + public StockItem (String name, int price) { + this.name = name; + this.price = price; + this.id = new Integer(++ lastId); + this.count = 0; + } + + StockItem() {} + + /** + * Returns the id of the item. + */ + public Integer getId() {return id; } + + /** + * Returns the name of the item. + */ + public String getName() { return name; } + + /** + * Returns the quantity of the item. + */ + public int getCount() { return count; } + + /** + * Returns the price of the item. + */ + public int getPrice() { return price; } + + /** + * Generates the price string + */ + public String getPriceString() { + int euro = price / 100; + int cent = price % 100; + return euro + "," + cent + " Euro"; + } + + /** + * Generates an entry string which describes the item. + */ + public String toString() { + return "StockItem "+id+" '"+name+"'\t #="+count+",\t a "+getPriceString(); + } + + /** + * Increases the number of pieces located in the storage. + */ + public void put (int count) { + this.count += count; + } + + /** + * Decreases the number of pieces located in the storage. + */ + public void take (int count) { + if (this.count > count) + this.count -= count; + else + this.count = 0; + } + + /** + * Invalidates the current item, meaning that something is wrong with + * this item's records. + * + * This method only prints to System.err since the Storage has no + * means for handling invalid items. + */ + public void invalidate () { + System.err.println("*****"); + System.err.println("*** Item "+this+"\n*** has been invalidated."); + System.err.println("*****"); + } +} diff --git a/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/store/Storage.java b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/store/Storage.java new file mode 100644 index 000000000..e6066719e --- /dev/null +++ b/othersrc/otdt-examples/OTSample-ordersystem-src/src/org/objectteams/samples/ordersystem/store/Storage.java @@ -0,0 +1,90 @@ +/********************************************************************** + * This file is part of "Object Teams Development Tooling"-Software + * + * Copyright 2004, 2010 Technical University Berlin, Germany, and others. + * + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * $Id: Storage.java 23502 2010-02-08 18:33:32Z stephan $ + * + * Please visit http://www.eclipse.org/objectteams for updates and contact. + * + * Contributors: + * Technical University Berlin - Initial API and implementation + **********************************************************************/ +package org.objectteams.samples.ordersystem.store; + +import java.util.HashMap; +import java.util.Iterator; +import java.io.PrintStream; + +/** + * This class is a simple model of a storage. A Storage comprises a number of + * <code>StockItem</code>s and has methods to add, delete and print these items. + */ +public class Storage { + + /** + * List of available items + */ + private HashMap<Integer, StockItem> items; + + /** + * Reference to the storage instance + */ + private static Storage instance = new Storage(); + + /** + * Storage constrctor + */ + private Storage () { + items = new HashMap<Integer, StockItem>(); + } + + /** + * Returns the storage instance. This method is used for the object creation (Singleton). + */ + public static Storage theInstance() { return instance; } + + /** + * Adds a new item to the storage. + */ + public void add(StockItem item) { + if (items.containsKey(item.getId())) + throw new RuntimeException("Already contained item "+item); + items.put(item.getId(), item); + } + + /** + * Deletes the given item from the storage. + */ + public void delete(StockItem item) { + if (!items.containsKey(item.getId())) + throw new RuntimeException("Not contained item "+item); + items.remove(item.getId()); + } + + /** + * Changes the number of pieces for the given item. + */ + public void changeCount(StockItem item, int difference) { + if (difference >= 0) + item.put(difference); + else + item.take(-difference); + } + + /** + * Prints a list of available items. + */ + public void print(PrintStream out) { + Iterator<StockItem> it=items.values().iterator(); + while (it.hasNext()) { + out.println(it.next().toString()); + } + out.println(); + } +} + |