diff --git a/mvvmfx-aspectj/.gitignore b/mvvmfx-aspectj/.gitignore new file mode 100644 index 000000000..03b3b8957 --- /dev/null +++ b/mvvmfx-aspectj/.gitignore @@ -0,0 +1,3 @@ +.idea +mvvmfx-aspectj.iml +target \ No newline at end of file diff --git a/mvvmfx-aspectj/README.md b/mvvmfx-aspectj/README.md new file mode 100644 index 000000000..930b641e7 --- /dev/null +++ b/mvvmfx-aspectj/README.md @@ -0,0 +1,157 @@ +# Architecture Checks with AspectJ + +AspectJ can be used to check MVVM-Architecture errors. + +These errors involve mostly on method calls or class-dependencies to unallowed layers within the MVVM pattern, like the View using Model objects or access to the _javafx.scene_ package in the ViewModel or the Model. + +Since every project has different model packages we have built a plugin to ease aspect configurations for the mvvmFX framework. +These aspects will not change any logic on the project and are only used for architecture checks for the MVVM pattern with mvvmFX. + +## Setting up Maven for mvvmFX architecture checks + + - add dependency to UI-module or project + +```xml + + org.aspectj + aspectjrt + 1.8.9 + +``` + - in the same file add the mvvmFX aspect creator plugin and the AspectJ compiler plugin + +```xml + + + de.saxsys + mvvmfx-aspect-creator-plugin + 1.6.0-SNAPSHOT + + + com.example.dao + com.example.business + com.example.mypackage + + + com.example.myotherpackage.MyClass + + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.8 + + 1.8 + 1.8 + 1.8 + true + + + + + compile + + + + + +``` + +## create the aspects and compile the project +To create the aspects we have to configure it first. To do this we add the packages or the fully qualified name of the classes in the configuration of the plugin. +The View and ViewModel classes don't have to be configured. + +After this we execute the plugin to create the aspects with "_mvn mvvmfx-aspect-creator:createaspects_". + +Compile the project or UI-module with "_mvn clean install_" or "_mvn aspectj:compile_". + +If there are some errors found the compiler will then throw error messages with the class, line of code and reason why there is an error. +If no errors were found, then good job! + +## For Multi-Module Maven Projects +If the project has Multi-Modules, where the Layers(View, ViewModel and Model) are in different Modules then the above method won't fully work. +This is because half of the Aspects won't be applied on the modules because the modules are compiled separately. + +To solve this issue we have to + +First create a new module for our aspects on the parent module. +It is important to note the "_\_". For the purpose of this example the module name will be "_aspects_" +In this module we add two plugins to our pom: +```xml + + + + de.saxsys + mvvmfx-aspect-creator-plugin + + + com.example.dao + com.example.business + com.example.mypackage + + + com.example.mypackage.SomeClass + + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.9 + + 1.8 + 1.8 + 1.8 + true + ignore + + + + + compile + + + + + + +``` + +We then create the aspects using the plugin with "_mvn mvvmfx-aspect-creator:createaspects_". This will create a folder aspect on src/main of the module. +We also have to compile this aspects with "_mvn aspectj:compile_" or "_mvn clean install_". +__NOTE: use this command while inside of the module if not the aspects will be created on the folder where the command was executed and you will have to move them to the aspects module__ + +After this we just have to add an aspectj plugin on every module that will apply our created aspects to each module. +The aspect library tag has to be directed to the module where the aspects where created + +```xml + + + + org.codehaus.mojo + aspectj-maven-plugin + 1.9 + + 1.8 + 1.8 + 1.8 + true + + + com.example + aspects + + + + + + + compile + + + + + + +``` \ No newline at end of file diff --git a/mvvmfx-aspectj/aspect-creator-plugin/pom.xml b/mvvmfx-aspectj/aspect-creator-plugin/pom.xml new file mode 100644 index 000000000..e3d9ccb84 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/pom.xml @@ -0,0 +1,51 @@ + + + + mvvmfx-aspectj + de.saxsys + 1.6.0-SNAPSHOT + + 4.0.0 + + mvvmfx-aspect-creator-plugin + maven-plugin + MvvmFX Aspect creator + + + + org.apache.maven + maven-plugin-api + 3.0 + + + + org.apache.maven.plugin-tools + maven-plugin-annotations + 3.5 + provided + + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.3 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-plugin-plugin + 3.3 + + + + + \ No newline at end of file diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/AspectMakerMojo.java b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/AspectMakerMojo.java new file mode 100644 index 000000000..7bef5e7e5 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/AspectMakerMojo.java @@ -0,0 +1,49 @@ +package de.saxsys.mvvmfx.aspectj.aspectcreator; + +import org.apache.maven.plugin.AbstractMojo; +import org.apache.maven.plugin.MojoExecutionException; +import org.apache.maven.plugin.logging.Log; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +import java.util.ArrayList; +import java.util.List; + +@Mojo(name = "createaspects") +public class AspectMakerMojo extends AbstractMojo{ + + /** + * Model Packages. + */ + @Parameter + private List modelPackages = new ArrayList<>(); + + /** + * Model Classes. + */ + @Parameter + private List modelClasses = new ArrayList<>(); + + public void execute() throws MojoExecutionException { + Log log = getLog(); + log.info("Creating aspects"); + + modelPackages.forEach((String p) -> { + p = p.trim() + "..*"; + Config.addToModel(p); + log.info("added as model: "+p); + }); + + modelClasses.forEach((String c) -> { + c = c.trim(); + Config.addToModel(c); + log.info("added as model: "+c); + + }); + + CodeGenerator codeGenerator = new CodeGenerator(); + codeGenerator.createAspects(); + + log.info("Aspects created"); + } +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/CodeGenerator.java b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/CodeGenerator.java new file mode 100644 index 000000000..2d3cf24b3 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/CodeGenerator.java @@ -0,0 +1,64 @@ +package de.saxsys.mvvmfx.aspectj.aspectcreator; + +import java.io.File; +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Collections; + +class CodeGenerator { + + CodeGenerator() { + } + + private Pointcut withinModelPointcut = new Pointcut("withinModel()", "within", Config.modelInterface); + private Pointcut withinViewModelPointcut = new Pointcut("withinViewModel()", "within", Config.viewModelInterface); + private Pointcut withinViewPointcut = new Pointcut("withinView()","within", Config.viewInterfaces); + + void createAspects() { + Path aspectsPath = Paths.get("./src/main/aspect"); + if (aspectsPath.toFile().exists()) { + deleteFiles(aspectsPath); + } + JarFileCopier.copyResourceDirectory(); + createWithinMVVMAspect(); + } + + private void createWithinMVVMAspect() { + String aspect = "package de.saxsys.mvvmfx.aspectj.aspects; \n\n" + + "public abstract aspect " + "WithinMVVM" + " {\n\n" + + " public " + withinModelPointcut.toString() + "\n" + + " public " + withinViewPointcut.toString() + "\n" + + " public " + withinViewModelPointcut.toString() + "\n\n" + + " " + Declaration.declareParents(Config.modelInterface, Config.model) + + "\n}"; + + Path withinMVVMPath = Paths.get("./src/main/aspect/de/saxsys/mvvmfx/aspectj/aspects/WithinMVVM.aj"); + byte data[] = aspect.getBytes(); + try { + if (!withinMVVMPath.toFile().exists()) { + Files.createFile(withinMVVMPath); + Files.write(withinMVVMPath, data); + } + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void deleteFiles(Path dir){ + try { + + Files.walk(dir) + .map(Path::toFile) + .sorted(Collections.reverseOrder()) + .forEach(File::delete); + + } catch (IOException e) { + e.printStackTrace(); + } + + } + + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Config.java b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Config.java new file mode 100644 index 000000000..416517557 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Config.java @@ -0,0 +1,17 @@ +package de.saxsys.mvvmfx.aspectj.aspectcreator; + +import java.util.ArrayList; + +final class Config { + + static ArrayList model = new ArrayList<>(); + static String modelInterface = "Model+"; + static String viewInterfaces = "de.saxsys.mvvmfx.JavaView+ || de.saxsys.mvvmfx.FxmlView+"; + static String viewModelInterface = "de.saxsys.mvvmfx.ViewModel+"; + + + static void addToModel(String packageName){ + model.add(packageName); + } + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Declaration.java b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Declaration.java new file mode 100644 index 000000000..78f6ff9e4 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Declaration.java @@ -0,0 +1,25 @@ +package de.saxsys.mvvmfx.aspectj.aspectcreator; + +import java.util.ArrayList; + +class Declaration { + + static String declareParents(String parentName, ArrayList signatures) { + if(signatures.isEmpty()) return ""; + + StringBuilder declaration = new StringBuilder("declare parents: "); + + for(int i = 0; i !jarEntry.isDirectory()) + .map(JarEntry::getName) + .filter(fileName -> fileName.startsWith(path)) + .forEach(JarFileCopier::copyFile); + } + + private static void copyFile(String fileName) { + try { + Path target = Paths.get("./src/main/aspect/" + fileName); + + FileOutputStream out = new FileOutputStream(target.toFile()); + byte[] byteArray = new byte[1024]; + int i; + //Copies file from .jar to a the target file + InputStream in = JarFileCopier.class.getClassLoader().getResourceAsStream(fileName); + while ((i = in.read(byteArray)) > 0) { + out.write(byteArray, 0, i); + } + + out.close(); + in.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Pointcut.java b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Pointcut.java new file mode 100644 index 000000000..337d89f69 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/java/de/saxsys/mvvmfx/aspectj/aspectcreator/Pointcut.java @@ -0,0 +1,26 @@ +package de.saxsys.mvvmfx.aspectj.aspectcreator; + +class Pointcut { + + + private String name; + private String signature; + private String primitive; + + Pointcut(String name, String primitive, String signature) { + this.name = name; + this.primitive = primitive; + this.signature = signature; + + } + + @Override + public String toString() { + return "pointcut " + name + ": " + + this.getExpression() + ";"; + } + + private String getExpression() { + return primitive + "(" + signature + ")"; + } +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/Model.java b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/Model.java new file mode 100644 index 000000000..9954a8b2c --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/Model.java @@ -0,0 +1,7 @@ +package de.saxsys.mvvmfx.aspectj.aspects; + +/** + * Created by gerardo.balderas on 31.08.2016. + */ +public interface Model { +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/Constructors.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/Constructors.aj new file mode 100644 index 000000000..913211106 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/Constructors.aj @@ -0,0 +1,15 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + + +import de.saxsys.mvvmfx.aspectj.aspects.WithinMVVM; + +/** + * Created by gerardo.balderas on 24.08.2016. + */ +public abstract aspect Constructors extends WithinMVVM { + + pointcut newViewCall(): call(de.saxsys.mvvmfx.FxmlView+.new(..)) || call(de.saxsys.mvvmfx.JavaView+.new(..)); + pointcut newViewModelCall(): call(de.saxsys.mvvmfx.ViewModel+.new(..)); + pointcut newModelCall(): call(de.saxsys.mvvmfx.aspectj.aspects.Model+.new(..)); + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ConstructorsWarning.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ConstructorsWarning.aj new file mode 100644 index 000000000..90384f467 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ConstructorsWarning.aj @@ -0,0 +1,13 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + +/** + * Created by gerardo.balderas on 14.09.2016. + */ +public aspect ConstructorsWarning extends Constructors{ + + + declare warning: withinView() && newModelCall(): "A Model Instance was made within the View Layer"; + declare warning: withinViewModel() && newViewCall(): "A View Instance was made within the Viewmodel Layer"; + declare warning: withinModel() && newViewCall(): "A View Instance was made within the Model Layer"; + declare warning: withinModel() && newViewModelCall(): "A ViewModel Instance was made within the Model Layer"; +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/Instancevariables.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/Instancevariables.aj new file mode 100644 index 000000000..82cfe203a --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/Instancevariables.aj @@ -0,0 +1,49 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + + +import de.saxsys.mvvmfx.aspectj.aspects.WithinMVVM; + +/** + * Created by gerardo.balderas on 24.08.2016. + */ +public abstract aspect Instancevariables extends WithinMVVM { + + pointcut getModelVarInView(): get(de.saxsys.mvvmfx.aspectj.aspects.Model+ de.saxsys.mvvmfx.FxmlView+.*) || + get(de.saxsys.mvvmfx.aspectj.aspects.Model+ de.saxsys.mvvmfx.JavaView+.*); + pointcut getGenModelVarInView(): get(*..* de.saxsys.mvvmfx.FxmlView+.*) || + get(*..* de.saxsys.mvvmfx.JavaView+.*); + + pointcut getViewVarInViewModel(): get(de.saxsys.mvvmfx.FxmlView+ de.saxsys.mvvmfx.ViewModel+.*) || + get(de.saxsys.mvvmfx.JavaView+ de.saxsys.mvvmfx.ViewModel+.*); + pointcut getGenViewVarInViewModel(): get(*..* de.saxsys.mvvmfx.ViewModel+.*) || + get(*..* de.saxsys.mvvmfx.ViewModel+.*); + + pointcut getViewVarInModel(): get(de.saxsys.mvvmfx.FxmlView+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*) || + get(de.saxsys.mvvmfx.JavaView+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut getGenViewVarInModel(): get(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*) || + get(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut getViewModelVarInModel(): get(de.saxsys.mvvmfx.ViewModel+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut getGenViewModelVarInModel(): get(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + + + + pointcut setModelVarInView(): set(de.saxsys.mvvmfx.aspectj.aspects.Model+ de.saxsys.mvvmfx.FxmlView+.*) || + set(de.saxsys.mvvmfx.aspectj.aspects.Model+ de.saxsys.mvvmfx.JavaView+.*); + pointcut setGenModelVarInView(): set(*..* de.saxsys.mvvmfx.FxmlView+.*) || + set(*..* de.saxsys.mvvmfx.JavaView+.*); + + pointcut setViewVarInViewModel(): set(de.saxsys.mvvmfx.FxmlView+ de.saxsys.mvvmfx.ViewModel+.*) || + set(de.saxsys.mvvmfx.JavaView+ de.saxsys.mvvmfx.ViewModel+.*); + pointcut setGenViewVarInViewModel(): set(*..* de.saxsys.mvvmfx.ViewModel+.*) || + set(*..* de.saxsys.mvvmfx.ViewModel+.*); + + + pointcut setViewVarInModel(): set(de.saxsys.mvvmfx.FxmlView+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*) || + set(de.saxsys.mvvmfx.JavaView+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut setViewModelVarInModel(): set(de.saxsys.mvvmfx.ViewModel+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut setGenViewVarInModel(): set(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*) || + set(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut setGenViewModelVarInModel(): set(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/InstancevariablesWarning.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/InstancevariablesWarning.aj new file mode 100644 index 000000000..df1ef8297 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/InstancevariablesWarning.aj @@ -0,0 +1,22 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + +/** + * Created by gerardo.balderas on 14.09.2016. + */ +public aspect InstancevariablesWarning extends Instancevariables { + + declare warning: getModelVarInView() || getGenModelVarInView(): "Model variable was accessed in View layer"; + + declare warning: getViewVarInModel() || getGenViewVarInModel(): "View variable was accessed in ViewModel layer"; + + declare warning: getViewVarInModel() || getGenViewVarInModel(): "View variable was accessed in Model layer"; + declare warning: getViewModelVarInModel() || getGenViewModelVarInModel(): "ViewModel variable was accessed in Model layer"; + + + declare warning: setModelVarInView() || setGenModelVarInView(): "Model variable was set in View layer"; + + declare warning: setViewVarInModel() || setGenViewVarInModel(): "View variable was set in ViewModel layer"; + + declare warning: setViewVarInModel() || setGenViewVarInModel(): "View variable was set in Model layer"; + declare warning: setViewModelVarInModel() || setGenViewModelVarInModel(): "ViewModel set was found in Model layer"; +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/MethodCalls.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/MethodCalls.aj new file mode 100644 index 000000000..2771511c2 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/MethodCalls.aj @@ -0,0 +1,26 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + + +import de.saxsys.mvvmfx.aspectj.aspects.WithinMVVM; + +/** + * Created by gerardo.balderas on 24.08.2016. + */ +public abstract aspect MethodCalls extends WithinMVVM { + + pointcut callToView(): call(* de.saxsys.mvvmfx.FxmlView+.*(..)) || + call(* de.saxsys.mvvmfx.JavaView+.*(..)); + pointcut callToViewModel(): call(* de.saxsys.mvvmfx.ViewModel+.*(..)); + pointcut callToModel(): call(* de.saxsys.mvvmfx.aspectj.aspects.Model+.*(..)); + + + pointcut callWithModelArgs(): call(* *.*(.., de.saxsys.mvvmfx.aspectj.aspects.Model+, ..)); + pointcut callWithGenericArgsModel(): call(* *.*(.., *..*, ..)); + pointcut callWithViewModelArgs(): call(* *.*(.., de.saxsys.mvvmfx.ViewModel+, ..)); + pointcut callWithGenericArgsViewModel(): call(* *.*(.., *..*, ..)); + pointcut callWithViewArgs(): call(* *.*(.., de.saxsys.mvvmfx.FxmlView+, ..)) || + call(* *.*(.., de.saxsys.mvvmfx.JavaView+, ..)); + pointcut callWithGenericArgsView(): call(* *.*(.., *..*, ..)) || + call(* *.*(.., *..*, ..)); + +} \ No newline at end of file diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/MethodCallsWarning.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/MethodCallsWarning.aj new file mode 100644 index 000000000..f72c3ffd7 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/MethodCallsWarning.aj @@ -0,0 +1,24 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + +/** + * Created by gerardo.balderas on 14.09.2016. + */ +public aspect MethodCallsWarning extends MethodCalls{ + + declare warning: withinView() && callToModel():"The Model layer was called within the View layer"; + declare warning: withinViewModel() && callToView():"The View layer was called within the Viewmodel layer"; + declare warning: withinModel() && withinView():"The View layer was called within the Model layer"; + declare warning: withinModel() && withinViewModel(): "The ViewModel layer was called within the Model layer"; + + + declare warning: withinModel() && callWithViewModelArgs(): "A method call with arguments of type ViewModel was made within the Model layer"; + declare warning: withinModel() && callWithGenericArgsViewModel(): "A method call with arguments of generic type ViewModel was made within the Model layer"; + declare warning: withinModel() && callWithViewArgs(): "A method call with arguments of type View was made within the Model layer"; + declare warning: withinModel() && callWithGenericArgsView(): "A method call with arguments of generic type ViewModel was made within the Model layer"; + + declare warning: withinViewModel() && callWithViewArgs(): "A method call with arguments of type View was made within the ViewModel layer"; + declare warning: withinViewModel() && callWithGenericArgsView(): "A method call with arguments of generic type View was made within the ViewModel layer"; + + declare warning: withinView() && callWithModelArgs(): "A method clal with arguments of type Model was made within the View layer"; + declare warning: withinView() && callWithGenericArgsModel(): "A method call with arguments of generic type Model was made within the View layer"; +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ReturnValues.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ReturnValues.aj new file mode 100644 index 000000000..4bc5952a3 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ReturnValues.aj @@ -0,0 +1,36 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + + +import de.saxsys.mvvmfx.aspectj.aspects.WithinMVVM; + +/** + * Created by gerardo.balderas on 24.08.2016. + */ +public abstract aspect ReturnValues extends WithinMVVM { + + // MODEL + pointcut executionModelReturn(): execution(de.saxsys.mvvmfx.aspectj.aspects.Model+ *.*(..)); + pointcut executionGenTypeModel(): execution(*..* *.*(..)); + pointcut callModelReturn(): call(de.saxsys.mvvmfx.aspectj.aspects.Model+ *.*(..)); + pointcut callGenTypeModel(): call(*..* *.*(..)); + + // VIEW-MODEL + pointcut executionViewModelReturn(): execution(de.saxsys.mvvmfx.ViewModel+ *.*(..)); + pointcut executionGenTypeViewModel(): execution(*..* *.*(..)); + pointcut callViewModelReturn(): call(de.saxsys.mvvmfx.ViewModel+ *.*(..)); + pointcut callGenTypeViewModel(): call(*..* *.*(..)); + + // VIEW + pointcut executionViewReturn(): execution(de.saxsys.mvvmfx.FxmlView+ *.*(..)) || + execution(de.saxsys.mvvmfx.JavaView+ *.*(..)); + pointcut executionGenTypeView(): execution(*..* *.*(..)) || + execution(*..* *.*(..)); + pointcut callViewReturn(): call(de.saxsys.mvvmfx.FxmlView+ *.*(..)) || + call(de.saxsys.mvvmfx.JavaView+ *.*(..)); + pointcut callGenTypeView(): call(*..* *.*(..)) || + call(*..* *.*(..)); + + + + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ReturnValuesWarning.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ReturnValuesWarning.aj new file mode 100644 index 000000000..44ec62ac0 --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/ReturnValuesWarning.aj @@ -0,0 +1,50 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + +/** + * Created by gerardo.balderas on 14.09.2016. + */ +public aspect ReturnValuesWarning extends ReturnValues{ + + // MODEL + declare warning: withinModel() && executionViewModelReturn(): + "A method with a return value of type ViewModel was executed within the Model layer"; + declare warning: withinModel() && executionGenTypeViewModel(): + "A method with a return value with generic type of ViewModel was executed within the Model layer"; + declare warning: withinModel() && callViewModelReturn(): + "A method with a return value of type ViewModel called within the Model layer"; + declare warning: withinModel() && callGenTypeViewModel(): + "A method with a return value with generic type of ViewModel was called within the Model layer"; + + declare warning: withinModel() && executionViewReturn(): + "A method with a return value of type ViewModel was executed within the Model layer"; + declare warning: withinModel() && executionGenTypeView(): + "A method with a return value with generic type of View was executed within the Model layer"; + declare warning: withinModel() && callViewReturn(): + "A method with a return value with of type View was called within the Model layer"; + declare warning: withinModel() && callGenTypeView(): + "A method with a return value with generic type of View was called within the Model layer"; + + + // VIEW-MODEL + declare warning: withinViewModel() && executionViewReturn(): + "A method with a return value of type View was executed within the ViewModel layer"; + declare warning: withinViewModel() && executionGenTypeView(): + "A method with a return value with generic type of View was executed within the ViewModel layer"; + declare warning: withinViewModel() && callViewReturn(): + "A method with a return value of type View was called within the ViewModel layer"; + declare warning: withinViewModel() && callGenTypeView(): + "A method with a return value with generic type of View was called within the ViewModel layer"; + + + // VIEW + declare warning: withinView() && executionModelReturn(): + "Method with a return value of type Model was executed in the View layer"; + declare warning: withinView() && executionGenTypeModel(): + "A method with a return value with generic type of Model was executed within the View layer"; + declare warning: withinView() && callModelReturn(): + "A method with a return value of type Model called within the View layer"; + declare warning: withinView() && callGenTypeModel(): + "A method with a return value with generic type of Model was called within the View layer"; + + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/UIElements.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/UIElements.aj new file mode 100644 index 000000000..bae837b9b --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/UIElements.aj @@ -0,0 +1,32 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + + +import de.saxsys.mvvmfx.aspectj.aspects.WithinMVVM; + +/** + * Created by gerardo.balderas on 24.08.2016. + */ +public abstract aspect UIElements extends WithinMVVM { + + pointcut callUILibrary(): call(* javafx.scene..*+.*(..)) || call(javafx.scene..*+.new(..)); + pointcut callForUIElements(): call(javafx.scene..*+ *.*(..)); + pointcut executionUIElements(): execution(javafx.scene..*+ *.*(..)); + + pointcut callGenericUIElement(): call(*..* *.*(..)); + pointcut executionGenericUIElements(): execution(*..* *.*(..)); + + + + pointcut setUIElementsOnModel(): set(javafx.scene..*+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut setGenericUIElementsOnModel(): set(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + + pointcut setUIElementsOnViewModel(): set(javafx.scene..*+ de.saxsys.mvvmfx.ViewModel+.*); + pointcut setGenericUIElementsOnViewModel(): set(*..* de.saxsys.mvvmfx.ViewModel+.*); + + pointcut getUIElementsOnModel(): get(javafx.scene..*+ de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + pointcut getGenericUIElementsOnModel(): get(*..* de.saxsys.mvvmfx.aspectj.aspects.Model+.*); + + pointcut getUIElementsOnViewModel(): get(javafx.scene..*+ de.saxsys.mvvmfx.ViewModel+.*); + pointcut getGenericUIElementsOnViewModel(): get(*..* de.saxsys.mvvmfx.ViewModel+.*); + +} diff --git a/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/UIElementsWarning.aj b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/UIElementsWarning.aj new file mode 100644 index 000000000..ea3a94e6b --- /dev/null +++ b/mvvmfx-aspectj/aspect-creator-plugin/src/main/resources/de/saxsys/mvvmfx/aspectj/aspects/warning/UIElementsWarning.aj @@ -0,0 +1,47 @@ +package de.saxsys.mvvmfx.aspectj.aspects.warning; + +/** + * Created by gerardo.balderas on 14.09.2016. + */ +public aspect UIElementsWarning extends UIElements { + + declare warning: withinViewModel() && callUILibrary(): + "The UI-library were called within the ViewModel layer"; + declare warning: withinModel() && callUILibrary(): + "The UI-library were called within the Model layer"; + + declare warning: withinViewModel() && callForUIElements(): + "A UI-element was called within the ViewModel layer"; + declare warning: withinModel() && callForUIElements(): + "A UI-element was called within the Model layer"; + + declare warning: withinViewModel() && executionUIElements(): + "Methods returning UI-elements were executed within the ViewModel layer"; + declare warning: withinModel() && executionUIElements(): + "Methods returning UI-elements were executed within the Model layer"; + + declare warning: withinViewModel() && executionGenericUIElements(): + "Methods returning a generic UI-Element were executed wihtin the ViewModel layer"; + declare warning: withinModel() && executionGenericUIElements(): + "Methods returning a generic UI-Element were executed wihtin the Model layer"; + + + declare warning: setUIElementsOnModel(): + "UI-Element was set on the Model layer"; + declare warning: setGenericUIElementsOnModel(): + "a generic UI-Element was set on the Model layer"; + declare warning: setUIElementsOnViewModel(): + "UI-Element was set on the ViewModel layer"; + declare warning: setGenericUIElementsOnViewModel(): + "UI-Element was set on the ViewModel layer"; + + declare warning: getUIElementsOnModel(): + "UI-Element was accessed on the Model layer"; + declare warning: getGenericUIElementsOnModel(): + "a generic UI-Element was accessed on the Model layer"; + declare warning: getUIElementsOnViewModel(): + "UI-Element was accessed on the ViewModel layer"; + declare warning: getGenericUIElementsOnViewModel(): + "UI-Element was accessed on the ViewModel layer"; + +} diff --git a/mvvmfx-aspectj/pom.xml b/mvvmfx-aspectj/pom.xml new file mode 100644 index 000000000..0fb7fd542 --- /dev/null +++ b/mvvmfx-aspectj/pom.xml @@ -0,0 +1,26 @@ + + + + mvvmfx-parent + de.saxsys + 1.6.0-SNAPSHOT + + 4.0.0 + + mvvmfx-aspectj + pom + + aspect-creator-plugin + + + + + + org.aspectj + aspectjrt + 1.8.9 + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index 205305804..0e88e1c09 100644 --- a/pom.xml +++ b/pom.xml @@ -84,6 +84,7 @@ mvvmfx-utils mvvmfx-testing-utils mvvmfx-easydi + mvvmfx-aspectj @@ -124,6 +125,11 @@ ${project.version} test + + de.saxsys + mvvmfx-aspectj + ${project.version} + org.slf4j