├── project
├── build.properties
└── assembly.sbt
├── screenshots
├── Capture.PNG
├── DePaCoG.png
├── Capture2.PNG
├── Capture3.PNG
├── Capture4.PNG
└── laptopFactory.png
├── target
└── scala-2.13
│ └── hw1-assembly-0.1.jar
├── outputs
└── com
│ ├── laptopAbstractFactory
│ ├── AMD.java
│ ├── Intel.java
│ ├── OS.java
│ ├── Processor.java
│ ├── OperatingSystem.java
│ ├── ChromeOS.java
│ ├── Ubuntu.java
│ ├── LaptopFactory.java
│ └── ChromeBookFactory.java
│ ├── usbAdapter
│ ├── TypeC.java
│ ├── MicroUSB.java
│ └── USBDongle.java
│ ├── coffeeDecorator
│ ├── Beverage.java
│ ├── Coffee.java
│ ├── CondimentDecorator.java
│ ├── Milk.java
│ └── WhipCream.java
│ └── weatherObserver
│ ├── SmartPhone.java
│ ├── DarkSkyServer.java
│ ├── AndroidPhone.java
│ └── WeatherServiceServer.java
├── src
├── main
│ ├── resources
│ │ ├── logback.xml
│ │ └── default.conf
│ └── java
│ │ └── com
│ │ ├── DesignPatternGenerator.java
│ │ ├── DePaCoG.java
│ │ ├── creational
│ │ ├── Singleton.java
│ │ ├── Prototype.java
│ │ ├── FactoryMethod.java
│ │ ├── AbstractFactory.java
│ │ └── Builder.java
│ │ ├── structural
│ │ ├── Adapter.java
│ │ ├── Proxy.java
│ │ ├── Composite.java
│ │ ├── Bridge.java
│ │ ├── Decorator.java
│ │ └── Flyweight.java
│ │ ├── behavioral
│ │ ├── TemplateMethod.java
│ │ ├── State.java
│ │ ├── ChainOfResponsibility.java
│ │ ├── Memento.java
│ │ ├── Command.java
│ │ ├── Strategy.java
│ │ ├── Observer.java
│ │ ├── Iterator.java
│ │ ├── Mediator.java
│ │ ├── Interpreter.java
│ │ └── Visitor.java
│ │ ├── Hw1DesignPatternGenerator.java
│ │ └── DesignPattern.java
└── test
│ └── java
│ └── com
│ ├── DesignPatternTest.java
│ └── Hw1DesignPatternGeneratorTest.java
├── LICENSE
├── .gitignore
└── README.md
/project/build.properties:
--------------------------------------------------------------------------------
1 | sbt.version = 1.3.8
--------------------------------------------------------------------------------
/project/assembly.sbt:
--------------------------------------------------------------------------------
1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.10")
--------------------------------------------------------------------------------
/screenshots/Capture.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samujjwaal/Design-Pattern-Code-Generator/HEAD/screenshots/Capture.PNG
--------------------------------------------------------------------------------
/screenshots/DePaCoG.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samujjwaal/Design-Pattern-Code-Generator/HEAD/screenshots/DePaCoG.png
--------------------------------------------------------------------------------
/screenshots/Capture2.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samujjwaal/Design-Pattern-Code-Generator/HEAD/screenshots/Capture2.PNG
--------------------------------------------------------------------------------
/screenshots/Capture3.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samujjwaal/Design-Pattern-Code-Generator/HEAD/screenshots/Capture3.PNG
--------------------------------------------------------------------------------
/screenshots/Capture4.PNG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samujjwaal/Design-Pattern-Code-Generator/HEAD/screenshots/Capture4.PNG
--------------------------------------------------------------------------------
/screenshots/laptopFactory.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samujjwaal/Design-Pattern-Code-Generator/HEAD/screenshots/laptopFactory.png
--------------------------------------------------------------------------------
/target/scala-2.13/hw1-assembly-0.1.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/samujjwaal/Design-Pattern-Code-Generator/HEAD/target/scala-2.13/hw1-assembly-0.1.jar
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/AMD.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * ProductA2, implements AbstractProductA interface
5 | */
6 | public class AMD implements Processor {
7 | }
8 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/Intel.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * ProductA1, implements AbstractProductA interface
5 | */
6 | public class Intel implements Processor {
7 | }
8 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/OS.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * ProductB1, implements AbstractProductB interface
5 | */
6 | public class OS implements OperatingSystem {
7 | }
8 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/Processor.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * AbstractProductA defines interface for ProductA objects
5 | */
6 | public interface Processor {
7 | }
8 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/OperatingSystem.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * AbstractProductB defines interface for ProductB objects
5 | */
6 | public interface OperatingSystem {
7 | }
8 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/ChromeOS.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * ProductB1, implements AbstractProductB interface
5 | */
6 | public class ChromeOS implements OperatingSystem {
7 | }
8 |
--------------------------------------------------------------------------------
/outputs/com/usbAdapter/TypeC.java:
--------------------------------------------------------------------------------
1 | package com.usbAdapter;
2 |
3 | /**
4 | * Target interface, defines domain-specific interface to which Adaptee will be adapted
5 | */
6 | public interface TypeC {
7 | String request();
8 | }
9 |
--------------------------------------------------------------------------------
/outputs/com/coffeeDecorator/Beverage.java:
--------------------------------------------------------------------------------
1 | package com.coffeeDecorator;
2 |
3 | /**
4 | * Component, defines interface for new features which will be added dynamically
5 | */
6 | public interface Beverage {
7 | void operation();
8 | }
9 |
--------------------------------------------------------------------------------
/outputs/com/coffeeDecorator/Coffee.java:
--------------------------------------------------------------------------------
1 | package com.coffeeDecorator;
2 |
3 | /**
4 | * ConcreteComponent, define object where new features can be added
5 | */
6 | public class Coffee implements Beverage {
7 | public void operation() {
8 | }
9 | }
10 |
--------------------------------------------------------------------------------
/outputs/com/usbAdapter/MicroUSB.java:
--------------------------------------------------------------------------------
1 | package com.usbAdapter;
2 |
3 | /**
4 | * Adaptee class, interface which will be adapted
5 | */
6 | public class MicroUSB {
7 | public String specialRequest() {
8 | return "specialRequest";
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/outputs/com/weatherObserver/SmartPhone.java:
--------------------------------------------------------------------------------
1 | package com.weatherObserver;
2 |
3 | /**
4 | * Observer defines an updating interface for objects that should be notified of changes in a subject.
5 | */
6 | public interface SmartPhone {
7 | void update();
8 | }
9 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/Ubuntu.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * Abstract Factory, defines interface for creation of the abstract product objects
5 | */
6 | public interface Ubuntu {
7 | Processor createProcessor();
8 |
9 | OperatingSystem createOperatingSystem();
10 | }
11 |
--------------------------------------------------------------------------------
/src/main/resources/logback.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | %d{HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n
5 |
6 |
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/outputs/com/coffeeDecorator/CondimentDecorator.java:
--------------------------------------------------------------------------------
1 | package com.coffeeDecorator;
2 |
3 | /**
4 | * Decorator, keep reference to Component object
5 | */
6 | abstract class CondimentDecorator implements Beverage {
7 | protected Beverage component;
8 |
9 | public abstract void operation();
10 |
11 | public void setComponent(Beverage component) {
12 | this.component = component;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/outputs/com/coffeeDecorator/Milk.java:
--------------------------------------------------------------------------------
1 | package com.coffeeDecorator;
2 |
3 | /**
4 | * ConcreteDecoratorA, add features to component
5 | */
6 | public class Milk extends CondimentDecorator {
7 | private boolean state;
8 |
9 | public void operation() {
10 | state = true;
11 | this.component.operation();
12 | }
13 |
14 | public boolean isState() {
15 | return state;
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/outputs/com/usbAdapter/USBDongle.java:
--------------------------------------------------------------------------------
1 | package com.usbAdapter;
2 |
3 | /**
4 | * Adapter class, adapts Adaptee to the Target interface
5 | */
6 | public class USBDongle implements TypeC {
7 | private MicroUSB adaptee;
8 |
9 | public USBDongle(MicroUSB adaptee) {
10 | this.adaptee = adaptee;
11 | }
12 |
13 | public String request() {
14 | return adaptee.specialRequest();
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/LaptopFactory.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * ConcreteFactory1, implements creation of the concrete Product1 objects
5 | */
6 | public class LaptopFactory implements Ubuntu {
7 | public Processor createProcessor() {
8 | return new Intel();
9 | }
10 |
11 | public OperatingSystem createOperatingSystem() {
12 | return new OS();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/outputs/com/laptopAbstractFactory/ChromeBookFactory.java:
--------------------------------------------------------------------------------
1 | package com.laptopAbstractFactory;
2 |
3 | /**
4 | * ConcreteFactory2, implements creation of the concrete Product2 objects
5 | */
6 | public class ChromeBookFactory implements Ubuntu {
7 | public Processor createProcessor() {
8 | return new AMD();
9 | }
10 |
11 | public OperatingSystem createOperatingSystem() {
12 | return new ChromeOS();
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/outputs/com/weatherObserver/DarkSkyServer.java:
--------------------------------------------------------------------------------
1 | package com.weatherObserver;
2 |
3 | /**
4 | * ConcreteSubject stores state of interest to ConcreteObserver objects, sends a notification to its observers
5 | * when its state changes.
6 | */
7 | public class DarkSkyServer extends WeatherServiceServer {
8 | private int state;
9 |
10 | public int getState() {
11 | return state;
12 | }
13 |
14 | public void setState(int state) {
15 | this.state = state;
16 | this.notifyObservers();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/outputs/com/coffeeDecorator/WhipCream.java:
--------------------------------------------------------------------------------
1 | package com.coffeeDecorator;
2 |
3 | /**
4 | * ConcreteDecoratorB, add features to component
5 | */
6 | public class WhipCream extends CondimentDecorator {
7 | private boolean behaviorMethodInvoked = false;
8 |
9 | public void operation() {
10 | this.component.operation();
11 | addedBehavior();
12 | }
13 |
14 | private void addedBehavior() {
15 | behaviorMethodInvoked = true;
16 | }
17 |
18 | protected boolean isBehaviorMethodInvoked() {
19 | return behaviorMethodInvoked;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/com/DesignPatternGenerator.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | import java.io.IOException;
4 |
5 | abstract class DesignPatternGenerator {
6 |
7 | protected String[] designPatterns = {"Singleton","Abstract Factory","Builder","Factory Method","Prototype",
8 | "Adapter","Bridge","Composite","Decorator","Facade","Flyweight","Proxy",
9 | "Chain of Responsibility","Command","Interpreter","Iterator","Mediator","Memento","Observer","State","Strategy","Visitor","Template Method"};
10 |
11 | abstract void displayDesignPatterns();
12 |
13 | abstract void generateDesignPattern() throws IOException;
14 |
15 | abstract void designPatternFactory() throws IOException;
16 | }
17 |
--------------------------------------------------------------------------------
/outputs/com/weatherObserver/AndroidPhone.java:
--------------------------------------------------------------------------------
1 | package com.weatherObserver;
2 |
3 | /**
4 | * ConcreteObserver maintains a reference to a ConcreteSubject object, stores
5 | * state that should stay consistent with the subject's, implements the Observer
6 | * updating interface to keep its state consistent with the subject's.
7 | */
8 | public class AndroidPhone implements SmartPhone {
9 | private int observerState;
10 |
11 | private DarkSkyServer subject;
12 |
13 | public AndroidPhone(DarkSkyServer subject) {
14 | this.subject = subject;
15 | }
16 |
17 | public void update() {
18 | observerState = subject.getState();
19 | }
20 |
21 | protected int getObserverState() {
22 | return observerState;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/outputs/com/weatherObserver/WeatherServiceServer.java:
--------------------------------------------------------------------------------
1 | package com.weatherObserver;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Iterator;
5 | import java.util.List;
6 |
7 | /**
8 | * Subject knows its observers. Any number of Observer objects may observe a subject.
9 | */
10 | abstract class WeatherServiceServer {
11 | private List observers = new ArrayList();
12 |
13 | public void attach(SmartPhone observer) {
14 | observers.add(observer);
15 | }
16 |
17 | public void detach(SmartPhone observer) {
18 | observers.remove(observer);
19 | }
20 |
21 | public void notifyObservers() {
22 | (Iterator iterator = observers.iterator(); iterator.hasNext();) {
23 | SmartPhone observer = (SmartPhone) iterator.next();
24 | observer.update();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/main/resources/default.conf:
--------------------------------------------------------------------------------
1 | {
2 | iterations = [
3 | {
4 | designPatternChoice = "2"
5 | classes = ["Processor", "Intel", "AMD",
6 | "OperatingSystem", "OS", "ChromeOS", "Ubuntu",
7 | "LaptopFactory", "ChromeBookFactory","LinuxLaptopFactory"]
8 | packageName = "com.laptopAbstractFactory"
9 | },
10 | {
11 | designPatternChoice = "9"
12 | classes = ["Beverage","Coffee","CondimentDecorator","Milk","WhipCream"]
13 | packageName = "com.coffeeDecorator"
14 | },
15 | {
16 | designPatternChoice = "6"
17 | classes = ["TypeC", "MicroUSB","USBDongle"]
18 | packageName = "com.usbAdapter"
19 | },
20 | {
21 | designPatternChoice = "19"
22 | classes = ["SmartPhone", "WeatherServiceServer","DarkSkyServer","AndroidPhone"]
23 | packageName = "com.weatherObserver"
24 | }]
25 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Samujjwaal Dey
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/test/java/com/DesignPatternTest.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | import com.squareup.javapoet.JavaFile;
4 | import com.structural.Flyweight;
5 | import org.junit.jupiter.api.Test;
6 |
7 | import java.io.File;
8 | import java.io.IOException;
9 | import java.nio.file.Files;
10 | import java.nio.file.Path;
11 | import java.nio.file.Paths;
12 |
13 | import static org.junit.jupiter.api.Assertions.*;
14 |
15 | class DesignPatternTest {
16 | String[] classNames = {"Flyweight", "ConcreteFlyweight","UnsharedConcreteFlyweight","FlyweightFactory"};
17 | String packageName = "com.test_generateCode.flyweight";
18 |
19 | @Test
20 | void test_generateCode() throws IOException {
21 |
22 | // Test Case to verify generateCode() returns JavaFile[] object
23 |
24 | assertEquals(JavaFile[].class,new Flyweight(0).generateCode(classNames, packageName).getClass());
25 | }
26 |
27 | @Test
28 | void test_writeJavaFiles() throws IOException {
29 |
30 | // Test Case to verify the generated java files are written successfully in the output folder
31 | int mode = 0;
32 | Flyweight test = new Flyweight(mode);
33 | JavaFile[] test_files = test.generateCode(classNames, packageName);
34 | test.writeJavaFiles(test_files);
35 | Path path = Paths.get("outputs/com/test_generateCode/flyweight");
36 | assertTrue(Files.exists(path));
37 |
38 |
39 | }
40 |
41 | }
--------------------------------------------------------------------------------
/src/test/java/com/Hw1DesignPatternGeneratorTest.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | import com.structural.Flyweight;
4 | import org.junit.jupiter.api.Test;
5 |
6 | import java.io.IOException;
7 |
8 |
9 | import static org.junit.jupiter.api.Assertions.*;
10 |
11 | class Hw1DesignPatternGeneratorTest {
12 |
13 |
14 | @Test
15 | void test_getInstance() {
16 |
17 | // Test Case to verify only 1 instance of Hw1DesignPatternGenerator is created each time
18 |
19 | Hw1DesignPatternGenerator firstInstance = Hw1DesignPatternGenerator.getInstance();
20 | Hw1DesignPatternGenerator secondInstance = Hw1DesignPatternGenerator.getInstance();
21 |
22 | assertEquals(firstInstance,secondInstance);
23 | }
24 |
25 |
26 | @Test
27 | void chooseDesignPattern() throws IOException {
28 |
29 | //Test Case to verify correct design pattern file is executed when user inputs the choice of design pattern
30 | // Here Flyweight( 11 ) is selected.
31 |
32 | DesignPattern design_pattern2 = Hw1DesignPatternGenerator.getInstance().chooseDesignPattern(11,0);
33 | assertEquals(Flyweight.class,design_pattern2.getClass());
34 |
35 | // Test Case to check null is returned on selecting incorrect design pattern choice
36 | int choice = 75;
37 | DesignPattern design_pattern = Hw1DesignPatternGenerator.getInstance().chooseDesignPattern(choice,0);
38 | assertNull(design_pattern);
39 |
40 | }
41 | }
--------------------------------------------------------------------------------
/src/main/java/com/DePaCoG.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | import com.squareup.javapoet.JavaFile;
4 | import com.typesafe.config.Config;
5 | import com.typesafe.config.ConfigFactory;
6 | import ch.qos.logback.classic.Logger;
7 | import org.slf4j.LoggerFactory;
8 | import java.io.IOException;
9 | import java.util.Arrays;
10 |
11 | public class DePaCoG {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(DePaCoG.class);
15 |
16 | public static void main(String[] args) throws IOException {
17 | logger.info("Started execution of main()");
18 |
19 | Hw1DesignPatternGenerator hw1 = Hw1DesignPatternGenerator.getInstance();
20 | // hw1.displayDesignPatterns();
21 |
22 | if(args[0].equals("0")){
23 |
24 | logger.info("Parsing input from default config file ");
25 |
26 | // parse the config file
27 | Config paramsConfig = ConfigFactory.load("default.conf");
28 |
29 | //mode for taking input from config file
30 | int mode = 0;
31 | // create array of Config objects to obtain inputs for every iterations of run
32 | Config[] iterations = paramsConfig.getConfigList("iterations").toArray(new Config[0]);
33 |
34 | for (Config iteration: iterations) {
35 | // get the choice of design pattern to be generated
36 | int choice = iteration.getInt("designPatternChoice");
37 | // get class names for output files
38 | Object[] classes = iteration.getStringList("classes").toArray();
39 | String[] classNames = Arrays.copyOf(classes,classes.length,String[].class);
40 | // get package name to set for output files
41 | String packageName = iteration.getString("packageName");
42 | // pass design pattern choice and mode
43 | DesignPattern outputDesignPattern = hw1.chooseDesignPattern(choice,mode);
44 | // get outputs files as JavaFile[]
45 | JavaFile[] files = outputDesignPattern.generateCode(classNames,packageName);
46 | // write generated design patterns into files
47 | outputDesignPattern.writeJavaFiles(files);
48 | }
49 | }
50 | if (args[0].equals("1")){
51 | logger.info("Displaying interactive menu");
52 | // to execute using custom inputs
53 | hw1.generateDesignPattern();
54 | }
55 | logger.info("End of execution");
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/creational/Singleton.java:
--------------------------------------------------------------------------------
1 | package com.creational;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 | import com.DesignPattern;
7 | import ch.qos.logback.classic.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public class Singleton implements DesignPattern {
11 |
12 | //Define a static logger variable so that it references the Logger instance
13 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Singleton.class);
14 |
15 | String[] defaultClasses = {"Singleton"};
16 | String packageName = "com.CreationalDP.singleton";
17 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
18 |
19 | public Singleton(int flag)throws IOException{
20 | logger.info("Executing Singleton()");
21 | if (flag == 1){
22 | createDesignPattern(defaultClasses, packageName);
23 | }
24 | // else{
25 | // System.out.println("Exit");
26 | // }
27 | }
28 |
29 |
30 | @Override
31 | public JavaFile[] generateCode(String[] classes, String packageName){
32 | logger.info("Executing generateCode()");
33 | int i = 0;
34 | ClassName Singleton = ClassName.get("", classes[i]);
35 |
36 | MethodSpec constructor = MethodSpec.constructorBuilder()
37 | .addModifiers(Modifier.PRIVATE)
38 | .build();
39 |
40 | FieldSpec instance = FieldSpec.builder(Singleton, "INSTANCE")
41 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
42 | .build();
43 |
44 | MethodSpec getInstance = MethodSpec.methodBuilder("getInstance")
45 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
46 | .returns(Singleton)
47 | .beginControlFlow("if ($N == null)", instance.name)
48 | .addStatement("$N = new $T()",instance.name, Singleton)
49 | .endControlFlow()
50 | .addStatement("return $N", instance.name)
51 | .build();
52 |
53 | TypeSpec singleton = TypeSpec.classBuilder(Singleton)
54 | .addModifiers(Modifier.PUBLIC)
55 | .addField(instance)
56 | .addMethod(constructor)
57 | .addMethod(getInstance)
58 | .build();
59 |
60 | generatedCode[i] = JavaFile.builder(packageName, singleton)
61 | .skipJavaLangImports(true)
62 | .build();
63 | i += 1;
64 |
65 | logger.info("Returning generated java code to be written in files");
66 |
67 | // javaFile.writeTo(new File("C:\\Users\\Samujjwaal Dey\\Desktop\\CS 474 OOLE\\outputs/singleton.java"));
68 | return generatedCode;
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/sbt,java,intellij
3 | # Edit at https://www.gitignore.io/?templates=sbt,java,intellij
4 |
5 | ### Intellij ###
6 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
7 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
8 |
9 | # User-specific stuff
10 | .idea/**/workspace.xml
11 | .idea/**/tasks.xml
12 | .idea/**/usage.statistics.xml
13 | .idea/**/dictionaries
14 | .idea/**/shelf
15 |
16 | # Generated files
17 | .idea/**/contentModel.xml
18 |
19 | # Sensitive or high-churn files
20 | .idea/**/dataSources/
21 | .idea/**/dataSources.ids
22 | .idea/**/dataSources.local.xml
23 | .idea/**/sqlDataSources.xml
24 | .idea/**/dynamic.xml
25 | .idea/**/uiDesigner.xml
26 | .idea/**/dbnavigator.xml
27 |
28 | # Gradle
29 | .idea/**/gradle.xml
30 | .idea/**/libraries
31 |
32 | # Gradle and Maven with auto-import
33 | # When using Gradle or Maven with auto-import, you should exclude module files,
34 | # since they will be recreated, and may cause churn. Uncomment if using
35 | # auto-import.
36 | # .idea/modules.xml
37 | # .idea/*.iml
38 | # .idea/modules
39 | # *.iml
40 | # *.ipr
41 |
42 | # CMake
43 | cmake-build-*/
44 |
45 | # Mongo Explorer plugin
46 | .idea/**/mongoSettings.xml
47 |
48 | # File-based project format
49 | *.iws
50 |
51 | # IntelliJ
52 | out/
53 |
54 | # mpeltonen/sbt-idea plugin
55 | .idea_modules/
56 |
57 | # JIRA plugin
58 | atlassian-ide-plugin.xml
59 |
60 | # Cursive Clojure plugin
61 | .idea/replstate.xml
62 |
63 | # Crashlytics plugin (for Android Studio and IntelliJ)
64 | com_crashlytics_export_strings.xml
65 | crashlytics.properties
66 | crashlytics-build.properties
67 | fabric.properties
68 |
69 | # Editor-based Rest Client
70 | .idea/httpRequests
71 |
72 | # Android studio 3.1+ serialized cache file
73 | .idea/caches/build_file_checksums.ser
74 |
75 | ### Intellij Patch ###
76 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
77 |
78 | # *.iml
79 | # modules.xml
80 | # .idea/misc.xml
81 | # *.ipr
82 |
83 | # Sonarlint plugin
84 | .idea/**/sonarlint/
85 |
86 | # SonarQube Plugin
87 | .idea/**/sonarIssues.xml
88 |
89 | # Markdown Navigator plugin
90 | .idea/**/markdown-navigator.xml
91 | .idea/**/markdown-navigator/
92 |
93 | ### Java ###
94 | # Compiled class file
95 | *.class
96 |
97 | # Log file
98 | *.log
99 |
100 | # BlueJ files
101 | *.ctxt
102 |
103 | # Mobile Tools for Java (J2ME)
104 | .mtj.tmp/
105 |
106 | # Package Files #
107 | *.jar
108 | *.war
109 | *.nar
110 | *.ear
111 | *.zip
112 | *.tar.gz
113 | *.rar
114 |
115 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
116 | hs_err_pid*
117 |
118 | ### SBT ###
119 | # Simple Build Tool
120 | # http://www.scala-sbt.org/release/docs/Getting-Started/Directories.html#configuring-version-control
121 |
122 | dist/*
123 | target/
124 | lib_managed/
125 | src_managed/
126 | project/boot/
127 | project/plugins/project/
128 | .history
129 | .cache
130 | .lib/
131 |
132 | # End of https://www.gitignore.io/api/sbt,java,intellij
133 |
134 | outputs/
135 | .idea
136 | target/streams
137 | project/project
138 | project/target
139 | !target/scala-2.13/hw1-assembly-0.1.jar
--------------------------------------------------------------------------------
/src/main/java/com/structural/Adapter.java:
--------------------------------------------------------------------------------
1 | package com.structural;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Adapter implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Adapter.class);
15 |
16 |
17 | String[] defaultClasses = {"Target", "Adaptee","Adapter"};
18 | String packageName = "com.StructuralDP.adapter";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 |
22 | public Adapter(int flag)throws IOException{
23 | logger.info("Executing Adapter()");
24 | if(flag == 1) {
25 | createDesignPattern(defaultClasses, packageName);
26 | }
27 | }
28 |
29 | public JavaFile[] generateCode(String[] classes, String packageName){
30 |
31 | int i = 0;
32 | logger.info("Executing generateCode()");
33 |
34 |
35 | // Target interface declaration
36 | ClassName Target = ClassName.get("",classes[i]);
37 | TypeSpec target = TypeSpec.interfaceBuilder(Target)
38 | .addModifiers(Modifier.PUBLIC)
39 | .addJavadoc("Target interface, defines domain-specific interface to which Adaptee will be adapted")
40 | .addMethod(MethodSpec.methodBuilder("request")
41 | .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC)
42 | .returns(String.class)
43 | .build())
44 | .build();
45 | generatedCode[i] = JavaFile.builder(packageName,target)
46 | .skipJavaLangImports(true)
47 | .build();
48 | i += 1;
49 | // Adaptee class declaration
50 | ClassName Adaptee = ClassName.get("",classes[i]);
51 | TypeSpec adaptee = TypeSpec.classBuilder(Adaptee)
52 | .addModifiers(Modifier.PUBLIC)
53 | .addJavadoc("Adaptee class, interface which will be adapted")
54 | .addMethod(MethodSpec.methodBuilder("specialRequest")
55 | .addModifiers(Modifier.PUBLIC)
56 | .returns(String.class)
57 | .addStatement("return $S","specialRequest")
58 | .build())
59 | .build();
60 | generatedCode[i] = JavaFile.builder(packageName,adaptee)
61 | .skipJavaLangImports(true)
62 | .build();
63 | i += 1;
64 | // Adapter class declaration
65 | ClassName Adapter =ClassName.get("",classes[i]);
66 | TypeSpec adapter = TypeSpec.classBuilder(Adapter)
67 | .addSuperinterface(Target)
68 | .addJavadoc("Adapter class, adapts Adaptee to the Target interface")
69 | .addModifiers(Modifier.PUBLIC)
70 | .addField(Adaptee, "adaptee",Modifier.PRIVATE)
71 | .addMethod(MethodSpec.constructorBuilder()
72 | .addModifiers(Modifier.PUBLIC)
73 | .addParameter(Adaptee, "adaptee")
74 | .addStatement("this.adaptee = adaptee")
75 | .build())
76 | .addMethod(MethodSpec.methodBuilder("request")
77 | .addModifiers(Modifier.PUBLIC)
78 | .returns(String.class)
79 | .addStatement("return adaptee.specialRequest()")
80 | .build())
81 | .build();
82 | generatedCode[i] = JavaFile.builder(packageName,adapter)
83 | .skipJavaLangImports(true)
84 | .build();
85 |
86 | logger.info("Returning generated java code to be written in files");
87 |
88 | return generatedCode;
89 |
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/TemplateMethod.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class TemplateMethod implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(TemplateMethod.class);
15 |
16 |
17 | String[] defaultClasses = {"AbstractClass", "ConcreteClass"};
18 | String packageName = "com.BehavioralDP.templateMethod";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public TemplateMethod(int flag)throws IOException{
22 | logger.info("Executing TemplateMethod()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 |
31 | int i = 0;
32 |
33 | ClassName abstractclass = ClassName.get("",classes[i]);
34 |
35 | // AbstractClass declaration
36 | MethodSpec primOp1 = MethodSpec.methodBuilder("primitiveOperation1")
37 | .addModifiers(Modifier.ABSTRACT)
38 | .returns(String.class)
39 | .build();
40 | MethodSpec primOp2 = MethodSpec.methodBuilder("primitiveOperation2")
41 | .addModifiers(Modifier.ABSTRACT)
42 | .returns(String.class)
43 | .build();
44 |
45 | TypeSpec abstractC = TypeSpec.classBuilder(abstractclass)
46 | .addModifiers(Modifier.ABSTRACT)
47 | .addJavadoc("Defines interfaces for primitive operations. Implements algorithm.")
48 | .addMethod(MethodSpec.methodBuilder("templateMethod")
49 | .addModifiers(Modifier.PUBLIC)
50 | .returns(String.class)
51 | .addJavadoc("Template method, implementation of algorithm which consists of\n" +
52 | "primitiveOperations\n" +
53 | "\n" +
54 | "@return result of the primitive operations")
55 | .addStatement("return this.$N() + this.$N()",primOp1.name,primOp2.name)
56 | .build())
57 | .addMethod(primOp1)
58 | .addMethod(primOp2)
59 | .build();
60 | generatedCode[i] = JavaFile.builder(packageName,abstractC)
61 | .skipJavaLangImports(true)
62 | .build();
63 | i += 1;
64 |
65 | // ConcreteClass declaration
66 | ClassName concreteclass = ClassName.get("",classes[i]);
67 | TypeSpec concreteC = TypeSpec.classBuilder(concreteclass)
68 | .superclass(abstractclass)
69 | .addJavadoc("Implements the primitive operations to carry out subclass-specific steps of\n" +
70 | "the algorithm.")
71 | .addModifiers(Modifier.PUBLIC)
72 | .addMethod(MethodSpec.methodBuilder(primOp1.name)
73 | .addModifiers(Modifier.PUBLIC)
74 | .returns(String.class)
75 | .addStatement("return $S","Template")
76 | .build())
77 | .addMethod(MethodSpec.methodBuilder(primOp2.name)
78 | .addModifiers(Modifier.PUBLIC)
79 | .returns(String.class)
80 | .addStatement("return $S","Method")
81 | .build())
82 | .build();
83 | generatedCode[i] = JavaFile.builder(packageName,concreteC)
84 | .skipJavaLangImports(true)
85 | .build();
86 |
87 | logger.info("Returning generated java code to be written in files");
88 |
89 | return generatedCode;
90 |
91 | }
92 | }
93 |
--------------------------------------------------------------------------------
/src/main/java/com/structural/Proxy.java:
--------------------------------------------------------------------------------
1 | package com.structural;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Proxy implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Proxy.class);
15 |
16 | String[] defaultClasses = {"Subject", "RealSubject","Proxy"};
17 | String packageName = "com.StructuralDP.proxy";
18 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
19 |
20 | public Proxy(int flag)throws IOException{
21 | logger.info("Executing Proxy()");
22 | if(flag == 1) {
23 | createDesignPattern(defaultClasses, packageName);
24 | }
25 | }
26 |
27 | public JavaFile[] generateCode(String[] classes, String packageName){
28 | logger.info("Executing generateCode()");
29 |
30 | int i = 0;
31 |
32 | // Proxy interface declaration
33 | MethodSpec doOp = MethodSpec.methodBuilder("doOperation")
34 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
35 | .returns(TypeName.VOID)
36 | .build();
37 | ClassName Subject = ClassName.get("",classes[i]);
38 | TypeSpec subject = TypeSpec.interfaceBuilder(Subject)
39 | .addModifiers(Modifier.PUBLIC)
40 | .addJavadoc("Subject interface defines common interface for RealSubject and Proxy")
41 | .addMethod(doOp)
42 | .build();
43 | generatedCode[i] = JavaFile.builder(packageName,subject)
44 | .skipJavaLangImports(true)
45 | .build();
46 | i += 1;
47 |
48 | // RealSubject class declaration
49 | ClassName RealSubject = ClassName.get("",classes[i]);
50 | TypeSpec realSubject = TypeSpec.classBuilder(RealSubject)
51 | .addSuperinterface(Subject)
52 | .addJavadoc("RealSubject class is a real object which is represented by Proxy")
53 | .addModifiers(Modifier.PUBLIC)
54 | .addMethod(MethodSpec.methodBuilder(doOp.name)
55 | .addModifiers(Modifier.PUBLIC)
56 | .build())
57 | .build();
58 | generatedCode[i] = JavaFile.builder(packageName,realSubject)
59 | .skipJavaLangImports(true)
60 | .build();
61 | i += 1;
62 |
63 | // Proxy class declaration
64 | ClassName Proxy = ClassName.get("",classes[i]);
65 | TypeSpec proxy = TypeSpec.classBuilder(Proxy)
66 | .addModifiers(Modifier.PUBLIC)
67 | .addSuperinterface(Subject)
68 | .addJavadoc("Proxy class keep reference on a real subject, define interface which\n" +
69 | "represents Subject, so he can: - act as a surrogate - control access to real\n" +
70 | "subject - can be responsible for creation and maintenance of the real\n" +
71 | "subject\n")
72 | .addField(RealSubject, "realSubject",Modifier.PRIVATE)
73 | .addMethod(MethodSpec.methodBuilder(doOp.name)
74 | .addModifiers(Modifier.PUBLIC)
75 | .addStatement("this.$N = new $T()","realSubject",RealSubject)
76 | .addStatement("this.$N.$N()","realSubject",doOp.name)
77 | .build())
78 | .addMethod(MethodSpec.methodBuilder("getRealSubject")
79 | .addModifiers(Modifier.PUBLIC)
80 | .returns(RealSubject)
81 | .addStatement("return $N","realSubject")
82 | .build())
83 | .build();
84 | generatedCode[i] = JavaFile.builder(packageName,proxy)
85 | .skipJavaLangImports(true)
86 | .build();
87 |
88 | logger.info("Returning generated java code to be written in files");
89 |
90 | return generatedCode;
91 |
92 | }
93 | }
94 |
--------------------------------------------------------------------------------
/src/main/java/com/structural/Composite.java:
--------------------------------------------------------------------------------
1 | package com.structural;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Composite implements DesignPattern {
12 | //Define a static logger variable so that it references the Logger instance
13 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Composite.class);
14 |
15 |
16 | String[] defaultClasses = {"Component", "Composite"};
17 | String packageName = "com.StructuralDP.composite";
18 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
19 |
20 | public Composite(int flag)throws IOException{
21 | logger.info("Executing Composite()");
22 | if(flag == 1) {
23 | createDesignPattern(defaultClasses, packageName);
24 | }
25 | }
26 |
27 | public JavaFile[] generateCode(String[] classes, String packageName){
28 |
29 | logger.info("Executing generateCode()");
30 | int i = 0;
31 |
32 | // Component interface declaration
33 | ClassName Component = ClassName.get("",classes[i]);
34 | MethodSpec oper = MethodSpec.methodBuilder("operation")
35 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
36 | .returns(TypeName.VOID)
37 | .build();
38 | TypeSpec component = TypeSpec.interfaceBuilder(Component)
39 | .addModifiers(Modifier.PUBLIC)
40 | .addJavadoc("Component declares the interface for objects in the composition")
41 | .addMethod(oper)
42 | .build();
43 | generatedCode[i] = JavaFile.builder(packageName,component)
44 | .skipJavaLangImports(true)
45 | .build();
46 | i += 1;
47 |
48 | // Composite class declaration
49 | ClassName Composite = ClassName.get("",classes[i]);
50 | ClassName list = ClassName.get("java.util", "List");
51 | ClassName arrayList = ClassName.get("java.util", "ArrayList");
52 | TypeName listOfComponents = ParameterizedTypeName.get(list,Component);
53 |
54 | FieldSpec child = FieldSpec.builder(listOfComponents,"children")
55 | .addModifiers(Modifier.PRIVATE)
56 | .initializer("new $T<$T>()",arrayList,Component)
57 | .build();
58 | TypeSpec composite = TypeSpec.classBuilder(Composite)
59 | .superclass(Component)
60 | .addModifiers(Modifier.PUBLIC)
61 | .addJavadoc("Composite class defines behavior for components having children, stores child\n" +
62 | "components, implements child-related operations in the Component interface")
63 | .addField(child)
64 | .addMethod(MethodSpec.methodBuilder(oper.name)
65 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
66 | .beginControlFlow("for($T component : $N)",Component,child.name)
67 | .addStatement("component.$N()",oper.name)
68 | .endControlFlow()
69 | .build())
70 | .addMethod(MethodSpec.methodBuilder("add")
71 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
72 | .addParameter(Component,"component")
73 | .addStatement("$N.add(component)",child.name)
74 | .build())
75 | .addMethod(MethodSpec.methodBuilder("remove")
76 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
77 | .addParameter(Component,"component")
78 | .addStatement("$N.remove(component)",child.name)
79 | .build())
80 | .addMethod(MethodSpec.methodBuilder("getChild")
81 | .addModifiers(Modifier.PUBLIC).returns(Component)
82 | .addParameter(int.class,"index")
83 | .addStatement("return $N.get(index)",child.name)
84 | .build())
85 | .build();
86 | generatedCode[i] = JavaFile.builder(packageName,composite)
87 | .skipJavaLangImports(true)
88 | .build();
89 |
90 | logger.info("Returning generated java code to be written in files");
91 |
92 | return generatedCode;
93 |
94 | }
95 | }
96 |
--------------------------------------------------------------------------------
/src/main/java/com/creational/Prototype.java:
--------------------------------------------------------------------------------
1 | package com.creational;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 | import com.DesignPattern;
7 | import ch.qos.logback.classic.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public class Prototype implements DesignPattern {
11 |
12 | //Define a static logger variable so that it references the Logger instance
13 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Prototype.class);
14 |
15 | String[] defaultClasses = {"Prototype","ConcretePrototype","Client"};
16 | String packageName = "com.CreationalDP.prototype";
17 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
18 |
19 | public Prototype(int flag)throws IOException {
20 | logger.info("Executing Prototype()");
21 |
22 | if (flag == 1) {
23 | createDesignPattern(defaultClasses, packageName);
24 | }
25 | }
26 |
27 | @Override
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 | int i = 0;
31 |
32 | // Prototype abstract class declaration
33 | ClassName Prototype = ClassName.get("",classes[i]);
34 | MethodSpec copyMe = MethodSpec.methodBuilder("copyMe")
35 | .addModifiers(Modifier.ABSTRACT)
36 | .addException(CloneNotSupportedException.class)
37 | .addJavadoc("Copy method.\n" +
38 | "@return copy of the object\n" +
39 | "@throws CloneNotSupportedException exception")
40 | .returns(Prototype)
41 | .build();
42 | TypeSpec prototype = TypeSpec.classBuilder(Prototype)
43 | .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC)
44 | .addSuperinterface(Cloneable.class)
45 | .addJavadoc("Declares interface to copy it self.")
46 | .addMethod(copyMe)
47 | .build();
48 | generatedCode[i] = JavaFile.builder(packageName,prototype)
49 | .skipJavaLangImports(true)
50 | .build();
51 | i += 1;
52 |
53 | // ConcretePrototype class declaration
54 | ClassName ConcretePrototype = ClassName.get("",classes[i]);
55 | TypeSpec concPrototype = TypeSpec.classBuilder(ConcretePrototype)
56 | .addModifiers(Modifier.PUBLIC)
57 | .superclass(Prototype)
58 | .addJavadoc("Declares interface to copy it self.")
59 | .addMethod(MethodSpec.methodBuilder(copyMe.name)
60 | .addModifiers(Modifier.PUBLIC)
61 | .addException(CloneNotSupportedException.class)
62 | .returns(Prototype)
63 | .addStatement("return ($T) this.clone()",Prototype)
64 | .build())
65 | .build();
66 | generatedCode[i] = JavaFile.builder(packageName,concPrototype)
67 | .skipJavaLangImports(true)
68 | .build();
69 | i += 1;
70 |
71 | // Client class declaration
72 | ClassName Client = ClassName.get("",classes[i]);
73 | FieldSpec proto = FieldSpec.builder(Prototype, "prototype",Modifier.PRIVATE).build();
74 | TypeSpec client = TypeSpec.classBuilder(Client)
75 | .addModifiers(Modifier.PUBLIC)
76 | .addJavadoc("Creates a new object by asking a Prototype to clone itself")
77 | .addField(proto)
78 | .addMethod(MethodSpec.constructorBuilder()
79 | .addModifiers(Modifier.PUBLIC)
80 | .addParameter(Prototype,"prototype")
81 | .addStatement("this.$N = prototype",proto.name)
82 | .build())
83 | .addMethod(MethodSpec.methodBuilder("operation")
84 | .addModifiers(Modifier.PUBLIC)
85 | .addException(CloneNotSupportedException.class)
86 | .returns(Prototype)
87 | .addStatement("return $N.$N()",proto.name,copyMe.name)
88 | .build())
89 | .build();
90 | generatedCode[i] = JavaFile.builder(packageName,client)
91 | .skipJavaLangImports(true)
92 | .build();
93 |
94 | logger.info("Returning generated java code to be written in files");
95 |
96 | return generatedCode;
97 |
98 |
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/State.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class State implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(State.class);
15 |
16 |
17 | String[] defaultClasses = {"State", "ConcreteState","Context"};
18 | String packageName = "com.BehavioralDP.state";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public State(int flag)throws IOException{
22 | logger.info("Executing State()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 |
31 | int i = 0;
32 |
33 | // State interface declaration
34 | ClassName State = ClassName.get("",classes[i]);
35 | MethodSpec handle = MethodSpec.methodBuilder("handle")
36 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
37 | .returns(TypeName.VOID)
38 | .build();
39 | TypeSpec state = TypeSpec.interfaceBuilder(State)
40 | .addModifiers(Modifier.PUBLIC)
41 | .addJavadoc("The interface for encapsulating the behavior associated with a particular\n" +
42 | "state of the Context.")
43 | .addMethod(handle)
44 | .build();
45 | generatedCode[i] = JavaFile.builder(packageName,state)
46 | .skipJavaLangImports(true)
47 | .build();
48 | i += 1;
49 |
50 | // ConcreteState class declaration
51 | ClassName ConcreteState = ClassName.get("",classes[i]);
52 | FieldSpec handleInv = FieldSpec.builder(TypeName.BOOLEAN,"handleInvoked")
53 | .addModifiers(Modifier.PRIVATE)
54 | .initializer("false")
55 | .build();
56 | TypeSpec concreteState = TypeSpec.classBuilder(ConcreteState)
57 | .addSuperinterface(State)
58 | .addModifiers(Modifier.PUBLIC)
59 | .addJavadoc("ConcreteState implements a behavior associated with a state of the Context.")
60 | .addField(handleInv)
61 | .addMethod(MethodSpec.methodBuilder(handle.name)
62 | .addModifiers(Modifier.PUBLIC)
63 | .returns(TypeName.VOID)
64 | .addStatement("this.$N = true",handleInv.name)
65 | .build())
66 | .addMethod(MethodSpec.methodBuilder("isHandleInvoked")
67 | .addModifiers(Modifier.PROTECTED)
68 | .returns(TypeName.BOOLEAN)
69 | .addStatement("return $N", handleInv)
70 | .build())
71 | .build();
72 | generatedCode[i] = JavaFile.builder(packageName,concreteState)
73 | .skipJavaLangImports(true)
74 | .build();
75 | i += 1;
76 |
77 | // Context class declaration
78 | ClassName Context = ClassName.get("",classes[i]);
79 | TypeSpec context = TypeSpec.classBuilder(Context)
80 | .addModifiers(Modifier.PUBLIC)
81 | .addJavadoc("Context maintains an instance of a ConcreteState subclass that defines the\n" +
82 | "current state.")
83 | .addField(ConcreteState, "state",Modifier.PRIVATE)
84 | .addMethod(MethodSpec.methodBuilder("request")
85 | .addModifiers(Modifier.PUBLIC)
86 | .addStatement("$N.$N()","state",handle.name)
87 | .build())
88 | .addMethod(MethodSpec.methodBuilder("setState")
89 | .addModifiers(Modifier.PUBLIC)
90 | .returns(TypeName.VOID)
91 | .addParameter(State, "state")
92 | .addStatement("this.$N = state", "state")
93 | .build())
94 | .build();
95 | generatedCode[i] = JavaFile.builder(packageName,context)
96 | .skipJavaLangImports(true)
97 | .build();
98 |
99 | logger.info("Returning generated java code to be written in files");
100 |
101 | return generatedCode;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/creational/FactoryMethod.java:
--------------------------------------------------------------------------------
1 | package com.creational;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class FactoryMethod implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(FactoryMethod.class);
15 |
16 | String[] defaultClasses = {"Product","Factory","ConcreteProductA","ConcreteProductB","ConcreteFactory"};
17 | String packageName = "com.CreationalDP.factoryMethod";
18 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
19 |
20 | public FactoryMethod(int flag)throws IOException {
21 | logger.info("Executing FactoryMethod()");
22 |
23 | if (flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | @Override
29 | public JavaFile[] generateCode(String[] classes, String packageName){
30 | logger.info("Executing generateCode()");
31 |
32 | int i = 0;
33 | // Product interface declaration
34 | ClassName Product = ClassName.get("",classes[i]);
35 | TypeSpec product = TypeSpec.interfaceBuilder(Product)
36 | .addModifiers(Modifier.PUBLIC)
37 | .addJavadoc("Product interface, defines the interface of the objects which factory method creates.")
38 | .build();
39 | generatedCode[i] = JavaFile.builder(packageName,product)
40 | .skipJavaLangImports(true)
41 | .build();
42 | i += 1;
43 | // Factory abstract class declaration
44 | ClassName Factory = ClassName.get("",classes[i]);
45 | MethodSpec factoryMethod = MethodSpec.methodBuilder("factoryMethod")
46 | .addModifiers(Modifier.ABSTRACT)
47 | .returns(Product)
48 | .addParameter(String.class,"type")
49 | .build();
50 | TypeSpec factory = TypeSpec.classBuilder(Factory)
51 | .addModifiers(Modifier.ABSTRACT)
52 | .addJavadoc("Factory class declares factory method")
53 | .addMethod(factoryMethod)
54 | .build();
55 | generatedCode[i] = JavaFile.builder(packageName,factory)
56 | .skipJavaLangImports(true)
57 | .build();
58 | i += 1;
59 | // ConcreteProductA class declaration
60 | ClassName ConcreteProductA = ClassName.get("",classes[i]);
61 | TypeSpec concProdA = TypeSpec.classBuilder(ConcreteProductA)
62 | .addModifiers(Modifier.PUBLIC)
63 | .addSuperinterface(Product)
64 | .addJavadoc("ConcreteProductA class implements Product interface")
65 | .build();
66 | generatedCode[i] = JavaFile.builder(packageName,concProdA)
67 | .skipJavaLangImports(true)
68 | .build();
69 | i += 1;
70 | // ConcreteProductB class declaration
71 | ClassName ConcreteProductB = ClassName.get("",classes[i]);
72 | TypeSpec concProdB = TypeSpec.classBuilder(ConcreteProductB)
73 | .addModifiers(Modifier.PUBLIC)
74 | .addSuperinterface(Product)
75 | .addJavadoc("ConcreteProductB class implements Product interface")
76 | .build();
77 | generatedCode[i] = JavaFile.builder(packageName,concProdB)
78 | .skipJavaLangImports(true)
79 | .build();
80 | i += 1;
81 | // ProductFactory class declaration
82 | ClassName ConcreteFactory = ClassName.get("",classes[i]);
83 | TypeSpec concFactory = TypeSpec.classBuilder(ConcreteFactory)
84 | .superclass(Factory)
85 | .addModifiers(Modifier.PUBLIC)
86 | .addMethod(MethodSpec.methodBuilder("productFactory")
87 | .addModifiers(Modifier.PUBLIC).returns(Product)
88 | .addParameter(String.class,"type")
89 | .beginControlFlow("if (type.equals(\"A\"))")
90 | .addStatement("return new $T()",ConcreteProductA)
91 | .nextControlFlow("else if (type.equals(\"B\"))")
92 | .addStatement("return new $T()",ConcreteProductB)
93 | .endControlFlow()
94 | .addStatement("return null")
95 | .build())
96 | .build();
97 | generatedCode[i] = JavaFile.builder(packageName,concFactory)
98 | .skipJavaLangImports(true)
99 | .build();
100 |
101 | logger.info("Returning generated java code to be written in files");
102 |
103 | return generatedCode;
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/ChainOfResponsibility.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 | import com.DesignPattern;
7 |
8 | public class ChainOfResponsibility implements DesignPattern {
9 |
10 | String[] defaultClasses = {"Handler", "ConcreteHandler1","ConcreteHandler2"};
11 | String packageName = "com.BehavioralDP.chainOfResponsibility";
12 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
13 |
14 | public ChainOfResponsibility(int flag)throws IOException{
15 | logger.info("Executing ChainOfResponsibility()");
16 | if(flag == 1) {
17 | createDesignPattern(defaultClasses, packageName);
18 | }
19 | }
20 |
21 | public JavaFile[] generateCode(String[] classes, String packageName){
22 |
23 | int i = 0;
24 |
25 | // Handler class declaration
26 | ClassName Handler = ClassName.get("",classes[i]);
27 | MethodSpec handleReq = MethodSpec.methodBuilder("handleRequest")
28 | .addModifiers(Modifier.ABSTRACT)
29 | .returns(TypeName.VOID)
30 | .build();
31 | TypeSpec handler = TypeSpec.classBuilder(Handler)
32 | .addModifiers(Modifier.ABSTRACT)
33 | .addJavadoc("Handler interface, declares an interface for request handling")
34 | .addField(Handler,"successor",Modifier.PROTECTED)
35 | .addMethod(handleReq)
36 | .addMethod(MethodSpec.methodBuilder("setSuccessor")
37 | .addModifiers(Modifier.PUBLIC)
38 | .returns(TypeName.VOID)
39 | .addParameter(Handler,"successor")
40 | .addStatement("this.$N = $N","successor","successor")
41 | .build())
42 | .build();
43 | generatedCode[i] = JavaFile.builder(packageName,handler)
44 | .skipJavaLangImports(true)
45 | .build();
46 | i += 1;
47 |
48 | // ConcreteHandler1 class declaration
49 | ClassName ConcreteHandler1 = ClassName.get("",classes[i]);
50 | FieldSpec handleReqInv = FieldSpec.builder(Boolean.TYPE,"handleRequestInvoked")
51 | .addModifiers(Modifier.PRIVATE)
52 | .initializer("false")
53 | .build();
54 | MethodSpec isHandleReqInv = MethodSpec.methodBuilder("isHandleRequestInvoked")
55 | .addModifiers(Modifier.PROTECTED)
56 | .returns(Boolean.TYPE)
57 | .addStatement("return $N",handleReqInv.name)
58 | .build();
59 | TypeSpec concHandler1 = TypeSpec.classBuilder(ConcreteHandler1)
60 | .superclass(Handler)
61 | .addModifiers(Modifier.PUBLIC)
62 | .addJavadoc("ConcreteHandler1 class, handles the request, can access to the next object in " +
63 | "a chain and forward the request if necessary.")
64 | .addField(handleReqInv)
65 | .addMethod(MethodSpec.methodBuilder(handleReq.name)
66 | .returns(TypeName.VOID)
67 | .addStatement("$N = true",handleReqInv.name)
68 | .addCode("\n")
69 | .addComment("if some condition call handleRequest on successor")
70 | .beginControlFlow("if ($N)",handleReqInv.name)
71 | .addStatement("$N.$N()","successor",handleReq.name)
72 | .endControlFlow()
73 | .build())
74 | .addMethod(isHandleReqInv)
75 | .build();
76 | generatedCode[i] = JavaFile.builder(packageName,concHandler1)
77 | .skipJavaLangImports(true)
78 | .build();
79 | i += 1;
80 |
81 | // ConcreteHandler2 class declaration
82 | ClassName ConcreteHandler2 = ClassName.get("",classes[i]);
83 | TypeSpec concHandler2 = TypeSpec.classBuilder(ConcreteHandler2)
84 | .superclass(Handler)
85 | .addModifiers(Modifier.PUBLIC)
86 | .addJavadoc("ConcreteHandler2 class, handles the request, can access to the " +
87 | "next object in a chain" +
88 | " and forward the request if necessary.")
89 | .addField(handleReqInv)
90 | .addMethod(MethodSpec.methodBuilder(handleReq.name)
91 | .returns(TypeName.VOID)
92 | .addStatement("$N = true",handleReqInv.name)
93 | .build())
94 | .addMethod(isHandleReqInv)
95 | .build();
96 | generatedCode[i] = JavaFile.builder(packageName,concHandler2)
97 | .skipJavaLangImports(true)
98 | .build();
99 |
100 | return generatedCode;
101 |
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/src/main/java/com/Hw1DesignPatternGenerator.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | import com.behavioral.*;
4 | import com.creational.*;
5 | import com.structural.*;
6 | import ch.qos.logback.classic.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import java.io.IOException;
10 | import java.util.InputMismatchException;
11 | import java.util.Scanner;
12 |
13 | public class Hw1DesignPatternGenerator extends DesignPatternGenerator {
14 |
15 | //Define a static logger variable so that it references the Logger instance
16 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Hw1DesignPatternGenerator.class);
17 |
18 | private static Hw1DesignPatternGenerator instance;
19 |
20 | private Hw1DesignPatternGenerator(){
21 | logger.info("Executing constructor Hw1DesignPatternGenerator()");
22 | }
23 |
24 | public static Hw1DesignPatternGenerator getInstance(){
25 | logger.info("Creating instance of {}",Hw1DesignPatternGenerator.class.getSimpleName());
26 |
27 | if (instance == null) {
28 | instance = new Hw1DesignPatternGenerator();
29 | }
30 | return instance;
31 | }
32 |
33 | @Override
34 | protected void generateDesignPattern() throws IOException {
35 | logger.info("Entering generateDesignPattern()");
36 | Scanner sc = new Scanner(System.in);
37 | char c;
38 | do {
39 | displayDesignPatterns();
40 | designPatternFactory();
41 |
42 | System.out.print("\nDo you want to try again ? ");
43 | c = sc.next().toLowerCase().charAt(0);
44 | if(c != 'y') {
45 | System.out.println("\nExiting . . .");
46 | }
47 | }while(c == 'y');
48 | }
49 |
50 | @Override
51 | protected void designPatternFactory() throws IOException {
52 | logger.info("Executing designPatternFactory()");
53 | int mode = 1;
54 |
55 | Scanner sc = new Scanner(System.in);
56 | int choice = 0 ;
57 | try {
58 | System.out.print("\nEnter your choice of design pattern(1 to 23): ");
59 | choice = sc.nextInt();
60 | }
61 | catch (InputMismatchException e){
62 | logger.error("Exception {} encountered ", InputMismatchException.class.getSimpleName());
63 | // System.out.println(e);
64 | System.out.println("\nInvalid choice! Enter a valid numeric value. Try Again! \n");
65 | }
66 | logger.info("Passing {} to chooseDesignPattern()",choice);
67 |
68 | chooseDesignPattern(choice, mode);
69 | }
70 |
71 | @Override
72 | protected void displayDesignPatterns(){
73 | logger.info("Entering displayDesignPatterns()");
74 |
75 | System.out.println("\nThe design patterns available are: ");
76 |
77 | for (int i = 0; i < 7; i++) {
78 | System.out.print((i+1)+"-" + designPatterns[i] + "\t ");
79 | }
80 | System.out.println("\n");
81 | for (int i = 7; i < 14; i++) {
82 | System.out.print((i+1)+"-" + designPatterns[i] + "\t ");
83 | }
84 | System.out.println("\n");
85 | for (int i = 15; i < 23; i++) {
86 | System.out.print((i+1)+"-" + designPatterns[i] + "\t ");
87 | }
88 | System.out.println("\n");
89 | }
90 |
91 | protected DesignPattern chooseDesignPattern(int choice, int mode) throws IOException {
92 | logger.info("Entering chooseDesignPattern()");
93 | DesignPattern dp = null;
94 | switch (choice) {
95 | case 1 : dp = new Singleton(mode); break;
96 | case 2 : dp = new AbstractFactory(mode); break;
97 | case 3 : dp = new Builder(mode); break;
98 | case 4 : dp = new FactoryMethod(mode); break;
99 | case 5 : dp = new Prototype(mode); break;
100 | case 6 : dp = new Adapter(mode); break;
101 | case 7 : dp = new Bridge(mode); break;
102 | case 8 : dp = new Composite(mode); break;
103 | case 9 : dp = new Decorator(mode); break;
104 | case 10 : System.out.println("Facade"); break;
105 | case 11 : dp = new Flyweight(mode); break;
106 | case 12 : dp = new Proxy(mode); break;
107 | case 13 : dp = new ChainOfResponsibility(mode); break;
108 | case 14 : dp = new Command(mode); break;
109 | case 15 : dp = new Interpreter(mode); break;
110 | case 16 : dp = new Iterator(mode); break;
111 | case 17 : dp = new Mediator(mode); break;
112 | case 18 : dp = new Memento(mode); break;
113 | case 19 : dp = new Observer(mode); break;
114 | case 20 : dp = new State(mode); break;
115 | case 21 : dp = new Strategy(mode); break;
116 | case 22 : dp = new Visitor(mode); break;
117 | case 23 : dp = new TemplateMethod(mode); break;
118 | default : System.out.println("\nInvalid Choice! Input a choice from 1 to 23. Try again! \n");
119 |
120 | logger.info("Exiting chooseDesignPattern()");
121 | }
122 | return dp;
123 |
124 | }
125 | }
126 |
--------------------------------------------------------------------------------
/src/main/java/com/DesignPattern.java:
--------------------------------------------------------------------------------
1 | package com;
2 |
3 | import com.squareup.javapoet.JavaFile;
4 | import ch.qos.logback.classic.Logger;
5 | import org.slf4j.LoggerFactory;
6 | import java.io.File;
7 | import java.io.IOException;
8 | import java.util.Scanner;
9 |
10 | public interface DesignPattern {
11 |
12 | //Define a static logger variable so that it references the Logger instance
13 | Logger logger = (Logger) LoggerFactory.getLogger(DesignPattern.class);
14 |
15 | // to display all available design pattern that can be generated
16 | default void displayClassNames(String[] classes){
17 |
18 | for (String name: classes) {
19 | System.out.print(name + " \t ");
20 | }
21 | }
22 |
23 | // to set custom class names from user input
24 | default String[] setClassNames(String[] oldClasses){
25 |
26 | Scanner sc = new Scanner(System.in);
27 | int n = oldClasses.length;
28 | String[] newClasses = new String[n];
29 | System.out.print("\n\nDo you want custom class names(y/n) ? ");
30 | char c ;
31 | // do-while loop to make user inputs y or n
32 | do {
33 | c = sc.next().toLowerCase().charAt(0);
34 | if (c == 'y'){
35 | for (int i = 0; i< n; i++) {
36 | boolean check;
37 | // do-while loop to ask for input again if user inputs invalid class name
38 | do {
39 | System.out.print("\nEnter class name for "+ oldClasses[i]+" : ");
40 | // get class names from user
41 | newClasses[i] = sc.next();
42 | // checking if classname starts with a letter or not
43 | check = Character.isAlphabetic(newClasses[i].toLowerCase().charAt(0));
44 | logger.info("Checking if classname entered is valid");
45 | if(!check){
46 | logger.error("Invalid classname");
47 | System.out.println("\nInvalid class name! Class name must start with a letter.");
48 | System.out.print("Enter the class name again: \n");
49 | }
50 | }while (!check);
51 | }
52 | }else if (c == 'n'){
53 | // default class names set as new class names
54 | newClasses = oldClasses;
55 | }
56 | else {
57 | logger.error("Invalid input");
58 | System.out.print("\nInvalid choice! Enter only y/n. Please try again: ");
59 | }
60 |
61 | }while(c != 'y'&& c!='n');
62 | logger.info("Returning class names to createDesignPattern()");
63 | return newClasses;
64 | }
65 |
66 | // to set custom package name from user input
67 | default String setPackageName(String defaultPckgName){
68 |
69 | Scanner sc = new Scanner(System.in);
70 | String pckgName = null;
71 | System.out.print("\nDo you want custom package name for generated design pattern java files(y/n) ? ");
72 | char c ;
73 | // do-while loop to make user inputs y or n
74 | do {
75 | c = sc.next().toLowerCase().charAt(0);
76 | if (c == 'y'){
77 | System.out.print("\nPlease enter the package name: ");
78 | // get package name from user
79 | pckgName = sc.next();
80 | System.out.println("\n");
81 | } else if (c == 'n'){
82 | pckgName = defaultPckgName;
83 | }
84 | else {
85 | logger.error("Invalid input");
86 | System.out.print("\nInvalid choice! Enter only y/n. Please try again: ");
87 | }
88 |
89 | }while(c != 'y'&& c!='n');
90 | logger.info("Returning package name to createDesignPattern()");
91 | return pckgName;
92 | }
93 |
94 | // method implementation in child class which implements this interface
95 | JavaFile[] generateCode(String[] classes, String packageName);
96 |
97 | //method to write generated code as .java file
98 | default void writeJavaFiles(JavaFile[] files) throws IOException {
99 | for(JavaFile file : files){
100 | // System.out.println(file);
101 | file.writeTo(new File("outputs"));
102 | }
103 | logger.info("Written java code into output files ");
104 | }
105 |
106 | default void createDesignPattern(String[] oldClasses, String oldPackageName) throws IOException {
107 | logger.info("Entering createDesignPattern()");
108 |
109 | System.out.println("\nThe Design pattern will contain following classes: ");
110 | displayClassNames(oldClasses);
111 | String[] newClasses = setClassNames(oldClasses);
112 | String pckgName = setPackageName(oldPackageName);
113 |
114 | logger.info("Generating java code using JavaPoet");
115 | JavaFile[] code = generateCode(newClasses,pckgName);
116 |
117 | logger.info("Writing java code into output files");
118 | writeJavaFiles(code);
119 | System.out.println("\nThe following java files have been created: ");
120 | displayClassNames(newClasses);
121 | System.out.println("\n\nAt package name: " + pckgName);
122 | System.out.println("\n");
123 |
124 | logger.info("Exiting createDesignPattern()");
125 |
126 | }
127 |
128 |
129 | }
130 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Memento.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Memento implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Memento.class);
15 |
16 |
17 | String[] defaultClasses = {"Memento", "Caretaker","Originator"};
18 | String packageName = "com.BehavioralDP.memento";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public Memento(int flag)throws IOException{
22 | logger.info("Executing Memento()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 |
31 | int i = 0;
32 |
33 | // Memento class declaration
34 | ClassName Memento = ClassName.get("",classes[i]);
35 | FieldSpec state = FieldSpec.builder(int.class,"state")
36 | .addModifiers(Modifier.PRIVATE)
37 | .build();
38 | MethodSpec getstate = MethodSpec.methodBuilder("getState")
39 | .addModifiers(Modifier.PUBLIC)
40 | .returns(int.class)
41 | .addStatement("return $N", "state")
42 | .build();
43 | TypeSpec memento = TypeSpec.classBuilder(Memento)
44 | .addModifiers(Modifier.PUBLIC)
45 | .addJavadoc("Memento stores internal state of the Originator object, protects against\n" +
46 | "access by objects other than the Originator.")
47 | .addField(state)
48 | .addMethod(MethodSpec.constructorBuilder()
49 | .addModifiers(Modifier.PUBLIC)
50 | .addParameter(int.class,"state")
51 | .addStatement("this.$N = $N",state.name,"state")
52 | .build())
53 | .addMethod(getstate)
54 | .build();
55 | generatedCode[i] = JavaFile.builder(packageName, memento)
56 | .skipJavaLangImports(true)
57 | .build();
58 | i += 1;
59 |
60 | // Caretaker class declaration
61 | ClassName Caretaker = ClassName.get("",classes[i]);
62 | TypeSpec caretaker = TypeSpec.classBuilder(Caretaker)
63 | .addModifiers(Modifier.PUBLIC)
64 | .addJavadoc("Caretaker responsible for the Memento's safekeeping.")
65 | .addField(Memento, "memento",Modifier.PRIVATE)
66 | .addMethod(MethodSpec.methodBuilder("getMemento")
67 | .addModifiers(Modifier.PUBLIC)
68 | .returns(Memento)
69 | .addStatement("return $N","memento")
70 | .build())
71 | .addMethod(MethodSpec.methodBuilder("setMemento")
72 | .addModifiers(Modifier.PUBLIC)
73 | .returns(TypeName.VOID)
74 | .addParameter(Memento, "memento")
75 | .addStatement("this.$N = memento","memento")
76 | .build())
77 | .build();
78 | generatedCode[i] = JavaFile.builder(packageName,caretaker)
79 | .skipJavaLangImports(true)
80 | .build();
81 | i += 1;
82 |
83 | // Originator class declaration
84 | ClassName Originator = ClassName.get("",classes[i]);
85 | TypeSpec originator = TypeSpec.classBuilder(Originator)
86 | .addModifiers(Modifier.PUBLIC)
87 | .addJavadoc("Originator creates a Memento containing a snapshot of its current internal\n" +
88 | "state. Originator use Memento to restore its internal state.")
89 | .addField(state)
90 | .addMethod(MethodSpec.methodBuilder("setMemento")
91 | .addModifiers(Modifier.PUBLIC)
92 | .returns(TypeName.VOID)
93 | .addParameter(Memento, "memento")
94 | .addStatement("this.$N = $N.$N()",state.name,"memento",getstate.name)
95 | .build())
96 | .addMethod(MethodSpec.methodBuilder("createMemento")
97 | .addModifiers(Modifier.PUBLIC)
98 | .returns(Memento)
99 | .addStatement("return new $T(this.$N)",Memento,state.name)
100 | .build())
101 | .addMethod(getstate)
102 | .addMethod(MethodSpec.methodBuilder("setState")
103 | .addModifiers(Modifier.PUBLIC)
104 | .returns(TypeName.VOID)
105 | .addParameter(int.class, "state")
106 | .addStatement("this.$N = $N",state.name,"state")
107 | .build())
108 | .build();
109 | generatedCode[i] = JavaFile.builder(packageName,originator)
110 | .skipJavaLangImports(true)
111 | .build();
112 |
113 | logger.info("Returning generated java code to be written in files");
114 |
115 | return generatedCode;
116 | }
117 | }
118 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Command.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 | import java.io.IOException;
5 | import com.DesignPattern;
6 | import ch.qos.logback.classic.Logger;
7 | import org.slf4j.LoggerFactory;
8 |
9 | import javax.lang.model.element.Modifier;
10 |
11 | public class Command implements DesignPattern {
12 | //Define a static logger variable so that it references the Logger instance
13 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Command.class);
14 |
15 |
16 | String[] defaultClasses = {"Command", "Invoker","Receiver","ConcreteCommand"};
17 | String packageName = "com.BehavioralDP.command";
18 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
19 |
20 | public Command(int flag)throws IOException{
21 | logger.info("Executing Command()");
22 | if(flag == 1) {
23 | createDesignPattern(defaultClasses, packageName);
24 | } }
25 |
26 | public JavaFile[] generateCode(String[] classes, String packageName){
27 | logger.info("Executing generateCode()");
28 |
29 | int i = 0;
30 |
31 | // Command interface declaration
32 | ClassName Command = ClassName.get("",classes[i]);
33 | MethodSpec execute = MethodSpec.methodBuilder("execute")
34 | .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC)
35 | .returns(TypeName.VOID)
36 | .build();
37 | TypeSpec command = TypeSpec.interfaceBuilder(Command)
38 | .addModifiers(Modifier.PUBLIC)
39 | .addJavadoc("Command interface, declares an interface for executing an operation")
40 | .addMethod(execute)
41 | .build();
42 | generatedCode[i] = JavaFile.builder(packageName,command)
43 | .skipJavaLangImports(true)
44 | .build();
45 | i += 1;
46 |
47 | // Invoker class declaration
48 | ClassName Invoker = ClassName.get("",classes[i]);
49 | TypeSpec invoker = TypeSpec.classBuilder(Invoker)
50 | .addModifiers(Modifier.PUBLIC)
51 | .addJavadoc("Invoker class, asks the command to carry out the request")
52 | .addField(Command, "command", Modifier.PRIVATE)
53 | .addMethod(MethodSpec.constructorBuilder()
54 | .addModifiers(Modifier.PUBLIC)
55 | .addParameter(Command,"command")
56 | .addStatement("this.$N = command", "command")
57 | .build())
58 | .addMethod(MethodSpec.methodBuilder(execute.name)
59 | .addModifiers(Modifier.PUBLIC)
60 | .returns(TypeName.VOID)
61 | .addStatement("$N.$N()","command", execute.name)
62 | .build())
63 | .build();
64 | generatedCode[i] = JavaFile.builder(packageName,invoker)
65 | .skipJavaLangImports(true)
66 | .build();
67 | i += 1;
68 |
69 | // Receiver class declaration
70 | ClassName Receiver = ClassName.get("",classes[i]);
71 | FieldSpec opPerf = FieldSpec.builder(Boolean.TYPE,"operationPerfomed")
72 | .addModifiers(Modifier.PRIVATE)
73 | .initializer("false")
74 | .build();
75 | TypeSpec receiver = TypeSpec.classBuilder(Receiver)
76 | .addModifiers(Modifier.PUBLIC)
77 | .addJavadoc("Receiver class, knows how to perform the operations associated with carrying\n" +
78 | "out a request")
79 | .addField(opPerf)
80 | .addMethod(MethodSpec.methodBuilder("action")
81 | .addModifiers(Modifier.PUBLIC)
82 | .returns(TypeName.VOID)
83 | .addStatement("$N = true",opPerf.name)
84 | .build())
85 | .addMethod(MethodSpec.methodBuilder("isOperationPerfomed")
86 | .addModifiers(Modifier.PROTECTED)
87 | .returns(TypeName.BOOLEAN)
88 | .addStatement("return $N",opPerf.name)
89 | .build())
90 | .build();
91 | generatedCode[i] = JavaFile.builder(packageName,receiver)
92 | .skipJavaLangImports(true)
93 | .build();
94 | i += 1;
95 |
96 | // ConcreteCommand class declaration
97 | ClassName ConcreteCommand = ClassName.get("",classes[i]);
98 | TypeSpec concreteCommand = TypeSpec.classBuilder(ConcreteCommand)
99 | .addSuperinterface(Command)
100 | .addModifiers(Modifier.PUBLIC)
101 | .addJavadoc("ConcreteCommand class, defines a binding between a Receiver object and an\n" +
102 | "operation")
103 | .addField(Receiver, "receiver",Modifier.PRIVATE)
104 | .addMethod(MethodSpec.constructorBuilder()
105 | .addModifiers(Modifier.PUBLIC)
106 | .addParameter(Receiver, "receiver")
107 | .addStatement("this.$N = receiver","receiver")
108 | .build())
109 | .addMethod(MethodSpec.methodBuilder(execute.name)
110 | .addModifiers(Modifier.PUBLIC)
111 | .returns(TypeName.VOID)
112 | .addStatement("this.$N.$N()","receiver","action")
113 | .build())
114 | .build();
115 | generatedCode[i] = JavaFile.builder(packageName,concreteCommand)
116 | .skipJavaLangImports(true)
117 | .build();
118 |
119 | logger.info("Returning generated java code to be written in files");
120 |
121 | return generatedCode;
122 | }
123 | }
124 |
--------------------------------------------------------------------------------
/src/main/java/com/structural/Bridge.java:
--------------------------------------------------------------------------------
1 | package com.structural;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 | import com.DesignPattern;
7 | import ch.qos.logback.classic.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public class Bridge implements DesignPattern {
11 |
12 | //Define a static logger variable so that it references the Logger instance
13 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Bridge.class);
14 |
15 |
16 | String[] defaultClasses = {"Implementor", "ConcreteImplementorA","ConcreteImplementorB","Abstraction","RefinedAbstraction"};
17 | String packageName = "com.StructuralDP.bridge";
18 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
19 |
20 | public Bridge(int flag)throws IOException{
21 | logger.info("Executing Bridge()");
22 | if(flag == 1) {
23 | createDesignPattern(defaultClasses, packageName);
24 | }
25 | }
26 |
27 | public JavaFile[] generateCode(String[] classes, String packageName){
28 | int i = 0 ;
29 | logger.info("Executing generateCode()");
30 |
31 |
32 | // Implementor interface declaration
33 | ClassName Implementor = ClassName.get("",classes[i]);
34 | MethodSpec implementation = MethodSpec.methodBuilder("implementation")
35 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(String.class)
36 | .build();
37 | TypeSpec implementor = TypeSpec.interfaceBuilder(Implementor)
38 | .addModifiers(Modifier.PUBLIC)
39 | .addJavadoc("Implementor, defines interface for implementation")
40 | .addMethod(implementation)
41 | .build();
42 | generatedCode[i] = JavaFile.builder(packageName,implementor).skipJavaLangImports(true).build();
43 | i += 1;
44 |
45 | // ConcreteImplementorA class declaration
46 | ClassName ConcreteImplementorA = ClassName.get("",classes[i]);
47 | TypeSpec concImplementorA = TypeSpec.classBuilder(ConcreteImplementorA)
48 | .addModifiers(Modifier.PUBLIC)
49 | .addSuperinterface(Implementor)
50 | .addJavadoc("ConcreteImplementorA, implements Implementor interface")
51 | .addMethod(MethodSpec.methodBuilder(implementation.name)
52 | .addModifiers(Modifier.PUBLIC).returns(String.class)
53 | .addStatement("return this.getClass().getName()")
54 | .build())
55 | .build();
56 | generatedCode[i] = JavaFile.builder(packageName,concImplementorA).skipJavaLangImports(true).build();
57 | i += 1;
58 |
59 | // ConcreteImplementorB class declaration
60 | ClassName ConcreteImplementorB = ClassName.get("",classes[i]);
61 | TypeSpec concImplementorB = TypeSpec.classBuilder(ConcreteImplementorB)
62 | .addModifiers(Modifier.PUBLIC)
63 | .addSuperinterface(Implementor)
64 | .addJavadoc("ConcreteImplementorB, implements Implementor interface")
65 | .addMethod(MethodSpec.methodBuilder(implementation.name)
66 | .addModifiers(Modifier.PUBLIC).returns(String.class)
67 | .addStatement("return this.getClass().getName()")
68 | .build())
69 | .build();
70 | generatedCode[i] = JavaFile.builder(packageName,concImplementorB).skipJavaLangImports(true).build();
71 | i += 1;
72 |
73 | // Abstraction abstract class declaration
74 | ClassName Abstraction = ClassName.get("",classes[i]);
75 | FieldSpec implement = FieldSpec.builder(Implementor,"implementor",Modifier.PROTECTED).build();
76 | MethodSpec oper = MethodSpec.methodBuilder("operation")
77 | .addModifiers(Modifier.ABSTRACT).returns(String.class)
78 | .build();
79 | TypeSpec abstraction = TypeSpec.classBuilder(Abstraction)
80 | .addModifiers(Modifier.ABSTRACT)
81 | .addJavadoc("Abstraction, defines abstraction interface, maintains a reference to object of type Implementor")
82 | .addField(implement)
83 | .addMethod(MethodSpec.constructorBuilder()
84 | .addModifiers(Modifier.PUBLIC)
85 | .addParameter(Implementor,"implementor")
86 | .addStatement("this.$N = implementor",implement.name)
87 | .build())
88 | .addMethod(oper)
89 | .build();
90 | generatedCode[i] = JavaFile.builder(packageName,abstraction).skipJavaLangImports(true).build();
91 | i += 1;
92 |
93 | // RefinedAbstraction class declaration
94 | ClassName RefinedAbstraction = ClassName.get("",classes[i]);
95 | TypeSpec refAbstraction = TypeSpec.classBuilder(RefinedAbstraction)
96 | .addModifiers(Modifier.PUBLIC)
97 | .superclass(Abstraction)
98 | .addJavadoc("Refined Abstraction, extends the interface defined by Abstraction")
99 | .addMethod(MethodSpec.constructorBuilder()
100 | .addModifiers(Modifier.PUBLIC)
101 | .addParameter(Implementor,"implementor")
102 | .addStatement("super(implementor)",implement.name)
103 | .build())
104 | .addMethod(MethodSpec.methodBuilder("operation")
105 | .addModifiers(Modifier.PUBLIC).returns(String.class)
106 | .addStatement("return this.$N.$N()",implement.name,implementation.name)
107 | .build())
108 | .build();
109 | generatedCode[i] = JavaFile.builder(packageName,refAbstraction).skipJavaLangImports(true).build();
110 |
111 | logger.info("Returning generated java code to be written in files");
112 |
113 | return generatedCode;
114 | }
115 | }
116 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Strategy.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Strategy implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Strategy.class);
15 |
16 |
17 | String[] defaultClasses = {"Strategy", "Context","ConcreteStrategyA","ConcreteStrategyB","ConcreteStrategyC"};
18 | String packageName = "com.BehavioralDP.strategy";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public Strategy(int flag)throws IOException{
22 | logger.info("Executing Strategy()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 |
31 | int i = 0;
32 |
33 | // Strategy interface declaration
34 | ClassName Strategy = ClassName.get("",classes[i]);
35 | MethodSpec algoInterface = MethodSpec.methodBuilder("algorithmInterface")
36 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
37 | .returns(String.class)
38 | .build();
39 | TypeSpec strategy = TypeSpec.interfaceBuilder(Strategy)
40 | .addModifiers(Modifier.PUBLIC)
41 | .addJavadoc("Declares an interface common to all supported algorithms. Context uses this interface to call the algorithm\n" +
42 | "defined by a ConcreteStrategy.")
43 | .addMethod(algoInterface)
44 | .build();
45 | generatedCode[i] = JavaFile.builder(packageName,strategy)
46 | .skipJavaLangImports(true)
47 | .build();
48 | i += 1;
49 |
50 | // Context class declaration
51 | ClassName Context = ClassName.get("",classes[i]);
52 | FieldSpec strategyField = FieldSpec.builder(Strategy,"strategy",Modifier.PRIVATE).build();
53 | TypeSpec context = TypeSpec.classBuilder(Context)
54 | .addModifiers(Modifier.PUBLIC)
55 | .addJavadoc(" Maintains a reference to a Strategy object. Invokes algorithm implemented in ConcreteStrategy.")
56 | .addField(strategyField)
57 | .addMethod(MethodSpec.constructorBuilder()
58 | .addModifiers(Modifier.PUBLIC)
59 | .addParameter(Strategy, "strategy")
60 | .addStatement("this.$N = strategy",strategyField.name)
61 | .build())
62 | .addMethod(MethodSpec.methodBuilder("contextInterface")
63 | .addModifiers(Modifier.PROTECTED).returns(String.class)
64 | .addStatement("return this.$N.$N()",strategyField.name,algoInterface.name)
65 | .build())
66 | .build();
67 | generatedCode[i] = JavaFile.builder(packageName,context)
68 | .skipJavaLangImports(true)
69 | .build();
70 | i += 1;
71 |
72 | // ConcreteStrategyA class declaration
73 | ClassName ConcreteStrategyA = ClassName.get("",classes[i]);
74 | TypeSpec concStratA = TypeSpec.classBuilder(ConcreteStrategyA)
75 | .addSuperinterface(Strategy)
76 | .addModifiers(Modifier.PUBLIC)
77 | .addJavadoc("Implements the algorithm defined in Strategy interface.")
78 | .addMethod(MethodSpec.methodBuilder(algoInterface.name)
79 | .addModifiers(Modifier.PUBLIC)
80 | .returns(String.class)
81 | .addStatement("return $S","Inside ConcreteStrategyA to invoke Algorithm A")
82 | .build())
83 | .build();
84 | generatedCode[i] = JavaFile.builder(packageName,concStratA)
85 | .skipJavaLangImports(true)
86 | .build();
87 | i += 1;
88 |
89 | // ConcreteStrategyB class declaration
90 | ClassName ConcreteStrategyB = ClassName.get("",classes[i]);
91 | TypeSpec concStratB = TypeSpec.classBuilder(ConcreteStrategyB)
92 | .addSuperinterface(Strategy)
93 | .addModifiers(Modifier.PUBLIC)
94 | .addJavadoc("Implements the algorithm defined in Strategy interface.")
95 | .addMethod(MethodSpec.methodBuilder(algoInterface.name)
96 | .addModifiers(Modifier.PUBLIC)
97 | .returns(String.class)
98 | .addStatement("return $S","Inside ConcreteStrategyB to invoke Algorithm B")
99 | .build())
100 | .build();
101 | generatedCode[i] = JavaFile.builder(packageName,concStratB)
102 | .skipJavaLangImports(true)
103 | .build();
104 | i += 1;
105 |
106 | // ConcreteStrategyC class declaration
107 | ClassName ConcreteStrategyC = ClassName.get("",classes[i]);
108 | TypeSpec concStratC = TypeSpec.classBuilder(ConcreteStrategyC)
109 | .addSuperinterface(Strategy)
110 | .addModifiers(Modifier.PUBLIC)
111 | .addJavadoc("Implements the algorithm defined in Strategy interface.")
112 | .addMethod(MethodSpec.methodBuilder(algoInterface.name)
113 | .addModifiers(Modifier.PUBLIC)
114 | .returns(String.class)
115 | .addStatement("return $S","Inside ConcreteStrategyC to invoke Algorithm C")
116 | .build())
117 | .build();
118 | generatedCode[i] = JavaFile.builder(packageName,concStratC)
119 | .skipJavaLangImports(true)
120 | .build();
121 |
122 | logger.info("Returning generated java code to be written in files");
123 |
124 | return generatedCode;
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/src/main/java/com/structural/Decorator.java:
--------------------------------------------------------------------------------
1 | package com.structural;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 | import com.DesignPattern;
7 | import ch.qos.logback.classic.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public class Decorator implements DesignPattern {
11 | //Define a static logger variable so that it references the Logger instance
12 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Decorator.class);
13 |
14 | String[] defaultClasses = {"Component","ConcreteComponent","Decorator","ConcreteDecoratorA","ConcreteDecoratorB"};
15 | String packageName = "com.StructuralDP.decorator";
16 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
17 |
18 | public Decorator(int flag)throws IOException{
19 | logger.info("Executing Decorator()");
20 | if(flag == 1) {
21 | createDesignPattern(defaultClasses, packageName);
22 | }
23 | }
24 |
25 | public JavaFile[] generateCode(String[] classes, String packageName){
26 | int i = 0;
27 | logger.info("Executing generateCode()");
28 |
29 | // Component interface declaration
30 | ClassName Component = ClassName.get("",classes[i]);
31 | MethodSpec oper = MethodSpec.methodBuilder("operation")
32 | .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC).returns(TypeName.VOID)
33 | .build();
34 | TypeSpec component = TypeSpec.interfaceBuilder(Component)
35 | .addModifiers(Modifier.PUBLIC)
36 | .addJavadoc("Component, defines interface for new features which will be added dynamically")
37 | .addMethod(oper)
38 | .build();
39 | generatedCode[i] = JavaFile.builder(packageName,component)
40 | .skipJavaLangImports(true)
41 | .build();
42 | i += 1;
43 |
44 | // ConcreteComponent class declaration
45 | ClassName ConcreteComponent = ClassName.get("",classes[i]);
46 | TypeSpec concComponent = TypeSpec.classBuilder(ConcreteComponent)
47 | .addModifiers(Modifier.PUBLIC)
48 | .addSuperinterface(Component)
49 | .addJavadoc("ConcreteComponent, define object where new features can be added")
50 | .addMethod(MethodSpec.methodBuilder(oper.name)
51 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
52 | .build())
53 | .build();
54 | generatedCode[i] = JavaFile.builder(packageName,concComponent)
55 | .skipJavaLangImports(true)
56 | .build();
57 | i += 1;
58 |
59 | // Decorator abstract class declaration
60 | ClassName Decorator = ClassName.get("",classes[i]);
61 | FieldSpec compo = FieldSpec.builder(Component, "component",Modifier.PROTECTED).build();
62 | TypeSpec decorator = TypeSpec.classBuilder(Decorator)
63 | .addModifiers(Modifier.ABSTRACT)
64 | .addSuperinterface(Component)
65 | .addJavadoc("Decorator, keep reference to Component object")
66 | .addField(compo)
67 | .addMethod(MethodSpec.methodBuilder(oper.name)
68 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.VOID)
69 | .build())
70 | .addMethod(MethodSpec.methodBuilder("setComponent")
71 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
72 | .addParameter(Component, "component")
73 | .addStatement("this.$N = component",compo.name)
74 | .build())
75 | .build();
76 | generatedCode[i] = JavaFile.builder(packageName,decorator)
77 | .skipJavaLangImports(true)
78 | .build();
79 | i += 1;
80 |
81 | // ConcreteDecoratorA class declaration
82 | ClassName ConcreteDecoratorA = ClassName.get("",classes[i]);
83 | FieldSpec state = FieldSpec.builder(Boolean.TYPE, "state",Modifier.PRIVATE).build();
84 | TypeSpec concDecoA = TypeSpec.classBuilder(ConcreteDecoratorA)
85 | .addModifiers(Modifier.PUBLIC)
86 | .superclass(Decorator)
87 | .addJavadoc("ConcreteDecoratorA, add features to component")
88 | .addField(state)
89 | .addMethod(MethodSpec.methodBuilder(oper.name)
90 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
91 | .addStatement("$N = true",state.name)
92 | .addStatement("this.$N.$N()",compo.name,oper.name)
93 | .build())
94 | .addMethod(MethodSpec.methodBuilder("isState")
95 | .addModifiers(Modifier.PUBLIC).returns(TypeName.BOOLEAN)
96 | .addStatement("return $N",state.name)
97 | .build())
98 | .build();
99 | generatedCode[i] = JavaFile.builder(packageName,concDecoA)
100 | .skipJavaLangImports(true)
101 | .build();
102 | i += 1;
103 |
104 | // ConcreteDecoratorB class declaration
105 | ClassName ConcreteDecoratorB = ClassName.get("",classes[i]);
106 | FieldSpec behMethInvok = FieldSpec.builder(Boolean.TYPE, "behaviorMethodInvoked",Modifier.PRIVATE)
107 | .initializer("false").build();
108 | MethodSpec addBehav = MethodSpec.methodBuilder("addedBehavior")
109 | .addModifiers(Modifier.PRIVATE).returns(TypeName.VOID)
110 | .addStatement("$N = true", behMethInvok.name)
111 | .build();
112 | TypeSpec concDecoB = TypeSpec.classBuilder(ConcreteDecoratorB)
113 | .addModifiers(Modifier.PUBLIC)
114 | .superclass(Decorator)
115 | .addJavadoc("ConcreteDecoratorB, add features to component")
116 | .addField(behMethInvok)
117 | .addMethod(MethodSpec.methodBuilder(oper.name)
118 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
119 | .addStatement("this.$N.$N()",compo.name,oper.name)
120 | .addStatement("$N()",addBehav.name)
121 | .build())
122 | .addMethod(addBehav)
123 | .addMethod(MethodSpec.methodBuilder("isBehaviorMethodInvoked")
124 | .addModifiers(Modifier.PROTECTED).returns(TypeName.BOOLEAN)
125 | .addStatement("return $N", behMethInvok.name)
126 | .build())
127 | .build();
128 | generatedCode[i] = JavaFile.builder(packageName,concDecoB)
129 | .skipJavaLangImports(true)
130 | .build();
131 |
132 | logger.info("Returning generated java code to be written in files");
133 |
134 | return generatedCode;
135 |
136 | }
137 |
138 | }
139 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Observer.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Observer implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Observer.class);
15 |
16 |
17 | String[] defaultClasses = {"Observer", "Subject","ConcreteSubject","ConcreteObserver"};
18 | String packageName = "com.BehavioralDP.observer";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public Observer(int flag)throws IOException{
22 | logger.info("Executing Observer()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 |
31 | int i = 0;
32 |
33 | // Observer interface declaration
34 | ClassName Observer = ClassName.get("",classes[i]);
35 | MethodSpec update = MethodSpec.methodBuilder("update")
36 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.VOID)
37 | .build();
38 | TypeSpec component = TypeSpec.interfaceBuilder(Observer)
39 | .addModifiers(Modifier.PUBLIC)
40 | .addJavadoc("Observer defines an updating interface for objects that should be notified of changes in a subject.")
41 | .addMethod(update)
42 | .build();
43 | generatedCode[i] = JavaFile.builder(packageName,component)
44 | .skipJavaLangImports(true)
45 | .build();
46 | i += 1;
47 |
48 | // Subject class declaration
49 | ClassName Subject = ClassName.get("",classes[i]);
50 | ClassName list = ClassName.get("java.util", "List");
51 | ClassName arrayList = ClassName.get("java.util", "ArrayList");
52 | ClassName Iterator = ClassName.get("java.util","Iterator");
53 | TypeName listOfObservers = ParameterizedTypeName.get(list,Observer);
54 |
55 | FieldSpec obs = FieldSpec.builder(listOfObservers,"observers",Modifier.PRIVATE)
56 | .initializer("new $T<$T>()",arrayList,Observer)
57 | .build();
58 | MethodSpec notifyObs = MethodSpec.methodBuilder("notifyObservers")
59 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
60 | .beginControlFlow("($T iterator = $N.iterator(); iterator.hasNext();)",Iterator,obs.name)
61 | .addStatement("$T observer = ($T) iterator.next()",Observer,Observer)
62 | .addStatement("observer.$N()",update.name)
63 | .endControlFlow()
64 | .build();
65 | TypeSpec subject = TypeSpec.classBuilder(Subject)
66 | .addModifiers(Modifier.ABSTRACT)
67 | .addJavadoc("Subject knows its observers. Any number of Observer objects may observe a subject.")
68 | .addField(obs)
69 | .addMethod(MethodSpec.methodBuilder("attach")
70 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
71 | .addParameter(Observer,"observer")
72 | .addStatement("$N.add(observer)",obs.name)
73 | .build())
74 | .addMethod(MethodSpec.methodBuilder("detach")
75 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
76 | .addParameter(Observer,"observer")
77 | .addStatement("$N.remove(observer)",obs.name)
78 | .build())
79 | .addMethod(notifyObs)
80 | .build();
81 | generatedCode[i] = JavaFile.builder(packageName,subject)
82 | .skipJavaLangImports(true).build();
83 | i += 1;
84 |
85 | // ConcreteSubject class declaration
86 | ClassName ConcreteSubject = ClassName.get("",classes[i]);
87 | FieldSpec state = FieldSpec.builder(int.class,"state",Modifier.PRIVATE).build();
88 | MethodSpec getstate = MethodSpec.methodBuilder("getState")
89 | .addModifiers(Modifier.PUBLIC).returns(int.class)
90 | .addStatement("return $N", state.name)
91 | .build();
92 | TypeSpec concSub = TypeSpec.classBuilder(ConcreteSubject)
93 | .superclass(Subject)
94 | .addModifiers(Modifier.PUBLIC)
95 | .addJavadoc("ConcreteSubject stores state of interest to ConcreteObserver objects, sends a notification to its observers\n" +
96 | "when its state changes.")
97 | .addField(state)
98 | .addMethod(getstate)
99 | .addMethod(MethodSpec.methodBuilder("setState")
100 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
101 | .addParameter(int.class, "state")
102 | .addStatement("this.$N = state",state.name)
103 | .addStatement("this.$N()",notifyObs.name)
104 | .build())
105 | .build();
106 | generatedCode[i] = JavaFile.builder(packageName,concSub)
107 | .skipJavaLangImports(true).build();
108 | i += 1;
109 |
110 | // ConcreteObserver class declaration
111 | ClassName ConcreteObserver = ClassName.get("",classes[i]);
112 | FieldSpec obsState = FieldSpec.builder(int.class, "observerState",Modifier.PRIVATE).build();
113 | FieldSpec subjectField = FieldSpec.builder(ConcreteSubject, "subject",Modifier.PRIVATE).build();
114 | TypeSpec concObs = TypeSpec.classBuilder(ConcreteObserver)
115 | .addModifiers(Modifier.PUBLIC)
116 | .addSuperinterface(Observer)
117 | .addJavadoc("ConcreteObserver maintains a reference to a ConcreteSubject object, stores\n" +
118 | "state that should stay consistent with the subject's, implements the Observer\n" +
119 | "updating interface to keep its state consistent with the subject's.")
120 | .addField(obsState)
121 | .addField(subjectField)
122 | .addMethod(MethodSpec.constructorBuilder()
123 | .addModifiers(Modifier.PUBLIC)
124 | .addParameter(ConcreteSubject, "subject")
125 | .addStatement("this.$N = subject",subjectField.name)
126 | .build())
127 | .addMethod(MethodSpec.methodBuilder("update")
128 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
129 | .addStatement("$N = subject.$N()",obsState.name,getstate.name)
130 | .build())
131 | .addMethod(MethodSpec.methodBuilder("getObserverState")
132 | .addModifiers(Modifier.PROTECTED).returns(int.class)
133 | .addStatement("return $N",obsState.name)
134 | .build())
135 | .build();
136 | generatedCode[i] = JavaFile.builder(packageName,concObs)
137 | .skipJavaLangImports(true).build();
138 |
139 | logger.info("Returning generated java code to be written in files");
140 |
141 | return generatedCode;
142 |
143 | }
144 | }
145 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Iterator.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 |
12 | public class Iterator implements DesignPattern {
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Iterator.class);
15 |
16 |
17 | String[] defaultClasses = {"Iterator", "Aggregate","ConcreteAggregate","ConcreteIterator"};
18 | String packageName = "com.BehavioralDP.iterator";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public Iterator(int flag)throws IOException{
22 | logger.info("Executing Iterator()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 |
31 | // Observer interface declaration
32 | ClassName Iterator = ClassName.get("",classes[0]);
33 | ClassName ConcreteIterator = ClassName.get("",classes[3]);
34 | MethodSpec first = MethodSpec.methodBuilder("first")
35 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.OBJECT)
36 | .build();
37 | MethodSpec next = MethodSpec.methodBuilder("next")
38 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.OBJECT)
39 | .build();
40 | MethodSpec isDone = MethodSpec.methodBuilder("isDone")
41 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.BOOLEAN)
42 | .build();
43 | MethodSpec currentItem = MethodSpec.methodBuilder("currentItem")
44 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.OBJECT)
45 | .build();
46 | TypeSpec iterator = TypeSpec.interfaceBuilder(Iterator)
47 | .addModifiers(Modifier.PUBLIC)
48 | .addJavadoc("Iterator defines an interface for accessing and traversing elements.")
49 | .addMethod(first)
50 | .addMethod(next)
51 | .addMethod(isDone)
52 | .addMethod(currentItem)
53 | .build();
54 | generatedCode[0] = JavaFile.builder(packageName,iterator)
55 | .skipJavaLangImports(true)
56 | .build();
57 |
58 | // Aggregate interface declaration
59 | ClassName Aggregate = ClassName.get("",classes[1]);
60 | MethodSpec createIterator = MethodSpec.methodBuilder("createIterator")
61 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(Iterator)
62 | .build();
63 | TypeSpec aggregate = TypeSpec.interfaceBuilder(Aggregate)
64 | .addModifiers(Modifier.PUBLIC)
65 | .addJavadoc("Aggregate defines an interface for creating an Iterator object.")
66 | .addMethod(createIterator)
67 | .build();
68 | generatedCode[1] = JavaFile.builder(packageName,aggregate)
69 | .skipJavaLangImports(true)
70 | .build();
71 |
72 | // ConcreteAggregate class declaration
73 | ClassName ConcreteAggregate = ClassName.get("",classes[2]);
74 | // String[] stringRecords = { "first", "second", "third", "fourth" };
75 | FieldSpec records = FieldSpec.builder(String[].class,"records",Modifier.FINAL,Modifier.PRIVATE)
76 | .initializer(" { \"first\", \"second\", \"third\", \"fourth\" }")
77 | .build();
78 | MethodSpec getRecords= MethodSpec.methodBuilder("getRecords")
79 | .addModifiers(Modifier.PROTECTED).returns(String[].class)
80 | .addStatement("return $N", records.name)
81 | .build();
82 | TypeSpec concreteAggregate = TypeSpec.classBuilder(ConcreteAggregate)
83 | .addSuperinterface(Aggregate)
84 | .addModifiers(Modifier.PUBLIC)
85 | .addJavadoc("ConcreteAggregate implements the Iterator creation interface to return an instance of the proper ConcreteIterator.")
86 | .addField(records)
87 | .addMethod(MethodSpec.methodBuilder(createIterator.name)
88 | .addModifiers(Modifier.PUBLIC).returns(Iterator)
89 | .addStatement("return new $T(this)", ConcreteIterator)
90 | .build())
91 | .addMethod(getRecords)
92 | .build();
93 | generatedCode[2] = JavaFile.builder(packageName,concreteAggregate)
94 | .skipJavaLangImports(true).build();
95 |
96 |
97 | // ConcreteIterator class declaration
98 | FieldSpec concAgg = FieldSpec.builder(ConcreteAggregate,"concreteAggregate",Modifier.PRIVATE)
99 | .build();
100 | FieldSpec index = FieldSpec.builder(int.class,"index",Modifier.PRIVATE)
101 | .initializer("-1")
102 | .build();
103 | TypeSpec concreteIterator = TypeSpec.classBuilder(ConcreteIterator)
104 | .addSuperinterface(Iterator)
105 | .addModifiers(Modifier.PUBLIC)
106 | .addJavadoc("ConcreteIterator implements the Iterator interface. Keeps track of the current position in the traversal of the aggregate.")
107 | .addField(concAgg)
108 | .addField(index)
109 | .addMethod(MethodSpec.constructorBuilder()
110 | .addModifiers(Modifier.PUBLIC)
111 | .addParameter(ConcreteAggregate, "concreteAggregate")
112 | .addStatement("this.$N = concreteAggregate",concAgg.name)
113 | .build())
114 | .addMethod(MethodSpec.methodBuilder(first.name)
115 | .addModifiers(Modifier.PUBLIC).returns(TypeName.OBJECT)
116 | .addStatement("$N = 0",index.name)
117 | .addStatement("return $N.$N()[$N]",concAgg.name,getRecords.name,index.name)
118 | .build())
119 | .addMethod(MethodSpec.methodBuilder(next.name)
120 | .addModifiers(Modifier.PUBLIC).returns(TypeName.OBJECT)
121 | .addStatement("$N++",index.name)
122 | .addStatement("return $N.$N()[$N]",concAgg.name,getRecords.name,index.name)
123 | .build())
124 | .addMethod(MethodSpec.methodBuilder(isDone.name)
125 | .addModifiers(Modifier.PUBLIC).returns(TypeName.BOOLEAN)
126 | .beginControlFlow("if ($N.$N().length == ($N + 1))",concAgg.name,getRecords.name,index.name)
127 | .addStatement("return true")
128 | .endControlFlow()
129 | .addStatement("return false")
130 | .build())
131 | .addMethod(MethodSpec.methodBuilder(currentItem.name)
132 | .addModifiers(Modifier.PUBLIC).returns(TypeName.OBJECT)
133 | .addStatement("return $N.$N()[$N]",concAgg.name,getRecords.name,index.name)
134 | .build())
135 | .build();
136 | generatedCode[3] = JavaFile.builder(packageName,concreteIterator)
137 | .skipJavaLangImports(true).build();
138 |
139 | logger.info("Returning generated java code to be written in files");
140 |
141 | return generatedCode;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/main/java/com/creational/AbstractFactory.java:
--------------------------------------------------------------------------------
1 | package com.creational;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class AbstractFactory implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(AbstractFactory.class);
15 |
16 | String[] defaultClasses = {"AbstractProductA","ProductA1","ProductA2","AbstractProductB","ProductB1","ProductB2",
17 | "AbstractFactory","ConcreteFactory1","ConcreteFactory2"};
18 | String packageName = "com.CreationalDP.abstractFactory";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public AbstractFactory(int flag)throws IOException {
22 | logger.info("Executing AbstractFactory()");
23 | if (flag == 1){
24 | createDesignPattern(defaultClasses,packageName);
25 | }
26 | }
27 |
28 | @Override
29 | public JavaFile[] generateCode(String[] classes, String packageName){
30 | logger.info("Executing generateCode()");
31 |
32 | int i = 0;
33 | // AbstractProductA interface declaration
34 | ClassName AbstractProductA = ClassName.get("",classes[i]);
35 | TypeSpec abstProductA = TypeSpec.interfaceBuilder(AbstractProductA)
36 | .addModifiers(Modifier.PUBLIC)
37 | .addJavadoc("AbstractProductA defines interface for ProductA objects")
38 | .build();
39 | generatedCode[i] = JavaFile.builder(packageName,abstProductA)
40 | .skipJavaLangImports(true)
41 | .build();
42 | i += 1;
43 |
44 | // ProductA1 class declaration
45 | ClassName ProductA1 = ClassName.get("",classes[i]);
46 | TypeSpec prodA1 = TypeSpec.classBuilder(ProductA1)
47 | .addModifiers(Modifier.PUBLIC)
48 | .addSuperinterface(AbstractProductA)
49 | .addJavadoc("ProductA1, implements AbstractProductA interface")
50 | .build();
51 | generatedCode[i] = JavaFile.builder(packageName,prodA1)
52 | .skipJavaLangImports(true)
53 | .build();
54 | i += 1;
55 |
56 | // ProductA2 class declaration
57 | ClassName ProductA2 = ClassName.get("",classes[i]);
58 | TypeSpec prodA2 = TypeSpec.classBuilder(ProductA2)
59 | .addModifiers(Modifier.PUBLIC)
60 | .addSuperinterface(AbstractProductA)
61 | .addJavadoc("ProductA2, implements AbstractProductA interface")
62 | .build();
63 | generatedCode[i] = JavaFile.builder(packageName,prodA2)
64 | .skipJavaLangImports(true)
65 | .build();
66 | i += 1;
67 |
68 | // AbstractProductB interface declaration
69 | ClassName AbstractProductB = ClassName.get("",classes[i]);
70 | TypeSpec abstProductB = TypeSpec.interfaceBuilder(AbstractProductB)
71 | .addModifiers(Modifier.PUBLIC)
72 | .addJavadoc("AbstractProductB defines interface for ProductB objects")
73 | .build();
74 | generatedCode[i] = JavaFile.builder(packageName,abstProductB)
75 | .skipJavaLangImports(true)
76 | .build();
77 | i += 1;
78 |
79 | // ProductB1 class declaration
80 | ClassName ProductB1 = ClassName.get("",classes[i]);
81 | TypeSpec prodB1 = TypeSpec.classBuilder(ProductB1)
82 | .addModifiers(Modifier.PUBLIC)
83 | .addSuperinterface(AbstractProductB)
84 | .addJavadoc("ProductB1, implements AbstractProductB interface")
85 | .build();
86 | generatedCode[i] = JavaFile.builder(packageName,prodB1)
87 | .skipJavaLangImports(true)
88 | .build();
89 | i += 1;
90 |
91 | // ProductB2 class declaration
92 | ClassName ProductB2 = ClassName.get("",classes[i]);
93 | TypeSpec prodB2 = TypeSpec.classBuilder(ProductB2)
94 | .addModifiers(Modifier.PUBLIC)
95 | .addSuperinterface(AbstractProductB)
96 | .addJavadoc("ProductB1, implements AbstractProductB interface")
97 | .build();
98 | generatedCode[i] = JavaFile.builder(packageName,prodB2)
99 | .skipJavaLangImports(true)
100 | .build();
101 | i += 1;
102 |
103 | // AbstractFactory interface declaration
104 | ClassName AbstractFactory = ClassName.get("",classes[i]);
105 | MethodSpec createProdA = MethodSpec.methodBuilder("create" + classes[0])
106 | .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC)
107 | .returns(AbstractProductA)
108 | .build();
109 | MethodSpec createProdB = MethodSpec.methodBuilder("create" + classes[3] )
110 | .addModifiers(Modifier.ABSTRACT,Modifier.PUBLIC)
111 | .returns(AbstractProductB)
112 | .build();
113 | TypeSpec abstractFactory = TypeSpec.interfaceBuilder(AbstractFactory)
114 | .addModifiers(Modifier.PUBLIC)
115 | .addJavadoc("Abstract Factory, defines interface for creation of the abstract product objects")
116 | .addMethod(createProdA)
117 | .addMethod(createProdB)
118 | .build();
119 | generatedCode[i] = JavaFile.builder(packageName,abstractFactory)
120 | .skipJavaLangImports(true)
121 | .build();
122 | i += 1;
123 |
124 | // ConcreteFactory1 interface declaration
125 | ClassName ConcreteFactory1 = ClassName.get("",classes[i]);
126 | TypeSpec concFactory1 = TypeSpec.classBuilder(ConcreteFactory1)
127 | .addModifiers(Modifier.PUBLIC)
128 | .addSuperinterface(AbstractFactory)
129 | .addJavadoc("ConcreteFactory1, implements creation of the concrete Product1 objects")
130 | .addMethod(MethodSpec.methodBuilder(createProdA.name)
131 | .addModifiers(Modifier.PUBLIC)
132 | .returns(AbstractProductA)
133 | .addStatement("return new $N()", prodA1.name)
134 | .build())
135 | .addMethod(MethodSpec.methodBuilder(createProdB.name)
136 | .addModifiers(Modifier.PUBLIC)
137 | .returns(AbstractProductB)
138 | .addStatement("return new $N()", prodB1.name)
139 | .build())
140 | .build();
141 | generatedCode[i] = JavaFile.builder(packageName,concFactory1)
142 | .skipJavaLangImports(true)
143 | .build();
144 | i += 1;
145 |
146 | // ConcreteFactory2 interface declaration
147 | ClassName ConcreteFactory2 = ClassName.get("",classes[i]);
148 | TypeSpec concFactory2 = TypeSpec.classBuilder(ConcreteFactory2)
149 | .addModifiers(Modifier.PUBLIC)
150 | .addSuperinterface(AbstractFactory)
151 | .addJavadoc("ConcreteFactory2, implements creation of the concrete Product2 objects")
152 | .addMethod(MethodSpec.methodBuilder(createProdA.name)
153 | .addModifiers(Modifier.PUBLIC)
154 | .returns(AbstractProductA)
155 | .addStatement("return new $N()", prodA2.name)
156 | .build())
157 | .addMethod(MethodSpec.methodBuilder(createProdB.name)
158 | .addModifiers(Modifier.PUBLIC)
159 | .returns(AbstractProductB)
160 | .addStatement("return new $N()", prodB2.name)
161 | .build())
162 | .build();
163 | generatedCode[i] = JavaFile.builder(packageName,concFactory2)
164 | .skipJavaLangImports(true)
165 | .build();
166 |
167 | logger.info("Returning generated java code to be written in files");
168 |
169 | return generatedCode;
170 | }
171 |
172 | }
173 |
--------------------------------------------------------------------------------
/src/main/java/com/creational/Builder.java:
--------------------------------------------------------------------------------
1 | package com.creational;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 | import com.DesignPattern;
7 | import ch.qos.logback.classic.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 |
11 | public class Builder implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Builder.class);
15 |
16 | String[] defaultClasses = {"Builder", "Director","Product","concreteBuilder"};
17 | String packageName = "com.CreationalDP.builder";
18 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
19 |
20 | public Builder(int flag)throws IOException{
21 | logger.info("Executing Builder()");
22 |
23 | if (flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | @Override
29 | public JavaFile[] generateCode(String[] classes, String packageName){
30 |
31 | logger.info("Executing generateCode()");
32 |
33 | int i = 0;
34 |
35 | // Abstract Builder class declaration
36 | ClassName Builder = ClassName.get("",classes[i]);
37 |
38 | MethodSpec createProduct = MethodSpec.methodBuilder("createProduct")
39 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
40 | .returns(Builder)
41 | .build();
42 |
43 | MethodSpec buildPart1 = MethodSpec.methodBuilder("buildPart1")
44 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
45 | .returns(Builder)
46 | .addParameter(String.class, "part")
47 | .build();
48 |
49 | MethodSpec buildPart2 = MethodSpec.methodBuilder("buildPart2")
50 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
51 | .returns(Builder)
52 | .addParameter(String.class, "part")
53 | .build();
54 |
55 | TypeSpec builder = TypeSpec.classBuilder(Builder)
56 | .addModifiers(Modifier.ABSTRACT)
57 | .addJavadoc("Builder, declares interface for creating parts of a Product object")
58 | .addMethod(createProduct)
59 | .addMethod(buildPart1)
60 | .addMethod(buildPart2)
61 | .build();
62 |
63 | generatedCode[i] = JavaFile.builder(packageName,builder)
64 | .addFileComment("Builder, declares interface for creating parts of a Product object")
65 | .skipJavaLangImports(true)
66 | .build();
67 |
68 | i += 1;
69 | // Director class declaration
70 |
71 | ClassName Director = ClassName.get("",classes[i]);
72 |
73 | MethodSpec constructorDirector = MethodSpec.constructorBuilder()
74 | .addModifiers(Modifier.PUBLIC)
75 | .addParameter(Builder,"builder")
76 | .addStatement("this.builder = builder")
77 | .build();
78 |
79 | MethodSpec construct = MethodSpec.methodBuilder("construct")
80 | .addModifiers(Modifier.PUBLIC)
81 | .returns(TypeName.VOID)
82 | .addStatement("builder.$N().$N($S).$N($S)",createProduct.name,buildPart1.name,"part1",buildPart2.name,"part2")
83 | .build();
84 |
85 | TypeSpec director = TypeSpec.classBuilder(Director)
86 | .addModifiers(Modifier.PUBLIC)
87 | .addJavadoc("Director class, constructs an object using the Builder interface")
88 | .addField(Builder,"builder",Modifier.PRIVATE)
89 | .addMethod(constructorDirector)
90 | .addMethod(construct)
91 | .build();
92 |
93 | generatedCode[i] = JavaFile.builder(packageName,director)
94 | .skipJavaLangImports(true)
95 | .build();
96 |
97 | i += 1;
98 | // Product class declaration
99 |
100 | ClassName Product = ClassName.get("",classes[i]);
101 |
102 | MethodSpec set1 = MethodSpec.methodBuilder("setPart1")
103 | .addModifiers(Modifier.PUBLIC)
104 | .returns(TypeName.VOID)
105 | .addParameter(String.class,"part1")
106 | .addStatement("this.$N() = $N","part1","part1")
107 | .build();
108 |
109 | MethodSpec set2 = MethodSpec.methodBuilder("setPart2")
110 | .addModifiers(Modifier.PUBLIC)
111 | .returns(TypeName.VOID)
112 | .addParameter(String.class,"part2")
113 | .addStatement("this.$N() = $N","part2","part2")
114 | .build();
115 |
116 | MethodSpec get1 = MethodSpec.methodBuilder("getPart1")
117 | .addModifiers(Modifier.PUBLIC)
118 | .returns(String.class)
119 | .addStatement("return $N","part1")
120 | .build();
121 |
122 | MethodSpec get2 = MethodSpec.methodBuilder("getPart2")
123 | .addModifiers(Modifier.PUBLIC)
124 | .returns(String.class)
125 | .addStatement("return $N","part2")
126 | .build();
127 |
128 | TypeSpec product = TypeSpec.classBuilder(Product)
129 | .addModifiers(Modifier.PUBLIC)
130 | .addJavadoc("Product class, represents complex object")
131 | .addField(String.class, "part1", Modifier.PRIVATE)
132 | .addField(String.class, "part2", Modifier.PRIVATE)
133 | .addMethod(set1)
134 | .addMethod(set2)
135 | .addMethod(get1)
136 | .addMethod(get2)
137 | .build();
138 |
139 | generatedCode[i] = JavaFile.builder(packageName,product)
140 | .skipJavaLangImports(true)
141 | .build();
142 |
143 | i += 1;
144 | // Concrete Builder class declaration
145 |
146 | ClassName concreteBuilder = ClassName.get("",classes[i]);
147 |
148 | MethodSpec createproduct = MethodSpec.methodBuilder("createProduct")
149 | .addModifiers(Modifier.PUBLIC)
150 | .returns(Builder)
151 | .addStatement("this.product = new $T()",Product)
152 | .addStatement("return this")
153 | .build();
154 |
155 | MethodSpec buildpart1 = MethodSpec.methodBuilder("buildPart1")
156 | .addModifiers(Modifier.PUBLIC)
157 | .returns(Builder)
158 | .addParameter(String.class,"part" )
159 | .addStatement("product.$N($N)",set1.name,"part")
160 | .addStatement("return this")
161 | .build();
162 |
163 | MethodSpec buildpart2 = MethodSpec.methodBuilder("buildPart2")
164 | .addModifiers(Modifier.PUBLIC)
165 | .returns(Builder)
166 | .addParameter(String.class,"part" )
167 | .addStatement("product.$N($N)",set2.name,"part")
168 | .addStatement("return this")
169 | .build();
170 |
171 | MethodSpec getresult = MethodSpec.methodBuilder("getResult")
172 | .addModifiers(Modifier.PUBLIC)
173 | .returns(Product)
174 | .addStatement("return product")
175 | .build();
176 |
177 | TypeSpec concretebuilder = TypeSpec.classBuilder(concreteBuilder)
178 | .superclass(Builder)
179 | .addModifiers(Modifier.PUBLIC)
180 | .addJavadoc("ConcreteBuilder class, constructs and assembles parts of the Product by\n" +
181 | "implementing the Builder interface")
182 | .addField(Product, "product", Modifier.PRIVATE)
183 | .addMethod(createproduct)
184 | .addMethod(buildpart1)
185 | .addMethod(buildpart2)
186 | .addMethod(getresult)
187 | .build();
188 |
189 | generatedCode[i] = JavaFile.builder(packageName,concretebuilder)
190 | .skipJavaLangImports(true)
191 | .build();
192 |
193 | logger.info("Returning generated java code to be written in files");
194 |
195 | return generatedCode;
196 | }
197 | }
198 |
--------------------------------------------------------------------------------
/src/main/java/com/structural/Flyweight.java:
--------------------------------------------------------------------------------
1 | package com.structural;
2 |
3 |
4 | import com.squareup.javapoet.*;
5 |
6 | import javax.lang.model.element.Modifier;
7 | import java.io.IOException;
8 | import com.DesignPattern;
9 | import ch.qos.logback.classic.Logger;
10 | import org.slf4j.LoggerFactory;
11 |
12 | public class Flyweight implements DesignPattern {
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Flyweight.class);
15 |
16 |
17 | String[] defaultClasses = {"Flyweight", "ConcreteFlyweight","UnsharedConcreteFlyweight","FlyweightFactory"};
18 | String packageName = "com.StructuralDP.flyweight";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public Flyweight(int flag) throws IOException {
22 | logger.info("Executing Flyweight()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses,packageName);
25 | }
26 |
27 | }
28 |
29 | public void create() throws IOException {
30 | createDesignPattern(defaultClasses,packageName);
31 | }
32 | public JavaFile[] generateCode(String[] classes, String packageName){
33 | logger.info("Executing generateCode()");
34 |
35 | int i = 0;
36 |
37 | // Flyweight interface declaration
38 | ClassName Flyweight = ClassName.get("",classes[i]);
39 | MethodSpec oper = MethodSpec.methodBuilder("operation")
40 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
41 | .returns(TypeName.VOID)
42 | .addParameter(TypeName.OBJECT, "extrinsicState")
43 | .build();
44 | TypeSpec flyweight = TypeSpec.interfaceBuilder(Flyweight)
45 | .addModifiers(Modifier.PUBLIC)
46 | .addJavadoc("Flyweight, interface through flyweight can receive and act on extrinsic state.")
47 | .addMethod(oper)
48 | .build();
49 | generatedCode[i] = JavaFile.builder(packageName,flyweight)
50 | .skipJavaLangImports(true)
51 | .build();
52 | i += 1;
53 |
54 | // ConcreteFlyweight class declaration
55 | ClassName ConcreteFlyweight = ClassName.get("",classes[i]);
56 | FieldSpec intrinsicState = FieldSpec.builder(TypeName.OBJECT,"intrinsicState",Modifier.PRIVATE).build();
57 | TypeSpec concreteFlyweight = TypeSpec.classBuilder(ConcreteFlyweight)
58 | .addModifiers(Modifier.PUBLIC)
59 | .addSuperinterface(Flyweight)
60 | .addJavadoc("ConcreteFlyweight,implements Flyweight, and add storage for intrinsic state.")
61 | .addField(intrinsicState)
62 | .addMethod(MethodSpec.constructorBuilder()
63 | .addModifiers(Modifier.PUBLIC)
64 | .addParameter(TypeName.OBJECT, "intrinsicState")
65 | .addStatement("this.$N = intrinsicState", intrinsicState.name)
66 | .build())
67 | .addMethod(MethodSpec.methodBuilder(oper.name)
68 | .addComment("Using extrinsicState as context and does NOT modify intrinsic state")
69 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
70 | .addParameter(TypeName.OBJECT, "extrinsicState")
71 | .build())
72 | .addMethod(MethodSpec.methodBuilder("getIntrinsicState")
73 | .addJavadoc("@return intrinsic state")
74 | .addModifiers(Modifier.PUBLIC).returns(TypeName.OBJECT)
75 | .addStatement("return $N", intrinsicState.name)
76 | .build())
77 | .build();
78 | generatedCode[i] = JavaFile.builder(packageName,concreteFlyweight)
79 | .skipJavaLangImports(true)
80 | .build();
81 | i += 1;
82 |
83 | // UnsharedConcreteFlyweight class declaration
84 | ClassName UnsharedConcreteFlyweight = ClassName.get("",classes[i]);
85 | FieldSpec state = FieldSpec.builder(TypeName.OBJECT,"state",Modifier.PRIVATE).build();
86 | TypeSpec unsharedConcreteFlyweight = TypeSpec.classBuilder(UnsharedConcreteFlyweight)
87 | .addModifiers(Modifier.PUBLIC)
88 | .addSuperinterface(Flyweight)
89 | .addJavadoc("UnsharedConcreteFlyweight, defines objects which are not shared.")
90 | .addField(state)
91 | .addMethod(MethodSpec.constructorBuilder()
92 | .addModifiers(Modifier.PUBLIC)
93 | .addParameter(TypeName.OBJECT, "state")
94 | .addStatement("this.$N = state", state.name)
95 | .build())
96 | .addMethod(MethodSpec.methodBuilder(oper.name)
97 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
98 | .addParameter(TypeName.OBJECT, "extrinsicState")
99 | .build())
100 | .addMethod(MethodSpec.methodBuilder("getState")
101 | .addModifiers(Modifier.PUBLIC).returns(TypeName.OBJECT)
102 | .addStatement("return $N", state.name)
103 | .build())
104 | .build();
105 | generatedCode[i] = JavaFile.builder(packageName,unsharedConcreteFlyweight)
106 | .skipJavaLangImports(true)
107 | .build();
108 | i += 1;
109 |
110 | // FlyweightFactory class declaration
111 | ClassName FlyweightFactory = ClassName.get("",classes[i]);
112 | ClassName hashMap = ClassName.get("java.util", "HashMap");
113 | ClassName map = ClassName.get("java.util", "Map");
114 | TypeName listOfFlyweights = ParameterizedTypeName.get(map,Flyweight);
115 | // TypeName listOfFlyweights = ParameterizedTypeName.get(map,TypeName.get(String.class.getComponentType()));
116 | // TypeName f = ParameterizedTypeName.get(String.class,listOfFlyweights );
117 |
118 | FieldSpec flyweights = FieldSpec.builder(listOfFlyweights,"flyweights")
119 | .addModifiers(Modifier.PRIVATE,Modifier.STATIC)
120 | .initializer("new $T<$T, $T>()",hashMap,String.class,Flyweight)
121 | .build();
122 | TypeSpec flyweightFact = TypeSpec.classBuilder(FlyweightFactory)
123 | .addModifiers(Modifier.PUBLIC)
124 | .addJavadoc("FlyweightFactory, creates and manages the flyweight objects.")
125 | .addField(flyweights)
126 | .addMethod(MethodSpec.methodBuilder("getFlyweight")
127 | .addModifiers(Modifier.PUBLIC,Modifier.STATIC).returns(Flyweight)
128 | .addParameter(String.class,"key")
129 | .addParameter(String.class,"value")
130 | .addJavadoc("Returns Flyweight object. Just for sake of example following logic is\n" +
131 | "applied, if key starts with phrase:unshared than UnsharedConcreteFlyweight\n" +
132 | "object is created. Otherwise ConcreteFlyweight object is created.\n" +
133 | "@param key\n" +
134 | "@return Flyweight")
135 | .beginControlFlow("if (key.startsWith(\"unshared\"))")
136 | .addStatement("$N.put(key, new $T(value))",flyweights.name,UnsharedConcreteFlyweight)
137 | .nextControlFlow("else { \n" +
138 | "if (!$N.containsKey(key))",flyweights.name)
139 | .addStatement("$N.put(key, new $T(value))",flyweights.name,ConcreteFlyweight)
140 | .addCode("}\n")
141 | .endControlFlow()
142 | .addStatement("return ($T) $N.get(key)",Flyweight,flyweights.name)
143 | .build())
144 | .build();
145 | generatedCode[i] = JavaFile.builder(packageName,flyweightFact)
146 | .skipJavaLangImports(true)
147 | .build();
148 |
149 | logger.info("Returning generated java code to be written in files");
150 |
151 | return generatedCode;
152 | }
153 | }
154 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Mediator.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 |
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Mediator implements DesignPattern {
12 |
13 | //Define a static logger variable so that it references the Logger instance
14 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Mediator.class);
15 |
16 |
17 | String[] defaultClasses = {"Colleague","ConcreteColleague1","ConcreteColleague2","Mediator","ConcreteMediator"};
18 | String packageName = "com.BehavioralDP.mediator";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public Mediator(int flag)throws IOException{
22 | logger.info("Executing Mediator()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 | int i = 0;
31 | ClassName Colleague = ClassName.get("",classes[0]);
32 | ClassName ConcreteColleague1 = ClassName.get("",classes[1]);
33 | ClassName ConcreteColleague2 = ClassName.get("",classes[2]);
34 | ClassName Mediator = ClassName.get("",classes[3]);
35 | ClassName ConcreteMediator = ClassName.get("",classes[4]);
36 |
37 | // Colleague abstract class declaration
38 | FieldSpec mediatorField = FieldSpec.builder(Mediator,"mediator",Modifier.PROTECTED).build();
39 | FieldSpec recMsg = FieldSpec.builder(String.class,"receivedMessage",Modifier.PRIVATE).build();
40 | MethodSpec notifyCol = MethodSpec.methodBuilder("notifyColleague")
41 | .addModifiers(Modifier.ABSTRACT).returns(TypeName.VOID)
42 | .addParameter(String.class,"message")
43 | .build();
44 | MethodSpec receive = MethodSpec.methodBuilder("receive")
45 | .addModifiers(Modifier.ABSTRACT).returns(TypeName.VOID)
46 | .addParameter(String.class,"message")
47 | .build();
48 | MethodSpec getRecMsg = MethodSpec.methodBuilder("getReceivedMessage")
49 | .addModifiers(Modifier.PROTECTED).returns(String.class)
50 | .addStatement("return this.$N",recMsg.name)
51 | .build();
52 | MethodSpec setRecMsg = MethodSpec.methodBuilder("setReceivedMessage")
53 | .addModifiers(Modifier.PROTECTED).returns(TypeName.VOID)
54 | .addParameter(String.class,"receivedMessage")
55 | .addStatement("this.$N = receivedMessage",recMsg.name)
56 | .build();
57 | TypeSpec colleague = TypeSpec.classBuilder(Colleague)
58 | .addModifiers(Modifier.ABSTRACT)
59 | .addJavadoc("Colleague defines an interface for communication with another Colleague via mediator.")
60 | .addField(mediatorField)
61 | .addField(recMsg)
62 | .addMethod(MethodSpec.constructorBuilder()
63 | .addModifiers(Modifier.PUBLIC)
64 | .addParameter(Mediator,"mediator")
65 | .addStatement("this.$N = mediator",mediatorField.name)
66 | .build())
67 | .addMethod(notifyCol)
68 | .addMethod(receive)
69 | .addMethod(getRecMsg)
70 | .addMethod(setRecMsg)
71 | .build();
72 | generatedCode[i] = JavaFile.builder(packageName,colleague)
73 | .skipJavaLangImports(true)
74 | .build();
75 | i += 1;
76 |
77 | // ConcreteColleague1 class declaration
78 | TypeSpec concCol1 = TypeSpec.classBuilder(ConcreteColleague1)
79 | .addModifiers(Modifier.PUBLIC).superclass(Colleague)
80 | .addJavadoc("ConcreteColleague1 implements Colleague interface.")
81 | .addMethod(MethodSpec.constructorBuilder()
82 | .addModifiers(Modifier.PUBLIC)
83 | .addParameter(Mediator, "mediator")
84 | .addStatement("super(mediator)")
85 | .build())
86 | .addMethod(MethodSpec.methodBuilder(notifyCol.name)
87 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
88 | .addParameter(String.class,"message")
89 | .addStatement("this.$N.$N(this, message)",mediatorField.name,notifyCol.name)
90 | .build())
91 | .addMethod(MethodSpec.methodBuilder(receive.name)
92 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
93 | .addParameter(String.class,"message")
94 | .addStatement("this.$N(message)",setRecMsg.name)
95 | .build())
96 | .build();
97 | generatedCode[i] = JavaFile.builder(packageName,concCol1)
98 | .skipJavaLangImports(true)
99 | .build();
100 | i += 1;
101 |
102 | // ConcreteColleague1 class declaration
103 | TypeSpec concCol2 = TypeSpec.classBuilder(ConcreteColleague2)
104 | .addModifiers(Modifier.PUBLIC).superclass(Colleague)
105 | .addJavadoc("ConcreteColleague2 implements Colleague interface.")
106 | .addMethod(MethodSpec.constructorBuilder()
107 | .addModifiers(Modifier.PUBLIC)
108 | .addParameter(Mediator, "mediator")
109 | .addStatement("super(mediator)")
110 | .build())
111 | .addMethod(MethodSpec.methodBuilder(notifyCol.name)
112 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
113 | .addParameter(String.class,"message")
114 | .addStatement("this.$N.$N(this, message)",mediatorField.name,notifyCol.name)
115 | .build())
116 | .addMethod(MethodSpec.methodBuilder(receive.name)
117 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
118 | .addParameter(String.class,"message")
119 | .addStatement("this.$N(message)",setRecMsg.name)
120 | .build())
121 | .build();
122 | generatedCode[i] = JavaFile.builder(packageName,concCol2)
123 | .skipJavaLangImports(true)
124 | .build();
125 | i += 1;
126 |
127 | // Mediator interface declaration
128 | TypeSpec mediator = TypeSpec.interfaceBuilder(Mediator)
129 | .addModifiers(Modifier.PUBLIC)
130 | .addMethod(MethodSpec.methodBuilder(notifyCol.name)
131 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.VOID)
132 | .addParameter(Colleague, "colleague")
133 | .addParameter(String.class,"message")
134 | .build())
135 | .build();
136 | generatedCode[i] = JavaFile.builder(packageName,mediator)
137 | .skipJavaLangImports(true)
138 | .build();
139 | i += 1;
140 |
141 | // ConcreteMediator class declaration
142 | ClassName list = ClassName.get("java.util", "List");
143 | ClassName arrayList = ClassName.get("java.util", "ArrayList");
144 | ClassName Iterator = ClassName.get("java.util","Iterator");
145 | TypeName listOfColleagues = ParameterizedTypeName.get(list,Colleague);
146 |
147 | FieldSpec cols = FieldSpec.builder(listOfColleagues,"colleagues",Modifier.PRIVATE)
148 | .build();
149 | TypeSpec concreteMediator = TypeSpec.classBuilder(ConcreteMediator)
150 | .addModifiers(Modifier.PUBLIC)
151 | .addSuperinterface(Mediator)
152 | .addJavadoc("ConcreteMediator implements Mediator, coordinates between Colleague objects.")
153 | .addField(cols)
154 | .addMethod(MethodSpec.constructorBuilder()
155 | .addModifiers(Modifier.PUBLIC)
156 | .addStatement("$N = new $T<$T>()", cols.name,arrayList,Colleague)
157 | .build())
158 | .addMethod(MethodSpec.methodBuilder("addColleague")
159 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
160 | .addParameter(Colleague,"colleague")
161 | .addStatement("$N.add(colleague)",cols.name)
162 | .build())
163 | .addMethod(MethodSpec.methodBuilder(notifyCol.name)
164 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
165 | .addParameter(Colleague, "colleague")
166 | .addParameter(String.class,"message")
167 | .addCode("\n")
168 | .beginControlFlow("for ($T iterator = $N.iterator(); iterator.hasNext();)",Iterator,cols.name)
169 | .addStatement("$T receiverColleague = ($T) iterator.next()",Colleague,Colleague)
170 | .addCode("\n")
171 | .beginControlFlow("if (colleague != receiverColleague)")
172 | .addStatement("receiverColleague.$N(message)",receive.name)
173 | .endControlFlow()
174 | .endControlFlow()
175 | .build())
176 | .build();
177 | generatedCode[i] = JavaFile.builder(packageName,concreteMediator)
178 | .skipJavaLangImports(true)
179 | .build();
180 |
181 | logger.info("Returning generated java code to be written in files");
182 |
183 | return generatedCode;
184 |
185 |
186 | }
187 |
188 | }
189 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Interpreter.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 |
5 | import javax.lang.model.element.Modifier;
6 | import java.io.IOException;
7 | import com.DesignPattern;
8 | import ch.qos.logback.classic.Logger;
9 | import org.slf4j.LoggerFactory;
10 |
11 | public class Interpreter implements DesignPattern {
12 | //Define a static logger variable so that it references the Logger instance
13 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Interpreter.class);
14 |
15 |
16 | String[] defaultClasses = {"Context", "AbstractExpression","OrExpression","AndExpression","TerminalExpression"};
17 | String packageName = "com.BehavioralDP.interpreter";
18 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
19 |
20 | public Interpreter(int flag)throws IOException{
21 | logger.info("Executing Interpreter()");
22 | if(flag == 1) {
23 | createDesignPattern(defaultClasses, packageName);
24 | }
25 | }
26 |
27 | public JavaFile[] generateCode(String[] classes, String packageName){
28 | logger.info("Executing generateCode()");
29 |
30 | int i = 0;
31 |
32 | // Context class declaration
33 | ClassName Context = ClassName.get("",classes[i]);
34 | ClassName list = ClassName.get("java.util", "List");
35 | ClassName arrayList = ClassName.get("java.util", "ArrayList");
36 | ClassName Boolean = ClassName.get("java.lang","Boolean");
37 | TypeName listOfBoolean = ParameterizedTypeName.get(list,Boolean);
38 |
39 | FieldSpec operands = FieldSpec.builder(listOfBoolean,"operands",Modifier.PRIVATE)
40 | .initializer("new $T<$T>()",arrayList,Boolean.class)
41 | .build();
42 | FieldSpec result = FieldSpec.builder(Boolean.class, "result",Modifier.PRIVATE)
43 | .initializer("null").build();
44 |
45 | MethodSpec getOperands = MethodSpec.methodBuilder("getOperands")
46 | .addModifiers(Modifier.PUBLIC).returns(listOfBoolean)
47 | .addStatement("return $N",operands.name).build();
48 | MethodSpec addOperand = MethodSpec.methodBuilder("addOperand")
49 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
50 | .addParameter(Boolean.class, "operand")
51 | .addStatement("$N.add(operand)",operands.name).build();
52 |
53 | TypeSpec context = TypeSpec.classBuilder(Context)
54 | .addModifiers(Modifier.PUBLIC)
55 | .addJavadoc("Context contains global information for Interpreter.")
56 | .addField(operands)
57 | .addField(result)
58 | .addMethod(getOperands)
59 | .addMethod(addOperand)
60 | .addMethod(MethodSpec.methodBuilder("isResult")
61 | .addModifiers(Modifier.PUBLIC).returns(TypeName.BOOLEAN)
62 | .addStatement("return $N",result.name).build())
63 | .addMethod(MethodSpec.methodBuilder("setResult")
64 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
65 | .addParameter(TypeName.BOOLEAN, "result")
66 | .addStatement("this.$N = result",result.name).build())
67 | .build();
68 | generatedCode[i] = JavaFile.builder(packageName,context).skipJavaLangImports(true).build();
69 | i += 1;
70 |
71 | // AbstractExpression class declaration
72 | ClassName AbstractExpression = ClassName.get("",classes[i]);
73 | MethodSpec interpret = MethodSpec.methodBuilder("interpret")
74 | .addModifiers(Modifier.ABSTRACT).returns(TypeName.VOID)
75 | .addParameter(Context, "context")
76 | .build();
77 |
78 | TypeSpec abstractExp = TypeSpec.classBuilder(AbstractExpression)
79 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT)
80 | .addJavadoc("AbstractExpresion defines interface for interpretation. Interface must be used by" +
81 | " TerminalExpression and NonTerminalExpression.")
82 | .addMethod(interpret).build();
83 | generatedCode[i] = JavaFile.builder(packageName,abstractExp).skipJavaLangImports(true).build();
84 | i += 1;
85 |
86 | // OrExpression class declaration
87 | ClassName OrExpression = ClassName.get("",classes[i]);
88 | FieldSpec firstAbsExp = FieldSpec.builder(AbstractExpression, "firstAbstractExpression",Modifier.PRIVATE).build();
89 | FieldSpec secondAbsExp = FieldSpec.builder(AbstractExpression, "secondAbstractExpression",Modifier.PRIVATE).build();
90 | TypeSpec orExp = TypeSpec.classBuilder(OrExpression)
91 | .superclass(AbstractExpression)
92 | .addModifiers(Modifier.PUBLIC)
93 | .addJavadoc("OrExpression implements AbstractExpression for logical OR grammar expression")
94 | .addField(firstAbsExp)
95 | .addField(secondAbsExp)
96 | .addMethod(MethodSpec.constructorBuilder()
97 | .addModifiers(Modifier.PUBLIC)
98 | .addParameter(AbstractExpression, "firstAbstractExpression")
99 | .addParameter(AbstractExpression, "secondAbstractExpression")
100 | .addStatement("this.$N = firstAbstractExpression",firstAbsExp)
101 | .addStatement("this.$N = secondAbstractExpression",secondAbsExp)
102 | .build())
103 | .addMethod(MethodSpec.methodBuilder(interpret.name)
104 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
105 | .addParameter(Context, "context")
106 | .addStatement("$N.$N(context)",firstAbsExp.name,interpret.name)
107 | .addStatement("$N.$N(context)",secondAbsExp.name,interpret.name)
108 | .addCode("\n")
109 | .addStatement("$T $N = context.$N()",listOfBoolean,operands.name,getOperands.name)
110 | .addCode("\n")
111 | .addStatement("Boolean firstOperand = operands.get(0)")
112 | .addStatement("Boolean secondOperand = operands.get(1)")
113 | .addCode("\n")
114 | .addStatement("$T $N = firstOperand || secondOperand",Boolean,result.name)
115 | .addStatement("$N.setResult($N)",context.name,result.name)
116 | .build())
117 | .build();
118 | generatedCode[i] = JavaFile.builder(packageName,orExp).skipJavaLangImports(true).build();
119 | i += 1;
120 |
121 | // OrExpression class declaration
122 | ClassName AndExpression = ClassName.get("",classes[i]);
123 | TypeSpec andExp = TypeSpec.classBuilder(AndExpression)
124 | .superclass(AbstractExpression)
125 | .addModifiers(Modifier.PUBLIC)
126 | .addJavadoc("AndExpression implements AbstractExpression for logical AND grammar expression")
127 | .addField(firstAbsExp)
128 | .addField(secondAbsExp)
129 | .addMethod(MethodSpec.constructorBuilder()
130 | .addModifiers(Modifier.PUBLIC)
131 | .addParameter(AbstractExpression, "firstAbstractExpression")
132 | .addParameter(AbstractExpression, "secondAbstractExpression")
133 | .addStatement("this.$N = firstAbstractExpression",firstAbsExp)
134 | .addStatement("this.$N = secondAbstractExpression",secondAbsExp)
135 | .build())
136 | .addMethod(MethodSpec.methodBuilder(interpret.name)
137 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
138 | .addParameter(Context, "context")
139 | .addStatement("$N.$N(context)",firstAbsExp.name,interpret.name)
140 | .addStatement("$N.$N(context)",secondAbsExp.name,interpret.name)
141 | .addCode("\n")
142 | .addStatement("$T $N = context.$N()",listOfBoolean,operands.name,getOperands.name)
143 | .addCode("\n")
144 | .addStatement("Boolean firstOperand = operands.get(0)")
145 | .addStatement("Boolean secondOperand = operands.get(1)")
146 | .addCode("\n")
147 | .addStatement("$T $N = firstOperand && secondOperand",Boolean,result.name)
148 | .addStatement("$N.setResult($N)",context.name,result.name)
149 | .build())
150 | .build();
151 | generatedCode[i] = JavaFile.builder(packageName,andExp).skipJavaLangImports(true).build();
152 | i += 1;
153 |
154 | // TerminalExpression class declaration
155 | ClassName TerminalExpression = ClassName.get("",classes[i]);
156 | FieldSpec data = FieldSpec.builder(boolean.class,"data",Modifier.PRIVATE).build();
157 | TypeSpec termExp = TypeSpec.classBuilder(TerminalExpression)
158 | .superclass(AbstractExpression)
159 | .addModifiers(Modifier.PUBLIC)
160 | .addJavadoc("TerminalExpresion implements AbstractExpression for literal symbol in grammar.")
161 | .addField(data)
162 | .addMethod(MethodSpec.constructorBuilder()
163 | .addModifiers(Modifier.PUBLIC)
164 | .addParameter(boolean.class,"data")
165 | .addStatement("this.$N = data",data.name)
166 | .build())
167 | .addMethod(MethodSpec.methodBuilder(interpret.name)
168 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
169 | .addParameter(Context,"context")
170 | .addStatement("context.$N(this.$N)",addOperand.name,data.name)
171 | .build())
172 | .build();
173 | generatedCode[i] = JavaFile.builder(packageName,termExp).skipJavaLangImports(true).build();
174 |
175 | logger.info("Returning generated java code to be written in files");
176 |
177 | return generatedCode;
178 | }
179 | }
180 |
--------------------------------------------------------------------------------
/src/main/java/com/behavioral/Visitor.java:
--------------------------------------------------------------------------------
1 | package com.behavioral;
2 |
3 | import com.squareup.javapoet.*;
4 | import javax.lang.model.element.Modifier;
5 | import java.io.IOException;
6 | import com.DesignPattern;
7 | import ch.qos.logback.classic.Logger;
8 | import org.slf4j.LoggerFactory;
9 |
10 | public class Visitor implements DesignPattern {
11 |
12 | //Define a static logger variable so that it references the Logger instance
13 | private static final Logger logger = (Logger) LoggerFactory.getLogger(Visitor.class);
14 |
15 |
16 | String[] defaultClasses = {"Element","ConcreteElementA","ConcreteElementB","Visitor","ConcreteVisitor1",
17 | "ConcreteVisitor2", "ObjectStructure"};
18 | String packageName = "com.BehavioralDP.visitor";
19 | JavaFile[] generatedCode = new JavaFile[defaultClasses.length];
20 |
21 | public Visitor(int flag)throws IOException{
22 | logger.info("Executing Visitor()");
23 | if(flag == 1) {
24 | createDesignPattern(defaultClasses, packageName);
25 | }
26 | }
27 |
28 | public JavaFile[] generateCode(String[] classes, String packageName){
29 | logger.info("Executing generateCode()");
30 |
31 | ClassName Element = ClassName.get("",classes[0]);
32 | ClassName ConcreteElementA = ClassName.get("",classes[1]);
33 | ClassName ConcreteElementB = ClassName.get("",classes[2]);
34 | ClassName Visitor = ClassName.get("",classes[3]);
35 | ClassName ConcreteVisitor1 = ClassName.get("",classes[4]);
36 | ClassName ConcreteVisitor2 = ClassName.get("",classes[5]);
37 | ClassName ObjectStructure = ClassName.get("",classes[6]);
38 |
39 | int i = 0;
40 | // Element interface declaration
41 | MethodSpec accept = MethodSpec.methodBuilder("accept")
42 | .addJavadoc("Defines an Accept operation that takes a visitor as an argument.")
43 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.VOID)
44 | .addParameter(Visitor, "visitor").build();
45 | TypeSpec element = TypeSpec.interfaceBuilder(Element)
46 | .addModifiers(Modifier.PUBLIC)
47 | .addMethod(accept).build();
48 | generatedCode[i] = JavaFile.builder(packageName,element)
49 | .skipJavaLangImports(true).build();
50 | i += 1;
51 |
52 |
53 | MethodSpec visitConcElementA = MethodSpec.methodBuilder("visitConcreteElementA")
54 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.VOID)
55 | .addParameter(ConcreteElementA,"concreteElementA").build();
56 |
57 | MethodSpec visitConcElementB = MethodSpec.methodBuilder("visitConcreteElementB")
58 | .addModifiers(Modifier.PUBLIC,Modifier.ABSTRACT).returns(TypeName.VOID)
59 | .addParameter(ConcreteElementB,"concreteElementB").build();
60 |
61 |
62 | // ConcreteElementA class decalaration
63 | FieldSpec counter = FieldSpec.builder(int.class,"counter",Modifier.PRIVATE)
64 | .initializer("0").build();
65 |
66 | MethodSpec operA = MethodSpec.methodBuilder("operationA")
67 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
68 | .addStatement("$N++",counter.name).build();
69 | MethodSpec getCounter = MethodSpec.methodBuilder("getCounter")
70 | .addModifiers(Modifier.PROTECTED).returns(TypeName.INT)
71 | .addStatement("return $N",counter.name).build();
72 |
73 | TypeSpec concElementA = TypeSpec.classBuilder(ConcreteElementA)
74 | .addModifiers(Modifier.PUBLIC)
75 | .addSuperinterface(Element)
76 | .addJavadoc("Implements accept operation.")
77 | .addField(counter)
78 | .addMethod(MethodSpec.methodBuilder(accept.name)
79 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
80 | .addParameter(Visitor,"visitor")
81 | .addStatement("visitor.$N(this)",visitConcElementA.name)
82 | .build())
83 | .addMethod(operA)
84 | .addMethod(getCounter)
85 | .build();
86 | generatedCode[i] = JavaFile.builder(packageName,concElementA)
87 | .skipJavaLangImports(true)
88 | .build();
89 | i += 1;
90 |
91 | // ConcreteElementB class decalaration
92 | MethodSpec operB = MethodSpec.methodBuilder("operationB")
93 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
94 | .addStatement("$N++",counter.name).build();
95 |
96 | TypeSpec concElementB = TypeSpec.classBuilder(ConcreteElementB)
97 | .addModifiers(Modifier.PUBLIC)
98 | .addSuperinterface(Element)
99 | .addJavadoc("Implements accept operation.")
100 | .addField(counter)
101 | .addMethod(MethodSpec.methodBuilder(accept.name)
102 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
103 | .addParameter(Visitor,"visitor")
104 | .addStatement("visitor.$N(this)",visitConcElementB.name)
105 | .build())
106 | .addMethod(operB)
107 | .addMethod(getCounter)
108 | .build();
109 | generatedCode[i] = JavaFile.builder(packageName,concElementB)
110 | .skipJavaLangImports(true)
111 | .build();
112 | i += 1;
113 |
114 | // Visitor interface declaration
115 | TypeSpec visitor = TypeSpec.interfaceBuilder(Visitor)
116 | .addModifiers(Modifier.PUBLIC)
117 | .addJavadoc("Declares a Visit operation for each class of ConcreteElement in the object structure")
118 | .addMethod(visitConcElementA)
119 | .addMethod(visitConcElementB).build();
120 | generatedCode[i] = JavaFile.builder(packageName,visitor)
121 | .skipJavaLangImports(true).build();
122 | i += 1;
123 |
124 | // ConcreteVisitor1 class declaration
125 | TypeSpec concVisitor1 = TypeSpec.classBuilder(ConcreteVisitor1)
126 | .addSuperinterface(Visitor)
127 | .addModifiers(Modifier.PUBLIC)
128 | .addMethod(MethodSpec.methodBuilder(visitConcElementA.name)
129 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
130 | .addParameter(ConcreteElementA,"concreteElementA")
131 | .addStatement("concreteElementA.$N()",operA.name)
132 | .build())
133 | .addMethod(MethodSpec.methodBuilder(visitConcElementB.name)
134 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
135 | .addParameter(ConcreteElementB,"concreteElementB")
136 | .addStatement("concreteElementB.$N()",operB.name)
137 | .build())
138 | .build();
139 | generatedCode[i] = JavaFile.builder(packageName,concVisitor1)
140 | .skipJavaLangImports(true).build();
141 | i += 1;
142 |
143 | // ConcreteVisitor2 class declaration
144 | TypeSpec concVisitor2 = TypeSpec.classBuilder(ConcreteVisitor2)
145 | .addSuperinterface(Visitor)
146 | .addModifiers(Modifier.PUBLIC)
147 | .addMethod(MethodSpec.methodBuilder(visitConcElementA.name)
148 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
149 | .addParameter(ConcreteElementA,"concreteElementA")
150 | .addStatement("concreteElementA.$N()",operA.name)
151 | .build())
152 | .addMethod(MethodSpec.methodBuilder(visitConcElementB.name)
153 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
154 | .addParameter(ConcreteElementB,"concreteElementB")
155 | .addStatement("concreteElementB.$N()",operB.name)
156 | .build())
157 | .build();
158 | generatedCode[i] = JavaFile.builder(packageName,concVisitor2)
159 | .skipJavaLangImports(true).build();
160 | i += 1;
161 |
162 | // ObjectStructure class declaration
163 | ClassName list = ClassName.get("java.util", "List");
164 | ClassName arrayList = ClassName.get("java.util", "ArrayList");
165 | ClassName Iterator = ClassName.get("java.util","Iterator");
166 | TypeName listOfElements = ParameterizedTypeName.get(list,Element);
167 |
168 | FieldSpec children = FieldSpec.builder(listOfElements,"children",Modifier.PRIVATE)
169 | .initializer("new $T<$T>()",arrayList,Element)
170 | .build();
171 |
172 | TypeSpec objStruct = TypeSpec.classBuilder(ObjectStructure)
173 | .addModifiers(Modifier.PUBLIC)
174 | .addJavadoc("Holds objects in structure. Provides interface to allow visitors to visit its elements.")
175 | .addField(children)
176 | .addMethod(MethodSpec.methodBuilder("add")
177 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
178 | .addParameter(Element,"element")
179 | .addStatement("$N.add(element)",children.name)
180 | .build())
181 | .addMethod(MethodSpec.methodBuilder("remove")
182 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
183 | .addParameter(Element,"element")
184 | .addStatement("$N.remove(element)",children.name)
185 | .build())
186 | .addMethod(MethodSpec.methodBuilder("getChild")
187 | .addModifiers(Modifier.PUBLIC).returns(Element)
188 | .addParameter(int.class,"index")
189 | .addStatement("return $N.get(index)",children.name)
190 | .build())
191 | .addMethod(MethodSpec.methodBuilder("acceptAll")
192 | .addModifiers(Modifier.PUBLIC).returns(TypeName.VOID)
193 | .addParameter(Visitor,"visitor")
194 | .beginControlFlow("($T iterator = $N.iterator(); iterator.hasNext();)",Iterator,children.name)
195 | .addStatement("$T element = ($T) iterator.next()",Element,Element)
196 | .addStatement("element.$N(visitor)",accept.name)
197 | .endControlFlow()
198 | .build())
199 | .build();
200 | generatedCode[i] = JavaFile.builder(packageName,objStruct)
201 | .skipJavaLangImports(true).build();
202 |
203 | logger.info("Returning generated java code to be written in files");
204 |
205 | return generatedCode;
206 |
207 | }
208 |
209 |
210 | }
211 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Design Pattern Code Generator
2 | This project is to generate the implementation code of the 23 Gang of Four(GoF) design patterns, as presented in the book “Design Patterns: Elements of Reusable Object-Oriented Software”.
3 |
4 | An [Intellij Plugin](https://github.com/samujjwaal/IntelliJ-DP-Generator-Plugin) to generate design pattern code based on this implementation.
5 |
6 |
7 | ## Index
8 |
9 | 1. [About Design Patterns](#1-about-design-patterns)
10 | 2. [About JavaPoet](#2-about-javapoet)
11 | 3. [Application Design](#3-application-design)
12 | 4. [Test Cases](#4-test-cases)
13 | 5. I[nstructions to Execute](#5-instructions-to-execute)
14 | 6. [Results of Execution](#6-results-of-execution)
15 |
16 | ------
17 |
18 | ### 1. About Design Patterns
19 |
20 | Design patterns are the best practices that a programmer can employ to solve trivial problems while designing an application. Design patterns help in speeding up the development process as they provide a set of time tested, proven development paradigms. They provide an industry standard approach to solve a recurring problem. Using design patterns promotes reusability that leads to more robust and highly maintainable code.
21 |
22 | The 23 Design Patterns are classified into 3 main categories:
23 |
24 | * Creational Design Patterns
25 | * Singleton
26 | * Abstract Factory
27 | * Builder
28 | * Factory Method
29 |
30 | * Structural Design Patterns
31 | * Adapter
32 | * Bridge
33 | * Composite
34 | * Decorator
35 | * Facade
36 | * Flyweight
37 | * Proxy
38 | * Behavioral Design Patterns
39 | * Chain of Responsibility
40 | * Command
41 | * Interpreter
42 | * Iterator
43 | * Mediator
44 | * Memento
45 | * Observer
46 | * State
47 | * Strategy
48 | * Template
49 | * Visitor
50 |
51 | ------
52 |
53 | ### 2. About JavaPoet
54 |
55 | [JavaPoet](https://github.com/square/javapoet), a successor to [JavaWriter](https://github.com/square/javapoet/tree/javawriter_2), is a Java API for generating .java source files. It can generate primitive types, reference types (like classes, interfaces, enumerated types, anonymous inner classes), fields, methods, parameters, annotations, and Javadocs.
56 |
57 | JavaPoet manages the import of the dependent classes automatically. It uses the ***Builder*** design pattern to specify the logic to generate Java code.
58 |
59 | A HelloWorld program like the one here:
60 |
61 | ```java
62 | package com.example.helloworld;
63 |
64 | public final class HelloWorld {
65 | public static void main(String[] args) {
66 | System.out.println("Hello, JavaPoet!");
67 | }
68 | }
69 | ```
70 |
71 | can be generated using JavaPoet as follows:
72 |
73 | ```java
74 | MethodSpec main = MethodSpec.methodBuilder("main")
75 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
76 | .returns(void.class)
77 | .addParameter(String[].class, "args")
78 | .addStatement("$T.out.println($S)", System.class, "Hello, JavaPoet!")
79 | .build();
80 |
81 | TypeSpec helloWorld = TypeSpec.classBuilder("HelloWorld")
82 | .addModifiers(Modifier.PUBLIC, Modifier.FINAL)
83 | .addMethod(main)
84 | .build();
85 |
86 | JavaFile javaFile = JavaFile.builder("com.example.helloworld", helloWorld)
87 | .build();
88 |
89 | javaFile.writeTo(System.out);
90 | ```
91 |
92 | `MethodSpec` "main" is configured with modifiers, return type, parameters and code statements to declare the main method. The main method is added to a `HelloWorld` class and then the class is added to a `HelloWorld.java` file.
93 |
94 | JavaPoet offers models for classes & interfaces (`TypeSpec`), fields (`FieldSpec`), methods & constructors (`MethodSpec`), parameters (`ParameterSpec`) and annotations (`AnnotationSpec`). It also generates the package folder structure for the output java source files.
95 |
96 | The most recent version of JavaPoet available as of now is 1.12.1.
97 |
98 | ------
99 |
100 | ### 3. Application Design
101 |
102 | To implement Design Pattern Code Generator(DePaCoG), I have employed the **Factory Method**, **Template Method** and **Singleton** design patterns.
103 |
104 | ------
105 |
106 | The **Factory Method**, a creational design pattern, creates two basic abstractions: the Product and Creator classes. Both these classes are abstract and clients need to extend them to realize their specific implementations. This pattern is used when there is a super class with multiple sub-classes and based on user input a particular sub-class needs to be instantiated. The responsibility of instantiation of a class is taken from the user to the factory class.
107 |
108 | In the case of DePaCoG, the `DesignPattern` and `DesignPatternGenerator` are the two abstractions I have chosen.
109 |
110 | * `DesignPattern` is an `interface` which declares methods for accepting and displaying the class names & package names from the user, generating java source code of the design patterns using JavaPoet and writing the java code into java files as output.
111 |
112 | ```java
113 | public interface DesignPattern {
114 |
115 | void displayClassNames(String[] classes);
116 |
117 | String[] setClassNames(String[] oldClasses);
118 |
119 | String setPackageName(String defaultPckgName);
120 |
121 | void createDesignPattern(String[] oldClasses, String oldPackageName);
122 |
123 | JavaFile[] generateCode(String[] classes, String packageName);
124 |
125 | void writeJavaFiles(JavaFile[] files);
126 | }
127 | ```
128 |
129 | There are 23 separate concrete classes(java files) to generate the java source code for each design pattern. Each concrete class `implements DesignPattern`. Interface `DesignPattern` provides the `default` method definition of all methods except the method `generateCode()` as the implementation of all other methods do not change according to the design patterns. Each concrete class of `DesignPattern` overrides `generateCode()`.
130 |
131 | * `DesignPatternGenerator` is an `abstract class` which declares methods to display a menu of all available design patterns and invoking appropriate classes to generate a user selected design pattern.
132 |
133 | ```java
134 | abstract class DesignPatternGenerator {
135 |
136 | protected String[] designPatterns;
137 |
138 | abstract void displayDesignPatterns();
139 |
140 | abstract void generateDesignPattern();
141 |
142 | abstract void designPatternFactory();
143 | }
144 | ```
145 |
146 | The field `designPatterns` declares all the design patterns available for creation. All the methods are abstract and are provided with the implementation in the concrete class `Hw1DesignPatternGenerator` which `extends DesignPatternGenerator.` The class `Hw1DesignPatternGenerator` also defines an additional method `chooseDesignPattern(int choice)` which takes in user’s choice of design pattern as input and instantiates an anonymous object of the appropriate design pattern class.
147 |
148 | * Advantages of using Factory Method pattern:
149 | * It provides an approach to “program to an interface, not an implementation”.
150 | * Through inheritance it provides an abstraction between implementation and client classes. It removes the instantiation of objects of implementation classes from the user/client code
151 | * It makes the code more robust, easy to extend and less coupled
152 | * New types of concrete products can be introduced without any modifications to the existing client code
153 | * Disadvantages of using Factory Method pattern:
154 | * For just creating a single instance of a particular concrete object the user might have to sub-class the creator, which complicates the hierarchy of creator classes
155 | * Makes the code difficult to interpret as all code is behind an abstraction that may also be hiding another set of abstractions
156 |
157 | ------
158 |
159 | The **Template Method**, a behavioral design pattern, is used to create method stub and defer the steps of implementation to the subclasses.
160 |
161 | The algorithm for generating design patterns has the following steps: display list of all design patterns, ask user which design pattern code is to be generated, ask for and set custom (or default) class names & package name, generate source file using JavaPoet and finally write into output files. The order of execution of these steps cannot be altered as the sequence is critical for the execution of the program. So here different methods are used to achieve the goal of generating the design pattern code. Steps like asking class names& package name and writing generated code into file are common for any design pattern whether it is a creational or structural design pattern.
162 |
163 | This is where Template Method design pattern is useful. It helps define the basic steps to execute an algorithm and can provide default implementation of the methods that might be common for all or a majority of the sub-classes implementing the design pattern. The method is which defines an exclusive property of a design pattern can be overridden by the sub-class.
164 |
165 | Template Method is implemented in the `interface DesignPattern` and its sub-classes. Interface `DesignPattern` provides the `default` method definition of all methods except the method `generateCode()` as the implementation of all other methods do not change according to the design patterns. Each concrete class of `DesignPattern` overrides `generateCode()`.
166 |
167 | Inside the `interface DesignPattern`:
168 |
169 | ```java
170 | JavaFile[] generateCode(String[] classes, String packageName);
171 | ```
172 |
173 | Inside `class Singleton` which implements `DesignPattern`:
174 |
175 | ```java
176 | public JavaFile[] generateCode(String[] classes, String packageName){
177 | int i = 0;
178 | ClassName Singleton = ClassName.get("", classes[i]);
179 | MethodSpec constructor = MethodSpec.constructorBuilder()
180 | .addModifiers(Modifier.PRIVATE)
181 | .build();
182 | FieldSpec instance = FieldSpec.builder(Singleton, "INSTANCE")
183 | .addModifiers(Modifier.PRIVATE, Modifier.STATIC)
184 | .build();
185 | MethodSpec getInstance = MethodSpec.methodBuilder("getInstance")
186 | .addModifiers(Modifier.PUBLIC, Modifier.STATIC)
187 | .returns(Singleton)
188 | .beginControlFlow("if ($N == null)", instance.name)
189 | .addStatement("$N = new $T()",instance.name, Singleton)
190 | .endControlFlow()
191 | .addStatement("return $N", instance.name)
192 | .build();
193 | TypeSpec singleton = TypeSpec.classBuilder(Singleton)
194 | .addModifiers(Modifier.PUBLIC)
195 | .addField(instance)
196 | .addMethod(constructor)
197 | .addMethod(getInstance)
198 | .build();
199 | generatedCode[i] = JavaFile.builder(packageName, singleton)
200 | .skipJavaLangImports(true)
201 | .build();
202 | return generatedCode;
203 | }
204 | ```
205 |
206 | * Advantages of using Template Method pattern:
207 | * All the duplicate code/methods of sub-classes can be put together in the super-class
208 | * Client can override only certain methods of a large algorithm, so that the other components of the algorithm are not affected
209 | * Disadvantages of using Template Method pattern:
210 | * Sometimes client might have to change certain fundamental aspects of the algorithm and changing only certain fixed components of the algorithm might not suffice
211 | * If the number of components in the algorithm being modelled is large, it is harder to maintain the code
212 |
213 | ------
214 |
215 | The **Singleton**, a creational design pattern, that helps in ensuring that a class has only one instance in a program while also providing a global access point to the instance. I have used Singleton to instantiate only one instance of the class `Hw1DesignPatternGenerator` so that in the client class `DePaCoG` the design pattern generating method is only called once at a time. The `instance` field in `Hw1DesignPatternGenerator` is lazy initialized.
216 |
217 | Inside class `Hw1DesignPatternGenerator`:
218 |
219 | ```java
220 | private static Hw1DesignPatternGenerator instance;
221 |
222 | private Hw1DesignPatternGenerator(){
223 | logger.info("Executing constructor Hw1DesignPatternGenerator()");
224 | generateDesignPattern();
225 | }
226 |
227 | public static Hw1DesignPatternGenerator getInstance(){
228 | if (instance == null) {
229 | instance = new Hw1DesignPatternGenerator();
230 | }
231 | return instance;
232 | }
233 | ```
234 |
235 | Creating instance inside `DePaCoG` class:
236 |
237 | ```java
238 | public class DePaCoG {
239 | public static void main(String[] args){
240 |
241 | Hw1DesignPatternGenerator.getInstance();
242 | }
243 | }
244 | ```
245 |
246 | * Advantages of using Singleton pattern:
247 | * It makes sure that a single instance is instantiated for a class
248 | * Helps to get a global access point to the instance
249 | * The object is only initialized when initially requested
250 | * Disadvantages of using Singleton pattern:
251 | * Sometimes singleton pattern can hide bad code design
252 | * It requires modifications to be used in a multi threaded environment to make sure multiple instances are not created by multiple threads
253 |
254 | ------
255 |
256 | The image below shows a class diagram for the complete application. For simplicity I have selected only 3 design pattern classes (each representing its category of design patterns) out of the 23.
257 |
258 | 
259 |
260 | The class `DePaCoG` has the main() method in it. It creates an instance of class `Hw1DesignPatternGenerator` (concrete implementation of `DesignPatternGenerator` ). Methods here are for displaying menu of design patterns and getting choice of design pattern from user. Depending on user’s choice the corresponding design pattern generating class (implementation of `DesignPattern`) is instantiated to generate the design pattern source code.
261 |
262 | ------
263 |
264 | ### 4. Test Cases
265 |
266 | There are 2 test classes `DesignPatternTest` and `Hw1DesignPatternGeneratorTest`, with a total of 5 test cases.
267 |
268 | * Test Case to verify only 1 instance of `Hw1DesignPatternGenerator` is created each time.
269 | * Test Case to verify correct design pattern file is executed when user inputs the choice of design pattern.
270 | * Test Case to check null is returned on selecting incorrect design pattern choice.
271 | * Test Case to verify `generateCode()` returns `JavaFile[]` object
272 | * Test Case to verify the generated java files are written successfully in the output folder.
273 |
274 | ------
275 |
276 | ### 5. Instructions to Execute
277 |
278 | First clone the repository from GitHub.
279 |
280 | Execution can be in two modes, using default config file or using interactive environment/menu to get custom inputs from user.
281 |
282 | The `default.conf` configuration file is present at `src/main/resources`.
283 |
284 | For command line execution, locate `hw1-assembly-0.1.jar` at `target\scala-2.13`.
285 |
286 | On Windows, the command to run the jar file: `java -jar hw1-assembly-0.1.jar mode`
287 |
288 | * Executing using default config file, then `mode = 0`:
289 |
290 | * run `java -jar hw1-assembly-0.1.jar 0`
291 |
292 | 
293 |
294 | * Executing using custom inputs from user, then `mode = 1`:
295 |
296 | * run `java -jar hw1-assembly-0.1.jar 1`
297 |
298 | 
299 |
300 | For execution in IntelliJ, use `run 0` or `run 1` for the preferred way of execution (argument passed has similar purpose like in the command line method)
301 |
302 | The output java files are saved under the package name provided in the config file (or as custom input) in a folder named `outputs`. The `outputs` folder is created in the current working directory during execution.
303 |
304 | ------
305 |
306 | ### 6. Results of Execution
307 |
308 | While executing the Design Pattern Code Generator, the main() method in class `DePaCoG` is executed along with a command line argument (`0` or `1`). The command line argument is to select whether inputs will be entered via a configuration file or via inputs through the interactive environment.
309 |
310 | Here is an example of config values to create Abstract Factory design pattern.
311 |
312 | ```
313 | {
314 | designPatternChoice = "2"
315 | classes = ["Processor", "Intel", "AMD",
316 | "OperatingSystem", "OS", "ChromeOS", "Ubuntu",
317 | "LaptopFactory", "ChromeBookFactory","LinuxLaptopFactory"]
318 | packageName = "com.laptopAbstractFacty"
319 | }
320 | ```
321 |
322 | For above config input, the output files will be saved at `outputs/com/laptopAbstractFactory`.
323 |
324 | The classes created are : `Processor.java, Intel.java, AMD.java, OperatingSystem.java, OS.java, ChromeOS.java, Ubuntu.java, LaptopFactory.java, ChromeBookFactory.java,LinuxLaptopFactory.java`
325 |
326 | The image below shows the class diagram of the classes generated after executing the config input values.
327 |
328 | 
329 |
330 | In addition to Abstract Factory, the `default.conf` configuration file also contains inputs for Decorator, Adapter and Observer design patterns.
331 |
332 | The `outputs` folder is created in the current working directory during execution.
333 |
334 |
335 |
336 |
--------------------------------------------------------------------------------