diff --git a/Kieker.WebGUI/.pmd b/Kieker.WebGUI/.pmd index 5bed86c3307255547c37a1f1c5fc435fa972ee5e..8305b0f7e8abc632746c5f9ef4f8578f9128fb42 100644 --- a/Kieker.WebGUI/.pmd +++ b/Kieker.WebGUI/.pmd @@ -243,10 +243,6 @@ <name>AvoidReassigningParameters</name> <ruleset>Design Rules</ruleset> </rule> - <rule> - <name>AvoidSynchronizedAtMethodLevel</name> - <ruleset>Design Rules</ruleset> - </rule> <rule> <name>BadComparison</name> <ruleset>Design Rules</ruleset> diff --git a/Kieker.WebGUI/.project b/Kieker.WebGUI/.project index 7007fdd75420152743009065b7fc886fdb07c1fc..5a6290a8f740e73efa8a3f67e4dd595cff728d7d 100644 --- a/Kieker.WebGUI/.project +++ b/Kieker.WebGUI/.project @@ -25,11 +25,17 @@ <arguments> </arguments> </buildCommand> + <buildCommand> + <name>net.sf.eclipsecs.core.CheckstyleBuilder</name> + <arguments> + </arguments> + </buildCommand> </buildSpec> <natures> <nature>org.eclipse.m2e.core.maven2Nature</nature> <nature>org.eclipse.jdt.core.javanature</nature> <nature>net.sourceforge.pmd.eclipse.plugin.pmdNature</nature> <nature>edu.umd.cs.findbugs.plugin.eclipse.findbugsNature</nature> + <nature>net.sf.eclipsecs.core.CheckstyleNature</nature> </natures> </projectDescription> diff --git a/Kieker.WebGUI/config/quality-config/cs-conf.xml b/Kieker.WebGUI/config/quality-config/cs-conf.xml index e0caec3380e526a9416b5bffee4e952b7e0c4f55..30cb12189eb4cace68a72832968516bbeda76639 100644 --- a/Kieker.WebGUI/config/quality-config/cs-conf.xml +++ b/Kieker.WebGUI/config/quality-config/cs-conf.xml @@ -1,1182 +1,255 @@ -<?xml version="1.0"?> -<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.1//EN" "http://www.puppycrawl.com/dtds/configuration_1_1.dtd"> - +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN" "http://www.puppycrawl.com/dtds/configuration_1_3.dtd"> + +<!-- + This configuration file was written by the eclipse-cs plugin configuration editor +--> +<!-- + Checkstyle-Configuration: CS-Config + Description: none +--> <module name="Checker"> - - <!-- KIEKER default is warning instead of error --> - <property name="severity" value="warning"/> - - <!-- KIEKER Filter --> - <module name="SuppressWithNearbyCommentFilter"> - <property name="commentFormat" value="NOCS"/> - <property name="checkFormat" value=".*"/> - <property name="influenceFormat" value="0"/> + <property name="severity" value="warning"/> + <module name="TreeWalker"> + <property name="tabWidth" value="4"/> + <module name="FileContentsHolder"/> + <module name="AnnotationUseStyle"/> + <module name="MissingDeprecated"> + <property name="severity" value="info"/> </module> - - <!-- - <property name="basedir" value=""/> - <property name="localeCountry" value=""/> JVM locale country - <property name="localeLanguage" value=""/> JVM locale language - <property name="charset" value=""/> JVM file.encoding property - !--> - - - <!-- - !________________________________________________________________________________________ - ! - ! D U P L I C A T E S - !________________________________________________________________________________________ - !--> - <!-- Performs a line-by-line comparison of all code lines and reports duplicate code. !--> - <!-- See http://checkstyle.sf.net/config_duplicates.html !--> - <!-- KIEKER Does not work with headers!! - <module name="StrictDuplicateCode"> - <property name="min" value="12"/> - <property name="fileExtensions" value=""/> + <module name="PackageAnnotation"/> + <module name="SuppressWarnings"> + <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, ANNOTATION_FIELD_DEF, ENUM_CONSTANT_DEF, PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF, CTOR_DEF"/> </module> - --> - - <!-- - !________________________________________________________________________________________ - ! - ! H E A D E R S - !________________________________________________________________________________________ - !--> - <!-- NOTE: You may enable zero or one of these header checks, but not both. !--> - - <!-- Checks that a source file begins with a specified header. !--> - <!-- See http://checkstyle.sf.net/config_header.html !--> - <!-- KIEKER !--> - <module name="Header"> - <!--<property name="headerFile" value="lib/checkstyle-5.4/header.txt"/>--> - <!--<property name="charset" value=""/>--> - <property name="header" value="/***************************************************************************\n * Copyright 2012 Kieker Project (http://kieker-monitoring.net)\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n ***************************************************************************/\n"/> - <property name="ignoreLines" value="2"/> - <property name="fileExtensions" value="java"/> + <module name="AvoidNestedBlocks"> + <property name="allowInSwitchCase" value="true"/> </module> - - <!-- Checks the header of a source file against a header file that contains a regular expression !--> - <!-- for each line of the source header. !--> - <!-- See http://checkstyle.sf.net/config_header.html !--> - <!-- Default: OFF - <module name="RegexpHeader"> - <property name="headerFile" value=""/> - <property name="charset" value=""/> - <property name="header" value=""/> - <property name="multiLines" value=""/> - <property name="fileExtensions" value=""/> + <module name="EmptyBlock"> + <property name="tokens" value="LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF, LITERAL_FOR, LITERAL_TRY, LITERAL_WHILE, INSTANCE_INIT, STATIC_INIT"/> </module> - !--> - - <!-- - !________________________________________________________________________________________ - ! - ! J A V A D O C S - !________________________________________________________________________________________ - !--> - <!-- Checks that each Java package has a Javadoc file used for commenting. !--> - <!-- See http://checkstyle.sourceforge.net/config_javadoc.html#JavadocPackage !--> - <!-- KIEKER: OFF - <module name="JavadocPackage"> - <property name="severity" value="info"/> - <property name="allowLegacy" value="false"/> + <module name="LeftCurly"> + <property name="maxLineLength" value="165"/> + <property name="tokens" value="CLASS_DEF, CTOR_DEF, INTERFACE_DEF, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_SWITCH, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, METHOD_DEF"/> </module> - !--> - - <!-- - !________________________________________________________________________________________ - ! - ! R E G E X P - !________________________________________________________________________________________ - !--> - <!-- A check for detecting that matches across multiple lines. Works with any file type. !--> - <!-- See http://checkstyle.sourceforge.net/config_regexp.html#RegexpMultiline !--> - <!-- Default: OFF - <module name="RegexpMultiline"> - <property name="format" value=""/> - <property name="message" value=""/> - <property name="ignoreCase" value="false"/> - <property name="minimum" value="0"/> - <property name="maximum" value="0"/> - <property name="fileExtensions" value=""/> + <module name="NeedBraces"> + <property name="tokens" value="LITERAL_DO, LITERAL_ELSE, LITERAL_IF, LITERAL_FOR, LITERAL_WHILE"/> </module> - !--> - - <!-- A check for detecting single lines that match a supplied regular expression. Works with any file type. !--> - <!-- See http://checkstyle.sourceforge.net/config_regexp.html#RegexpSingleline !--> - <!-- Default: OFF - <module name="RegexpSingleline"> - <property name="format" value=""/> - <property name="message" value=""/> - <property name="ignoreCase" value="false"/> - <property name="minimum" value="0"/> - <property name="maximum" value="0"/> - <property name="fileExtensions" value=""/> + <module name="RightCurly"> + <property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE"/> </module> - !--> - - <!-- - !________________________________________________________________________________________ - ! - ! M I S C E L L A N E O U S - !________________________________________________________________________________________ - !--> - <!-- Checks whether files end with a new line. !--> - <!-- See http://checkstyle.sf.net/config_misc.html#NewlineAtEndOfFile !--> - <module name="NewlineAtEndOfFile"> - <property name="lineSeparator" value="system"/> - <property name="fileExtensions" value="*.*"/> + <module name="FinalClass"/> + <module name="HideUtilityClassConstructor"/> + <module name="InnerTypeLast"/> + <module name="InterfaceIsType"/> + <module name="MutableException"/> + <module name="VisibilityModifier"> + <property name="protectedAllowed" value="true"/> + <property name="publicMemberPattern" value="^serialVersionUID$"/> </module> - - <!-- Checks that property files contain the same keys. !--> - <!-- See http://checkstyle.sf.net/config_misc.html#Translation !--> - <module name="Translation"> - <property name="fileExtensions" value="properties"/> + <module name="ArrayTrailingComma"/> + <module name="AvoidInlineConditionals"> + <property name="severity" value="ignore"/> + <metadata name="net.sf.eclipsecs.core.lastEnabledSeverity" value="inherit"/> </module> - - - <!-- - !________________________________________________________________________________________ - ! - ! S I Z E V I O L A T I O N S - !________________________________________________________________________________________ - !--> - <!-- Checks for long source files. !--> - <!-- See http://checkstyle.sf.net/config_sizes.html !--> - <module name="FileLength"> - <property name="max" value="2000"/> - <property name="fileExtensions" value=""/> + <module name="CovariantEquals"/> + <module name="DeclarationOrder"/> + <module name="DefaultComesLast"/> + <module name="EmptyStatement"/> + <module name="EqualsAvoidNull"/> + <module name="EqualsHashCode"/> + <module name="FallThrough"> + <property name="reliefPattern" value="fallthru|falls??through"/> </module> - - - <!-- - !________________________________________________________________________________________ - ! - ! W H I T E S P A C E - !________________________________________________________________________________________ - !--> - <!-- Checks that there are no tab characters ('\t') in the source code. !--> - <!-- See http://checkstyle.sourceforge.net/config_whitespace.html#FileTabCharacter !--> - <!-- KIEKER we use TABs - <module name="FileTabCharacter"> - <property name="eachLine" value="false"/> - <property name="fileExtensions" value=""/> + <module name="FinalLocalVariable"/> + <module name="HiddenField"> + <property name="tokens" value="PARAMETER_DEF, VARIABLE_DEF"/> + <property name="ignoreConstructorParameter" value="true"/> + <property name="ignoreSetter" value="true"/> </module> - --> - - <module name="TreeWalker"> - <!-- KIEKER --> - <property name="tabWidth" value="4"/> - <module name="FileContentsHolder"/> - - <!-- - !________________________________________________________________________________________ - ! - ! A N N O T A T I O N S - !________________________________________________________________________________________ - !--> - <!-- This check controls the usage style of annotations. !--> - <!-- See http://checkstyle.sourceforge.net/config_annotation.html#AnnotationUseStyle !--> - <module name ="AnnotationUseStyle"> - <property name="elementStyle" value="compact_no_array"/> - <property name="closingParens" value="never"/> - <property name="trailingArrayComma" value="never"/> - </module> - - <!-- Verifies that both the java.lang.Deprecated import is present and the @deprecated Javadoc tag is present when either is present. !--> - <!-- See http://checkstyle.sourceforge.net/config_annotation.html#MissingDeprecated !--> - <!-- KIEKER --> - <module name="MissingDeprecated"> - <property name="severity" value="info"/> - </module> - - <!-- Verifies that the java.lang.Override annotation is present when the {@inheritDoc} javadoc tag is present. !--> - <!-- See http://checkstyle.sourceforge.net/config_annotation.html#MissingOverride !--> - <!-- problems with Java 1.5 - <module name="MissingOverride"> - <property name="javaFiveCompatibility" value="false"/> - </module> - --> - - <!-- This check makes sure that all package annotations are in the package-info.java file. !--> - <!-- See http://checkstyle.sourceforge.net/config_annotation.html#PackageAnnotation !--> - <module name="PackageAnnotation"/> - - <!-- This check allows you to specify what warnings that SuppressWarnings is not allowed to suppress. !--> - <!-- You can also specify a list of TokenTypes that the configured warning(s) cannot be suppressed on. !--> - <!-- See http://checkstyle.sourceforge.net/config_annotation.html#SuppressWarnings !--> - <module name="SuppressWarnings"> - <property name="format" value="^$|^\s+$"/> - <property name="tokens" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF, ANNOTATION_DEF, - ANNOTATION_FIELD_DEF, ENUM_CONSTANT_DEF, PARAMETER_DEF, - VARIABLE_DEF, METHOD_DEF, CTOR_DEF"/> - </module> - - - <!-- - !________________________________________________________________________________________ - ! - ! B L O C K S - !________________________________________________________________________________________ - !--> - <!-- Finds nested blocks, i.e. blocks that are used freely in the code. !--> - <!-- See http://checkstyle.sf.net/config_blocks.html !--> - <!-- KIEKER allowInSwitchCase !--> - <module name="AvoidNestedBlocks"> - <property name="allowInSwitchCase" value="true"/> - </module> - - <!-- Checks for empty blocks. !--> - <!-- See http://checkstyle.sf.net/config_blocks.html !--> - <!-- KIEKER removed LITERAL_CATCH !--> - <module name="EmptyBlock"> - <property name="option" value="stmt"/> - <property name="tokens" value="LITERAL_DO, - LITERAL_ELSE, LITERAL_FINALLY, LITERAL_IF, LITERAL_FOR, - LITERAL_TRY, LITERAL_WHILE, INSTANCE_INIT, STATIC_INIT"/> - </module> - - <!-- Checks for the placement of left curly braces ('{') for code blocks. !--> - <!-- See http://checkstyle.sf.net/config_blocks.html !--> - <module name="LeftCurly"> - <property name="option" value="eol"/> - <property name="maxLineLength" value="165"/> - <property name="tokens" value="CLASS_DEF, CTOR_DEF, - INTERFACE_DEF, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, - LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_SWITCH, - LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, - METHOD_DEF"/> - </module> - - <!-- Checks for braces around code blocks. !--> - <!-- See http://checkstyle.sf.net/config_blocks.html !--> - <module name="NeedBraces"> - <property name="tokens" value="LITERAL_DO, LITERAL_ELSE, LITERAL_IF, LITERAL_FOR, LITERAL_WHILE"/> - </module> - - <!-- Checks the placement of right curly braces ('}') for else, try, and catch tokens. !--> - <!-- See http://checkstyle.sf.net/config_blocks.html !--> - <module name="RightCurly"> - <property name="option" value="same"/> - <property name="tokens" value="LITERAL_TRY, LITERAL_CATCH, LITERAL_FINALLY, LITERAL_IF, LITERAL_ELSE"/> - <property name="shouldStartLine" value="true"/> - </module> - - - <!-- - !________________________________________________________________________________________ - ! - ! C L A S S D E S I G N - !________________________________________________________________________________________ - !--> - <!-- Checks that classes are designed for extension. !--> - <!-- See http://checkstyle.sf.net/config_design.html !--> - <!-- Default: OFF - <module name="DesignForExtension"/> - !--> - - <!-- Checks that a class which has only private constructors is declared as final. !--> - <!-- See http://checkstyle.sf.net/config_design.html !--> - <module name="FinalClass"/> - - <!-- Make sure that utility classes (classes that contain only static methods) do not have a public constructor. !--> - <!-- See http://checkstyle.sf.net/config_design.html !--> - <module name="HideUtilityClassConstructor"/> - - <!-- Check nested (internal) classes/interfaces are declared at the bottom of the class after all method and field declarations. !--> - <!-- See http://checkstyle.sourceforge.net/config_design.html#InnerTypeLast !--> - <module name="InnerTypeLast"/> - - <!-- Implements Bloch, Effective Java, Item 17 - Use Interfaces only to define types. !--> - <!-- See http://checkstyle.sf.net/config_design.html !--> - <module name="InterfaceIsType"> - <property name="allowMarkerInterfaces" value="true"/> - </module> - - <!-- Ensures that exceptions (defined as any class name conforming to some regular expression) are immutable. !--> - <!-- That is, have only final fields. !--> - <!-- See http://checkstyle.sf.net/config_design.html !--> - <module name="MutableException"> - <property name="format" value="^.*Exception$|^.*Error$"/> - </module> - - <!-- Restricts throws statements to a specified count. !--> - <!-- See http://checkstyle.sf.net/config_design.html !--> - <!-- KIEKER off - <module name="ThrowsCount"> - <property name="max" value="1"/> - </module> - !--> - - <!-- Checks visibility of class members. !--> - <!-- See http://checkstyle.sf.net/config_design.html !--> - <module name="VisibilityModifier"> - <property name="packageAllowed" value="false"/> - <property name="protectedAllowed" value="true"/> - <property name="publicMemberPattern" value="^serialVersionUID$"/> - </module> - - - <!-- - !________________________________________________________________________________________ - ! - ! C O D I N G - !________________________________________________________________________________________ - !--> - <!-- Checks that array initialization contains a trailing comma. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="ArrayTrailingComma"/> - - <!-- Detects inline conditionals. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="AvoidInlineConditionals"/> - - <!-- Checks that classes that define a covariant equals() method also override method equals(java.lang.Object). !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="CovariantEquals"/> - - <!-- Checks declaration order according to Code Conventions for the Java Programming Language. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="DeclarationOrder"> - <property name="ignoreConstructors" value="false"/> - <property name="ignoreMethods" value="false"/> - <property name="ignoreModifiers" value="false"/> - </module> - - <!-- Check that the default is after all the cases in a switch statement. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="DefaultComesLast"/> - - <!-- The "double-checked locking" idiom (DCL) tries to avoid the runtime cost of synchronization. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="DoubleCheckedLocking"/> - - <!-- Detects empty statements (standalone ;). !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="EmptyStatement"/> - - <!-- Checks that any combination of String literals with optional assignment is on the left side of an equals() comparison. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#EqualsAvoidNull !--> - <module name="EqualsAvoidNull"/> - - <!-- Checks that classes that override equals() also override hashCode(). !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="EqualsHashCode"/> - - <!-- Checks if any class or object member explicitly initialized to default for its type value. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <!-- KIEKER off - <module name="ExplicitInitialization"/> - !--> - - <!-- Checks for fall through in switch statements Finds locations where a case contains Java code ... !--> - <!-- but lacks a break, return, throw or continue statement. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="FallThrough"> - <property name="checkLastCaseGroup" value="false"/> - <property name="reliefPattern" value="fallthru|falls??through"/> - </module> - - <!-- Checks that local variables that never have their values changed are declared final. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="FinalLocalVariable"> - <property name="tokens" value="VARIABLE_DEF"/> - </module> - - <!-- Checks that a local variable or a parameter does not shadow a field that is defined in the same class. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <!-- KIEKER ignoreConstructorParameter, ignoreSetter --> - <module name="HiddenField"> - <property name="tokens" value="PARAMETER_DEF, VARIABLE_DEF"/> - <!-- - <property name="ignoreFormat" value=""/> - !--> - <property name="ignoreConstructorParameter" value="true"/> - <property name="ignoreSetter" value="true"/> - <property name="ignoreAbstractMethods" value="false"/> - </module> - - <!-- Catching java.lang.Exception, java.lang.Error or java.lang.RuntimeException is almost never acceptable. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="IllegalCatch"> - <property name="illegalClassNames" value="java.lang.Exception, java.lang.Throwable, java.lang.RuntimeException"/> - </module> - - <!-- Checks for illegal instantiations where a factory method is preferred. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <!-- KIEKER on for ??? !--> - <module name="IllegalInstantiation"> - <property name="classes" value="java.lang.Boolean"/> - </module> - - <!-- This check can be used to ensure that types are not declared to be thrown. !--> - <!-- Declaring to throw java.lang.Error or java.lang.RuntimeException is almost never acceptable. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#IllegalThrows !--> - <module name="IllegalThrows"> - <property name="illegalClassNames" value="java.lang.Throwable, java.lang.Error, java.lang.RuntimeException"/> - </module> - - <!-- Checks for illegal tokens. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <!-- KIEKER off - <module name="IllegalToken"> - <property name="tokens" value="LITERAL_SWITCH, POST_INC, POST_DEC"/> - </module> - !--> - - <!-- Checks for illegal token text. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <!-- Default: OFF - <module name="IllegalTokenText"> - <property name="tokens" value=""/> - <property name="format" value=""/> - <property name="ignoreCase" value="false"/> - <property name="message" value=""/> - </module> - !--> - - <!-- Checks that particular classes are never used as types in variable declarations, return values or parameters. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <!-- KIEKER removed format value="^(.*[\\.])?Abstract.*$" !--> - <module name="IllegalType"> - <property name="tokens" value="PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF"/> - <property name="illegalClassNames" value="java.util.GregorianCalendar, java.util.Hashtable, - java.util.HashSet, java.util.HashMap, java.util.ArrayList, - java.util.LinkedList, java.util.LinkedHashMap, - java.util.LinkedHashSet, java.util.TreeSet, - java.util.TreeMap, java.util.Vector"/> - <property name="legalAbstractClassNames" value=""/> - <property name="ignoredMethodNames" value="getInitialContext, getEnvironment"/> - <property name="format" value="XXX"/> - </module> - - <!-- Checks for assignments in subexpressions, such as in String s = Integer.toString(i = 2);. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="InnerAssignment"> - <property name="tokens" value="ASSIGN, BAND_ASSIGN, BOR_ASSIGN, BSR_ASSIGN, BXOR_ASSIGN, - DIV_ASSIGN, MINUS_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, SL_ASSIGN, - SR_ASSIGN, STAR_ASSIGN"/> - </module> - - <!-- Ensures that the setUp(), tearDown()methods are named correctly, have no arguments, !--> - <!-- return void and are either public or protected. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="JUnitTestCase"/> - - <!-- Checks that there are no "magic numbers", where a magic number is a numeric literal !--> - <!-- that is not defined as a constant. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <!-- deactivated for Kieker - <module name="MagicNumber"> - <property name="tokens" value="NUM_DOUBLE, NUM_FLOAT, NUM_INT, NUM_LONG"/> - <property name="ignoreNumbers" value="-1, 0, 1, 2"/> - <property name="ignoreHashCodeMethod" value="false"/> - </module> - !--> - - <!-- Checks that classes (except abtract one) define a ctor and don't rely on the default one. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="MissingCtor"/> - - <!-- Checks that switch statement has "default" clause. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="MissingSwitchDefault"/> - - <!-- Check for ensuring that for loop control variables are not modified inside the for block. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#ModifiedControlVariable !--> - <module name="ModifiedControlVariable"/> - - <!-- Checks for multiple occurrences of the same string literal within a single file. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#MultipleStringLiterals !--> - <!-- KIEKER off for now - <module name="MultipleStringLiterals"> - <property name="allowedDuplicates" value="1"/> - <property name="ignoreStringsRegexp" value='^""$'/> - <property name="ignoreOccurrenceContext" value="ANNOTATION"/> - </module> - !--> - - <!-- Checks that each variable declaration is in its own statement and on its own line. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="MultipleVariableDeclarations"/> - - <!-- Restricts nested for blocks to a specified depth. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#NestedForDepth !--> - <module name="NestedForDepth"> - <property name="max" value="2"/> - </module> - - <!-- Restricts nested if-else blocks to a specified depth. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="NestedIfDepth"> - <property name="max" value="3"/> - </module> - - <!-- Restricts nested try-catch blocks to a specified depth. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="NestedTryDepth"> - <property name="max" value="1"/> - </module> - - <!-- Checks that the clone method is not overridden from the Object class. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#NoClone !--> - <module name="NoClone"/> - - <!-- Verifies there are no finalize() methods defined in a class. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#NoFinalizer !--> - <module name="NoFinalizer"/> - - <!-- Checks there is only one statement per line. !--> - <!-- See http://checkstyle.sourceforge.net/config_coding.html#OneStatementPerLine !--> - <module name="OneStatementPerLine"/> - - <!-- Ensure a class has a package declaration. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="PackageDeclaration"> - <property name="ignoreDirectoryName" value="false"/> - </module> - - <!-- Disallow assignment of parameters. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="ParameterAssignment"/> - - <!-- Checks for redundant exceptions declared in throws clause such as duplicates, !--> - <!-- unchecked exceptions or subclasses of another declared exception. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="RedundantThrows"> - <property name="allowUnchecked" value="true"/> - <property name="allowSubclasses" value="false"/> - <property name="logLoadErrors" value="true"/> - <property name="suppressLoadErrors" value="false"/> - </module> - - <!-- Checks that code doesn't rely on the "this." default. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="RequireThis"> - <property name="checkFields" value="true"/> - <property name="checkMethods" value="true"/> - </module> - - <!-- Restrict the number of return statements. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="ReturnCount"> - <property name="max" value="2"/> - <property name="format" value=""/> - </module> - - <!-- Checks for overly complicated boolean expressions. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="SimplifyBooleanExpression"/> - - <!-- Checks for overly complicated boolean return statements. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="SimplifyBooleanReturn"/> - - <!-- Checks that string literals are not used with == or !=. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="StringLiteralEquality"/> - - <!-- Checks that an overriding clone() method invokes super.clone(). !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="SuperClone"/> - - <!-- Checks that an overriding finalize() method invokes super.finalize(). !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="SuperFinalize"/> - - <!-- Checks for the use of unnecessary parentheses. !--> - <!-- See http://checkstyle.sf.net/config_coding.html !--> - <module name="UnnecessaryParentheses"/> - - - <!-- - !________________________________________________________________________________________ - ! - ! I M P O R T S - !________________________________________________________________________________________ - !--> - <!-- Checks that there are no import statements that use the * notation. !--> - <!-- See http://checkstyle.sf.net/config_import.html !--> - <module name="AvoidStarImport"> - <property name="excludes" value=""/> - <property name="allowClassImports" value="false"/> - <property name="allowStaticMemberImports" value="false"/> - </module> - - <!-- Checks that there are no static import statements. !--> - <!-- See http://checkstyle.sourceforge.net/config_imports.html#AvoidStaticImport !--> - <module name="AvoidStaticImport"> - <property name="excludes" value=""/> - </module> - - <!-- Checks for imports from a set of illegal packages. !--> - <!-- See http://checkstyle.sf.net/config_import.html !--> - <module name="IllegalImport"> - <property name="illegalPkgs" value="sun"/> - <property name="illegalPkgs" value="org.apache.commons.logging"/> - </module> - - <!-- Controls what can be imported in each package. Useful for ensuring that application layering rules !--> - <!-- are not violated, especially on large projects. !--> - <!-- See http://checkstyle.sourceforge.net/config_imports.html#ImportControl !--> - <!-- Default: OFF - <module name="ImportControl"> - <property name="file" value=""/> - <property name="url" value=""/> - </module> - !--> - - <!-- Checks the ordering/grouping of imports. !--> - <!-- See http://checkstyle.sf.net/config_import.html !--> - <module name="ImportOrder"> - <property name="option" value="under"/> - <property name="groups" value="java,javax,junit,org,com,kieker,org.primefaces,org.eclipse"/> - <property name="ordered" value="true"/> - <property name="separated" value="true"/> - <property name="caseSensitive" value="true"/> - </module> - - <!-- Checks for redundant import statements. !--> - <!-- See http://checkstyle.sf.net/config_import.html !--> - <module name="RedundantImport"/> - - <!-- Checks for unused import statements. !--> - <!-- See http://checkstyle.sf.net/config_import.html !--> - <module name="UnusedImports"/> - - - <!-- - !________________________________________________________________________________________ - ! - ! J A V A D O C S - !________________________________________________________________________________________ - !--> - <!-- Checks to ensure that the javadoc tags exist (if required) !--> - <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocMethod !--> - <module name="JavadocMethod"> - <property name="severity" value="info"/> - <property name="scope" value="private"/> - <!-- - <property name="excludeScope" value=""/> - !--> - <property name="allowUndeclaredRTE" value="false"/> - <property name="allowThrowsTagsForSubclasses" value="false"/> - <property name="allowMissingParamTags" value="false"/> - <property name="allowMissingThrowsTags" value="false"/> - <property name="allowMissingReturnTag" value="false"/> - <property name="allowMissingJavadoc" value="false"/> - <property name="allowMissingPropertyJavadoc" value="false"/> - <property name="logLoadErrors" value="true"/> - <property name="suppressLoadErrors" value="false"/> - <property name="tokens" value="METHOD_DEF, CTOR_DEF"/> - </module> - - <!-- Validates Javadoc comments to help ensure they are well formed. !--> - <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocStyle !--> - <module name="JavadocStyle"> - <property name="severity" value="info"/> - <property name="scope" value="private"/> - <!-- - <property name="excludeScope" value=""/> - !--> - <property name="checkFirstSentence" value="true"/> -<!--TODO: <property name="endOfSentenceFormat" value="([.?!][ \t\n\r\f<])|([.?!]$)"/> !--> - <property name="checkEmptyJavadoc" value="false"/> - <property name="checkHtml" value="true"/> - <property name="tokens" value="INTERFACE_DEF, CLASS_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/> - </module> - - <!-- Checks Javadoc comments for class and interface definitions. !--> - <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocType !--> - <module name="JavadocType"> - <property name="severity" value="info"/> - <property name="scope" value="private"/> - <!-- - <property name="excludeScope" value=""/> - !--> - <property name="authorFormat" value=""/> - <!--<property name="versionFormat" value=""/>!--> - <property name="allowMissingParamTags" value="false"/> - <property name="allowUnknownTags" value="false"/> - <property name="tokens" value="INTERFACE_DEF, CLASS_DEF"/> - </module> - - <module name="JavadocType"> - <property name="severity" value="warning"/> - <property name="scope" value="package"/> - <property name="authorFormat" value="\S"/> - </module> - - <!-- Checks that variables have Javadoc comments. !--> - <!-- See http://checkstyle.sf.net/config_javadoc.html#JavadocVariable !--> - <module name="JavadocVariable"> - <property name="severity" value="info"/> - <property name="scope" value="package"/> - <!-- - <property name="excludeScope" value=""/> - !--> - </module> - - <!-- Outputs a JavaDoc tag as information. !--> - <!-- See http://checkstyle.sourceforge.net/config_javadoc.html#WriteTag !--> - <!-- KIEKER - <module name="WriteTag"> - <property name="severity" value="info"/> - <property name="tag" value=""/> - <property name="tagFormat" value=""/> - <property name="tagSeverity" value="info"/> - </module> - --> - - - <!-- - !________________________________________________________________________________________ - ! - ! M E T R I C S - !________________________________________________________________________________________ - !--> - <!-- Restrict the number of number of &&, || and ^ in an expression. !--> - <!-- See http://checkstyle.sf.net/config_metrics.html !--> - <module name="BooleanExpressionComplexity"> - <property name="severity" value="info"/> - <property name="max" value="3"/> - <property name="tokens" value="LAND, BAND, LOR, BOR, BXOR"/> - </module> - - <!-- Checks cyclomatic complexity against a specified limit. !--> - <!-- See http://checkstyle.sf.net/config_metrics.html !--> - <module name="CyclomaticComplexity"> - <property name="severity" value="info"/> - <property name="max" value="10"/> - </module> - - <!-- Determines complexity of methods, classes and files by counting the Non Commenting Source Statements (NCSS). !--> - <!-- See http://checkstyle.sourceforge.net/config_metrics.html#JavaNCSS !--> - <module name="JavaNCSS"> - <property name="severity" value="info"/> - <property name="methodMaximum" value="50"/> - <property name="classMaximum" value="1500"/> - <property name="fileMaximum" value="2000"/> - </module> - - <!-- The NPATH metric computes the number of possible execution paths through a function. !--> - <!-- See http://checkstyle.sf.net/config_metrics.html !--> - <module name="NPathComplexity"> - <property name="severity" value="info"/> - <property name="max" value="200"/> - </module> - - - <!-- - !________________________________________________________________________________________ - ! - ! M I S C E L L A N E O U S - !________________________________________________________________________________________ - !--> - <!-- Checks the style of array type definitions. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <module name="ArrayTypeStyle"> - <property name="javaStyle" value="true"/> - </module> - - <!-- Checks for restricted tokens beneath other tokens. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <!-- Default: OFF - <module name="DescendantToken"> - <property name="tokens" value=""/> - <property name="limitedTokens" value=""/> - <property name="minimumDepth" value="0"/> - <property name="maximumDepth" value="java.lang.Integer.MAX_VALUE"/> - <property name="minimumNumber" value="0"/> - <property name="maximumNumber" value="java.lang.Integer.MAX_VALUE"/> - <property name="sumTokenCounts" value="false"/> - <property name="minimumMessage" value="descendant.token.min"/> - <property name="maximumMessage" value="descendant.token.max"/> - </module> - !--> - - <!-- Check that method/constructor parameters are final. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <module name="FinalParameters"> - <property name="tokens" value="METHOD_DEF, CTOR_DEF"/> - </module> - - <!-- A generic check for code problems - the user can search for any pattern. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <!-- Default: OFF - <module name="GenericIllegalRegexp"> - <property name="format" value="\S\s+$"/> - <property name="message" value="Line has trailing spaces."/> - <property name="ignoreCase" value="false"/> - <property name="ignoreComments" value="false"/> - </module> - !--> - - <!-- Checks correct indentation of Java Code. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <!-- KIEKER --> - <module name="Indentation"> - <property name="severity" value="info"/> - <property name="basicOffset" value="4"/> - <property name="braceAdjustment" value="0"/> - <property name="caseIndent" value="0"/> - </module> - - <!-- Checks that the outer type name and the file name match. !--> - <!-- See http://checkstyle.sourceforge.net/config_misc.html#OuterTypeFilename !--> - <module name="OuterTypeFilename"/> - - <!-- A check for TODO: comments. Actually it is a generic regular expression matcher on Java comments. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <!-- Kieker !--> - <module name="TodoComment"> - <property name="format" value="TODO"/> - </module> - - <!-- The check to ensure that requires that comments be the only thing on a line. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <!-- KIEKER we use them - <module name="TrailingComment"> - <property name="format" value="^[\\s\\}\\);]*$"/> - <property name="legalComment" value=""/> - </module> - --> - - <!-- Checks for uncommented main() methods (debugging leftovers). !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <module name="UncommentedMain"> - <property name="severity" value="info"/> - <property name="excludedClasses" value="Main$"/> - </module> - - <!-- Checks that long constants are defined with an upper ell. That is 'L' and not 'l'. !--> - <!-- See http://checkstyle.sf.net/config_misc.html !--> - <module name="UpperEll"/> - - - <!-- - !________________________________________________________________________________________ - ! - ! M O D I F I E R S - !________________________________________________________________________________________ - !--> - <!-- Checks that the order of modifiers conforms to the suggestions in the Java Language specification, !--> - <!-- sections 8.1.1, 8.3.1 and 8.4.3. !--> - <!-- See http://checkstyle.sf.net/config_modifiers.html !--> - <module name="ModifierOrder"/> - - <!-- Checks that there are no redundant modifiers. !--> - <!-- See http://checkstyle.sf.net/config_modifiers.html !--> - <!-- KIEKER off - <module name="RedundantModifier"> - <property name="tokens" value="METHOD_DEF, VARIABLE_DEF, ANNOTATION_FIELD_DEF"/> - </module> - !--> - - <!-- - !________________________________________________________________________________________ - ! - ! N A M I N G C O N V E N T I O N S - !________________________________________________________________________________________ - !--> - <!-- Checks for abstract class name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <!-- KIEKER removed |^.*Factory$ --> - <module name="AbstractClassName"> - <property name="format" value="^Abstract.*$"/> - <property name="ignoreModifier" value="false"/> - <property name="ignoreName" value="false"/> - </module> - - <!-- Checks for class type parameter name naming conventions. !--> - <!-- See http://checkstyle.sourceforge.net/config_naming.html#ClassTypeParameterName !--> - <module name="ClassTypeParameterName"> - <property name="format" value="^[A-Z]$"/> - </module> - - <!-- Checks for constant name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="ConstantName"> - <property name="format" value="^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$"/> - <property name="applyToPublic" value="true"/> - <property name="applyToProtected" value="true"/> - <property name="applyToPackage" value="true"/> - <property name="applyToPrivate" value="true"/> - </module> - - <!-- Checks for local final variable name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="LocalFinalVariableName"> - <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> - <property name="tokens" value="VARIABLE_DEF, PARAMETER_DEF"/> - </module> - - <!-- Checks for local variable name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="LocalVariableName"> - <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> - <property name="tokens" value="PARAMETER_DEF"/> - </module> - - <!-- Checks for member variable name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="MemberName"> - <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> - <property name="applyToPublic" value="true"/> - <property name="applyToProtected" value="true"/> - <property name="applyToPackage" value="true"/> - <property name="applyToPrivate" value="true"/> - </module> - - <!-- Checks for method name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="MethodName"> - <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> - </module> - - <!-- Checks for method type parameter name naming conventions. !--> - <!-- See http://checkstyle.sourceforge.net/config_naming.html#MethodTypeParameterName !--> - <module name="MethodTypeParameterName"> - <property name="format" value="^[A-Z]$"/> - </module> - - <!-- Checks for package name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="PackageName"> - <property name="format" value="^[a-z]+(\.[a-zA-Z_][a-zA-Z0-9_]*)*$"/> - </module> - - <!-- Checks for parameter name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="ParameterName"> - <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> - </module> - - <!-- Checks for static variable name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <module name="StaticVariableName"> - <property name="format" value="^[a-z][a-zA-Z0-9]*$"/> - <property name="applyToPublic" value="true"/> - <property name="applyToProtected" value="true"/> - <property name="applyToPackage" value="true"/> - <property name="applyToPrivate" value="true"/> - </module> - - <!-- Checks for type name naming conventions. !--> - <!-- See http://checkstyle.sf.net/config_naming.html !--> - <!-- KIEKER: modded --> - <module name="TypeName"> - <property name="format" value="^[A-Z][a-zA-Z0-9]*$"/> - <property name="tokens" value="CLASS_DEF"/> - <property name="applyToPublic" value="true"/> - <property name="applyToProtected" value="true"/> - <property name="applyToPackage" value="true"/> - <property name="applyToPrivate" value="true"/> - </module> - - <module name="TypeName"> - <property name="format" value="^I[A-Z][a-zA-Z0-9]*$"/> - <property name="tokens" value="INTERFACE_DEF"/> - <property name="applyToPublic" value="true"/> - <property name="applyToProtected" value="true"/> - <property name="applyToPackage" value="true"/> - <property name="applyToPrivate" value="true"/> - </module> - - - <!-- - !________________________________________________________________________________________ - ! - ! R E G E X P - !________________________________________________________________________________________ - !--> - <!-- A check that makes sure that a specified pattern exists, exists less than a set number of times, !--> - <!-- or does not exist in the file. !--> - <!-- See http://checkstyle.sourceforge.net/config_misc.html#Regexp !--> - <!-- Default: OFF - <module name="Regexp"> - <property name="format" value=""/> - <property name="message" value=""/> - <property name="illegalPattern" value="false"/> - <property name="duplicateLimit" value="-1"/> - <property name="errorLimit" value="100"/> - <property name="ignoreComments" value="false"/> - </module> - !--> - - <!-- This class is variation on RegexpSingleline for detecting single lines that match a !--> - <!-- supplied regular expression in Java files. It supports suppressing matches in Java comments. !--> - <!-- See http://checkstyle.sourceforge.net/config_regexp.html#RegexpSinglelineJava !--> - <!-- Default: OFF - <module name="RegexpSinglelineJava"> - <property name="format" value=""/> - <property name="message" value=""/> - <property name="ignoreCase" value="false"/> - <property name="minimum" value="0"/> - <property name="maximum" value="0"/> - <property name="ignoreComments" value="false"/> - </module> - !--> - - <!-- - !________________________________________________________________________________________ - ! - ! S I Z E V I O L A T I O N S - !________________________________________________________________________________________ - !--> - <!-- Checks for long anonymous inner classes. !--> - <!-- See http://checkstyle.sf.net/config_sizes.html !--> - <module name="AnonInnerLength"> - <property name="severity" value="info"/> - <property name="max" value="20"/> - </module> - - <!-- Restricts the number of executable statements to a specified limit. !--> - <!-- See http://checkstyle.sf.net/config_sizes.html !--> - <!-- KIEKER off - <module name="ExecutableStatementCount"> - <property name="severity" value="info"/> - <property name="max" value="30"/> - <property name="tokens" value="CTOR_DEF, METHOD_DEF, INSTANCE_INIT, STATIC_INIT"/> - </module> - !--> - - <!-- See http://checkstyle.sf.net/config_sizes.html !--> - <!-- Checks for long lines. !--> - <module name="LineLength"> - <property name="severity" value="info"/> - <property name="ignorePattern" value="^$"/> - <property name="max" value="165"/> - </module> - - <!-- Checks the number of methods declared in each type. This includes the number of each scope !--> - <!-- (private, package, protected and public) as well as an overall total. !--> - <!-- See http://checkstyle.sourceforge.net/config_sizes.html#MethodCount !--> - <module name="MethodCount"> - <property name="severity" value="info"/> - <property name="maxTotal" value="100"/> - <property name="maxPrivate" value="100"/> - <property name="maxPackage" value="100"/> - <property name="maxProtected" value="100"/> - <property name="maxPublic" value="100"/> - </module> - - <!-- Checks for long methods and constructors. !--> - <!-- See http://checkstyle.sf.net/config_sizes.html !--> - <module name="MethodLength"> - <property name="severity" value="info"/> - <property name="max" value="150"/> - <property name="countEmpty" value="true"/> - <property name="tokens" value="METHOD_DEF, CTOR_DEF"/> - </module> - - <!-- Checks for the number of types declared at the outer (or root) level in a file. !--> - <!-- See http://checkstyle.sourceforge.net/config_sizes.html#OuterTypeNumber !--> - <!-- KIEKER 2 !--> - <module name="OuterTypeNumber"> - <property name="max" value="2"/> - </module> - - <!-- Checks the number of parameters of a method or constructor. !--> - <!-- See http://checkstyle.sf.net/config_sizes.html !--> - <!-- KIEKER off - <module name="ParameterNumber"> - <property name="severity" value="info"/> - <property name="max" value="7"/> - <property name="tokens" value="METHOD_DEF, CTOR_DEF"/> - </module> - !--> - - <!-- - !________________________________________________________________________________________ - ! - ! W H I T E S P A C E - !________________________________________________________________________________________ - !--> - <!-- Checks the padding of an empty for initializer. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="EmptyForInitializerPad"> - <property name="option" value="nospace"/> - </module> - - <!-- Checks the padding of an empty for iterator. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="EmptyForIteratorPad"> - <property name="option" value="nospace"/> - </module> - - <!-- Checks that the whitespace around the Generic tokens < and > is correct to the typical convention. !--> - <!-- See http://checkstyle.sourceforge.net/config_whitespace.html#GenericWhitespace !--> - <module name="GenericWhitespace"/> - - <!-- Checks the padding between the identifier of a method definition, !--> - <!-- constructor definition, method call, or constructor invocation; and the left parenthesis of the parameter list. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="MethodParamPad"> - <property name="allowLineBreaks" value="false"/> - <property name="option" value="nospace"/> - <property name="tokens" value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF, SUPER_CTOR_CALL "/> - </module> - - <!-- Checks that there is no whitespace after a token. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <!-- KIEKER removed ARRAY_INIT !--> - <module name="NoWhitespaceAfter"> - <property name="allowLineBreaks" value="true"/> - <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS"/> - </module> - - <!-- Checks that there is no whitespace before a token. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="NoWhitespaceBefore"> - <property name="allowLineBreaks" value="false"/> - <property name="tokens" value="SEMI, POST_DEC, POST_INC"/> - </module> - - <!-- Checks the policy on how to wrap lines on operators. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="OperatorWrap"> - <property name="option" value="nl"/> - <property name="tokens" value="BAND, BOR, BSR, BXOR, COLON, DIV, - EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, - LOR, LT, MINUS, MOD, NOT_EQUAL, - PLUS, QUESTION, SL, SR, STAR"/> - </module> - - <!-- Checks the policy on the padding of parentheses. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="ParenPad"> - <property name="option" value="nospace"/> - <property name="tokens" value="CTOR_CALL, LPAREN, METHOD_CALL, RPAREN, SUPER_CTOR_CALL"/> - </module> - - <!-- Checks the policy on the padding of parentheses for typecasts. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="TypecastParenPad"> - <property name="option" value="nospace"/> - <property name="tokens" value="TYPECAST, RPAREN"/> - </module> - - <!-- Checks that a token is followed by whitespace. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="WhitespaceAfter"> - <property name="tokens" value="COMMA, SEMI, TYPECAST"/> - </module> - - <!-- Checks that a token is surrounded by whitespace. !--> - <!-- See http://checkstyle.sf.net/config_whitespace.html !--> - <module name="WhitespaceAround"> - <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, - BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, - LE, LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, - LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, - LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, - MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, - QUESTION, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN"/> - <property name="allowEmptyConstructors" value="true"/> - <property name="allowEmptyMethods" value="true"/> - </module> - + <module name="IllegalCatch"/> + <module name="IllegalInstantiation"> + <property name="classes" value="java.lang.Boolean"/> </module> - + <module name="IllegalThrows"/> + <module name="IllegalType"> + <property name="tokens" value="PARAMETER_DEF, VARIABLE_DEF, METHOD_DEF"/> + <property name="illegalClassNames" value="java.util.GregorianCalendar, java.util.Hashtable, java.util.HashSet, java.util.HashMap, java.util.ArrayList, java.util.LinkedList, java.util.LinkedHashMap, java.util.LinkedHashSet, java.util.TreeSet, java.util.TreeMap, java.util.Vector"/> + <property name="format" value="XXX"/> + </module> + <module name="InnerAssignment"> + <property name="tokens" value="ASSIGN, BAND_ASSIGN, BOR_ASSIGN, BSR_ASSIGN, BXOR_ASSIGN, DIV_ASSIGN, MINUS_ASSIGN, MOD_ASSIGN, PLUS_ASSIGN, SL_ASSIGN, SR_ASSIGN, STAR_ASSIGN"/> + </module> + <module name="JUnitTestCase"/> + <module name="MissingCtor"/> + <module name="MissingSwitchDefault"/> + <module name="ModifiedControlVariable"/> + <module name="MultipleVariableDeclarations"/> + <module name="NestedForDepth"> + <property name="max" value="2"/> + </module> + <module name="NestedIfDepth"> + <property name="max" value="3"/> + </module> + <module name="NestedTryDepth"/> + <module name="NoClone"/> + <module name="NoFinalizer"/> + <module name="OneStatementPerLine"/> + <module name="PackageDeclaration"/> + <module name="ParameterAssignment"/> + <module name="RedundantThrows"> + <property name="allowUnchecked" value="true"/> + </module> + <module name="RequireThis"/> + <module name="ReturnCount"/> + <module name="SimplifyBooleanExpression"/> + <module name="SimplifyBooleanReturn"/> + <module name="StringLiteralEquality"/> + <module name="SuperClone"/> + <module name="SuperFinalize"/> + <module name="UnnecessaryParentheses"/> + <module name="AvoidStarImport"/> + <module name="AvoidStaticImport"/> + <module name="IllegalImport"> + <property name="illegalPkgs" value="org.apache.commons.logging"/> + </module> + <module name="ImportOrder"> + <property name="groups" value="java,javax,junit,org,com,kieker,org.primefaces,org.eclipse"/> + <property name="separated" value="true"/> + </module> + <module name="RedundantImport"/> + <module name="UnusedImports"/> + <module name="JavadocMethod"> + <property name="severity" value="info"/> + <property name="tokens" value="METHOD_DEF, CTOR_DEF"/> + </module> + <module name="JavadocStyle"> + <property name="severity" value="info"/> + <property name="tokens" value="INTERFACE_DEF, CLASS_DEF, METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/> + </module> + <module name="JavadocType"> + <property name="severity" value="info"/> + <property name="tokens" value="INTERFACE_DEF, CLASS_DEF"/> + </module> + <module name="JavadocType"> + <property name="severity" value="warning"/> + <property name="scope" value="package"/> + <property name="authorFormat" value="\S"/> + </module> + <module name="JavadocVariable"> + <property name="severity" value="info"/> + <property name="scope" value="package"/> + </module> + <module name="BooleanExpressionComplexity"> + <property name="severity" value="info"/> + <property name="tokens" value="LAND, BAND, LOR, BOR, BXOR"/> + </module> + <module name="CyclomaticComplexity"> + <property name="severity" value="info"/> + </module> + <module name="JavaNCSS"> + <property name="severity" value="info"/> + </module> + <module name="NPathComplexity"> + <property name="severity" value="info"/> + </module> + <module name="ArrayTypeStyle"/> + <module name="FinalParameters"> + <property name="tokens" value="METHOD_DEF, CTOR_DEF"/> + </module> + <module name="Indentation"> + <property name="severity" value="info"/> + <property name="caseIndent" value="0"/> + </module> + <module name="OuterTypeFilename"/> + <module name="TodoComment"> + <property name="format" value="TODO"/> + </module> + <module name="UncommentedMain"> + <property name="severity" value="info"/> + <property name="excludedClasses" value="Main$"/> + </module> + <module name="UpperEll"/> + <module name="ModifierOrder"/> + <module name="AbstractClassName"> + <property name="format" value="^Abstract.*$"/> + </module> + <module name="ClassTypeParameterName"/> + <module name="ConstantName"/> + <module name="LocalFinalVariableName"/> + <module name="LocalVariableName"> + <property name="tokens" value="PARAMETER_DEF"/> + </module> + <module name="MemberName"/> + <module name="MethodName"/> + <module name="MethodTypeParameterName"/> + <module name="PackageName"/> + <module name="ParameterName"/> + <module name="StaticVariableName"/> + <module name="TypeName"> + <property name="tokens" value="CLASS_DEF"/> + </module> + <module name="TypeName"> + <property name="format" value="^I[A-Z][a-zA-Z0-9]*$"/> + <property name="tokens" value="INTERFACE_DEF"/> + </module> + <module name="AnonInnerLength"> + <property name="severity" value="info"/> + </module> + <module name="LineLength"> + <property name="severity" value="info"/> + <property name="max" value="165"/> + </module> + <module name="MethodCount"> + <property name="severity" value="info"/> + </module> + <module name="MethodLength"> + <property name="severity" value="info"/> + <property name="tokens" value="METHOD_DEF, CTOR_DEF"/> + </module> + <module name="OuterTypeNumber"> + <property name="max" value="2"/> + </module> + <module name="EmptyForInitializerPad"/> + <module name="EmptyForIteratorPad"/> + <module name="GenericWhitespace"/> + <module name="MethodParamPad"> + <property name="tokens" value="CTOR_DEF, LITERAL_NEW, METHOD_CALL, METHOD_DEF, SUPER_CTOR_CALL "/> + </module> + <module name="NoWhitespaceAfter"> + <property name="tokens" value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS"/> + </module> + <module name="NoWhitespaceBefore"> + <property name="tokens" value="SEMI, POST_DEC, POST_INC"/> + </module> + <module name="OperatorWrap"> + <property name="tokens" value="BAND, BOR, BSR, BXOR, COLON, DIV, EQUAL, GE, GT, LAND, LE, LITERAL_INSTANCEOF, LOR, LT, MINUS, MOD, NOT_EQUAL, PLUS, QUESTION, SL, SR, STAR"/> + </module> + <module name="ParenPad"> + <property name="tokens" value="CTOR_CALL, LPAREN, METHOD_CALL, RPAREN, SUPER_CTOR_CALL"/> + </module> + <module name="TypecastParenPad"> + <property name="tokens" value="TYPECAST, RPAREN"/> + </module> + <module name="WhitespaceAfter"> + <property name="tokens" value="COMMA, SEMI, TYPECAST"/> + </module> + <module name="WhitespaceAround"> + <property name="tokens" value="ASSIGN, BAND, BAND_ASSIGN, BOR, BOR_ASSIGN, BSR, BSR_ASSIGN, BXOR, BXOR_ASSIGN, COLON, DIV, DIV_ASSIGN, EQUAL, GE, GT, LAND, LE, LITERAL_ASSERT, LITERAL_CATCH, LITERAL_DO, LITERAL_ELSE, LITERAL_FINALLY, LITERAL_FOR, LITERAL_IF, LITERAL_RETURN, LITERAL_SYNCHRONIZED, LITERAL_TRY, LITERAL_WHILE, LOR, LT, MINUS, MINUS_ASSIGN, MOD, MOD_ASSIGN, NOT_EQUAL, PLUS, PLUS_ASSIGN, QUESTION, SL, SLIST, SL_ASSIGN, SR, SR_ASSIGN, STAR, STAR_ASSIGN"/> + <property name="allowEmptyConstructors" value="true"/> + <property name="allowEmptyMethods" value="true"/> + </module> + </module> + <module name="SuppressWithNearbyCommentFilter"> + <property name="commentFormat" value="NOCS"/> + </module> + <module name="Header"> + <property name="header" value="/***************************************************************************\n * Copyright 2012 Kieker Project (http://kieker-monitoring.net)\n *\n * Licensed under the Apache License, Version 2.0 (the "License");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an "AS IS" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n ***************************************************************************/\n"/> + <property name="ignoreLines" value="2"/> + <property name="fileExtensions" value="java"/> + </module> + <module name="NewlineAtEndOfFile"> + <property name="fileExtensions" value="*.*"/> + </module> + <module name="Translation"/> + <module name="FileLength"/> </module> diff --git a/Kieker.WebGUI/config/quality-config/fb-filter.xml b/Kieker.WebGUI/config/quality-config/fb-filter.xml index 7c54c756874481efa836f4dd3e0cc44349c52df4..1c7a80d428eb78b384b1b8e4a699ce61ef35140d 100644 --- a/Kieker.WebGUI/config/quality-config/fb-filter.xml +++ b/Kieker.WebGUI/config/quality-config/fb-filter.xml @@ -1,3 +1,11 @@ <FindBugsFilter> - + <Match> + <Class name="kieker.webgui.persistence.impl.util.CloseableURLClassLoader" /> + <Bug code="DP, RI" /> + </Match> + + <Match> + <Class name="kieker.webgui.persistence.impl.DerbyUserDAOImpl" /> + <Bug code="ODR, OBL" /> + </Match> </FindBugsFilter> \ No newline at end of file diff --git a/Kieker.WebGUI/config/quality-config/pmdrules.xml b/Kieker.WebGUI/config/quality-config/pmdrules.xml index 47c4870b7cf97c78858a75da5cf3b8a3dabea213..3dc278260a401fc8161b174c0dfcca556c9fd07f 100644 --- a/Kieker.WebGUI/config/quality-config/pmdrules.xml +++ b/Kieker.WebGUI/config/quality-config/pmdrules.xml @@ -36,6 +36,7 @@ <rule ref="rulesets/design.xml"> <exclude name="ConfusingTernary"/> + <exclude name="AvoidSynchronizedAtMethodLevel"/> </rule> <rule ref="rulesets/finalizers.xml"/> diff --git a/Kieker.WebGUI/nb-configuration.xml b/Kieker.WebGUI/nb-configuration.xml index 508f207db29790e2eaa1be761dc0bc3347a2924a..e226fa62400598ebb5e2a3879a910c26f679849c 100644 --- a/Kieker.WebGUI/nb-configuration.xml +++ b/Kieker.WebGUI/nb-configuration.xml @@ -21,10 +21,10 @@ Any value defined here will override the pom.xml file value but is only applicab </properties> <spring-data xmlns="http://www.netbeans.org/ns/spring-data/1"> <config-files> - <config-file>src/main/webapp/WEB-INF/spring-config.xml</config-file> - <config-file>src/main/webapp/WEB-INF/spring-security-taglib.xml</config-file> - <config-file>src/main/webapp/WEB-INF/spring-database-config.xml</config-file> <config-file>src/main/webapp/WEB-INF/spring-bean-config.xml</config-file> + <config-file>src/main/webapp/WEB-INF/spring-common-config.xml</config-file> + <config-file>src/main/webapp/WEB-INF/spring-database-config.xml</config-file> + <config-file>src/main/webapp/WEB-INF/spring-security-config.xml</config-file> </config-files> <config-file-groups/> </spring-data> diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java deleted file mode 100644 index 5c62d286d25a5ab59f6fc8d3c453e45c9a8fa710..0000000000000000000000000000000000000000 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentControllerBean.java +++ /dev/null @@ -1,336 +0,0 @@ -/*************************************************************************** - * Copyright 2012 Kieker Project (http://kieker-monitoring.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -package kieker.webgui.beans.view; - -import java.io.IOException; -import java.io.PrintWriter; -import java.io.StringWriter; -import java.io.Writer; -import java.util.ArrayList; -import java.util.Collection; -import java.util.Date; -import java.util.List; - -import kieker.analysis.AnalysisController; -import kieker.common.logging.Log; -import kieker.common.logging.LogFactory; -import kieker.webgui.beans.application.ProjectsBean; -import kieker.webgui.common.IProjectManager; -import kieker.webgui.common.exception.AnalysisInitializationException; -import kieker.webgui.common.exception.AnalysisStateException; -import kieker.webgui.common.exception.ProjectNotExistingException; - -/** - * /** - * The {@link CurrentControllerBean} contains the necessary data behind an instance of the analysis controller. The class is a Spring managed bean with view scope to - * make sure that one user (even in one session) can open multiple projects at a time without causing any problems. - * - * @author Nils Christian Ehmke - */ -public final class CurrentControllerBean { - - private static final Log LOG = LogFactory.getLog(CurrentControllerBean.class); - - private IProjectManager projectManagerFacade; - private final List<String> logEntries = new ArrayList<String>(); - private String projectName; - private ProjectsBean projectsBean; - - /** - * Creates a new instance of this class. <b>Do not use this constructor. This bean is Spring managed.</b> - */ - public CurrentControllerBean() { - // No code necessary - } - - /** - * The getter for the {@link #projectsBean}-property. - * - * @return {@link #projectsBean} - */ - public ProjectsBean getProjectsBean() { - return this.projectsBean; - } - - public void setProjectManagerFacade(final IProjectManager projectManagerFacade) { - this.projectManagerFacade = projectManagerFacade; - } - - /** - * The setter for the {@link #projectsBean}-property. - * - * @param projectsBean - * The new value for {@link #projectsBean}. - */ - public void setProjectsBean(final ProjectsBean projectsBean) { - this.projectsBean = projectsBean; - } - - /** - * This method sets the project stored within this bean and returns the new page for the navigation. - * - * @param newName - * The name of the project. - */ - public void setProjectName(final String newName) { - synchronized (this) { - // Remember the given parameters - this.projectName = newName; - } - } - - /** - * This method delivers the project name stored in this bean. - * - * @return The project name for this user. - */ - public String getProjectName() { - synchronized (this) { - return this.projectName; - } - } - - /** - * This method starts the current analysis and informs the user about a fail. - */ - public void startAnalysis() { - synchronized (this) { - this.addLogEntry("Starting Analysis for project '" + this.projectName + "'"); - try { - this.projectManagerFacade.startAnalysis(this.projectName); - } catch (final AnalysisStateException ex) { - CurrentControllerBean.LOG.info("The analysis has already been started.", ex); - this.addLogEntry(ex); - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - this.addLogEntry(ex); - } - } - } - - /** - * This method stops the current analysis and informs the user about a fail. - */ - public void stopAnalysis() { - try { - this.addLogEntry("Stopping Analysis for project '" + this.projectName + "'"); - synchronized (this) { - this.projectManagerFacade.stopAnalysis(this.projectName); - } - } catch (final AnalysisStateException ex) { - CurrentControllerBean.LOG.info("The analysis has not been started yet.", ex); - this.addLogEntry(ex); - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - this.addLogEntry(ex); - } - } - - /** - * This method initializes the current analysis and informs the user about a fail. - */ - public void instantiateAnalysis() { - synchronized (this) { - this.addLogEntry("Instantiating Analysis for project '" + this.projectName + "'"); - try { - this.projectManagerFacade.initializeAnalysis(this.projectName, this.projectManagerFacade.getClassLoader(this.projectName)); // NOPMD (ClassLoader) - } catch (final AnalysisStateException ex) { - CurrentControllerBean.LOG.error("The analysis has already been instantiated.", ex); - this.addLogEntry(ex); - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - this.addLogEntry(ex); - } catch (final IOException ex) { - CurrentControllerBean.LOG.info("An error occured during the initialization.", ex); - this.addLogEntry(ex); - } catch (final AnalysisInitializationException ex) { - CurrentControllerBean.LOG.info("An error occured during the initialization.", ex); - this.addLogEntry(ex); - } - } - } - - /** - * This method cleans the current analysis instance. - */ - public void cleanAnalysis() { - synchronized (this) { - this.addLogEntry("Cleaning Analysis for project '" + this.projectName + "'"); - try { - this.projectManagerFacade.cleanAnalysis(this.projectName); - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - this.addLogEntry(ex); - } catch (final AnalysisStateException ex) { - CurrentControllerBean.LOG.error("The analysis has not been instantiated yet.", ex); - this.addLogEntry(ex); - } - } - } - - /** - * Checks whether the analysis is currently running. - * - * @return true if and only if the analysis is running. - */ - public boolean isAnalysisRunning() { - synchronized (this) { - try { - return this.projectManagerFacade.getCurrentState(this.projectName) == AnalysisController.STATE.RUNNING; - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - return false; - } catch (final NullPointerException ex) { - // This exception can occur, when the projectsBean has not been initialized - CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); - return false; - } - } - } - - /** - * Checks whether the analysis is currently in the ready state. - * - * @return true if and only if the analysis is ready to be started. - */ - public boolean isAnalysisReady() { - synchronized (this) { - try { - return this.projectManagerFacade.getCurrentState(this.projectName) == AnalysisController.STATE.READY; - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - return false; - } catch (final NullPointerException ex) { - // This exception can occur, when the projectsBean has not been initialized - CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); - return false; - } - } - } - - /** - * Checks whether the analysis is not available. - * - * @return true if and only if the analysis is <b>not</b> available. - */ - public boolean isAnalysisNotAvailable() { - synchronized (this) { - try { - return this.projectManagerFacade.getCurrentState(this.projectName) == null; - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - return true; - } catch (final NullPointerException ex) { - // This exception can occur, when the projectsBean has not been initialized - CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); - return true; - } - } - } - - /** - * Checks whether the analysis is currently terminated. - * - * @return true if and only if the analysis has been terminated. - */ - public boolean isAnalysisTerminated() { - synchronized (this) { - try { - return this.projectManagerFacade.getCurrentState(this.projectName) == AnalysisController.STATE.TERMINATED; - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - return false; - } catch (final NullPointerException ex) { - // This exception can occur, when the projectsBean has not been initialized - CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); - return false; - } - } - } - - /** - * Checks whether the analysis is currently in the failed state. - * - * @return true if and only if the analysis has failed. - */ - public boolean isAnalysisFailed() { - synchronized (this) { - try { - return this.projectManagerFacade.getCurrentState(this.projectName) == AnalysisController.STATE.FAILED; - } catch (final ProjectNotExistingException ex) { - CurrentControllerBean.LOG.info("The project does not exist.", ex); - return false; - } catch (final NullPointerException ex) { - // This exception can occur, when the projectsBean has not been initialized - CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); - return false; - } - } - } - - /** - * Delivers the available log entries of the current analysis controller instance. - * - * @return The current log entries. - */ - public Object[] getAnalysisLog() { - try { - return this.projectManagerFacade.getLogEntries(this.projectName); - } catch (final AnalysisStateException ex) { - // Ignore - return new Object[0]; - } - } - - /** - * Delivers the available log entries of the current view. - * - * @return The current log entries. - */ - public Collection<String> getViewLog() { - return this.logEntries; - } - - /** - * Adds the element to the log. - * - * @param cause - * The element to be added. - */ - private void addLogEntry(final Throwable cause) { - final Writer result = new StringWriter(); - final PrintWriter printWriter = new PrintWriter(result); - cause.printStackTrace(printWriter); - this.addLogEntry(result.toString()); - } - - /** - * Adds the element (with the current time) to the log. - * - * @param msg - * The log message. - */ - private void addLogEntry(final String msg) { - final String finalMsg = new Date().toString() + " : " + msg; - synchronized (this) { - if (this.logEntries.size() > 50) { - this.logEntries.remove(0); - } - this.logEntries.add(finalMsg); - } - } -} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentUserManagementBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentUserManagementBean.java deleted file mode 100644 index f044ba0a8c135f6292fbecd95a8c2b0260d1b6ed..0000000000000000000000000000000000000000 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentUserManagementBean.java +++ /dev/null @@ -1,116 +0,0 @@ -/*************************************************************************** - * Copyright 2012 Kieker Project (http://kieker-monitoring.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -package kieker.webgui.beans.view; - -import java.util.ArrayList; -import java.util.List; - -import kieker.webgui.common.IUserManager; -import kieker.webgui.common.Role; -import kieker.webgui.common.User; - -/** - * @author Nils Christian Ehmke - */ -public final class CurrentUserManagementBean { - - private IUserManager userManagerFacade; - /** - * This list contains all available users. - */ - private List<User> users = new ArrayList<User>(); - - /** - * Default constructor. <b>Do not call this constructor manually. It will only be accessed by Spring.</b> - */ - public CurrentUserManagementBean() { - // No code necessary - } - - /** - * Setter for the property {@link CurrentUserManagementBean#userManagerFacade}. - * - * @param userManagerFacade - * The new value for the property. - */ - public void setUserManagerFacade(final IUserManager userManagerFacade) { - this.userManagerFacade = userManagerFacade; - } - - /** - * This method adds the given user to the database and informs about success via the growl component. - * - * @param username - * The name of the new user. - * @param password - * The password of the new user. - * @param roles - * The roles of the new user. - */ - public void addUser(final String username, final String password, final List<Role> roles) { - this.userManagerFacade.addUser(username, password, roles); - // TODO Check that the op was successful before adding the user to our list - this.users.add(new User(username, roles, true)); - } - - /** - * This method removed the given user from the database and informs about success via the growl component. - * - * @param username - * The name of the user. - */ - public void removeUser(final String username) { - this.userManagerFacade.removeUser(username); - } - - /** - * This method edits the given user within the database and informs about success via the growl component. - * - * @param username - * The name of the user. - * @param password - * The (new) password of the user. - * @param roles - * The (new) roles of the user. - */ - public void editUser(final String username, final String password, final Role... roles) { - this.userManagerFacade.editUser(username, password, roles); - } - - /** - * This method initializes the bean. <b>Do not call this method manually. It will only be accessed by Spring.</b> - */ - protected void initialialize() { - this.updateList(); - } - - /** - * Updates the list containing the available users. - */ - public void updateList() { - this.users = this.userManagerFacade.getUsers(); - } - - /** - * This method delivers all available users. - * - * @return All currently available users. - */ - public List<User> getUsers() { - return this.users; - } -} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/IUserManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/IUserManager.java deleted file mode 100644 index c8266c2b5596321638cdc6468ac09efa16cbc888..0000000000000000000000000000000000000000 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/IUserManager.java +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * Copyright 2012 Kieker Project (http://kieker-monitoring.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -package kieker.webgui.common; - -import java.util.List; - -import org.springframework.security.access.prepost.PreAuthorize; - -public interface IUserManager { - - @PreAuthorize("hasRole('ROLE_ADMIN')") - public void addUser(final String username, final String password, final List<Role> roles); - - @PreAuthorize("hasRole('ROLE_ADMIN')") - public void removeUser(final String username); - - @PreAuthorize("hasRole('ROLE_ADMIN')") - public void editUser(final String username, final String password, final Role... roles); - - @PreAuthorize("hasRole('ROLE_ADMIN')") - public List<User> getUsers(); - -} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/Role.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/Role.java deleted file mode 100644 index 8819d3cb098432988fcc1fcfee2ee2a4d7a5eec3..0000000000000000000000000000000000000000 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/Role.java +++ /dev/null @@ -1,40 +0,0 @@ -/*************************************************************************** - * Copyright 2012 Kieker Project (http://kieker-monitoring.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -package kieker.webgui.common; - -public enum Role { - - ROLE_USER(1), ROLE_ADMIN(2); - - private int id; - - private Role(final int id) { - this.id = id; - } - - public int getID() { - return this.id; - } - - public static Role fromID(final int id) { - if (id == 2) { - return Role.ROLE_ADMIN; - } else { - return Role.ROLE_USER; - } - } -} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/User.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/User.java deleted file mode 100644 index 784eaf26d3a0c875e8a42af2952ad7b6305c571f..0000000000000000000000000000000000000000 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/User.java +++ /dev/null @@ -1,46 +0,0 @@ -/*************************************************************************** - * Copyright 2012 Kieker Project (http://kieker-monitoring.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -package kieker.webgui.common; - -import java.util.List; - -public class User { - - private final String name; - private final List<Role> roles; - private final boolean enabled; - - public User(final String name, final List<Role> roles, final boolean enabled) { - this.name = name; - this.roles = roles; - this.enabled = enabled; - } - - public String getName() { - return this.name; - } - - public List<Role> getRoles() { - return this.roles; - } - - public boolean isEnabled() { - return enabled; - } - - -} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/ViewScope.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ViewScope.java similarity index 91% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/util/ViewScope.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/common/ViewScope.java index d16f3ce1bb0ffd1a5fd282c323b1f36ad0177d36..af0baa16eeee37b8a180d65aec6f31953d94070f 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/ViewScope.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/ViewScope.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.common.util; +package kieker.webgui.common; import java.util.Map; @@ -29,6 +29,12 @@ import org.springframework.beans.factory.config.Scope; * @author Nils Christian Ehmke */ public class ViewScope implements Scope { + /** + * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> + */ + public ViewScope() { + // No code necessary. + } @SuppressWarnings("rawtypes") @Override diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/DataAccessException.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/DataAccessException.java new file mode 100644 index 0000000000000000000000000000000000000000..5905cd560489fb7339e052e6da77de4e981212bc --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/common/exception/DataAccessException.java @@ -0,0 +1,54 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package kieker.webgui.common.exception; + +/** + * @author Nils Christian Ehmke + */ +public final class DataAccessException extends AbstractKiekerWebGUIException { + + private static final long serialVersionUID = 1L; + + /** + * Creates a new instance of this class. + */ + public DataAccessException() { + super(); + } + + /** + * Creates a new instance of this class using the given parameters. + * + * @param msg + * The message used for the exception. + */ + public DataAccessException(final String msg) { + super(msg); + } + + /** + * Creates a new instance of this class using the given parameters. + * + * @param msg + * The message used for the exception. + * @param cause + * The cause for the exception. + */ + public DataAccessException(final String msg, final Throwable cause) { + super(msg, cause); + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/UserManagerImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/UserManagerImpl.java deleted file mode 100644 index 8054f581de48033851ad62fa9243860caec6cce8..0000000000000000000000000000000000000000 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/UserManagerImpl.java +++ /dev/null @@ -1,175 +0,0 @@ -/*************************************************************************** - * Copyright 2012 Kieker Project (http://kieker-monitoring.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -package kieker.webgui.common.impl; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.TreeMap; - -import javax.sql.DataSource; - -import org.springframework.security.access.prepost.PreAuthorize; - -import kieker.common.logging.Log; -import kieker.common.logging.LogFactory; -import kieker.webgui.common.IUserManager; -import kieker.webgui.common.Role; -import kieker.webgui.common.User; - -public class UserManagerImpl implements IUserManager { - - private static final Log LOG = LogFactory.getLog(UserManagerImpl.class); - private DataSource dataSource; - private Connection connection; - - /** - * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> - */ - public UserManagerImpl() { - // No code necessary - } - - /** - * This method initializes the object.. <b>Do not call this method manually. It will only be accessed by Spring.</b> - */ - public void initialize() { - try { - this.connection = this.dataSource.getConnection(); - } catch (final SQLException ex) { - UserManagerImpl.LOG.error("Could not establish database connection.", ex); - } - } - - public void destroy() { - try { - this.connection.close(); - } catch (final SQLException ex) { - UserManagerImpl.LOG.error("Could not close database connection.", ex); - } - } - - public void setDataSource(final DataSource dataSource) { - this.dataSource = dataSource; - } - - @Override - @PreAuthorize("hasRole('ROLE_ADMIN')") - public void addUser(final String username, final String password, final List<Role> roles) { - PreparedStatement userCmd = null; - PreparedStatement roleCmd = null; - try { - userCmd = this.connection.prepareStatement("INSERT INTO KIEKERUser (name, password, enabled) VALUES (?, ?, True)"); - roleCmd = this.connection.prepareStatement("INSERT INTO Userroles (name, role) VALUES (?, ?)"); - - userCmd.setString(1, username); - userCmd.setString(2, password); - userCmd.execute(); - - roleCmd.setString(1, username); - for (final Role role : roles) { - roleCmd.setInt(2, role.getID()); - roleCmd.execute(); - } - } catch (final SQLException ex) { - UserManagerImpl.LOG.error("Could not add user to the database.", ex); - } finally { - if (userCmd != null) { - try { - userCmd.close(); - } catch (final SQLException ex) { - UserManagerImpl.LOG.error("Could not close prepared statement.", ex); - } - } - if (roleCmd != null) { - try { - roleCmd.close(); - } catch (final SQLException ex) { - UserManagerImpl.LOG.error("Could not close prepared statement.", ex); - } - } - } - } - - @Override - @PreAuthorize("hasRole('ROLE_ADMIN')") - public void removeUser(final String username) { - // TODO Auto-generated method stub - - } - - @Override - @PreAuthorize("hasRole('ROLE_ADMIN')") - public void editUser(final String username, final String password, final Role... roles) { - // TODO Auto-generated method stub - - } - - @Override - @PreAuthorize("hasRole('ROLE_ADMIN')") - public List<User> getUsers() { - // FIXME Users without roles - final List<User> result = new ArrayList<User>(); - ResultSet queryResult = null; - - try { - final Map<String, User> tempMap = new TreeMap<String, User>(); - - final PreparedStatement getQuery = this.connection - .prepareStatement("select u.name, ur.role, u.enabled from KIEKERUser u, Userroles ur where u.name=ur.name"); - - // Run through all results - queryResult = getQuery.executeQuery(); - while (queryResult.next()) { - // Get both the username and the role from the current entry - final String username = queryResult.getString(1); - final int roleID = queryResult.getInt(2); - final Role role = Role.fromID(roleID); - final boolean enabled = queryResult.getBoolean(3); - - // If the user doesn't exist in our map yet, add him. - // In each case we add the role to the user - if (tempMap.containsKey(username)) { - tempMap.get(username).getRoles().add(role); - } else { - final List<Role> roles = new ArrayList<Role>(); - roles.add(role); - tempMap.put(username, new User(username, roles, enabled)); - } - } - - // Now convert the map to the list - result.addAll(tempMap.values()); - } catch (final SQLException ex) { - UserManagerImpl.LOG.error("Could not receive user list.", ex); - } finally { - try { - if (queryResult != null) { - queryResult.close(); - } - } catch (final SQLException ex) { - UserManagerImpl.LOG.error("Could not close query result.", ex); - } - } - - return result; - } -} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/package-info.java deleted file mode 100644 index 06fc0c4fa5dbcafa46bc350eb3979157634169e7..0000000000000000000000000000000000000000 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/*************************************************************************** - * Copyright 2012 Kieker Project (http://kieker-monitoring.net) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - ***************************************************************************/ - -/** - * This package contains utility classes, which are used in the parent-package. The classes within this package are not for public use. They should only be used by - * the classes in {@code kieker.webgui.common}. - * - * @author Nils Christian Ehmke - */ -package kieker.webgui.common.util; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/domain/Project.java b/Kieker.WebGUI/src/main/java/kieker/webgui/domain/Project.java new file mode 100644 index 0000000000000000000000000000000000000000..dd2002f45824c1c11067255a6b2326c73c75c448 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/domain/Project.java @@ -0,0 +1,90 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package kieker.webgui.domain; + +import kieker.analysis.model.analysisMetaModel.MIProject; + +/** + * @author Nils Christian Ehmke + */ +public class Project { + + private String owner; + private String lastEditor; + private MIProject projectInstance; + + public Project(final MIProject projectInstace) { + this.projectInstance = projectInstace; + } + + /** + * Getter for the property {@link Project#projectInstance}. + * + * @return The current value of the property. + */ + public MIProject getProjectInstance() { + return this.projectInstance; + } + + /** + * Setter for the property {@link Project#projectInstance}. + * + * @param projectInstace + * The new value of the property. + */ + public void setProjectInstance(final MIProject projectInstance) { + this.projectInstance = projectInstance; + } + + /** + * Getter for the property {@link Project#owner}. + * + * @return The current value of the property. + */ + public String getOwner() { + return this.owner; + } + + /** + * Setter for the property {@link Project#owner}. + * + * @param owner + * The new value of the property. + */ + public void setOwner(final String owner) { + this.owner = owner; + } + + /** + * Getter for the property {@link Project#lastEditor}. + * + * @return The current value of the property. + */ + public String getLastEditor() { + return this.lastEditor; + } + + /** + * Setter for the property {@link Project#lastEditor}. + * + * @param lastEditor + * The new value of the property. + */ + public void setLastEditor(final String lastEditor) { + this.lastEditor = lastEditor; + } + +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/domain/User.java b/Kieker.WebGUI/src/main/java/kieker/webgui/domain/User.java new file mode 100644 index 0000000000000000000000000000000000000000..cf8cc6ec94ba1afc67a26b08ffe0a99cbec027aa --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/domain/User.java @@ -0,0 +1,190 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package kieker.webgui.domain; + +/** + * This is a domain object representing a user within the system. + * + * @author Nils Christian Ehmke + */ +public class User { + + private String name; + private String password; + private Role role; + private boolean enabled; + + /** + * Creates a new instance of this class. + * + * @param name + * The name of the user. + * @param password + * The password of the user. + * @param role + * The role of the user. + * @param enabled + * A flag whether the user is enabled or not. + */ + public User(final String name, final String password, final Role role, final boolean enabled) { + this.name = name; + this.role = role; + this.enabled = enabled; + this.password = password; + } + + /** + * Getter for the property {@link User#name}. + * + * @return The current value of the property. + */ + public String getName() { + return this.name; + } + + /** + * Setter for the property {@link User#name}. + * + * @param name + * The new value of the property. + */ + public void setName(final String name) { + this.name = name; + } + + /** + * Getter for the property {@link User#password}. + * + * @return The current value of the property. + */ + public String getPassword() { + return this.password; + } + + /** + * Setter for the property {@link User#password}. + * + * @param password + * The new value of the property. + */ + public void setPassword(final String password) { + this.password = password; + } + + /** + * Getter for the property {@link User#role}. + * + * @return The current value of the property. + */ + public Role getRole() { + return this.role; + } + + /** + * Setter for the property {@link User#role}. + * + * @param role + * The new value of the property. + */ + public void setRole(final Role role) { + this.role = role; + } + + /** + * Getter for the property {@link User#enabled}. + * + * @return The current value of the property. + */ + public boolean isEnabled() { + return this.enabled; + } + + /** + * Setter for the property {@link User#enabled}. + * + * @param enabled + * The new value of the property. + */ + public void setEnabled(final boolean enabled) { + this.enabled = enabled; + } + + /** + * This enum represents the available roles within this systen. + * + * @author Nils Christian Ehmke + */ + public static enum Role { + + /** + * Represents a guest within the system. + */ + ROLE_GUEST(0), + /** + * Represents an user within the system. + */ + ROLE_USER(1), + /** + * Represents an admin within the system. + */ + ROLE_ADMIN(2); + + private int id; + + /** + * Creates a new instance of this enum. + * + * @param id + * The id of the role. + */ + private Role(final int id) { + this.id = id; + } + + /** + * Getter for the property {@link Role#id}. + * + * @return The current value of the property. + */ + public int getID() { + return this.id; + } + + /** + * Delivers the corresponding role to the given id. if the id cannot be recognized the value {@link Role#ROLE_GUEST} will be returned. + * + * @param id + * The id to be recognized. + * @return The corresponding role. + */ + public static Role fromID(final int id) { + final Role role; + + if (id == 2) { + role = Role.ROLE_ADMIN; + } else { + if (id == 1) { + role = Role.ROLE_USER; + } else { + role = Role.ROLE_GUEST; + } + } + + return role; + } + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/converter/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/domain/package-info.java similarity index 95% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/converter/package-info.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/domain/package-info.java index 7d66d4494cbfd8565eb90383c1ef37e3b1c5d862..3931eafb0ca213a61d8263c05774ad757a5ece35 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/converter/package-info.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/domain/package-info.java @@ -16,6 +16,5 @@ /** * @author Nils Christian Ehmke - * */ -package kieker.webgui.common.converter; \ No newline at end of file +package kieker.webgui.domain; \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java new file mode 100644 index 0000000000000000000000000000000000000000..3468746a11894fc3f3922438616fc13474416728 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IProjectDAO.java @@ -0,0 +1,231 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package kieker.webgui.persistence; + +import java.io.File; +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Collection; +import java.util.List; + +import org.springframework.security.access.prepost.PreAuthorize; + +import kieker.analysis.model.analysisMetaModel.MIDependency; +import kieker.analysis.model.analysisMetaModel.MIProject; +import kieker.webgui.common.ClassAndMethodContainer; +import kieker.webgui.common.exception.LibraryAlreadyExistingException; +import kieker.webgui.common.exception.NewerProjectException; +import kieker.webgui.common.exception.ProjectAlreadyExistingException; +import kieker.webgui.common.exception.ProjectNotExistingException; + +import org.primefaces.model.UploadedFile; + +/** + * This is the interface for the data access object(s) which will access for example the file system to manage the available projects. + * + * @author Nils Christian Ehmke + */ +public interface IProjectDAO { + + /** + * This method adds a new project to the application. It creates an empty, but nevertheless valid kax-file to the file system. If the method fails due to an + * {@link IOException}, it will make sure that the project-directories will be removed as if the method would never have been called. + * + * @param projectName + * The name of the new project. + * @throws ProjectAlreadyExistingException + * If a project with the same name exists already. + * @throws IOException + * If something went wrong during the creation of the project. + */ + @PreAuthorize("hasAnyRole('User', 'Administrator')") + public abstract void addProject(String projectName) throws ProjectAlreadyExistingException, IOException; + + /** + * This method makes a copy of a project and saves it under another name. If the method fails due to an {@link IOException}, it will make sure that the + * project-directories of the destination-project will be removed as if the method would never have been called. + * + * @param originalProjectName + * The name of the source project. + * @param newProjectName + * The name of the target project. + * @throws ProjectNotExistingException + * If a project with the given (source) name doesn't exist. + * @throws ProjectAlreadyExistingException + * If a project with the same (target) name exists already. + * @throws IOException + * If something went wrong during the creation of the target-project or during the loading of the source-project. + */ + @PreAuthorize("hasAnyRole('User', 'Administrator')") + public abstract void copyProject(String originalProjectName, String newProjectName) throws ProjectNotExistingException, ProjectAlreadyExistingException, + IOException; + + /** + * This method loads the kax-file for the given project name and delivers an initializes instance of {@link MIProject}. + * + * @param projectName + * The name of the project to be loaded. + * @return The model instance as defined by the corresponding kax-file. + * @throws ProjectNotExistingException + * If a project with the given (source) name doesn't exist. + * @throws IOException + * If something went wrong during the opening of the project. + */ + @PreAuthorize("isAuthenticated()") + public abstract MIProject openProject(String projectName) throws ProjectNotExistingException, IOException; + + /** + * This method loads the kax-file for the given project name and delivers an initializes instance of {@link MIProject} - but instead of using the "normal" class + * loader, it uses the methods and classes stored in the given instance of {@link ClassAndMethodContainer}. This means that this method <b>does</b> return an + * instance of {@link MIProject}, but the one defined in the container. This is also the reason why this method has to return an {@link Object}-instance. + * + * @param projectName + * The name of the project to be loaded. + * @param classAndMethodContainer + * The container, which will be used to load the project instance. + * @return The model instance as defined by the corresponding kax-file. + * @throws ProjectNotExistingException + * If a project with the given (source) name doesn't exist. + * @throws IOException + * If something went wrong during the opening of the project. This can also mean that the given {@link ClassAndMethodContainer} is somehow invalid. + */ + @PreAuthorize("isAuthenticated()") + public abstract Object openProject(String projectName, ClassAndMethodContainer classAndMethodContainer) throws ProjectNotExistingException, IOException; + + /** + * This method tries to save the given model instance for the given project. The given time stamp will be compared (if the corresponding flag says so) with the + * current time stamp of the project. If the project on the file system has been modified in the meantime, a {@link NewerProjectException} will be thrown. If + * something goes wrong during the storage, it is <b>not</b> guaranteed that the resulting file will be valid. + * + * @param projectName + * The name of the project which has to be saved. + * @param project + * The model instance to be stored in the corresponding kax-file. + * @param timeStamp + * The time stamp which has to be compared with the "real" time stamp of the project. + * @param overwriteNewerProject + * Determines whether a newer project file will be overwritten without further warning or not- + * @throws ProjectNotExistingException + * If a project with the given name does not exist. + * @throws IOException + * If something went wrong during the storage of the model instance. + * @throws NewerProjectException + * If the project on the file system is newer and the overwriteNewerProject-flag has not been set. + */ + @PreAuthorize("hasAnyRole('User', 'Administrator')") + public abstract void saveProject(String projectName, MIProject project, long timeStamp, boolean overwriteNewerProject) throws + ProjectNotExistingException, IOException, NewerProjectException; + + /** + * Delivers the current time stamp of the given project. + * + * @param projectName + * The name of the project whose time stamp will be delivered. + * @return The current time stamp. + * @throws ProjectNotExistingException + * If a project with the given name does not exist. + */ + @PreAuthorize("isAuthenticated()") + public abstract long getCurrTimeStamp(String projectName) throws ProjectNotExistingException; + + /** + * This method tries to upload a dependency to the given project. + * + * @param file + * The file to be uploaded to the project. + * @param projectName + * The name of the project. + * @throws ProjectNotExistingException + * If a project with the given name does not exist. + * @throws IOException + * If something went wrong during the uploading. + * @throws LibraryAlreadyExistingException + * If a library with the same name exists already. + */ + @PreAuthorize("hasAnyRole('User', 'Administrator')") + public abstract void uploadLibrary(UploadedFile file, String projectName) throws ProjectNotExistingException, IOException, LibraryAlreadyExistingException; + + /** + * This method delivers a class loader containing the currently available libraries of the given project. + * + * @param projectName + * The name of the project. + * @param requester + * The requester of the classloader. + * @return A class loader for the given project. + * @throws ProjectNotExistingException + * If a project with the given name does not exist. + * @throws IOException + * If something went wrong during the initialization of the class loader. + */ + @PreAuthorize("isAuthenticated()") + public ClassLoader getClassLoader(final String projectName, final Object requester) throws ProjectNotExistingException, IOException; + + /** + * This method lists all available libraries of the given project. + * + * @param projectName + * The name of the project whose libraries have to be delivered. + * @return A list containing all available library-names of the project. + * @throws ProjectNotExistingException + * If a project with the given name does not exist. + */ + @PreAuthorize("isAuthenticated()") + public abstract List<String> listAllLibraries(String projectName) throws ProjectNotExistingException; + + /** + * This method lists all available projects on the file system. + * + * @return A list containing all available project names. + */ + @PreAuthorize("isAuthenticated()") + public abstract Collection<String> listAllProjects(); + + /** + * This method can be used to deliver the fully qualified URL of a given dependency for a given project. + * + * @param lib + * The library whose URL should be delivered. + * @param project + * The corresponding project of the library. + * @return The URL to the given library if everything went well. + * @throws MalformedURLException + * If the URL is for some reason invalid. + */ + @PreAuthorize("isAuthenticated()") + public abstract URL getURL(MIDependency lib, String project) throws MalformedURLException; + + /** + * Delivers the {@link URL}-element pointing to the kieker library. + * + * @return The kieker library. + */ + @PreAuthorize("isAuthenticated()") + public abstract URL getKiekerURL(); + + /** + * Delivers the kax-file for the given project. + * + * @param projectName + * The name of the project. + * @return The kax-file of the project. + */ + @PreAuthorize("isAuthenticated()") + public abstract File getProjectFile(String projectName); + +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IUserDAO.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IUserDAO.java new file mode 100644 index 0000000000000000000000000000000000000000..a8b3881ba163e7f05866f4c8733b8b59fe4db6d5 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/IUserDAO.java @@ -0,0 +1,81 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package kieker.webgui.persistence; + +import java.util.List; + +import org.springframework.security.access.prepost.PreAuthorize; + +import kieker.webgui.common.exception.DataAccessException; +import kieker.webgui.domain.User; + +/** + * This is the interface for the data access object(s) which will access for example a database to manage the available users. The methods within this interface are + * only accessible by administrators. Furthermore the methods should be transactional. + * + * @author Nils Christian Ehmke + */ +public interface IUserDAO { + + /** + * Adds a user to the system. + * + * @param user + * The domain object used to extract the necessary data to create the user. + * @throws DataAccessException + * If it was not possible to add the user to the system. Either because a constraint was violated or because the connection to the database has + * somehow been damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public void addUser(final User user) throws DataAccessException; + + /** + * Deletes a user from the system. + * + * @param user + * The domain object used to extract the necessary data to delete the user. + * @throws DataAccessException + * If it was not possible to delete the user. Either because a constraint was violated or because the connection to the database has somehow been + * damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public void deleteUser(final User user) throws DataAccessException; + + /** + * Edits a given user. If the password field of the given domain object is empty, the password won't be changed. If it is filled, it will be changed. + * + * @param user + * The domain object used to extract the necessary data to edit the user. + * @throws DataAccessException + * If it was not possible to edit the user. Either because a constraint was violated or because the connection to the database has somehow been + * damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public void editUser(final User user) throws DataAccessException; + + /** + * Delivers a list containing the available users within the system. The password fields of the returned domain objects will be empty. The list is always a copy + * and can be modified at will. + * + * @return A list with the available users. + * @throws DataAccessException + * If something went wrong during the reading. This happens probably if the connection to the database has somehow been damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public List<User> getUsers() throws DataAccessException; + +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/DerbyUserDAOImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/DerbyUserDAOImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..b7756edaca38f509930d626f8c6a049f1f8839b0 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/DerbyUserDAOImpl.java @@ -0,0 +1,248 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package kieker.webgui.persistence.impl; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.annotation.PreDestroy; +import javax.sql.DataSource; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.jdbc.datasource.DataSourceUtils; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; + +import kieker.common.logging.Log; +import kieker.common.logging.LogFactory; +import kieker.webgui.common.exception.DataAccessException; +import kieker.webgui.domain.User; +import kieker.webgui.domain.User.Role; +import kieker.webgui.persistence.IUserDAO; + +/** + * An implementation of the {@link IUserDAO} interface, which uses Apache Derby to store and manage the available users. A transaction manager is not necessary, as + * all of the used commands are atomic (except for the getUsers() method, which is read only though). + * + * @author Nils Christian Ehmke + */ +@Service +public class DerbyUserDAOImpl implements IUserDAO { + + private static final Log LOG = LogFactory.getLog(DerbyUserDAOImpl.class); + + @Autowired + private DataSource dataSource; + private Connection connection; + + /** + * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> + */ + public DerbyUserDAOImpl() { + // No code necessary + } + + /** + * This method initializes the object. <b>Do not call this method manually. It will only be accessed by Spring.</b> + * + * @throws SQLException + * If something went wrong during the initialization. + */ + @PostConstruct + public void initialize() throws SQLException { + this.connection = DataSourceUtils.getConnection(this.dataSource); + } + + /** + * This method "destroys" the object by closing the connection to the database. <b>Do not call this method manually. It will only be accessed by Spring.</b> + * + * @throws SQLException + * If something went wrong during the initialization. + */ + @PreDestroy + public void destroy() throws SQLException { + this.connection.close(); + } + + /* + * (non-Javadoc) + * + * @see kieker.webgui.persistence.IserDAO#addUser(user) + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public void addUser(final User user) throws DataAccessException { + PreparedStatement userCmd = null; + try { + userCmd = this.connection.prepareStatement("INSERT INTO Users (name, password, isGuest, isUser, isAdministrator, isEnabled) VALUES (?, ?, ?, ?, ?, ?)"); + + // Use all properties of the given object + userCmd.setString(1, user.getName()); + userCmd.setString(2, user.getPassword()); + userCmd.setBoolean(3, user.getRole() == Role.ROLE_GUEST); + userCmd.setBoolean(4, user.getRole() == Role.ROLE_USER); + userCmd.setBoolean(5, user.getRole() == Role.ROLE_ADMIN); + userCmd.setBoolean(6, user.isEnabled()); + + // Run the command + userCmd.execute(); + } catch (final SQLException ex) { + // Something went wrong. Inform the calling method. + throw new DataAccessException("Could not add user to the database.", ex); + } finally { + // Try to close the statement. If that doesn't work then log it, but it is not necessary to inform the calling method. + if (userCmd != null) { + try { + userCmd.close(); + } catch (final SQLException ex) { + DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see kieker.webgui.persistence.IserDAO#deleteUser(user) + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public void deleteUser(final User user) throws DataAccessException { + PreparedStatement delCmd = null; + try { + delCmd = this.connection.prepareStatement("DELETE FROM Users WHERE name=?"); + + delCmd.setString(1, user.getName()); + + delCmd.execute(); + } catch (final SQLException ex) { + // Something went wrong. Inform the calling method. + throw new DataAccessException("Could not delete user from the database.", ex); + } finally { + // Try to close the statement. If that doesn't work then log it, but it is not necessary to inform the calling method. + if (delCmd != null) { + try { + delCmd.close(); + } catch (final SQLException ex) { + DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see kieker.webgui.persistence.IserDAO#editUser(user) + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public void editUser(final User user) throws DataAccessException { + PreparedStatement updateCmd = null; + try { + // Choose the right update command, depending on whether the password has to be changed or not + if (user.getPassword() == null) { + updateCmd = this.connection.prepareStatement("UPDATE Users SET name=?, isGuest=?, isUser=?, isAdministrator=?, isEnabled=? WHERE name=?"); + } else { + // In this case we have to set the password as well + updateCmd = this.connection + .prepareStatement("UPDATE Users SET name=?, isGuest=?, isUser=?, isAdministrator=?, isEnabled=?, password=? WHERE name=?"); + updateCmd.setString(6, user.getPassword()); + } + + // Set the other values + updateCmd.setString(1, user.getName()); + updateCmd.setBoolean(2, user.getRole() == Role.ROLE_GUEST); + updateCmd.setBoolean(3, user.getRole() == Role.ROLE_USER); + updateCmd.setBoolean(4, user.getRole() == Role.ROLE_ADMIN); + updateCmd.setBoolean(5, user.isEnabled()); + + // Run the command + updateCmd.execute(); + } catch (final SQLException ex) { + throw new DataAccessException("Could not update user within the database.", ex); + } finally { + // Try to close the statement. If that doesn't work then log it, but it is not necessary to inform the calling method. + if (updateCmd != null) { + try { + updateCmd.close(); + } catch (final SQLException ex) { + DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex); + } + } + } + } + + /* + * (non-Javadoc) + * + * @see List<User> kieker.webgui.persistence.getUsers() + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public List<User> getUsers() throws DataAccessException { + final List<User> result = new ArrayList<User>(); + + ResultSet queryResult = null; + PreparedStatement getQuery = null; + + try { + getQuery = this.connection.prepareStatement("SELECT name, isGuest, isUser, isAdministrator, isEnabled FROM Users"); + + // Run through all results + queryResult = getQuery.executeQuery(); + while (queryResult.next()) { + final String username = queryResult.getString(1); + final boolean isGuest = queryResult.getBoolean(2); + final boolean isUser = queryResult.getBoolean(3); + final boolean isAdministrator = queryResult.getBoolean(4); + final boolean isEnabled = queryResult.getBoolean(5); + + // The case that the user has no role cannot happen, as the database should make sure that this is not possible + final Role role = isAdministrator ? Role.ROLE_ADMIN : (isUser ? Role.ROLE_USER : (isGuest ? Role.ROLE_GUEST : null)); // NOPMD (Null assigning) + + result.add(new User(username, null, role, isEnabled)); + } + } catch (final SQLException ex) { + DerbyUserDAOImpl.LOG.error("Could not receive user list.", ex); + } finally { + // Try to close the everything. If that doesn't work then log it, but it is not necessary to inform the calling method. + try { + if (queryResult != null) { + queryResult.close(); + } + } catch (final SQLException ex) { + DerbyUserDAOImpl.LOG.error("Could not close query result.", ex); + } + if (getQuery != null) { + try { + getQuery.close(); + } catch (final SQLException ex) { + DerbyUserDAOImpl.LOG.error("Could not close prepared statement.", ex); + } + } + } + + return result; + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/FSManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java similarity index 64% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/util/FSManager.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java index d5716a93c928c82251a11ec714552e74104e9442..e13bd892f9e0fdb5ea5509ea48be7af3a2ece5a9 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/FSManager.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/FSProjectDAOImpl.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.common.util; +package kieker.webgui.persistence.impl; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; @@ -23,9 +23,9 @@ import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.lang.ref.WeakReference; import java.net.MalformedURLException; import java.net.URL; -import java.net.URLClassLoader; import java.nio.channels.ByteChannel; import java.nio.channels.FileChannel; import java.security.AccessController; @@ -33,6 +33,16 @@ import java.security.PrivilegedAction; import java.util.ArrayList; import java.util.Collection; import java.util.List; +import java.util.Map; +import java.util.Map.Entry; +import java.util.concurrent.ConcurrentHashMap; + +import javax.annotation.PostConstruct; + +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; +import org.springframework.util.WeakReferenceMonitor; +import org.springframework.util.WeakReferenceMonitor.ReleaseListener; import kieker.analysis.AnalysisController; import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory; @@ -46,19 +56,21 @@ import kieker.webgui.common.exception.LibraryAlreadyExistingException; import kieker.webgui.common.exception.NewerProjectException; import kieker.webgui.common.exception.ProjectAlreadyExistingException; import kieker.webgui.common.exception.ProjectNotExistingException; +import kieker.webgui.persistence.IProjectDAO; +import kieker.webgui.persistence.impl.util.CloseableURLClassLoader; import org.primefaces.model.UploadedFile; /** - * This is a singleton class for the access to the file system. It makes sure that the necessary directories for the execution of the application exist. <b>Do - * not</b> remove directories created from this manager during runtime! Directories are created during first access to the class.<br> - * This class <b>does not</b> use any kind of synchronization to handle the access to the projects. + * This is an implementation of the {@link IProjectDAO} interface, which uses the file system to store the available projects and everything. * * @author Nils Christian Ehmke */ -public final class FSManager { +@Service +public class FSProjectDAOImpl implements IProjectDAO, ReleaseListener { + + private static final Log LOG = LogFactory.getLog(FSProjectDAOImpl.class); - private static final Log LOG = LogFactory.getLog(FSManager.class); private static final String KAX_EXTENSION = "kax"; private static final String LIB_EXTENSION = "jar"; private static final String LIB_DIRECTORY = "lib"; @@ -73,40 +85,40 @@ public final class FSManager { private static final int BUF_SIZE_BYTES = 1024 * 1024; private final MIAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory(); + private final Map<CloseableURLClassLoader, WeakReference<Object>> classLoaders = new ConcurrentHashMap<CloseableURLClassLoader, WeakReference<Object>>(); /** * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> */ - public FSManager() { + public FSProjectDAOImpl() { // no code necessary } /** - * This method initializes the class. Normally this method should be called via the @PostConstruction annotation, but for unknown reason it does only work for - * beans. + * This method initializes the object. <b>Do not call this method manually. It will only be accessed by Spring.</b> + * + * @throws IOException + * If the creation of the necessary directories failed. */ - protected void initialize() { + @PostConstruct + public void initialize() throws IOException { // Check for our root-directory and create it if necessary - final File rootDir = new File(FSManager.ROOT_DIRECTORY); + final File rootDir = new File(FSProjectDAOImpl.ROOT_DIRECTORY); if (!rootDir.exists()) { final boolean result = rootDir.mkdir(); if (!result) { - FSManager.LOG.error("Could not create root directory."); + throw new IOException("Could not create root directory."); } } } - /** - * This method adds a new project to the application. It creates an empty, but nevertheless valid kax-file to the file system. If the method fails due to an - * {@link IOException}, it will make sure that the project-directories will be removed as if the method would never have been called. + /* + * (non-Javadoc) * - * @param projectName - * The name of the new project. - * @throws ProjectAlreadyExistingException - * If a project with the same name exists already. - * @throws IOException - * If something went wrong during the creation of the project. + * @see kieker.webgui.persistence.IProjectDAO#addProject(java.lang.String) */ + @Override + @PreAuthorize("hasAnyRole('User', 'Administrator')") public void addProject(final String projectName) throws ProjectAlreadyExistingException, IOException { // Assemble all necessary paths and files for the given project final File projectDir = this.assembleProjectDir(projectName); @@ -146,21 +158,13 @@ public final class FSManager { } } - /** - * This method makes a copy of a project and saves it under another name. If the method fails due to an {@link IOException}, it will make sure that the - * project-directories of the destination-project will be removed as if the method would never have been called. + /* + * (non-Javadoc) * - * @param originalProjectName - * The name of the source project. - * @param newProjectName - * The name of the target project. - * @throws ProjectNotExistingException - * If a project with the given (source) name doesn't exist. - * @throws ProjectAlreadyExistingException - * If a project with the same (target) name exists already. - * @throws IOException - * If something went wrong during the creation of the target-project or during the loading of the source-project. + * @see kieker.webgui.persistence.IProjectDAO#copyProject(java.lang.String, java.lang.String) */ + @Override + @PreAuthorize("hasAnyRole('User', 'Administrator')") public void copyProject(final String originalProjectName, final String newProjectName) throws ProjectNotExistingException, ProjectAlreadyExistingException, IOException { // Get the necessary paths @@ -205,17 +209,13 @@ public final class FSManager { } } - /** - * This method loads the kax-file for the given project name and delivers an initializes instance of {@link MIProject}. + /* + * (non-Javadoc) * - * @param projectName - * The name of the project to be loaded. - * @return The model instance as defined by the corresponding kax-file. - * @throws ProjectNotExistingException - * If a project with the given (source) name doesn't exist. - * @throws IOException - * If something went wrong during the opening of the project. + * @see kieker.webgui.persistence.IProjectDAO#openProject(java.lang.String) */ + @Override + @PreAuthorize("isAuthenticated()") public MIProject openProject(final String projectName) throws ProjectNotExistingException, IOException { if (projectName == null) { throw new IOException("Project is null"); @@ -229,21 +229,13 @@ public final class FSManager { } } - /** - * This method loads the kax-file for the given project name and delivers an initializes instance of {@link MIProject} - but instead of using the "normal" class - * loader, it uses the methods and classes stored in the given instance of {@link ClassAndMethodContainer}. This means that this method <b>does</b> return an - * instance of {@link MIProject}, but the one defined in the container. This is also the reason why this method has to return an {@link Object}-instance. + /* + * (non-Javadoc) * - * @param projectName - * The name of the project to be loaded. - * @param classAndMethodContainer - * The container, which will be used to load the project instance. - * @return The model instance as defined by the corresponding kax-file. - * @throws ProjectNotExistingException - * If a project with the given (source) name doesn't exist. - * @throws IOException - * If something went wrong during the opening of the project. This can also mean that the given {@link ClassAndMethodContainer} is somehow invalid. + * @see kieker.webgui.persistence.IProjectDAO#openProject(java.lang.String, kieker.webgui.common.ClassAndMethodContainer) */ + @Override + @PreAuthorize("isAuthenticated()") public Object openProject(final String projectName, final ClassAndMethodContainer classAndMethodContainer) throws ProjectNotExistingException, IOException { if (projectName == null) { throw new IOException("Project is null"); @@ -260,26 +252,13 @@ public final class FSManager { } } - /** - * This method tries to save the given model instance for the given project. The given time stamp will be compared (if the corresponding flag says so) with the - * current time stamp of the project. If the project on the file system has been modified in the meantime, a {@link NewerProjectException} will be thrown. If - * something goes wrong during the storage, it is <b>not</b> guaranteed that the resulting file will be valid. + /* + * (non-Javadoc) * - * @param projectName - * The name of the project which has to be saved. - * @param project - * The model instance to be stored in the corresponding kax-file. - * @param timeStamp - * The time stamp which has to be compared with the "real" time stamp of the project. - * @param overwriteNewerProject - * Determines whether a newer project file will be overwritten without further warning or not- - * @throws ProjectNotExistingException - * If a project with the given name does not exist. - * @throws IOException - * If something went wrong during the storage of the model instance. - * @throws NewerProjectException - * If the project on the file system is newer and the overwriteNewerProject-flag has not been set. + * @see kieker.webgui.persistence.IProjectDAO#saveProject(java.lang.String, kieker.analysis.model.analysisMetaModel.MIProject, long, boolean) */ + @Override + @PreAuthorize("hasAnyRole('User', 'Administrator')") public void saveProject(final String projectName, final MIProject project, final long timeStamp, final boolean overwriteNewerProject) throws ProjectNotExistingException, IOException, NewerProjectException { // Check whether the project exists @@ -297,15 +276,13 @@ public final class FSManager { AnalysisController.saveToFile(this.assembleKaxFile(projectName), project); } - /** - * Delivers the current time stamp of the given project. + /* + * (non-Javadoc) * - * @param projectName - * The name of the project whose time stamp will be delivered. - * @return The current time stamp. - * @throws ProjectNotExistingException - * If a project with the given name does not exist. + * @see kieker.webgui.persistence.IProjectDAO#getCurrTimeStamp(java.lang.String) */ + @Override + @PreAuthorize("isAuthenticated()") public long getCurrTimeStamp(final String projectName) throws ProjectNotExistingException { // Check whether the project exists if (!this.projectExists(projectName)) { @@ -314,20 +291,13 @@ public final class FSManager { return this.assembleKaxFile(projectName).lastModified(); } - /** - * This method tries to upload a dependency to the given project. + /* + * (non-Javadoc) * - * @param file - * The file to be uploaded to the project. - * @param projectName - * The name of the project. - * @throws ProjectNotExistingException - * If a project with the given name does not exist. - * @throws IOException - * If something went wrong during the uploading. - * @throws LibraryAlreadyExistingException - * If a library with the same name exists already. + * @see kieker.webgui.persistence.IProjectDAO#uploadLibrary(org.primefaces.model.UploadedFile, java.lang.String) */ + @Override + @PreAuthorize("hasAnyRole('User', 'Administrator')") public void uploadLibrary(final UploadedFile file, final String projectName) throws ProjectNotExistingException, IOException, LibraryAlreadyExistingException { // Check whether the project exists if (!this.projectExists(projectName)) { @@ -350,7 +320,7 @@ public final class FSManager { // Get the streams. in = new BufferedInputStream(file.getInputstream()); out = new BufferedOutputStream(new FileOutputStream(dstFile)); - final byte[] buf = new byte[FSManager.BUF_SIZE_BYTES]; + final byte[] buf = new byte[FSProjectDAOImpl.BUF_SIZE_BYTES]; int count; // Transfer the file. @@ -383,18 +353,14 @@ public final class FSManager { } } - /** - * This method delivers a class loader containing the currently available libraries of the given project. + /* + * (non-Javadoc) * - * @param projectName - * The name of the project. - * @return A class loader for the given project. - * @throws ProjectNotExistingException - * If a project with the given name does not exist. - * @throws IOException - * If something went wrong during the initialization of the class loader. + * @see kieker.webgui.persistence.IProjectDAO#getClassLoader(java.lang.String) */ - public ClassLoader getClassLoader(final String projectName) throws ProjectNotExistingException, IOException { + @Override + @PreAuthorize("isAuthenticated()") + public ClassLoader getClassLoader(final String projectName, final Object requester) throws ProjectNotExistingException, IOException { // Check whether the project exists if (!this.projectExists(projectName)) { throw new ProjectNotExistingException("A project with the name '" + projectName + "' does not exist."); @@ -405,13 +371,13 @@ public final class FSManager { // Collect all libraries of the project // Run through the libs and put them into our list. - final File libDir = new File(FSManager.ROOT_DIRECTORY + File.separator + projectName + File.separator + FSManager.LIB_DIRECTORY); + final File libDir = new File(FSProjectDAOImpl.ROOT_DIRECTORY + File.separator + projectName + File.separator + FSProjectDAOImpl.LIB_DIRECTORY); final File[] files = libDir.listFiles(); if (files != null) { for (final File file : files) { - if (file.getName().endsWith("." + FSManager.LIB_EXTENSION)) { + if (file.getName().endsWith("." + FSProjectDAOImpl.LIB_EXTENSION)) { try { - libs.add(file.toURL()); + libs.add(file.toURI().toURL()); } catch (final MalformedURLException ex) { ex.printStackTrace(); } @@ -424,18 +390,22 @@ public final class FSManager { // Now assemble the URL class loader final PrivilegedClassLoaderAction action = new PrivilegedClassLoaderAction(libs); - return AccessController.doPrivileged(action); + final CloseableURLClassLoader classLoader = AccessController.doPrivileged(action); + + // Remember the requester + this.classLoaders.put(classLoader, new WeakReference<Object>(requester)); + WeakReferenceMonitor.monitor(requester, this); + + return classLoader; } - /** - * This method lists all available libraries of the given project. + /* + * (non-Javadoc) * - * @param projectName - * The name of the project whose libraries have to be delivered. - * @return A list containing all available library-names of the project. - * @throws ProjectNotExistingException - * If a project with the given name does not exist. + * @see kieker.webgui.persistence.IProjectDAO#listAllLibraries(java.lang.String) */ + @Override + @PreAuthorize("isAuthenticated()") public List<String> listAllLibraries(final String projectName) throws ProjectNotExistingException { // Check whether the project exists if (!this.projectExists(projectName)) { @@ -448,7 +418,7 @@ public final class FSManager { final File[] files = this.assembleLibDir(projectName).listFiles(); if (files != null) { for (final File file : files) { - if (file.getName().endsWith("." + FSManager.LIB_EXTENSION)) { + if (file.getName().endsWith("." + FSProjectDAOImpl.LIB_EXTENSION)) { result.add(file.getName()); } } @@ -457,16 +427,18 @@ public final class FSManager { return result; } - /** - * This method lists all available projects on the file system. + /* + * (non-Javadoc) * - * @return A list containing all available project names. + * @see kieker.webgui.persistence.IProjectDAO#listAllProjects() */ + @Override + @PreAuthorize("isAuthenticated()") public Collection<String> listAllProjects() { final List<String> result = new ArrayList<String>(); // Get all directories within our root-dir - final File[] files = new File(FSManager.ROOT_DIRECTORY).listFiles(); + final File[] files = new File(FSProjectDAOImpl.ROOT_DIRECTORY).listFiles(); for (final File file : files) { if (file.isDirectory()) { result.add(file.getName()); @@ -505,7 +477,7 @@ public final class FSManager { result = dst.setLastModified(src.lastModified()); } catch (final IOException ex) { - FSManager.LOG.error("An IO error occured", ex); + FSProjectDAOImpl.LOG.error("An IO error occured", ex); result = false; } finally { // Try to close the streams @@ -513,7 +485,7 @@ public final class FSManager { try { fileInputStream.close(); } catch (final IOException ex) { - FSManager.LOG.error("An IO error occured", ex); + FSProjectDAOImpl.LOG.error("An IO error occured", ex); result = false; } } @@ -521,7 +493,7 @@ public final class FSManager { try { fileOutputStream.close(); } catch (final IOException ex) { - FSManager.LOG.error("An IO error occured", ex); + FSProjectDAOImpl.LOG.error("An IO error occured", ex); result = false; } } @@ -547,7 +519,7 @@ public final class FSManager { private void transfer(final FileChannel fileChannel, final ByteChannel byteChannel, final long lengthInBytes) throws IOException { long overallBytesTransfered = 0L; while (overallBytesTransfered < lengthInBytes) { - final long count = Math.min(FSManager.BUF_SIZE_BYTES, lengthInBytes - overallBytesTransfered); + final long count = Math.min(FSProjectDAOImpl.BUF_SIZE_BYTES, lengthInBytes - overallBytesTransfered); final long bytesTransfered = fileChannel.transferTo(overallBytesTransfered, count, byteChannel); overallBytesTransfered += bytesTransfered; } @@ -564,21 +536,17 @@ public final class FSManager { return this.assembleKaxFile(projectName).exists(); } - /** - * This method can be used to deliver the fully qualified URL of a given dependency for a given project. + /* + * (non-Javadoc) * - * @param lib - * The library whose URL should be delivered. - * @param project - * The corresponding project of the library. - * @return The URL to the given library if everything went well. - * @throws MalformedURLException - * If the URL is for some reason invalid. + * @see kieker.webgui.persistence.IProjectDAO#getURL(kieker.analysis.model.analysisMetaModel.MIDependency, java.lang.String) */ + @Override + @PreAuthorize("isAuthenticated()") public URL getURL(final MIDependency lib, final String project) throws MalformedURLException { - final File file = new File(FSManager.ROOT_DIRECTORY + File.separator + project + File.separator + FSManager.LIB_DIRECTORY + File.separator + final File file = new File(FSProjectDAOImpl.ROOT_DIRECTORY + File.separator + project + File.separator + FSProjectDAOImpl.LIB_DIRECTORY + File.separator + lib.getFilePath()); - return file.toURL(); + return file.toURI().toURL(); } /** @@ -589,7 +557,7 @@ public final class FSManager { * @return The directory of the project. */ private File assembleProjectDir(final String projectName) { - return new File(FSManager.ROOT_DIRECTORY + File.separator + projectName); + return new File(FSProjectDAOImpl.ROOT_DIRECTORY + File.separator + projectName); } /** @@ -600,7 +568,7 @@ public final class FSManager { * @return The kax-file of the project. */ private File assembleKaxFile(final String projectName) { - return new File(FSManager.ROOT_DIRECTORY + File.separator + projectName + File.separator + projectName + "." + FSManager.KAX_EXTENSION); + return new File(FSProjectDAOImpl.ROOT_DIRECTORY + File.separator + projectName + File.separator + projectName + "." + FSProjectDAOImpl.KAX_EXTENSION); } /** @@ -611,36 +579,70 @@ public final class FSManager { * @return The library directory of the project. */ private File assembleLibDir(final String projectName) { - return new File(FSManager.ROOT_DIRECTORY + File.separator + projectName + File.separator + FSManager.LIB_DIRECTORY); + return new File(FSProjectDAOImpl.ROOT_DIRECTORY + File.separator + projectName + File.separator + FSProjectDAOImpl.LIB_DIRECTORY); } - /** - * Delivers the {@link URL}-element pointing to the kieker library. + /* + * (non-Javadoc) * - * @return The kieker library. + * @see kieker.webgui.persistence.IProjectDAO#getKiekerURL() */ + @Override + @PreAuthorize("isAuthenticated()") public URL getKiekerURL() { - return Thread.currentThread().getContextClassLoader().getResource(FSManager.KIEKER_LIB); + return Thread.currentThread().getContextClassLoader().getResource(FSProjectDAOImpl.KIEKER_LIB); } - /** - * Delivers the kax-file for the given project. + /* + * (non-Javadoc) * - * @param projectName - * The name of the project. - * @return The kax-file of the project. + * @see kieker.webgui.persistence.IProjectDAO#getProjectFile(java.lang.String) */ + @Override + @PreAuthorize("isAuthenticated()") public File getProjectFile(final String projectName) { return this.assembleKaxFile(projectName); } + /* + * (non-Javadoc) + * + * @see org.springframework.util.WeakReferenceMonitor.ReleaseListener#released() + */ + @Override + public void released() { + synchronized (this.classLoaders) { + int open = 0; + + final List<CloseableURLClassLoader> toBeRemoved = new ArrayList<CloseableURLClassLoader>(); + // Run through the class loaders and check which of them can be closed + for (final Entry<CloseableURLClassLoader, WeakReference<Object>> entry : this.classLoaders.entrySet()) { + if (entry.getValue().get() == null) { + toBeRemoved.add(entry.getKey()); + } else { + open++; + } + } + for (final CloseableURLClassLoader classLoader : toBeRemoved) { + try { + classLoader.close(); + this.classLoaders.remove(classLoader); + FSProjectDAOImpl.LOG.info("Closed classloader (" + classLoader + ")"); + } catch (final IOException ex) { + FSProjectDAOImpl.LOG.error("Could not close classloader (" + classLoader + ")"); + } + } + FSProjectDAOImpl.LOG.info(open + " classloaders still open."); + } + } + /** * This helper class is responsible for creating a classloader as a privileged action. This is recommended due to the java security manager. * * @author Nils Christian Ehmke * @version 1.0 */ - private static class PrivilegedClassLoaderAction implements PrivilegedAction<URLClassLoader> { + private static class PrivilegedClassLoaderAction implements PrivilegedAction<CloseableURLClassLoader> { /** * The list of libraries used to create the class loader. */ @@ -662,9 +664,9 @@ public final class FSManager { * @return The class loader. */ @Override - public URLClassLoader run() { + public CloseableURLClassLoader run() { // We use "null" as an explicit parent to make sure that the class loader is completely independent from the web gui class loader. - return new URLClassLoader(this.libs.toArray(new URL[this.libs.size()]), null); + return new CloseableURLClassLoader(this.libs.toArray(new URL[this.libs.size()]), null); } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/util/CloseableURLClassLoader.java b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/util/CloseableURLClassLoader.java new file mode 100644 index 0000000000000000000000000000000000000000..e20604da4a4f0813ed314669b19a4b815f8d556a --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/persistence/impl/util/CloseableURLClassLoader.java @@ -0,0 +1,79 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package kieker.webgui.persistence.impl.util; + +import java.io.Closeable; +import java.io.IOException; +import java.net.URL; +import java.net.URLClassLoader; +import java.util.Collection; + +/** + * A class loader which extends the {@link URLClassLoader} with a close-method using a hack. This will probably only work for a Sun VM. The class itself will + * partially <b>not</b> be checked by Findbugs (there is an exception-rule in the configuration-file) as I <b>know</b> that the code is dangerous. It is a hack after + * all. + * + * @author Nils Christian Ehmke + */ +public class CloseableURLClassLoader extends URLClassLoader implements Closeable { + + /** + * Creates a new instance of this class using the given parameters. + * + * @param urls + * The URLs to be used by the classloader. + * @param parent + * The parent of this classloader. + */ + public CloseableURLClassLoader(final URL[] urls, final ClassLoader parent) { + super(urls, parent); + } + + /* + * (non-Javadoc) + * + * @see java.io.Closeable#close() + */ + @Override + public void close() throws IOException { + try { + final Class<URLClassLoader> clazz = URLClassLoader.class; + final java.lang.reflect.Field ucp = clazz.getDeclaredField("ucp"); + ucp.setAccessible(true); + + final Object sunMiscURLClassPath = ucp.get(this); + final java.lang.reflect.Field loaders = sunMiscURLClassPath.getClass().getDeclaredField("loaders"); + loaders.setAccessible(true); + + // Run through all available loaders and try to close them + final Object javaUtilCollection = loaders.get(sunMiscURLClassPath); + for (final Object sunMiscURLClassPathJarLoader : ((Collection<?>) javaUtilCollection).toArray()) { + try { + final java.lang.reflect.Field loader = sunMiscURLClassPathJarLoader.getClass().getDeclaredField("jar"); + loader.setAccessible(true); + final Object javaUtilIarJarFile = loader.get(sunMiscURLClassPathJarLoader); + ((java.util.jar.JarFile) javaUtilIarJarFile).close(); + } catch (final Throwable t) { // NOCS, NOPMD (Catch of Throwable) + // if we got this far, this is probably not a JAR loader so skip it + } + } + } catch (final Throwable ex) { // NOCS, NOPMD (Catch of Throwable) + // probably not a SUN VM + throw new IOException("Not a Sun VM.", ex); + } + } + +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/IProjectManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java similarity index 97% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/IProjectManager.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java index d7e68c1172ce855721d4d038407797198987a1fa..fc30376a0b4f9345f32f8a19a708b7638f695acf 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/IProjectManager.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IProjectService.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.common; +package kieker.webgui.service; import java.io.IOException; import java.util.Collection; @@ -25,6 +25,7 @@ import kieker.analysis.model.analysisMetaModel.MIDependency; import kieker.analysis.model.analysisMetaModel.MIProject; import kieker.analysis.plugin.AbstractPlugin; import kieker.analysis.repository.AbstractRepository; +import kieker.webgui.common.ClassAndMethodContainer; import kieker.webgui.common.exception.AnalysisInitializationException; import kieker.webgui.common.exception.AnalysisStateException; import kieker.webgui.common.exception.DisplayNotFoundException; @@ -43,7 +44,7 @@ import org.primefaces.model.UploadedFile; * * @author Nils Christian Ehmke */ -public interface IProjectManager { +public interface IProjectService { /** * This method adds a new project to the application. It creates an empty, but nevertheless valid kax-file to the file system. If the method fails due to an @@ -161,13 +162,15 @@ public interface IProjectManager { * * @param projectName * The name of the project. + * @param requester + * The requester of the class loader. * @return A class loader for the given project. * @throws ProjectNotExistingException * If a project with the given name does not exist. * @throws IOException * If something went wrong during the initialization of the class loader. */ - public ClassLoader getClassLoader(final String projectName) throws ProjectNotExistingException, IOException; + public ClassLoader getClassLoader(final String projectName, final Object requester) throws ProjectNotExistingException, IOException; /** * This method lists all available libraries of the given project. @@ -330,10 +333,8 @@ public interface IProjectManager { * @param projectName * The name of the project whose state have to be returned. * @return The state of the given project, if available. {@code null} otherwise. - * @throws ProjectNotExistingException - * If a project with the given name does not exist. */ - public STATE getCurrentState(final String projectName) throws ProjectNotExistingException; + public STATE getCurrentState(final String projectName); /** * This method delivers the available log entries of the analysis controller of the given project. diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/IUserService.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IUserService.java new file mode 100644 index 0000000000000000000000000000000000000000..e5820f2c405f5581620409b30cd242e13054996a --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/IUserService.java @@ -0,0 +1,80 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package kieker.webgui.service; + +import java.util.List; + +import org.springframework.security.access.prepost.PreAuthorize; + +import kieker.webgui.common.exception.DataAccessException; +import kieker.webgui.domain.User; + +/** + * This is an interface to the service which can be used to manage the available users within the system. The methods within this interface are only accessible by + * administrators. + * + * @author Nils Christian Ehmke + */ +public interface IUserService { + + /** + * Adds a user to the system. + * + * @param user + * The domain object used to extract the necessary data to create the user. + * @throws DataAccessException + * If it was not possible to add the user to the system. Either because a constraint was violated or because the connection to the database has + * somehow been damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public void addUser(final User user) throws DataAccessException; + + /** + * Deletes a user from the system. + * + * @param user + * The domain object used to extract the necessary data to delete the user. + * @throws DataAccessException + * If it was not possible to delete the user. Either because a constraint was violated or because the connection to the database has somehow been + * damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public void deleteUser(final User user) throws DataAccessException; + + /** + * Edits a given user. If the password field of the given domain object is empty, the password won't be changed. If it is filled, it will be changed. + * + * @param user + * The domain object used to extract the necessary data to edit the user. + * @throws DataAccessException + * If it was not possible to edit the user. Either because a constraint was violated or because the connection to the database has somehow been + * damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public void editUser(final User user) throws DataAccessException; + + /** + * Delivers a list containing the available users within the system. The password fields of the returned domain objects will be empty. The list is always a copy + * and can be modified at will. + * + * @return A list with the available users. + * @throws DataAccessException + * If something went wrong during the reading. This happens probably if the connection to the database has somehow been damaged. + */ + @PreAuthorize("hasRole('Administrator')") + public List<User> getUsers() throws DataAccessException; + +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/ProjectManagerImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java similarity index 80% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/ProjectManagerImpl.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java index 497457ca84fb6f4a3dfb4f5d54933483d9c48345..c156a6ca4d9951bbd3b93f829b7ec5ed55ea8ec2 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/ProjectManagerImpl.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/ProjectServiceImpl.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.common.impl; +package kieker.webgui.service.impl; import java.io.IOException; import java.net.MalformedURLException; @@ -22,13 +22,15 @@ import java.util.Collection; import java.util.List; import java.util.concurrent.ConcurrentHashMap; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; + import kieker.analysis.AnalysisController.STATE; import kieker.analysis.model.analysisMetaModel.MIDependency; import kieker.analysis.model.analysisMetaModel.MIProject; import kieker.analysis.plugin.AbstractPlugin; import kieker.analysis.repository.AbstractRepository; import kieker.webgui.common.ClassAndMethodContainer; -import kieker.webgui.common.IProjectManager; import kieker.webgui.common.exception.AnalysisInitializationException; import kieker.webgui.common.exception.AnalysisStateException; import kieker.webgui.common.exception.DisplayNotFoundException; @@ -37,9 +39,10 @@ import kieker.webgui.common.exception.LibraryLoadException; import kieker.webgui.common.exception.NewerProjectException; import kieker.webgui.common.exception.ProjectAlreadyExistingException; import kieker.webgui.common.exception.ProjectNotExistingException; -import kieker.webgui.common.util.ACManager; -import kieker.webgui.common.util.FSManager; -import kieker.webgui.common.util.PluginFinder; +import kieker.webgui.persistence.IProjectDAO; +import kieker.webgui.service.IProjectService; +import kieker.webgui.service.impl.util.ACManager; +import kieker.webgui.service.impl.util.PluginFinder; import org.primefaces.model.UploadedFile; @@ -48,54 +51,31 @@ import org.primefaces.model.UploadedFile; * * @author Nils Christian Ehmke */ -public final class ProjectManagerImpl implements IProjectManager { +@Service +public final class ProjectServiceImpl implements IProjectService { private final ConcurrentHashMap<String, Object> fileSystemLocks = new ConcurrentHashMap<String, Object>(); private final ConcurrentHashMap<String, Object> analysesLocks = new ConcurrentHashMap<String, Object>(); + @Autowired private ACManager acManager; - private FSManager fsManager; + @Autowired + private IProjectDAO projectDAO; + @Autowired private PluginFinder pluginFinder; /** * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> */ - public ProjectManagerImpl() { + public ProjectServiceImpl() { // No code necessary. } - /** - * The setter for the property {@link ProjectManagerImpl#acManager}. <b>Do not use this method. This property is Spring managed.</b> - * - * @param acManager - */ - public void setAcManager(final ACManager acManager) { - this.acManager = acManager; - } - - /** - * The setter for the property {@link ProjectManagerImpl#fsManager}. <b>Do not use this method. This property is Spring managed.</b> - * - * @param fsManager - */ - public void setFsManager(final FSManager fsManager) { - this.fsManager = fsManager; - } - - /** - * The setter for the property {@link ProjectManagerImpl#pluginFinder}. <b>Do not use this method. This property is Spring managed.</b> - * - * @param pluginFinder - */ - public void setPluginFinder(final PluginFinder pluginFinder) { - this.pluginFinder = pluginFinder; - } - @Override public void addProject(final String projectName) throws ProjectAlreadyExistingException, IOException { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - this.fsManager.addProject(projectName); + this.projectDAO.addProject(projectName); } } @@ -121,7 +101,7 @@ public final class ProjectManagerImpl implements IProjectManager { synchronized (lockFst) { synchronized (lockSnd) { - this.fsManager.copyProject(originalProjectName, newProjectName); + this.projectDAO.copyProject(originalProjectName, newProjectName); } } } @@ -131,7 +111,7 @@ public final class ProjectManagerImpl implements IProjectManager { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - return this.fsManager.openProject(projectName); + return this.projectDAO.openProject(projectName); } } @@ -140,7 +120,7 @@ public final class ProjectManagerImpl implements IProjectManager { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - return this.fsManager.openProject(projectName, classAndMethodContainer); + return this.projectDAO.openProject(projectName, classAndMethodContainer); } } @@ -150,7 +130,7 @@ public final class ProjectManagerImpl implements IProjectManager { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - this.fsManager.saveProject(projectName, project, timeStamp, overwriteNewerProject); + this.projectDAO.saveProject(projectName, project, timeStamp, overwriteNewerProject); } } @@ -159,7 +139,7 @@ public final class ProjectManagerImpl implements IProjectManager { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - return this.fsManager.getCurrTimeStamp(projectName); + return this.projectDAO.getCurrTimeStamp(projectName); } } @@ -168,16 +148,16 @@ public final class ProjectManagerImpl implements IProjectManager { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - this.fsManager.uploadLibrary(file, projectName); + this.projectDAO.uploadLibrary(file, projectName); } } @Override - public ClassLoader getClassLoader(final String projectName) throws ProjectNotExistingException, IOException { + public ClassLoader getClassLoader(final String projectName, final Object requester) throws ProjectNotExistingException, IOException { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - return this.fsManager.getClassLoader(projectName); // NOPMD (ClassLoader) + return this.projectDAO.getClassLoader(projectName, requester); // NOPMD (ClassLoader) } } @@ -188,7 +168,7 @@ public final class ProjectManagerImpl implements IProjectManager { synchronized (projectLock) { try { - return this.pluginFinder.getAllRepositoriesWithinJar(this.fsManager.getURL(lib, projectName), classLoader, classAndMethodContainer); + return this.pluginFinder.getAllRepositoriesWithinJar(this.projectDAO.getURL(lib, projectName), classLoader, classAndMethodContainer); } catch (final MalformedURLException ex) { throw new LibraryLoadException("An error occured while loading the library.", ex); } @@ -202,7 +182,7 @@ public final class ProjectManagerImpl implements IProjectManager { synchronized (projectLock) { try { - return this.pluginFinder.getAllPluginsWithinJar(this.fsManager.getURL(lib, projectName), classLoader, classAndMethodContainer); + return this.pluginFinder.getAllPluginsWithinJar(this.projectDAO.getURL(lib, projectName), classLoader, classAndMethodContainer); } catch (final MalformedURLException ex) { throw new LibraryLoadException("An error occured while loading the library.", ex); } @@ -213,7 +193,7 @@ public final class ProjectManagerImpl implements IProjectManager { public List<Class<AbstractRepository>> getAllRepositoriesWithinKiekerLib(final ClassLoader classLoader, final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException { try { - return this.pluginFinder.getAllRepositoriesWithinJar(this.fsManager.getKiekerURL(), classLoader, classAndMethodContainer); + return this.pluginFinder.getAllRepositoriesWithinJar(this.projectDAO.getKiekerURL(), classLoader, classAndMethodContainer); } catch (final NullPointerException ex) { throw new LibraryLoadException("An error occured while loading the library.", ex); @@ -224,7 +204,7 @@ public final class ProjectManagerImpl implements IProjectManager { public List<Class<AbstractPlugin>> getAllPluginsWithinKiekerLib(final ClassLoader classLoader, final ClassAndMethodContainer classAndMethodContainer) throws LibraryLoadException { try { - return this.pluginFinder.getAllPluginsWithinJar(this.fsManager.getKiekerURL(), classLoader, classAndMethodContainer); + return this.pluginFinder.getAllPluginsWithinJar(this.projectDAO.getKiekerURL(), classLoader, classAndMethodContainer); } catch (final NullPointerException ex) { throw new LibraryLoadException("An error occured while loading the library.", ex); @@ -236,13 +216,13 @@ public final class ProjectManagerImpl implements IProjectManager { final Object projectLock = this.getLock(projectName, this.fileSystemLocks); synchronized (projectLock) { - return this.fsManager.listAllLibraries(projectName); + return this.projectDAO.listAllLibraries(projectName); } } @Override public Collection<String> listAllProjects() { - return this.fsManager.listAllProjects(); + return this.projectDAO.listAllProjects(); } @Override @@ -297,7 +277,7 @@ public final class ProjectManagerImpl implements IProjectManager { } @Override - public STATE getCurrentState(final String projectName) throws ProjectNotExistingException { + public STATE getCurrentState(final String projectName) { final Object analysisLock = this.getLock(projectName, this.analysesLocks); synchronized (analysisLock) { diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/UserServiceImpl.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/UserServiceImpl.java new file mode 100644 index 0000000000000000000000000000000000000000..23ac51187abc4c73ef90e7ca95936d3c248cc676 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/UserServiceImpl.java @@ -0,0 +1,91 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ +package kieker.webgui.service.impl; + +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.security.access.prepost.PreAuthorize; +import org.springframework.stereotype.Service; + +import kieker.webgui.common.exception.DataAccessException; +import kieker.webgui.domain.User; +import kieker.webgui.persistence.IUserDAO; +import kieker.webgui.service.IUserService; + +/** + * This is an implementation of the {@link IUserService} interface. The work will be delegated to the underlying data access object. + * + * @author Nils Christian Ehmke + */ +@Service +public class UserServiceImpl implements IUserService { + + @Autowired + private IUserDAO userDAO; + + /** + * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> + */ + public UserServiceImpl() { + // No code necessary + } + + /* + * (non-Javadoc) + * + * @see kieker.webgui.service.IUserService#addUser(kieker.webgui.domain.User) + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public void addUser(final User user) throws DataAccessException { + this.userDAO.addUser(user); + } + + /* + * (non-Javadoc) + * + * @see kieker.webgui.service.IUserService#getUsers() + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public List<User> getUsers() throws DataAccessException { + return this.userDAO.getUsers(); + } + + /* + * (non-Javadoc) + * + * @see kieker.webgui.service.IUserService#deleteUser(kieker.webgui.domain.User) + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public void deleteUser(final User user) throws DataAccessException { + this.userDAO.deleteUser(user); + } + + /* + * (non-Javadoc) + * + * @see kieker.webgui.service.IUserService#editUser(kieker.webgui.domain.User) + */ + @Override + @PreAuthorize("hasRole('Administrator')") + public void editUser(final User user) throws DataAccessException { + this.userDAO.editUser(user); + } + +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..87c267d4af0b95ceab05df8d051e82f9b424fc5f --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/package-info.java @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +/** + * @author Nils Christian Ehmke + */ +package kieker.webgui.service.impl; \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/ACManager.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/ACManager.java similarity index 86% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/util/ACManager.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/ACManager.java index 6d03d91604565f28818a7c880cf38a53f2f2277d..a9addbe3fee38a5bbe92495e051cf263919ffefb 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/ACManager.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/ACManager.java @@ -14,17 +14,19 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.common.util; +package kieker.webgui.service.impl.util; import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Service; import kieker.analysis.AnalysisController.STATE; import kieker.webgui.common.exception.AnalysisInitializationException; import kieker.webgui.common.exception.AnalysisStateException; import kieker.webgui.common.exception.DisplayNotFoundException; import kieker.webgui.common.exception.ProjectNotExistingException; +import kieker.webgui.persistence.IProjectDAO; /** * This manager is responsible for the currently used and running instances of {@code AnalysisController}. It supplies methods to check the states of analysis, @@ -32,6 +34,7 @@ import kieker.webgui.common.exception.ProjectNotExistingException; * * @author Nils Christian Ehmke */ +@Service public final class ACManager { /** * This list contains the current analysis controllers and their corresponding threads. Not every project does have a controller, but every project can have @@ -39,7 +42,7 @@ public final class ACManager { */ private final ConcurrentHashMap<String, Analysis> analyses = new ConcurrentHashMap<String, Analysis>(); @Autowired - private FSManager fsManager; + private IProjectDAO projectDAO; /** * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> @@ -48,10 +51,6 @@ public final class ACManager { // No code necessary. } - public void setFsManager(final FSManager fsManager) { - this.fsManager = fsManager; - } - /** * This method initializes the analysis for the given project. * @@ -73,7 +72,7 @@ public final class ACManager { throw new AnalysisStateException("The analysis has not been cleaned yet."); } - final Analysis analysis = new Analysis(classLoader, this.fsManager.getProjectFile(projectName)); + final Analysis analysis = new Analysis(classLoader, this.projectDAO.getProjectFile(projectName)); this.analyses.put(projectName, analysis); } @@ -195,41 +194,36 @@ public final class ACManager { } /** - * This method delivers the current state of the analysis, if it is available, an exception otherwise. + * This method delivers the current state of the analysis, if it is available, null otherwise. * * @param projectName * The name of the project. * @return The state of the given project. - * @throws ProjectNotExistingException - * If a project with the given name does not exist. */ - public STATE getCurrentState(final String projectName) throws ProjectNotExistingException { - // The analysis for the given project must exist! - if (!this.analyses.containsKey(projectName)) { - throw new ProjectNotExistingException("The analysis has not been initialized yet."); - } - - final Analysis analysis = this.analyses.get(projectName); - final Enum<?> state = analysis.getCurrentState(); - - if (state == null) { - throw new ProjectNotExistingException("Unknown state."); - } + public STATE getCurrentState(final String projectName) { + STATE retState = null; - if (STATE.FAILED.toString().equals(state.toString())) { - return STATE.FAILED; - } - if (STATE.READY.toString().equals(state.toString())) { - return STATE.READY; - } - if (STATE.RUNNING.toString().equals(state.toString())) { - return STATE.RUNNING; - } - if (STATE.TERMINATED.toString().equals(state.toString())) { - return STATE.TERMINATED; + // The analysis for the given project must exist! + if (this.analyses.containsKey(projectName)) { + final Analysis analysis = this.analyses.get(projectName); + final Enum<?> state = analysis.getCurrentState(); + + if (state != null) { + if (STATE.FAILED.toString().equals(state.toString())) { + retState = STATE.FAILED; + } + if (STATE.READY.toString().equals(state.toString())) { + retState = STATE.READY; + } + if (STATE.RUNNING.toString().equals(state.toString())) { + retState = STATE.RUNNING; + } + if (STATE.TERMINATED.toString().equals(state.toString())) { + retState = STATE.TERMINATED; + } + } } - - throw new ProjectNotExistingException("Unknown state."); + return retState; } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/Analysis.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/Analysis.java similarity index 99% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/util/Analysis.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/Analysis.java index 74180ef306d141f8c85ae3f615a218fcd8da9b65..bf72d284ba58ad230aa1b15efe00cb9342111d4b 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/Analysis.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/Analysis.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.common.util; +package kieker.webgui.service.impl.util; import java.io.File; import java.lang.reflect.InvocationTargetException; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/PluginFinder.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/PluginFinder.java similarity index 98% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/util/PluginFinder.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/PluginFinder.java index 8e414cb19c262ad82e9706a1d60eb4ea92777a13..a5ba59b746fc4b543f87d3152e2bae04b02817ea 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/util/PluginFinder.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/PluginFinder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ -package kieker.webgui.common.util; +package kieker.webgui.service.impl.util; import java.io.IOException; import java.net.URL; @@ -22,6 +22,8 @@ import java.util.List; import java.util.jar.JarEntry; import java.util.jar.JarInputStream; +import org.springframework.stereotype.Service; + import kieker.analysis.plugin.AbstractPlugin; import kieker.analysis.repository.AbstractRepository; import kieker.webgui.common.ClassAndMethodContainer; @@ -31,6 +33,7 @@ import kieker.webgui.common.ClassAndMethodContainer; * * @author Nils Christian Ehmke */ +@Service public final class PluginFinder { /** diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..9ee712888aaf6dc7ee3545e92a6d676dfd75e2d6 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/impl/util/package-info.java @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +/** + * @author Nils Christian Ehmke + */ +package kieker.webgui.service.impl.util; \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/service/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/service/package-info.java new file mode 100644 index 0000000000000000000000000000000000000000..ee1129d260b3fc85d5b1b02ee6301e07f60c41f6 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/service/package-info.java @@ -0,0 +1,20 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +/** + * @author Nils Christian Ehmke + */ +package kieker.webgui.service; \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/GlobalPropertiesBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/GlobalPropertiesBean.java similarity index 99% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/GlobalPropertiesBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/GlobalPropertiesBean.java index d93a1bdc564dcccc2a1a96b1c0fa1ee6dc8afe84..1f1caa7e7178e21543e90bc6f8541d403fc3a90b 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/GlobalPropertiesBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/GlobalPropertiesBean.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.application; +package kieker.webgui.web.beans.application; import java.io.Serializable; import java.util.ResourceBundle; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ProjectsBean.java similarity index 89% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ProjectsBean.java index f28ed6708a28be0dcaea7e56cee9d7f15d9b7627..88b7f9e114cc6226065d00b91dbd4ffc2ef929c5 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ProjectsBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ProjectsBean.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.application; +package kieker.webgui.web.beans.application; import java.io.IOException; import java.util.ArrayList; @@ -22,16 +22,22 @@ import java.util.Collections; import java.util.Date; import java.util.List; +import javax.annotation.PostConstruct; import javax.faces.application.FacesMessage; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Lazy; +import org.springframework.stereotype.Component; + +import kieker.analysis.AnalysisController.STATE; import kieker.analysis.model.analysisMetaModel.MIProject; import kieker.common.logging.Log; import kieker.common.logging.LogFactory; -import kieker.webgui.beans.view.CurrentProjectOverviewBean; -import kieker.webgui.common.IProjectManager; import kieker.webgui.common.exception.ProjectAlreadyExistingException; import kieker.webgui.common.exception.ProjectLoadException; import kieker.webgui.common.exception.ProjectNotExistingException; +import kieker.webgui.service.IProjectService; +import kieker.webgui.web.beans.view.CurrentProjectOverviewBean; /** * The {@link ProjectsBean} is a Spring managed bean to manage a list with all application wide available projects. It provides methods to receive this list as well @@ -42,6 +48,8 @@ import kieker.webgui.common.exception.ProjectNotExistingException; * * @author Nils Christian Ehmke */ +@Component +@Lazy public final class ProjectsBean { private static final Log LOG = LogFactory.getLog(ProjectsBean.class); @@ -49,8 +57,8 @@ public final class ProjectsBean { private static final String DEFAULT_ANALYSIS_STATE = ""; private final List<String> projects = Collections.synchronizedList(new ArrayList<String>()); - - private IProjectManager projectManagerFacade; + @Autowired + private IProjectService projectService; /** * Default constructor. <b>Do not use this constructor. This bean is Spring managed.</b> @@ -59,22 +67,13 @@ public final class ProjectsBean { // No code necessary } - /** - * The Setter for the property {@link ProjectsBean#projectManagerFacade}. <b>Do not use this method. This property is Spring managed.</b> - * - * @param projectManagerFacade - * The new value for the property. - */ - public void setProjectManagerFacade(final IProjectManager projectManagerFacade) { - this.projectManagerFacade = projectManagerFacade; - } - /** * This method does some initialization work after construction. <b>Do not call this method. The method is Spring managed.</b> */ + @PostConstruct protected void initialize() { // Load a list with all available projects on the FS - this.projects.addAll(this.projectManagerFacade.listAllProjects()); + this.projects.addAll(this.projectService.listAllProjects()); } /** @@ -93,7 +92,7 @@ public final class ProjectsBean { public void addProject(final String project, final CurrentProjectOverviewBean currentProjectOverviewBean) { try { // Try and use the FS-Manager to create the project atomically. - this.projectManagerFacade.addProject(project); + this.projectService.addProject(project); // If there were no exception, everything went well. We can add the project to our list. this.projects.add(project); // Inform the user @@ -126,7 +125,7 @@ public final class ProjectsBean { public void copyProject(final String sourceProject, final String destinationProject, final CurrentProjectOverviewBean currentProjectOverviewBean) { try { // Try and use the FS-Manager to copy the project atomically. - this.projectManagerFacade.copyProject(sourceProject, destinationProject); + this.projectService.copyProject(sourceProject, destinationProject); // If there were no exception, everything went well. We can add the project to our list. this.projects.add(destinationProject); // Inform the user @@ -158,7 +157,7 @@ public final class ProjectsBean { */ public MIProject openProject(final String project) throws ProjectLoadException { try { - return this.projectManagerFacade.openProject(project); + return this.projectService.openProject(project); } catch (final IOException ex) { ProjectsBean.LOG.error("An error occured while loading the project.", ex); throw new ProjectLoadException("An error occured while loading the project.", ex); @@ -179,7 +178,7 @@ public final class ProjectsBean { public String getCurrTimeStamp(final String project) { try { // Get the current time stamp of the project - final long timeStamp = this.projectManagerFacade.getCurrTimeStamp(project); + final long timeStamp = this.projectService.getCurrTimeStamp(project); // Convert the stamp into a human readable string. return new Date(timeStamp).toString(); } catch (final ProjectNotExistingException ex) { @@ -210,10 +209,10 @@ public final class ProjectsBean { * @return The current state of the corresponding AnalysisController. */ public String getAnalysisControllerState(final String project) { - try { - return this.projectManagerFacade.getCurrentState(project).toString(); - } catch (final ProjectNotExistingException ex) { - ProjectsBean.LOG.info("A project with the given name does not exist.", ex); + final STATE state = this.projectService.getCurrentState(project); + if (state != null) { + return state.toString(); + } else { return ProjectsBean.DEFAULT_ANALYSIS_STATE; } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ThemeSwitcherBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ThemeSwitcherBean.java similarity index 97% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ThemeSwitcherBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ThemeSwitcherBean.java index 91bb4b3775e1887360876b130fe7ad191396790a..d2b1bd351a50f56dd158d97b7b276dbf322b213d 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/ThemeSwitcherBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/ThemeSwitcherBean.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.application; +package kieker.webgui.web.beans.application; import java.util.Collections; import java.util.Map; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/package-info.java similarity index 95% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/package-info.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/package-info.java index 07aa9a7350f75b910d9801c5a9173dba62aef592..f79bc88f1f0daefe319ea3b83eeba0560518f055 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/application/package-info.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/application/package-info.java @@ -19,5 +19,5 @@ * * @author Nils Christian Ehmke */ -package kieker.webgui.beans.application; +package kieker.webgui.web.beans.application; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/NewUserBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/NewUserBean.java similarity index 81% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/NewUserBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/NewUserBean.java index 23c42a308deadb77bed3eabf9abe7cbb5d354f54..d54fc22cdf671474ae61547102e96f78cc6ca7b3 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/NewUserBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/NewUserBean.java @@ -14,12 +14,12 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.request; +package kieker.webgui.web.beans.request; -import java.util.ArrayList; -import java.util.List; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; -import kieker.webgui.common.Role; +import kieker.webgui.domain.User.Role; /** * This simple bean is request scoped and can be used to store the necessary data for a new user during a request. It is not to be used to deliver a list of users @@ -27,9 +27,11 @@ import kieker.webgui.common.Role; * * @author Nils Christian Ehmke */ +@Component +@Scope("request") public class NewUserBean { - private List<Role> roles; + private final Role role; private String username; private String password; @@ -37,28 +39,18 @@ public class NewUserBean { * Creates a new instance of this bean and initializes it with empty fields. <b>Do not use this constructor. This bean is Spring managed.</b> */ public NewUserBean() { - this.roles = new ArrayList<Role>(); + this.role = Role.ROLE_GUEST; this.username = ""; this.password = ""; } /** - * Delivers the current value of the property {@link NewUserBean#roles}. + * Getter for the property {@link NewUserBean#role}. * * @return The current value of the property. */ - public List<Role> getRoles() { - return this.roles; - } - - /** - * Setter for the property {@link NewUserBean#roles}. - * - * @param roles - * The new value for the property. - */ - public void setRoles(final List<Role> roles) { - this.roles = roles; + public Role getRole() { + return this.role; } /** diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/StringBean.java similarity index 94% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/StringBean.java index caabc4aeb126b04ef40a67065377dd2fa4fa6662..720d2fee45d43a93674cc55ec7a58d8d8f9b10e3 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/StringBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/StringBean.java @@ -14,7 +14,10 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.request; +package kieker.webgui.web.beans.request; + +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; /** * This simple bean can be used to store a string during a request. Furthermore it provides some simple methods to handle strings within the application where a bean @@ -23,6 +26,8 @@ package kieker.webgui.beans.request; * * @author Nils Christian Ehmke */ +@Component +@Scope("request") public final class StringBean { private String string; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/package-info.java similarity index 95% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/package-info.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/package-info.java index 26cfe25c23162f1f1618067bf0951a560de31731..53adcd24460450fc1b33e2b0c08e90483b44b929 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/request/package-info.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/request/package-info.java @@ -19,5 +19,5 @@ * * @author Nils Christian Ehmke */ -package kieker.webgui.beans.request; +package kieker.webgui.web.beans.request; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/UserBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/session/UserBean.java similarity index 86% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/UserBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/session/UserBean.java index a9a6025d2dc05a3007d7a1c014f577c077a7e88c..df01e14fac5166742f7e8979093f38b9bd27cf58 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/UserBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/session/UserBean.java @@ -14,19 +14,25 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.session; +package kieker.webgui.web.beans.session; import java.io.Serializable; +import java.util.Iterator; import java.util.Map; +import javax.annotation.PostConstruct; import javax.faces.context.FacesContext; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.security.core.GrantedAuthority; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; -import kieker.webgui.beans.application.GlobalPropertiesBean; +import kieker.webgui.web.beans.application.GlobalPropertiesBean; /** * This bean contains information about the user of this session (like the properties and configurations). This class is a Spring managed bean with session scope. @@ -34,6 +40,8 @@ import kieker.webgui.beans.application.GlobalPropertiesBean; * * @author Nils Christian Ehmke */ +@Component +@Scope("session") public final class UserBean implements Serializable { private static final long serialVersionUID = 6422563876003638348L; @@ -42,9 +50,7 @@ public final class UserBean implements Serializable { private String gridColor; private int gridSize; - /** - * This property is injected by Spring. - */ + @Autowired private GlobalPropertiesBean globalPropertiesBean; /** @@ -58,6 +64,7 @@ public final class UserBean implements Serializable { * This method initializes the bean. In fact it loads the default values before trying to load the values of the user from their cookies. <b>Do not call this * method. The method is Spring managed.</b> */ + @PostConstruct protected void initialize() { this.loadDefaultValues(); this.loadValuesFromCookies(); @@ -69,22 +76,39 @@ public final class UserBean implements Serializable { * @return The user name of the session user. */ public String getUsername() { - final String username; + String username = "N/A"; - // Try to get the principal - final Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); - if (principal instanceof UserDetails) { - // Looks like it worked. Extract the username. - final UserDetails userDetails = (UserDetails) principal; + final UserDetails userDetails = UserBean.getUserDetails(); + if (userDetails != null) { username = userDetails.getUsername(); - } else { - // Something went wrong - username = "N/A"; } return username; } + public String getUserrole() { + String userrole = "N/A"; + + final UserDetails userDetails = UserBean.getUserDetails(); + if (userDetails != null) { + final Iterator<? extends GrantedAuthority> authorities = userDetails.getAuthorities().iterator(); + // If there is at least one authority, we know that it must be the first (we only have one authority per user). + if (authorities.hasNext()) { + userrole = authorities.next().getAuthority(); + } + } + + return userrole; + } + + private static UserDetails getUserDetails() { + final Object principal = SecurityContextHolder.getContext().getAuthentication().getPrincipal(); + if (principal instanceof UserDetails) { + return (UserDetails) principal; + } + return null; + } + /** * The setter for the property {@link UserBean#globalPropertiesBean}. <b>Do not use this method. This property is Spring managed.</b> * diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/session/package-info.java similarity index 95% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/package-info.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/session/package-info.java index ecc09dcefc8c9ef382cc86ca664794b4293531be..64e96c5fe156f7d12e25c29297f04c736f1176ef 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/session/package-info.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/session/package-info.java @@ -19,5 +19,5 @@ * * @author Nils Christian Ehmke */ -package kieker.webgui.beans.session; +package kieker.webgui.web.beans.session; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java similarity index 63% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java index 4462c676781c60972e7853fbbe6837aab0904fc4..57bb009b61c36205f9d6e880e58ad3003e62cc06 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorBean.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.view; +package kieker.webgui.web.beans.view; import java.io.IOException; import java.lang.annotation.Annotation; @@ -29,6 +29,10 @@ import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; import javax.faces.event.ValueChangeEvent; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory; import kieker.analysis.model.analysisMetaModel.MIDependency; import kieker.analysis.model.analysisMetaModel.MIDisplay; @@ -49,16 +53,16 @@ import kieker.analysis.plugin.reader.AbstractReaderPlugin; import kieker.analysis.repository.AbstractRepository; import kieker.common.logging.Log; import kieker.common.logging.LogFactory; -import kieker.webgui.beans.application.GlobalPropertiesBean; -import kieker.webgui.beans.application.ProjectsBean; -import kieker.webgui.beans.session.UserBean; import kieker.webgui.common.ClassAndMethodContainer; -import kieker.webgui.common.IProjectManager; import kieker.webgui.common.exception.LibraryAlreadyExistingException; import kieker.webgui.common.exception.LibraryLoadException; import kieker.webgui.common.exception.NewerProjectException; import kieker.webgui.common.exception.ProjectLoadException; import kieker.webgui.common.exception.ProjectNotExistingException; +import kieker.webgui.service.IProjectService; +import kieker.webgui.web.beans.application.GlobalPropertiesBean; +import kieker.webgui.web.beans.application.ProjectsBean; +import kieker.webgui.web.beans.session.UserBean; import org.primefaces.context.RequestContext; import org.primefaces.event.FileUploadEvent; @@ -79,6 +83,8 @@ import org.eclipse.emf.ecore.EObject; * * @author Nils Christian Ehmke */ +@Component +@Scope("view") public final class CurrentAnalysisEditorBean { /** * This field contains the log-object for the whole class, which will be used to log all important errors and exceptions which occur. @@ -132,10 +138,15 @@ public final class CurrentAnalysisEditorBean { * This field contains the currently selected component (this can either be a plugin ({@link MIPlugin}) or a repository ({@link MIRepository})). */ private EObject selectedComponent; - private IProjectManager projectManagerFacade; + @Autowired + private IProjectService projectService; + @Autowired private ProjectsBean projectsBean; + @Autowired private CurrentAnalysisEditorGraphBean currentAnalysisEditorGraphBean; + @Autowired private UserBean userBean; + @Autowired private GlobalPropertiesBean globalPropertiesBean; /** @@ -145,63 +156,13 @@ public final class CurrentAnalysisEditorBean { // No code necessary } - /** - * Setter for the attribute {@link CurrentAnalysisEditorBean#projectManagerFacade}. - * - * @param projectManagerFacade - * The new value of the attribute. - */ - public void setProjectManagerFacade(final IProjectManager projectManagerFacade) { - this.projectManagerFacade = projectManagerFacade; - } - - /** - * Getter for the attribute {@link CurrentAnalysisEditorBean#currentAnalysisEditorGraphBean}. - * - * @return Delivers the value of the attribute. - */ - public CurrentAnalysisEditorGraphBean getCurrentAnalysisEditorGraphBean() { - return this.currentAnalysisEditorGraphBean; - } - - /** - * Setter for the attribute {@link CurrentAnalysisEditorBean#currentAnalysisEditorGraphBean}. - * - * @param currentAnalysisEditorGraphBean - * The new value of the attribute. - */ - public void setCurrentAnalysisEditorGraphBean(final CurrentAnalysisEditorGraphBean currentAnalysisEditorGraphBean) { - this.currentAnalysisEditorGraphBean = currentAnalysisEditorGraphBean; - } - - /** - * Getter for the attribute {@link CurrentAnalysisEditorBean#projectsBean}. - * - * @return Delivers the value of the attribute. - */ - public ProjectsBean getProjectsBean() { - return this.projectsBean; - } - - /** - * Setter for the attribute {@link CurrentAnalysisEditorBean#projectsBean}. - * - * @param projectsBean - * The new value of the attribute. - */ - public void setProjectsBean(final ProjectsBean projectsBean) { - this.projectsBean = projectsBean; - } - /** * This method delivers the project stored in this bean. * * @return The project for this user. */ - public MIProject getProject() { - synchronized (this) { - return this.project; - } + public synchronized MIProject getProject() { + return this.project; } /** @@ -210,42 +171,38 @@ public final class CurrentAnalysisEditorBean { * @param newName * The name of the project. */ - public void setProjectName(final String newName) { - synchronized (this) { - // Remember the given parameters - this.projectName = newName; - } + public synchronized void setProjectName(final String newName) { + // Remember the given parameters + this.projectName = newName; } /** * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by * Spring.</b> */ - public void initialize() { - synchronized (this) { - try { - // Make sure that the initialization will only be done for the init request. During all other requests, the method call have to be ignored. - if (!FacesContext.getCurrentInstance().isPostback()) { - // Load the project itself - this.project = this.projectsBean.openProject(this.projectName); - // Remember the current time! This is important for the later comparison of the time stamps. - this.resetTimeStamp(); - // Update the class loader and the specific classes used within various methods in this bean - this.reloadClassLoader(); - this.reloadClassesAndMethods(); - // Add the libraries within the lib-folder to the current model - this.initializeModelLibraries(); - // Load the available readers, filters and repositories - this.initializeToolPalette(); - } - } catch (final ProjectLoadException ex) { - CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException()); - } catch (final NullPointerException ex) { - // This exception can occur, when a property has not been initialized - CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException()); + public synchronized void initialize() { + try { + // Make sure that the initialization will only be done for the init request. During all other requests, the method call have to be ignored. + if (!FacesContext.getCurrentInstance().isPostback()) { + // Load the project itself + this.project = this.projectsBean.openProject(this.projectName); + // Remember the current time! This is important for the later comparison of the time stamps. + this.resetTimeStamp(); + // Update the class loader and the specific classes used within various methods in this bean + this.reloadClassLoader(); + this.reloadClassesAndMethods(); + // Add the libraries within the lib-folder to the current model + this.initializeModelLibraries(); + // Load the available readers, filters and repositories + this.initializeToolPalette(); } + } catch (final ProjectLoadException ex) { + CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException()); + } catch (final NullPointerException ex) { + // This exception can occur, when a property has not been initialized + CurrentAnalysisEditorBean.LOG.error("An error occured while loading the project.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectLoadingException()); } } @@ -255,10 +212,8 @@ public final class CurrentAnalysisEditorBean { * @throws ProjectLoadException * If one or more of the classes and methods necessary for {@link ClassAndMethodContainer} could not be found using the given class loader. */ - private void reloadClassesAndMethods() throws ProjectLoadException { - synchronized (this) { - this.classAndMethodContainer = new ClassAndMethodContainer(this.classLoader); - } + private synchronized void reloadClassesAndMethods() throws ProjectLoadException { + this.classAndMethodContainer = new ClassAndMethodContainer(this.classLoader); } /** @@ -267,24 +222,22 @@ public final class CurrentAnalysisEditorBean { * @throws ProjectLoadException * If something went wrong during the loading of the libraries. */ - private void initializeToolPalette() throws ProjectLoadException { - synchronized (this) { - try { - // Clean our tool palette - this.availableFilters.clear(); - this.availableReaders.clear(); - this.availableRepositories.clear(); - - // Run through all libraries and add their content to our lists - for (final MIDependency lib : this.project.getDependencies()) { - this.addContentsToToolPalette(lib); - } - // Run also through the kieker library - this.addKiekerContentsToToolPalette(); - } catch (final LibraryLoadException ex) { - CurrentAnalysisEditorBean.LOG.error("A library could not be loaded correctly.", ex); - throw new ProjectLoadException("A library could not be loaded correctly.", ex); + private synchronized void initializeToolPalette() throws ProjectLoadException { + try { + // Clean our tool palette + this.availableFilters.clear(); + this.availableReaders.clear(); + this.availableRepositories.clear(); + + // Run through all libraries and add their content to our lists + for (final MIDependency lib : this.project.getDependencies()) { + this.addContentsToToolPalette(lib); } + // Run also through the kieker library + this.addKiekerContentsToToolPalette(); + } catch (final LibraryLoadException ex) { + CurrentAnalysisEditorBean.LOG.error("A library could not be loaded correctly.", ex); + throw new ProjectLoadException("A library could not be loaded correctly.", ex); } } @@ -296,10 +249,10 @@ public final class CurrentAnalysisEditorBean { * @throws LibraryLoadException * If something went wrong during the loading of the library. */ - private void addContentsToToolPalette(final MIDependency dependency) throws LibraryLoadException { + private synchronized void addContentsToToolPalette(final MIDependency dependency) throws LibraryLoadException { this.addContentsToToolPalette( - this.projectManagerFacade.getAllPluginsWithinLib(dependency, this.projectName, this.classLoader, this.classAndMethodContainer), - this.projectManagerFacade.getAllRepositoriesWithinLib(dependency, this.projectName, this.classLoader, this.classAndMethodContainer)); + this.projectService.getAllPluginsWithinLib(dependency, this.projectName, this.classLoader, this.classAndMethodContainer), + this.projectService.getAllRepositoriesWithinLib(dependency, this.projectName, this.classLoader, this.classAndMethodContainer)); } /** @@ -308,10 +261,10 @@ public final class CurrentAnalysisEditorBean { * @throws LibraryLoadException * If something went wrong during the loading of the library. */ - private void addKiekerContentsToToolPalette() throws LibraryLoadException { + private synchronized void addKiekerContentsToToolPalette() throws LibraryLoadException { this.addContentsToToolPalette( - this.projectManagerFacade.getAllPluginsWithinKiekerLib(this.classLoader, this.classAndMethodContainer), - this.projectManagerFacade.getAllRepositoriesWithinKiekerLib(this.classLoader, this.classAndMethodContainer)); + this.projectService.getAllPluginsWithinKiekerLib(this.classLoader, this.classAndMethodContainer), + this.projectService.getAllRepositoriesWithinKiekerLib(this.classLoader, this.classAndMethodContainer)); } /** @@ -323,37 +276,35 @@ public final class CurrentAnalysisEditorBean { * The available repositories. */ @SuppressWarnings("unchecked") - private void addContentsToToolPalette(final List<Class<AbstractPlugin>> plugins, final List<Class<AbstractRepository>> repositories) { - synchronized (this) { - // Now run through the available classes and add all non-abstract classes to our lists. - for (final Class<AbstractRepository> repository : repositories) { - if (!Modifier.isAbstract(repository.getModifiers())) { - // Make also sure that the current repository is not "programmaticOnly" - final Annotation annotationRepository = repository.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass()); - final boolean programmaticOnly = (Boolean) ClassAndMethodContainer.invokeMethod( - this.classAndMethodContainer.getRepositoryProgrammaticOnlyMethod(), - annotationRepository, false); - if (!programmaticOnly) { - this.availableRepositories.add(repository); - } + private synchronized void addContentsToToolPalette(final List<Class<AbstractPlugin>> plugins, final List<Class<AbstractRepository>> repositories) { + // Now run through the available classes and add all non-abstract classes to our lists. + for (final Class<AbstractRepository> repository : repositories) { + if (!Modifier.isAbstract(repository.getModifiers())) { + // Make also sure that the current repository is not "programmaticOnly" + final Annotation annotationRepository = repository.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass()); + final boolean programmaticOnly = (Boolean) ClassAndMethodContainer.invokeMethod( + this.classAndMethodContainer.getRepositoryProgrammaticOnlyMethod(), + annotationRepository, false); + if (!programmaticOnly) { + this.availableRepositories.add(repository); } } + } - for (final Class<?> plugin : plugins) { - // Make sure that the current plugin is neither abstract nor "programmaticOnly" - final Annotation annotationPlugin = plugin.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass()); - final boolean programmaticOnly = (Boolean) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginProgrammaticOnlyMethod(), - annotationPlugin, false); - final boolean isAbstract = Modifier.isAbstract(plugin.getModifiers()); - - if (!isAbstract && !programmaticOnly) { - // The following cast results in the unchecked-cast-warnings, but we know that the cast should be correct. - if (this.classAndMethodContainer.getAbstractFilterPluginClass().isAssignableFrom(plugin)) { - this.availableFilters.add((Class<AbstractFilterPlugin>) plugin); - } else { - if (this.classAndMethodContainer.getAbstractReaderPluginClass().isAssignableFrom(plugin)) { - this.availableReaders.add((Class<AbstractReaderPlugin>) plugin); - } + for (final Class<?> plugin : plugins) { + // Make sure that the current plugin is neither abstract nor "programmaticOnly" + final Annotation annotationPlugin = plugin.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass()); + final boolean programmaticOnly = (Boolean) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPluginProgrammaticOnlyMethod(), + annotationPlugin, false); + final boolean isAbstract = Modifier.isAbstract(plugin.getModifiers()); + + if (!isAbstract && !programmaticOnly) { + // The following cast results in the unchecked-cast-warnings, but we know that the cast should be correct. + if (this.classAndMethodContainer.getAbstractFilterPluginClass().isAssignableFrom(plugin)) { + this.availableFilters.add((Class<AbstractFilterPlugin>) plugin); + } else { + if (this.classAndMethodContainer.getAbstractReaderPluginClass().isAssignableFrom(plugin)) { + this.availableReaders.add((Class<AbstractReaderPlugin>) plugin); } } } @@ -366,22 +317,20 @@ public final class CurrentAnalysisEditorBean { * @throws ProjectLoadException * If something went wrong during the loading of the libraries. */ - private void initializeModelLibraries() throws ProjectLoadException { - synchronized (this) { - try { - final List<String> libs = this.projectManagerFacade.listAllLibraries(this.projectName); - // Add them, but remove all existing dependencies so far to avoid double entries. This also makes sure that the model - after it has been opened - - // points - // just to valid dependencies (and to all of them). - this.project.getDependencies().clear(); - for (final String lib : libs) { - final MIDependency dep = this.factory.createDependency(); - dep.setFilePath(lib); - this.project.getDependencies().add(dep); - } - } catch (final ProjectNotExistingException ex) { - throw new ProjectLoadException("The project does not exist.", ex); + private synchronized void initializeModelLibraries() throws ProjectLoadException { + try { + final List<String> libs = this.projectService.listAllLibraries(this.projectName); + // Add them, but remove all existing dependencies so far to avoid double entries. This also makes sure that the model - after it has been opened - + // points + // just to valid dependencies (and to all of them). + this.project.getDependencies().clear(); + for (final String lib : libs) { + final MIDependency dep = this.factory.createDependency(); + dep.setFilePath(lib); + this.project.getDependencies().add(dep); } + } catch (final ProjectNotExistingException ex) { + throw new ProjectLoadException("The project does not exist.", ex); } } @@ -392,27 +341,23 @@ public final class CurrentAnalysisEditorBean { * @throws ProjectLoadException * If something went wrong. */ - private void reloadClassLoader() throws ProjectLoadException { - synchronized (this) { - try { - this.classLoader = this.projectManagerFacade.getClassLoader(this.projectName); // NOPMD (ClassLoader) - } catch (final NullPointerException ex) { - throw new ProjectLoadException("Invalid class loader.", ex); - } catch (final IOException ex) { - throw new ProjectLoadException("Could not load classes.", ex); - } catch (final ProjectNotExistingException ex) { - throw new ProjectLoadException("Project does not exist.", ex); - } + private synchronized void reloadClassLoader() throws ProjectLoadException { + try { + this.classLoader = this.projectService.getClassLoader(this.projectName, this); // NOPMD (ClassLoader) + } catch (final NullPointerException ex) { + throw new ProjectLoadException("Invalid class loader.", ex); + } catch (final IOException ex) { + throw new ProjectLoadException("Could not load classes.", ex); + } catch (final ProjectNotExistingException ex) { + throw new ProjectLoadException("Project does not exist.", ex); } } /** * This method sets the time stamp to the current system time. */ - public void resetTimeStamp() { - synchronized (this) { - this.timeStamp = System.currentTimeMillis(); - } + public synchronized void resetTimeStamp() { + this.timeStamp = System.currentTimeMillis(); } /** @@ -420,10 +365,8 @@ public final class CurrentAnalysisEditorBean { * * @return The project name for this user. */ - public String getProjectName() { - synchronized (this) { - return this.projectName; - } + public synchronized String getProjectName() { + return this.projectName; } /** @@ -431,10 +374,8 @@ public final class CurrentAnalysisEditorBean { * * @return The time stamp for this user. */ - public long getTimeStamp() { - synchronized (this) { - return this.timeStamp; - } + public synchronized long getTimeStamp() { + return this.timeStamp; } /** @@ -445,7 +386,7 @@ public final class CurrentAnalysisEditorBean { * The class whose description should be extracted. * @return The description for the class or a substitute if none is available. This is in either case human readable. */ - public String getDescription(final Class<?> clazz) { + public synchronized String getDescription(final Class<?> clazz) { // Get the two potential annotations final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass()); final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass()); @@ -473,7 +414,7 @@ public final class CurrentAnalysisEditorBean { * The class whose dependencies should be extracted. * @return The dependencies for the class or a substitute if none is available. This is in either case human readable. */ - public String getDependencies(final Class<?> clazz) { + public synchronized String getDependencies(final Class<?> clazz) { // Get the two potential annotations final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass()); final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass()); @@ -503,7 +444,7 @@ public final class CurrentAnalysisEditorBean { * The name of the property in question. * @return The description of the property. */ - public String getDescription(final EObject component, final String propertyName) { + public synchronized String getDescription(final EObject component, final String propertyName) { try { final String className; if (component instanceof MIPlugin) { @@ -539,7 +480,7 @@ public final class CurrentAnalysisEditorBean { * The class whose properties will be delivered. * @return A list of properties. It contains instances of {@link Property} - but those from the project class loader. */ - public List<Annotation> getProperties(final Class<?> clazz) { + public synchronized List<Annotation> getProperties(final Class<?> clazz) { // Get the two potential annotations final Annotation annotationPlugin = clazz.getAnnotation(this.classAndMethodContainer.getPluginAnnotationClass()); final Annotation annotationRepository = clazz.getAnnotation(this.classAndMethodContainer.getRepositoryAnnotationClass()); @@ -570,7 +511,7 @@ public final class CurrentAnalysisEditorBean { * The class to be analyzed. * @return A list containing the available input ports. */ - public List<Annotation> getInputPorts(final Class<?> clazz) { + public synchronized List<Annotation> getInputPorts(final Class<?> clazz) { final List<Annotation> result = new ArrayList<Annotation>(); for (final Method method : clazz.getMethods()) { @@ -592,7 +533,7 @@ public final class CurrentAnalysisEditorBean { * The class to be analyzed. * @return A list containing the available output ports. */ - public List<Annotation> getOutputPorts(final Class<?> clazz) { + public synchronized List<Annotation> getOutputPorts(final Class<?> clazz) { final List<Annotation> result = new ArrayList<Annotation>(); // Get the potential annotation @@ -616,7 +557,7 @@ public final class CurrentAnalysisEditorBean { * The class to be analyzed. * @return A list containing the available repository ports. */ - public List<Annotation> getRepositoryPorts(final Class<?> clazz) { + public synchronized List<Annotation> getRepositoryPorts(final Class<?> clazz) { final List<Annotation> result = new ArrayList<Annotation>(); // Get the potential annotation @@ -640,7 +581,7 @@ public final class CurrentAnalysisEditorBean { * The class to be analyzed. * @return A list containing the available displays. */ - public List<Annotation> getDisplays(final Class<?> clazz) { + public synchronized List<Annotation> getDisplays(final Class<?> clazz) { final List<Annotation> result = new ArrayList<Annotation>(); for (final Method method : clazz.getMethods()) { @@ -661,21 +602,19 @@ public final class CurrentAnalysisEditorBean { * @param event * The upload event. */ - public void handleFileUpload(final FileUploadEvent event) { + public synchronized void handleFileUpload(final FileUploadEvent event) { // Get the file from the event final UploadedFile file = event.getFile(); try { // Use the file system manager to upload the new file final MIDependency lib; - synchronized (this) { - this.projectManagerFacade.uploadLibrary(file, this.projectName); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgLibraryUploaded()); - // As it seem to have worked, we can add the library to our model. - lib = this.factory.createDependency(); - lib.setFilePath(file.getFileName()); - this.project.getDependencies().add(lib); - } + this.projectService.uploadLibrary(file, this.projectName); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgLibraryUploaded()); + // As it seem to have worked, we can add the library to our model. + lib = this.factory.createDependency(); + lib.setFilePath(file.getFileName()); + this.project.getDependencies().add(lib); // Update our class loader and the available plugins & repositories this.reloadClassLoader(); this.reloadClassesAndMethods(); @@ -706,21 +645,19 @@ public final class CurrentAnalysisEditorBean { * * @return The available libraries. */ - public List<String> getLibraries() { - synchronized (this) { - try { - final List<String> result = this.projectManagerFacade.listAllLibraries(this.projectName); - result.add(0, "Kieker"); - - return result; - } catch (final ProjectNotExistingException ex) { - CurrentAnalysisEditorBean.LOG.error("The project does not exist.", ex); - return new ArrayList<String>(); - } catch (final NullPointerException ex) { - // This exception occurs when a property has not been initialized correctly. - CurrentAnalysisEditorBean.LOG.error("A null pointer exception occured.", ex); - return new ArrayList<String>(); - } + public synchronized List<String> getLibraries() { + try { + final List<String> result = this.projectService.listAllLibraries(this.projectName); + result.add(0, "Kieker"); + + return result; + } catch (final ProjectNotExistingException ex) { + CurrentAnalysisEditorBean.LOG.error("The project does not exist.", ex); + return new ArrayList<String>(); + } catch (final NullPointerException ex) { + // This exception occurs when a property has not been initialized correctly. + CurrentAnalysisEditorBean.LOG.error("A null pointer exception occured.", ex); + return new ArrayList<String>(); } } @@ -729,7 +666,7 @@ public final class CurrentAnalysisEditorBean { * * @return A list with all readers. */ - public final List<Class<AbstractReaderPlugin>> getAvailableReaders() { + public synchronized List<Class<AbstractReaderPlugin>> getAvailableReaders() { return this.availableReaders; } @@ -738,7 +675,7 @@ public final class CurrentAnalysisEditorBean { * * @return A list with all filter. */ - public final List<Class<AbstractFilterPlugin>> getAvailableFilters() { + public synchronized List<Class<AbstractFilterPlugin>> getAvailableFilters() { return this.availableFilters; } @@ -747,7 +684,7 @@ public final class CurrentAnalysisEditorBean { * * @return A list with all repositories. */ - public final List<Class<AbstractRepository>> getAvailableRepositories() { + public synchronized List<Class<AbstractRepository>> getAvailableRepositories() { return this.availableRepositories; } @@ -757,25 +694,23 @@ public final class CurrentAnalysisEditorBean { * @param overwriteNewerProject * This flag determines whether a newer project should be overwritten. */ - public void saveProject(final boolean overwriteNewerProject) { - synchronized (this) { - try { - this.projectManagerFacade.saveProject(this.projectName, this.project, this.timeStamp, overwriteNewerProject); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgProjectSaved()); - // Update the time stamp! - this.resetTimeStamp(); - } catch (final IOException ex) { - CurrentAnalysisEditorBean.LOG.error("An error occured while saving the project.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectSavingException()); - } catch (final NewerProjectException ex) { - CurrentAnalysisEditorBean.LOG.info("The project has been modified externally in the meanwhile.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_WARN, this.globalPropertiesBean.getMsgProjectModified()); - // Give the user the possibility to force-save the project - RequestContext.getCurrentInstance().execute("forceSaveDlg.show()"); - } catch (final ProjectNotExistingException ex) { - CurrentAnalysisEditorBean.LOG.error("The project does not exist.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectNotExistingException()); - } + public synchronized void saveProject(final boolean overwriteNewerProject) { + try { + this.projectService.saveProject(this.projectName, this.project, this.timeStamp, overwriteNewerProject); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgProjectSaved()); + // Update the time stamp! + this.resetTimeStamp(); + } catch (final IOException ex) { + CurrentAnalysisEditorBean.LOG.error("An error occured while saving the project.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectSavingException()); + } catch (final NewerProjectException ex) { + CurrentAnalysisEditorBean.LOG.info("The project has been modified externally in the meanwhile.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_WARN, this.globalPropertiesBean.getMsgProjectModified()); + // Give the user the possibility to force-save the project + RequestContext.getCurrentInstance().execute("forceSaveDlg.show()"); + } catch (final ProjectNotExistingException ex) { + CurrentAnalysisEditorBean.LOG.error("The project does not exist.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgProjectNotExistingException()); } } @@ -788,15 +723,13 @@ public final class CurrentAnalysisEditorBean { * @param plugin * The plugin to be filled. */ - private void fillDisplays(final Class<AbstractPlugin> clazz, final MIPlugin plugin) { - synchronized (this) { - // Get the displays and convert them into model instances - final List<Annotation> displays = this.getDisplays(clazz); - for (final Annotation display : displays) { - final MIDisplay mDisplay = this.factory.createDisplay(); - mDisplay.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getDisplayNameMethod(), display, "N/A")); - plugin.getDisplays().add(mDisplay); - } + private synchronized void fillDisplays(final Class<AbstractPlugin> clazz, final MIPlugin plugin) { + // Get the displays and convert them into model instances + final List<Annotation> displays = this.getDisplays(clazz); + for (final Annotation display : displays) { + final MIDisplay mDisplay = this.factory.createDisplay(); + mDisplay.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getDisplayNameMethod(), display, "N/A")); + plugin.getDisplays().add(mDisplay); } } @@ -809,36 +742,34 @@ public final class CurrentAnalysisEditorBean { * @param plugin * The plugin to be filled. */ - private void fillPorts(final Class<AbstractPlugin> clazz, final MIPlugin plugin) { - synchronized (this) { - // Get the ports - final List<Annotation> inputPorts = this.getInputPorts(clazz); - final List<Annotation> outputPorts = this.getOutputPorts(clazz); - final List<Annotation> repositoryPorts = this.getRepositoryPorts(clazz); - - // Add input ports - if (plugin instanceof MIFilter) { - for (final Annotation inputPort : inputPorts) { - final MIInputPort mInputPort = this.factory.createInputPort(); - mInputPort.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getInputPortNameMethod(), inputPort, "N/A")); - mInputPort.setParent((MIFilter) plugin); - } + private synchronized void fillPorts(final Class<AbstractPlugin> clazz, final MIPlugin plugin) { + // Get the ports + final List<Annotation> inputPorts = this.getInputPorts(clazz); + final List<Annotation> outputPorts = this.getOutputPorts(clazz); + final List<Annotation> repositoryPorts = this.getRepositoryPorts(clazz); + + // Add input ports + if (plugin instanceof MIFilter) { + for (final Annotation inputPort : inputPorts) { + final MIInputPort mInputPort = this.factory.createInputPort(); + mInputPort.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getInputPortNameMethod(), inputPort, "N/A")); + mInputPort.setParent((MIFilter) plugin); } + } - // Add output ports. - for (final Annotation outputPort : outputPorts) { - final MIOutputPort mOutputPort = this.factory.createOutputPort(); - mOutputPort.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getOutputPortNameMethod(), outputPort, "N/A")); - mOutputPort.setParent(plugin); - } + // Add output ports. + for (final Annotation outputPort : outputPorts) { + final MIOutputPort mOutputPort = this.factory.createOutputPort(); + mOutputPort.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getOutputPortNameMethod(), outputPort, "N/A")); + mOutputPort.setParent(plugin); + } - // Add repository ports. - for (final Annotation repositoryPort : repositoryPorts) { - final MIRepositoryConnector mConnector = this.factory.createRepositoryConnector(); - mConnector.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getRepositoryPortNameMethod(), repositoryPort, - "N/A")); - plugin.getRepositories().add(mConnector); - } + // Add repository ports. + for (final Annotation repositoryPort : repositoryPorts) { + final MIRepositoryConnector mConnector = this.factory.createRepositoryConnector(); + mConnector.setName((String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getRepositoryPortNameMethod(), repositoryPort, + "N/A")); + plugin.getRepositories().add(mConnector); } } @@ -851,7 +782,7 @@ public final class CurrentAnalysisEditorBean { * @param component * The component to be filled. */ - private void fillProperties(final Class<?> clazz, final EObject component) { + private synchronized void fillProperties(final Class<?> clazz, final EObject component) { // Get the default configuration and use it to initialize the model repository final List<Annotation> properties = this.getProperties(clazz); @@ -876,7 +807,7 @@ public final class CurrentAnalysisEditorBean { * @param clazz * The class of the repository to be added. */ - public void addRepository(final Class<AbstractRepository> clazz) { + public synchronized void addRepository(final Class<AbstractRepository> clazz) { try { // Create a new instance for the model final MIRepository repository = this.factory.createRepository(); @@ -884,12 +815,10 @@ public final class CurrentAnalysisEditorBean { repository.setName(clazz.getSimpleName()); this.fillProperties(clazz, repository); - synchronized (this) { - // Add it to the project - and to the graph - this.project.getRepositories().add(repository); - this.currentAnalysisEditorGraphBean.addRepository(repository); - this.currentAnalysisEditorGraphBean.refreshGraph(); - } + // Add it to the project - and to the graph + this.project.getRepositories().add(repository); + this.currentAnalysisEditorGraphBean.addRepository(repository); + this.currentAnalysisEditorGraphBean.refreshGraph(); } catch (final NoClassDefFoundError ex) { // This exception can occur if (for example) a class is missing GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgRepositoryCreationException()); @@ -903,7 +832,7 @@ public final class CurrentAnalysisEditorBean { * @param clazz * The class of the plugin to be added. This can be both, a filter or a reader. */ - public void addPlugin(final Class<AbstractPlugin> clazz) { + public synchronized void addPlugin(final Class<AbstractPlugin> clazz) { try { // Create a new instance for the model final MIPlugin plugin; @@ -919,18 +848,16 @@ public final class CurrentAnalysisEditorBean { this.fillPorts(clazz, plugin); this.fillDisplays(clazz, plugin); - synchronized (this) { - // Add it to the project - this.project.getPlugins().add(plugin); + // Add it to the project + this.project.getPlugins().add(plugin); - // Add the element to the graph - if (plugin instanceof MIReader) { - this.currentAnalysisEditorGraphBean.addReader((MIReader) plugin); - } else { - this.currentAnalysisEditorGraphBean.addFilter((MIFilter) plugin); - } - this.currentAnalysisEditorGraphBean.refreshGraph(); + // Add the element to the graph + if (plugin instanceof MIReader) { + this.currentAnalysisEditorGraphBean.addReader((MIReader) plugin); + } else { + this.currentAnalysisEditorGraphBean.addFilter((MIFilter) plugin); } + this.currentAnalysisEditorGraphBean.refreshGraph(); } catch (final NoClassDefFoundError ex) { // This exception can occur if (for example) a class is missing GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, this.globalPropertiesBean.getMsgPluginCreationException()); @@ -943,10 +870,8 @@ public final class CurrentAnalysisEditorBean { * * @return The currently selected plugin or repository. */ - public EObject getSelectedPlugin() { - synchronized (this) { - return this.selectedComponent; - } + public synchronized EObject getSelectedPlugin() { + return this.selectedComponent; } /** @@ -956,23 +881,21 @@ public final class CurrentAnalysisEditorBean { * @return A list with all properties of the plugin plus the name- and class-properties. If no plugin is selected, the list of the selected repository is * delivered. */ - public List<Object> getAdvancedPluginProperties() { - synchronized (this) { - final List<Object> result = new ArrayList<Object>(); + public synchronized List<Object> getAdvancedPluginProperties() { + final List<Object> result = new ArrayList<Object>(); - // Add the properties as strings - result.add("Name"); - result.add("ClassName"); + // Add the properties as strings + result.add("Name"); + result.add("ClassName"); - // Get the original properties of the plugin - if (this.selectedComponent instanceof MIPlugin) { - result.addAll(((MIPlugin) this.selectedComponent).getProperties()); - } else { - result.addAll(((MIRepository) this.selectedComponent).getProperties()); - } - - return result; + // Get the original properties of the plugin + if (this.selectedComponent instanceof MIPlugin) { + result.addAll(((MIPlugin) this.selectedComponent).getProperties()); + } else { + result.addAll(((MIRepository) this.selectedComponent).getProperties()); } + + return result; } /** @@ -981,19 +904,17 @@ public final class CurrentAnalysisEditorBean { * * @return A list with the available filters. */ - public List<MIPlugin> getFilters() { - synchronized (this) { - final EList<MIPlugin> plugins = this.project.getPlugins(); - final List<MIPlugin> filter = new ArrayList<MIPlugin>(); - - for (final MIPlugin plugin : plugins) { - if (plugin instanceof MIFilter) { - filter.add(plugin); - } - } + public synchronized List<MIPlugin> getFilters() { + final EList<MIPlugin> plugins = this.project.getPlugins(); + final List<MIPlugin> filter = new ArrayList<MIPlugin>(); - return filter; + for (final MIPlugin plugin : plugins) { + if (plugin instanceof MIFilter) { + filter.add(plugin); + } } + + return filter; } /** @@ -1001,10 +922,8 @@ public final class CurrentAnalysisEditorBean { * * @return A list with all repositories within the model. */ - public EList<MIRepository> getRepositories() { - synchronized (this) { - return this.project.getRepositories(); - } + public synchronized EList<MIRepository> getRepositories() { + return this.project.getRepositories(); } /** @@ -1012,37 +931,25 @@ public final class CurrentAnalysisEditorBean { * * @return The name of the plugin/repository. */ - public String getCurrentPluginName() { - synchronized (this) { - if (this.selectedComponent != null) { - if (this.selectedComponent instanceof MIPlugin) { - return ((MIPlugin) this.selectedComponent).getName(); - } else { - return ((MIRepository) this.selectedComponent).getName(); - } + public synchronized String getCurrentPluginName() { + if (this.selectedComponent != null) { + if (this.selectedComponent instanceof MIPlugin) { + return ((MIPlugin) this.selectedComponent).getName(); } else { - return ""; + return ((MIRepository) this.selectedComponent).getName(); } + } else { + return ""; } } - /** - * The setter for the property {@link CurrentAnalysisEditorBean#userBean}. - * - * @param userBean - * The new value of the property. - */ - public void setUserBean(final UserBean userBean) { - this.userBean = userBean; - } - /** * This method should be called if the grid color has been modified. * * @param event * The change event. */ - public void gridColorListener(final ValueChangeEvent event) { + public synchronized void gridColorListener(final ValueChangeEvent event) { this.currentAnalysisEditorGraphBean.setGridColor((String) event.getNewValue()); } @@ -1052,7 +959,7 @@ public final class CurrentAnalysisEditorBean { * @param event * The change event. */ - public void gridSizeListener(final ValueChangeEvent event) { + public synchronized void gridSizeListener(final ValueChangeEvent event) { this.currentAnalysisEditorGraphBean.setGridSize((Integer) event.getNewValue()); } @@ -1060,7 +967,7 @@ public final class CurrentAnalysisEditorBean { * This method initializes the modified jit-graph by delivering the necessary javascript commands to the client. It prints all current existing plugins, * repositories and their connections. All further components will be added mostly by other methods. */ - public void initializeGraph() { + public synchronized void initializeGraph() { // Make sure that the currentAnalysisEditorGraphBean knows "this" as well. this.currentAnalysisEditorGraphBean.setCurrentAnalysisEditorBean(this); @@ -1116,10 +1023,8 @@ public final class CurrentAnalysisEditorBean { * @param node * The new node to be selected. */ - public void nodeSelected(final EObject node) { - synchronized (this) { - this.selectedComponent = node; - } + public synchronized void nodeSelected(final EObject node) { + this.selectedComponent = node; } /** @@ -1128,53 +1033,41 @@ public final class CurrentAnalysisEditorBean { * @param node * The new node to be removed. */ - public void nodeRemoved(final EObject node) { - synchronized (this) { - // Remove the component from the project - if (node instanceof MIPlugin) { - this.project.getPlugins().remove(node); - - // Remove the corresponding connections - final List<MIInputPort> toBeRemoved = new ArrayList<MIInputPort>(); - for (final MIPlugin plugin : this.project.getPlugins()) { - for (final MIOutputPort oPort : plugin.getOutputPorts()) { - toBeRemoved.clear(); - for (final MIInputPort iPort : oPort.getSubscribers()) { - if (iPort.getParent() == node) { - toBeRemoved.add(iPort); - } + public synchronized void nodeRemoved(final EObject node) { + // Remove the component from the project + if (node instanceof MIPlugin) { + this.project.getPlugins().remove(node); + + // Remove the corresponding connections + final List<MIInputPort> toBeRemoved = new ArrayList<MIInputPort>(); + for (final MIPlugin plugin : this.project.getPlugins()) { + for (final MIOutputPort oPort : plugin.getOutputPorts()) { + toBeRemoved.clear(); + for (final MIInputPort iPort : oPort.getSubscribers()) { + if (iPort.getParent() == node) { + toBeRemoved.add(iPort); } - oPort.getSubscribers().removeAll(toBeRemoved); } + oPort.getSubscribers().removeAll(toBeRemoved); } - } else { - this.project.getRepositories().remove(node); + } + } else { + this.project.getRepositories().remove(node); - // Remove the corresponding connections - for (final MIPlugin plugin : this.project.getPlugins()) { - for (final MIRepositoryConnector repoConn : plugin.getRepositories()) { - if (repoConn.getRepository() == node) { - repoConn.setRepository(null); - } + // Remove the corresponding connections + for (final MIPlugin plugin : this.project.getPlugins()) { + for (final MIRepositoryConnector repoConn : plugin.getRepositories()) { + if (repoConn.getRepository() == node) { + repoConn.setRepository(null); } } } - - // Unselect the currently selected node if it is the one which has just been removed - if (this.selectedComponent == node) { - this.selectedComponent = null; // NOPMD - } } - } - /** - * The setter for the property {@link CurrentAnalysisEditorBean#globalPropertiesBean}. - * - * @param globalPropertiesBean - * The new value of the property. - */ - public void setGlobalPropertiesBean(final GlobalPropertiesBean globalPropertiesBean) { - this.globalPropertiesBean = globalPropertiesBean; + // Unselect the currently selected node if it is the one which has just been removed + if (this.selectedComponent == node) { + this.selectedComponent = null; // NOPMD + } } /** @@ -1185,7 +1078,7 @@ public final class CurrentAnalysisEditorBean { * @param targetPort * The target port. */ - public void edgeCreated(final MIOutputPort sourcePort, final MIInputPort targetPort) { + public synchronized void edgeCreated(final MIOutputPort sourcePort, final MIInputPort targetPort) { sourcePort.getSubscribers().add(targetPort); } @@ -1197,7 +1090,7 @@ public final class CurrentAnalysisEditorBean { * @param targetPort * The target port. */ - public void edgeRemoved(final MIOutputPort sourcePort, final MIInputPort targetPort) { + public synchronized void edgeRemoved(final MIOutputPort sourcePort, final MIInputPort targetPort) { sourcePort.getSubscribers().remove(targetPort); } @@ -1209,7 +1102,7 @@ public final class CurrentAnalysisEditorBean { * @param target * The target repository. */ - public void edgeCreated(final MIRepositoryConnector sourcePort, final MIRepository target) { + public synchronized void edgeCreated(final MIRepositoryConnector sourcePort, final MIRepository target) { sourcePort.setRepository(target); } @@ -1221,7 +1114,7 @@ public final class CurrentAnalysisEditorBean { * @param target * The target repository. */ - public void edgeRemoved(final MIRepositoryConnector sourcePort, final MIRepository target) { + public synchronized void edgeRemoved(final MIRepositoryConnector sourcePort, final MIRepository target) { sourcePort.setRepository(null); } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorGraphBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorGraphBean.java similarity index 90% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorGraphBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorGraphBean.java index ca3f6c4345c14e7286e3d207e889227417e7c140..5140ac41768a2be3791f341fcec26039ac646018 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentAnalysisEditorGraphBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentAnalysisEditorGraphBean.java @@ -14,12 +14,15 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.view; +package kieker.webgui.web.beans.view; import java.util.Map; import javax.faces.context.FacesContext; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + import kieker.analysis.model.analysisMetaModel.MIFilter; import kieker.analysis.model.analysisMetaModel.MIInputPort; import kieker.analysis.model.analysisMetaModel.MIOutputPort; @@ -45,6 +48,8 @@ import org.eclipse.emf.ecore.EObject; * * @author Nils Christian Ehmke */ +@Component +@Scope("view") public final class CurrentAnalysisEditorGraphBean { /** * This is the log for errors, exceptions etc. @@ -163,7 +168,7 @@ public final class CurrentAnalysisEditorGraphBean { /** * Declares the the graph variable. */ - public void declareGraph() { + public synchronized void declareGraph() { RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_CREATE_GRAPH_VAR); RequestContext.getCurrentInstance().execute("graph.setNodeIcon('Filter', '../img/graphIcons/FilterIcon.png');"); RequestContext.getCurrentInstance().execute("graph.setNodeIcon('Reader', '../img/graphIcons/ReaderIcon.png');"); @@ -173,7 +178,7 @@ public final class CurrentAnalysisEditorGraphBean { /** * Initializes the listeners for the graph. */ - public void initListeners() { + public synchronized void initListeners() { RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_CLICK_LISTENER); RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_REMOVE_NODE_LISTENER); RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_CREATE_EDGE_LISTENER); @@ -183,14 +188,14 @@ public final class CurrentAnalysisEditorGraphBean { /** * Adds the edge constraints to the graph. */ - public void addEdgeConstraints() { + public synchronized void addEdgeConstraints() { RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_EDGE_CONSTRAINTS); } /** * Refreshes the graph after changes have been made. */ - public void refreshGraph() { + public synchronized void refreshGraph() { RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_REFRESH_GRAPH); } @@ -200,7 +205,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param filter * The filter which should be added to the graph. */ - public void addFilter(final MIFilter filter) { + public synchronized void addFilter(final MIFilter filter) { RequestContext.getCurrentInstance().execute( String.format(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_FILTER, 0, 0, this.assembleGraphString(filter), this.assembleGraphRepositoryPortString(filter.getRepositories()), this.assembleGraphInputPortString(filter), @@ -213,7 +218,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param reader * The reader which should be added to the graph. */ - public void addReader(final MIReader reader) { + public synchronized void addReader(final MIReader reader) { RequestContext.getCurrentInstance().execute(String.format(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_READER, 0, 0, this.assembleGraphString(reader), this.assembleGraphRepositoryPortString(reader.getRepositories()), this.assembleGraphOutputPortString(reader))); } @@ -224,7 +229,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param repository * The repository which should be added to the graph. */ - public void addRepository(final MIRepository repository) { + public synchronized void addRepository(final MIRepository repository) { final String repoPort = String.format(CurrentAnalysisEditorGraphBean.JS_CMD_PORT, CurrentAnalysisEditorGraphBean.JS_CMD_PORT_TYPE_INPUT, CurrentAnalysisEditorGraphBean.REPOSITORY_INPUT_PORT, "N/A"); RequestContext.getCurrentInstance().execute(String.format(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_REPOSITORY, 0, 0, @@ -244,7 +249,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param inputPort * The input port. */ - public void addConnection(final MIPlugin source, final MIPlugin destination, final MIOutputPort outputPort, final MIInputPort inputPort) { + public synchronized void addConnection(final MIPlugin source, final MIPlugin destination, final MIOutputPort outputPort, final MIInputPort inputPort) { RequestContext.getCurrentInstance().execute(String.format(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_EDGE, this.assembleGraphPortID(source, outputPort), this.assembleGraphPortID(destination, inputPort), "")); } @@ -259,7 +264,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param port * The repository port. */ - public void addConnection(final MIPlugin source, final MIRepository destination, final MIRepositoryConnector port) { + public synchronized void addConnection(final MIPlugin source, final MIRepository destination, final MIRepositoryConnector port) { RequestContext.getCurrentInstance().execute(String.format(CurrentAnalysisEditorGraphBean.JS_CMD_ADD_EDGE, this.assembleGraphPortID(source, port), this.assembleGraphPortID(destination), "")); } @@ -271,7 +276,7 @@ public final class CurrentAnalysisEditorGraphBean { * The ports to be used within the string command. * @return A string containing the JS commands to create the ports. */ - private String assembleGraphPortString(final EList<? extends MIPort> ports) { + private synchronized String assembleGraphPortString(final EList<? extends MIPort> ports) { final StringBuilder builder = new StringBuilder(); final int len = ports.size(); @@ -297,7 +302,7 @@ public final class CurrentAnalysisEditorGraphBean { * The ports which will be used. * @return A string containing the JS commands to create the repository ports. */ - private String assembleGraphRepositoryPortString(final EList<MIRepositoryConnector> ports) { + private synchronized String assembleGraphRepositoryPortString(final EList<MIRepositoryConnector> ports) { final StringBuilder builder = new StringBuilder(); final int len = ports.size(); @@ -322,7 +327,7 @@ public final class CurrentAnalysisEditorGraphBean { * The filter whose input ports will be used. * @return A string containing the JS commands to create the input ports. */ - private String assembleGraphInputPortString(final MIFilter filter) { + private synchronized String assembleGraphInputPortString(final MIFilter filter) { return this.assembleGraphPortString(filter.getInputPorts()); } @@ -333,7 +338,7 @@ public final class CurrentAnalysisEditorGraphBean { * The plugin whose output ports will be used. * @return A string containing the JS commands to create the output ports. */ - private String assembleGraphOutputPortString(final MIPlugin plugin) { + private synchronized String assembleGraphOutputPortString(final MIPlugin plugin) { return this.assembleGraphPortString(plugin.getOutputPorts()); } @@ -346,7 +351,7 @@ public final class CurrentAnalysisEditorGraphBean { * The port itself. * @return The ID for the port within the graph */ - private String assembleGraphPortID(final MIPlugin plugin, final MIPort port) { + private synchronized String assembleGraphPortID(final MIPlugin plugin, final MIPort port) { return this.componentMap.get(plugin) + "." + this.componentMap.get(port); } @@ -359,7 +364,7 @@ public final class CurrentAnalysisEditorGraphBean { * The port itself. * @return The ID for the port within the graph */ - private Object assembleGraphPortID(final MIPlugin plugin, final MIRepositoryConnector port) { + private synchronized Object assembleGraphPortID(final MIPlugin plugin, final MIRepositoryConnector port) { return this.componentMap.get(plugin) + "." + this.componentMap.get(port); } @@ -370,7 +375,7 @@ public final class CurrentAnalysisEditorGraphBean { * The parent repository of the port. * @return The ID for the port within the graph */ - private Object assembleGraphPortID(final MIRepository repository) { + private synchronized Object assembleGraphPortID(final MIRepository repository) { return this.componentMap.get(repository) + "." + CurrentAnalysisEditorGraphBean.REPOSITORY_INPUT_PORT; } @@ -381,7 +386,7 @@ public final class CurrentAnalysisEditorGraphBean { * The repository whose ID should be delivered. * @return A human readable ID. */ - private String assembleGraphString(final MIRepository repository) { + private synchronized String assembleGraphString(final MIRepository repository) { final String className = repository.getClassname(); final String shortName = className.substring(className.lastIndexOf('.') + 1); return String.format(CurrentAnalysisEditorGraphBean.JS_CMD_NODE, this.componentMap.get(repository), repository.getName(), shortName, className); @@ -394,7 +399,7 @@ public final class CurrentAnalysisEditorGraphBean { * The plugin whose ID should be delivered. * @return A human readable ID. */ - private String assembleGraphString(final MIPlugin plugin) { + private synchronized String assembleGraphString(final MIPlugin plugin) { final String className = plugin.getClassname(); final String shortName = className.substring(className.lastIndexOf('.') + 1); return String.format(CurrentAnalysisEditorGraphBean.JS_CMD_NODE, this.componentMap.get(plugin), plugin.getName(), shortName, className); @@ -404,7 +409,7 @@ public final class CurrentAnalysisEditorGraphBean { * This is the action which can be called from the javascript code to show that a node has been clicked. It informs the connected * {@link CurrentAnalysisEditorBean} about this. */ - public void nodeClicked() { + public synchronized void nodeClicked() { // Get the parameters final Map<String, String> paramMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); final String clickedNodeID = paramMap.get("ID"); @@ -425,7 +430,7 @@ public final class CurrentAnalysisEditorGraphBean { * This is the action which can be called from the javascript code to show that a node has been removed. It informs the connected * {@link CurrentAnalysisEditorBean} about this. */ - public void nodeRemoved() { + public synchronized void nodeRemoved() { // Get the parameters final Map<String, String> paramMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); final String clickedNodeID = paramMap.get("ID"); @@ -445,7 +450,7 @@ public final class CurrentAnalysisEditorGraphBean { * This is the action which can be called from the javascript code to show that an edge has been created. It informs the connected * {@link CurrentAnalysisEditorBean} about this. */ - public void edgeCreated() { + public synchronized void edgeCreated() { // Get the parameters final Map<String, String> paramMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); @@ -481,7 +486,7 @@ public final class CurrentAnalysisEditorGraphBean { * This is the action which can be called from the javascript code to show that an edge has been removed. It informs the connected * {@link CurrentAnalysisEditorBean} about this. */ - public void edgeRemoved() { + public synchronized void edgeRemoved() { // Get the parameters final Map<String, String> paramMap = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap(); @@ -518,7 +523,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param color * The new color as a HTML color (FF0080 e.g.). */ - public void setGridColor(final String color) { + public synchronized void setGridColor(final String color) { final String cmd = String.format(CurrentAnalysisEditorGraphBean.JS_CMD_SET_GRID_COLOR, "#" + color); RequestContext.getCurrentInstance().execute(cmd); this.refreshGraph(); @@ -530,7 +535,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param size * The new grid size. */ - public void setGridSize(final int size) { + public synchronized void setGridSize(final int size) { final String cmd = String.format(CurrentAnalysisEditorGraphBean.JS_CMD_SET_GRID_SIZE, size); RequestContext.getCurrentInstance().execute(cmd); this.refreshGraph(); @@ -539,14 +544,14 @@ public final class CurrentAnalysisEditorGraphBean { /** * This method scales the graph to fit the current view. After this method-call, all components of the graph should be visible. */ - public void scaleToFit() { + public synchronized void scaleToFit() { RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_SCALE_TO_FIT); } /** * This method switches the visibility of the grid within the graph. */ - public void switchGrid() { + public synchronized void switchGrid() { if (this.gridEnabled) { RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_DISABLE_GRID); } else { @@ -560,7 +565,7 @@ public final class CurrentAnalysisEditorGraphBean { /** * This method switches the grid snap within the graph. */ - public void switchSnap() { + public synchronized void switchSnap() { if (this.snapEnabled) { RequestContext.getCurrentInstance().execute(CurrentAnalysisEditorGraphBean.JS_CMD_DISABLE_SNAP); } else { @@ -575,7 +580,7 @@ public final class CurrentAnalysisEditorGraphBean { * * @return The current value of the property. */ - public boolean isGridEnabled() { + public synchronized boolean isGridEnabled() { return this.gridEnabled; } @@ -584,7 +589,7 @@ public final class CurrentAnalysisEditorGraphBean { * * @return The current value of the property. */ - public boolean isSnapEnabled() { + public synchronized boolean isSnapEnabled() { return this.snapEnabled; } @@ -594,7 +599,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param currentAnalysisEditorBean * The new value for this field. */ - public void setCurrentAnalysisEditorBean(final CurrentAnalysisEditorBean currentAnalysisEditorBean) { + public synchronized void setCurrentAnalysisEditorBean(final CurrentAnalysisEditorBean currentAnalysisEditorBean) { this.currentAnalysisEditorBean = currentAnalysisEditorBean; } @@ -606,7 +611,7 @@ public final class CurrentAnalysisEditorGraphBean { * @param newName * The new name of the node. */ - public void renameNode(final EObject node, final String newName) { + public synchronized void renameNode(final EObject node, final String newName) { RequestContext.getCurrentInstance().execute(String.format(CurrentAnalysisEditorGraphBean.JS_CMD_RENAME_NODE, this.componentMap.get(node), newName)); this.refreshGraph(); } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java similarity index 55% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java index 529e1d84566348ec07903c811ee4908796fe548c..60a650f439f04ab95739a060f01337dde2a9a0b5 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitBean.java @@ -14,23 +14,27 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.view; +package kieker.webgui.web.beans.view; import java.io.IOException; import javax.faces.application.FacesMessage; import javax.faces.context.FacesContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + import kieker.analysis.model.analysisMetaModel.MIProject; import kieker.analysis.model.analysisMetaModel.MIView; import kieker.common.logging.Log; import kieker.common.logging.LogFactory; -import kieker.webgui.beans.application.GlobalPropertiesBean; -import kieker.webgui.beans.application.ProjectsBean; import kieker.webgui.common.ClassAndMethodContainer; -import kieker.webgui.common.IProjectManager; import kieker.webgui.common.exception.DisplayNotFoundException; import kieker.webgui.common.exception.ProjectNotExistingException; +import kieker.webgui.service.IProjectService; +import kieker.webgui.web.beans.application.GlobalPropertiesBean; +import kieker.webgui.web.beans.application.ProjectsBean; /** * The {@link CurrentCockpitBean} contains the necessary data behind an instance of the cockpit. It provides methods to read the state of the currently selected @@ -40,14 +44,18 @@ import kieker.webgui.common.exception.ProjectNotExistingException; * * @author Nils Christian Ehmke */ +@Component +@Scope("view") public final class CurrentCockpitBean { private static final Log LOG = LogFactory.getLog(CurrentCockpitBean.class); - private IProjectManager projectManagerFacade; + @Autowired + private IProjectService projectService; private String projectName; private MIProject project; private MIView activeView; private ClassAndMethodContainer classAndMethodContainer; + @Autowired private ProjectsBean projectsBean; /** @@ -62,14 +70,12 @@ public final class CurrentCockpitBean { * * @return The project for this user. */ - public MIProject getProject() { - synchronized (this) { - return this.project; - } + public synchronized MIProject getProject() { + return this.project; } - public void setProjectManagerFacade(final IProjectManager projectManagerFacade) { - this.projectManagerFacade = projectManagerFacade; + public synchronized void setProjectService(final IProjectService projectService) { + this.projectService = projectService; } /** @@ -77,10 +83,8 @@ public final class CurrentCockpitBean { * * @return {@link #projectsBean} */ - public ProjectsBean getProjectsBean() { - synchronized (this) { - return this.projectsBean; - } + public synchronized ProjectsBean getProjectsBean() { + return this.projectsBean; } /** @@ -89,10 +93,8 @@ public final class CurrentCockpitBean { * @param projectsBean * The new value for {@link #projectsBean}. */ - public void setProjectsBean(final ProjectsBean projectsBean) { - synchronized (this) { - this.projectsBean = projectsBean; - } + public synchronized void setProjectsBean(final ProjectsBean projectsBean) { + this.projectsBean = projectsBean; } /** @@ -101,42 +103,38 @@ public final class CurrentCockpitBean { * @param newName * The name of the project. */ - public void setProjectName(final String newName) { - synchronized (this) { - // Remember the given parameters - this.projectName = newName; - } + public synchronized void setProjectName(final String newName) { + // Remember the given parameters + this.projectName = newName; } /** * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by * Spring.</b> */ - public void initalize() { + public synchronized void initalize() { // TODO Replace the log messages with the localizes messages - synchronized (this) { - try { - // Make sure that the initialization will only be done for the init request. - if (!FacesContext.getCurrentInstance().isPostback()) { - // Remember the given parameters - this.project = this.projectsBean.openProject(this.projectName); - - if (this.project != null) { - final ClassLoader classLoader = this.projectManagerFacade.getClassLoader(this.projectName); // NOPMD (ClassLoader) - this.classAndMethodContainer = new ClassAndMethodContainer(classLoader); - } + try { + // Make sure that the initialization will only be done for the init request. + if (!FacesContext.getCurrentInstance().isPostback()) { + // Remember the given parameters + this.project = this.projectsBean.openProject(this.projectName); + + if (this.project != null) { + final ClassLoader classLoader = this.projectService.getClassLoader(this.projectName, this); // NOPMD (ClassLoader) + this.classAndMethodContainer = new ClassAndMethodContainer(classLoader); } - } catch (final ProjectNotExistingException ex) { - CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); - } catch (final IOException ex) { - CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); - } catch (final NullPointerException ex) { - // This exception occurs, when the projectsBean has not been initialized - CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); } + } catch (final ProjectNotExistingException ex) { + CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); + } catch (final IOException ex) { + CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); + } catch (final NullPointerException ex) { + // This exception occurs, when the projectsBean has not been initialized + CurrentCockpitBean.LOG.error("An error occured while loading the project.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); } } @@ -145,10 +143,8 @@ public final class CurrentCockpitBean { * * @return The project name for this user. */ - public String getProjectName() { - synchronized (this) { - return this.projectName; - } + public synchronized String getProjectName() { + return this.projectName; } /** @@ -159,20 +155,18 @@ public final class CurrentCockpitBean { * @return The current content of the display, if it exists. If the display does not exist or the active view is not set 'N/A' will be returned. If an access to * the display fails, "Error" will be returned. */ - public String updatePlainTextDisplay(final String displayName) { - synchronized (this) { - if ((this.activeView != null) && (this.projectName != null)) { - try { - final Object displayObj = this.projectManagerFacade.getDisplay(this.projectName, this.activeView.getName(), displayName); - final String result = (String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPlainTextgetTextMethod(), displayObj, - "Error"); - return result; - } catch (final DisplayNotFoundException ex) { - CurrentCockpitBean.LOG.warn("Display not found.", ex); - } + public synchronized String updatePlainTextDisplay(final String displayName) { + if ((this.activeView != null) && (this.projectName != null)) { + try { + final Object displayObj = this.projectService.getDisplay(this.projectName, this.activeView.getName(), displayName); + final String result = (String) ClassAndMethodContainer.invokeMethod(this.classAndMethodContainer.getPlainTextgetTextMethod(), displayObj, + "Error"); + return result; + } catch (final DisplayNotFoundException ex) { + CurrentCockpitBean.LOG.warn("Display not found.", ex); } - return "N/A"; } + return "N/A"; } /** @@ -180,7 +174,7 @@ public final class CurrentCockpitBean { * * @return Currently this method returns only N/A. */ - public String updateHtmlTextDisplay() { + public synchronized String updateHtmlTextDisplay() { return "N/A"; } @@ -189,7 +183,7 @@ public final class CurrentCockpitBean { * * @return Currently this method returns only N/A. */ - public String updateImageDisplay() { + public synchronized String updateImageDisplay() { return "N/A"; } @@ -198,10 +192,8 @@ public final class CurrentCockpitBean { * * @return The active view. */ - public MIView getActiveView() { - synchronized (this) { - return this.activeView; - } + public synchronized MIView getActiveView() { + return this.activeView; } /** @@ -210,9 +202,7 @@ public final class CurrentCockpitBean { * @param activeView * The new active view. */ - public void setActiveView(final MIView activeView) { - synchronized (this) { - this.activeView = activeView; - } + public synchronized void setActiveView(final MIView activeView) { + this.activeView = activeView; } } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java similarity index 56% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java index 68fc91ebf3a247e6a203ba1bc8a6cca400c27d9d..ea73f84cd1af292fe2d6a00c83eb3d15624f128a 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentCockpitEditorBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentCockpitEditorBean.java @@ -14,7 +14,7 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.view; +package kieker.webgui.web.beans.view; import java.io.IOException; import java.lang.annotation.Annotation; @@ -30,6 +30,10 @@ import javax.faces.component.UIInput; import javax.faces.component.html.HtmlOutputText; import javax.faces.context.FacesContext; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + import kieker.analysis.display.annotation.Display; import kieker.analysis.model.analysisMetaModel.MIAnalysisMetaModelFactory; import kieker.analysis.model.analysisMetaModel.MIDisplay; @@ -40,13 +44,13 @@ import kieker.analysis.model.analysisMetaModel.impl.MAnalysisMetaModelFactory; import kieker.analysis.plugin.AbstractPlugin; import kieker.common.logging.Log; import kieker.common.logging.LogFactory; -import kieker.webgui.beans.application.GlobalPropertiesBean; -import kieker.webgui.beans.application.ProjectsBean; import kieker.webgui.common.ClassAndMethodContainer; -import kieker.webgui.common.IProjectManager; import kieker.webgui.common.exception.NewerProjectException; import kieker.webgui.common.exception.ProjectLoadException; import kieker.webgui.common.exception.ProjectNotExistingException; +import kieker.webgui.service.IProjectService; +import kieker.webgui.web.beans.application.GlobalPropertiesBean; +import kieker.webgui.web.beans.application.ProjectsBean; import org.primefaces.component.dashboard.Dashboard; import org.primefaces.component.panel.Panel; @@ -64,13 +68,16 @@ import org.primefaces.model.DefaultDashboardModel; * * @author Nils Christian Ehmke */ +@Component +@Scope("view") public final class CurrentCockpitEditorBean { private static final int NUMBER_COLUMNS = 2; private static final Log LOG = LogFactory.getLog(CurrentCockpitEditorBean.class); private final MIAnalysisMetaModelFactory factory = new MAnalysisMetaModelFactory(); - private IProjectManager projectManagerFacade; + @Autowired + private IProjectService projectService; private ClassAndMethodContainer classAndMethodContainer; private long timeStamp; @@ -80,8 +87,9 @@ public final class CurrentCockpitEditorBean { private ClassLoader classLoader; private Dashboard dashboard; private DashboardModel dashboardModel; - + @Autowired private ProjectsBean projectsBean; + @Autowired private GlobalPropertiesBean globalPropertiesBean; /** @@ -91,17 +99,7 @@ public final class CurrentCockpitEditorBean { this.createDashboard(); } - /** - * Setter for the property {@link CurrentCockpitEditorBean#projectManagerFacade}. - * - * @param projectManagerFacade - * The new value of the property. - */ - public void setProjectManagerFacade(final IProjectManager projectManagerFacade) { - this.projectManagerFacade = projectManagerFacade; - } - - private void createDashboard() { + private synchronized void createDashboard() { final FacesContext fc = FacesContext.getCurrentInstance(); final Application application = fc.getApplication(); @@ -118,7 +116,7 @@ public final class CurrentCockpitEditorBean { this.dashboard.setModel(this.dashboardModel); } - private void fillDashboard() { + private synchronized void fillDashboard() { // Dump the old entries this.clearDashboard(); @@ -149,7 +147,7 @@ public final class CurrentCockpitEditorBean { } } - private void clearDashboard() { + private synchronized void clearDashboard() { // Run through all columns of the dashboard and remove the items final List<DashboardColumn> columns = this.dashboard.getModel().getColumns(); for (final DashboardColumn column : columns) { @@ -159,50 +157,31 @@ public final class CurrentCockpitEditorBean { this.dashboard.getChildren().clear(); } - /** - * Getter for the attribute {@link CurrentCockpitEditorBean#projectsBean}. - * - * @return Delivers the value of the attribute. - */ - public ProjectsBean getProjectsBean() { - return this.projectsBean; - } - - /** - * Setter for the attribute {@link CurrentCockpitEditorBean#projectsBean}. - * - * @param projectsBean - * The new value of the attribute. - */ - public void setProjectsBean(final ProjectsBean projectsBean) { - this.projectsBean = projectsBean; - } - /** * This method initializes the bean by using the current project name to load the project. <b>Do not call this method manually. It will only be accessed by * Spring.</b> */ - public void initalize() { - synchronized (this) { - try { - // Make sure that the initialization will only be done for the init request. - if (!FacesContext.getCurrentInstance().isPostback()) { - // Remember the given parameters - this.project = this.projectsBean.openProject(this.projectName); - if (this.project != null) { - // Remember the current time! This is important for the later comparison of the time stamps. - this.resetTimeStamp(); - // Update the class loader and the specific classes used within various methods in this bean - this.reloadClassLoader(); - this.reloadClassesAndMethods(); - this.fillDashboard(); - } + public synchronized void initalize() { + + try { + // Make sure that the initialization will only be done for the init request. + if (!FacesContext.getCurrentInstance().isPostback()) { + // Remember the given parameters + this.project = this.projectsBean.openProject(this.projectName); + if (this.project != null) { + // Remember the current time! This is important for the later comparison of the time stamps. + this.resetTimeStamp(); + // Update the class loader and the specific classes used within various methods in this bean + this.reloadClassLoader(); + this.reloadClassesAndMethods(); + this.fillDashboard(); } - } catch (final ProjectLoadException ex) { - CurrentCockpitEditorBean.LOG.error("An error occured while loading the project.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); } + } catch (final ProjectLoadException ex) { + CurrentCockpitEditorBean.LOG.error("An error occured while loading the project.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while loading the project."); } + } /** @@ -211,10 +190,8 @@ public final class CurrentCockpitEditorBean { * @throws ProjectLoadException * If one or more of the classes and methods necessary for {@link ClassAndMethodContainer} could not be found using the given class loader. */ - private void reloadClassesAndMethods() throws ProjectLoadException { - synchronized (this) { - this.classAndMethodContainer = new ClassAndMethodContainer(this.classLoader); - } + private synchronized void reloadClassesAndMethods() throws ProjectLoadException { + this.classAndMethodContainer = new ClassAndMethodContainer(this.classLoader); } /** @@ -224,17 +201,15 @@ public final class CurrentCockpitEditorBean { * @throws ProjectLoadException * If something went wrong. */ - private void reloadClassLoader() throws ProjectLoadException { - synchronized (this) { - try { - this.classLoader = this.projectManagerFacade.getClassLoader(this.projectName); // NOPMD (ClassLoader) - } catch (final NullPointerException ex) { - throw new ProjectLoadException("Invalid class loader.", ex); - } catch (final IOException ex) { - throw new ProjectLoadException("Could not load classes.", ex); - } catch (final ProjectNotExistingException ex) { - throw new ProjectLoadException("Project does not exist.", ex); - } + private synchronized void reloadClassLoader() throws ProjectLoadException { + try { + this.classLoader = this.projectService.getClassLoader(this.projectName, this); // NOPMD (ClassLoader) + } catch (final NullPointerException ex) { + throw new ProjectLoadException("Invalid class loader.", ex); + } catch (final IOException ex) { + throw new ProjectLoadException("Could not load classes.", ex); + } catch (final ProjectNotExistingException ex) { + throw new ProjectLoadException("Project does not exist.", ex); } } @@ -243,10 +218,8 @@ public final class CurrentCockpitEditorBean { * * @return The project for this user. */ - public MIProject getProject() { - synchronized (this) { - return this.project; - } + public synchronized MIProject getProject() { + return this.project; } /** @@ -255,10 +228,8 @@ public final class CurrentCockpitEditorBean { * @param newName * The name of the project. */ - public void setProjectName(final String newName) { - synchronized (this) { - this.projectName = newName; - } + public synchronized void setProjectName(final String newName) { + this.projectName = newName; } /** @@ -266,10 +237,8 @@ public final class CurrentCockpitEditorBean { * * @return The project name for this user. */ - public String getProjectName() { - synchronized (this) { - return this.projectName; - } + public synchronized String getProjectName() { + return this.projectName; } /** @@ -279,7 +248,7 @@ public final class CurrentCockpitEditorBean { * The display whose description should be extracted. * @return The description for the display or a substitute if none is available. This is in either case human readable. */ - public String getDescription(final MIDisplay display) { + public synchronized String getDescription(final MIDisplay display) { try { final String classname = display.getParent().getClassname(); final String displayName = display.getName(); @@ -311,35 +280,31 @@ public final class CurrentCockpitEditorBean { * @param overwriteNewerProject * This flag determines whether a newer project should be overwritten. */ - public void saveProject(final boolean overwriteNewerProject) { - synchronized (this) { - try { - this.projectManagerFacade.saveProject(this.projectName, this.project, this.timeStamp, overwriteNewerProject); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgProjectSaved()); - // Update the time stamp! - this.resetTimeStamp(); - } catch (final IOException ex) { - CurrentCockpitEditorBean.LOG.error("An error occured while saving the projet.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while saving the project."); - } catch (final NewerProjectException ex) { - CurrentCockpitEditorBean.LOG.info("The project has been modified externally in the meanwhile.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_WARN, "The project has been modified externally in the meanwhile."); - // Give the user the possibility to force-save the project - RequestContext.getCurrentInstance().execute("forceSaveDlg.show()"); - } catch (final ProjectNotExistingException ex) { - CurrentCockpitEditorBean.LOG.error("A project with the given name does not exist.", ex); - GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "A project with the given name does not exist."); - } + public synchronized void saveProject(final boolean overwriteNewerProject) { + try { + this.projectService.saveProject(this.projectName, this.project, this.timeStamp, overwriteNewerProject); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, this.globalPropertiesBean.getMsgProjectSaved()); + // Update the time stamp! + this.resetTimeStamp(); + } catch (final IOException ex) { + CurrentCockpitEditorBean.LOG.error("An error occured while saving the projet.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while saving the project."); + } catch (final NewerProjectException ex) { + CurrentCockpitEditorBean.LOG.info("The project has been modified externally in the meanwhile.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_WARN, "The project has been modified externally in the meanwhile."); + // Give the user the possibility to force-save the project + RequestContext.getCurrentInstance().execute("forceSaveDlg.show()"); + } catch (final ProjectNotExistingException ex) { + CurrentCockpitEditorBean.LOG.error("A project with the given name does not exist.", ex); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "A project with the given name does not exist."); } } /** * This method sets the time stamp to the current system time. */ - public void resetTimeStamp() { - synchronized (this) { - this.timeStamp = System.currentTimeMillis(); - } + public synchronized void resetTimeStamp() { + this.timeStamp = System.currentTimeMillis(); } /** @@ -349,19 +314,17 @@ public final class CurrentCockpitEditorBean { * The plugin whose displays should be delivered. * @return The available displays. */ - public List<Display> getDisplays(final Class<AbstractPlugin> clazz) { + public synchronized List<Display> getDisplays(final Class<AbstractPlugin> clazz) { final List<Display> result = new ArrayList<Display>(); - synchronized (this) { - if (clazz != null) { - // Run through all available methods and find the annotated ones - final Method[] methods = clazz.getMethods(); - for (final Method method : methods) { - final Display displayAnnot = method.getAnnotation(Display.class); - // Check whether the annotation is available. If yes - add it to our result list - if (displayAnnot != null) { - result.add(displayAnnot); - } + if (clazz != null) { + // Run through all available methods and find the annotated ones + final Method[] methods = clazz.getMethods(); + for (final Method method : methods) { + final Display displayAnnot = method.getAnnotation(Display.class); + // Check whether the annotation is available. If yes - add it to our result list + if (displayAnnot != null) { + result.add(displayAnnot); } } } @@ -375,15 +338,13 @@ public final class CurrentCockpitEditorBean { * @param viewName * The name of the new view. */ - public void addView(final String viewName) { - synchronized (this) { - if (this.project != null) { - // Create the view and add it to our project - final MIView view = this.factory.createView(); - view.setName(viewName); - view.setDescription("No description available."); - this.project.getViews().add(view); - } + public synchronized void addView(final String viewName) { + if (this.project != null) { + // Create the view and add it to our project + final MIView view = this.factory.createView(); + view.setName(viewName); + view.setDescription("No description available."); + this.project.getViews().add(view); } } @@ -392,10 +353,8 @@ public final class CurrentCockpitEditorBean { * * @return The currently active view. */ - public MIView getActiveView() { - synchronized (this) { - return this.activeView; - } + public synchronized MIView getActiveView() { + return this.activeView; } /** @@ -404,12 +363,10 @@ public final class CurrentCockpitEditorBean { * @param view * The new active view. */ - public void setActiveView(final MIView view) { - synchronized (this) { - this.activeView = view; + public synchronized void setActiveView(final MIView view) { + this.activeView = view; - this.fillDashboard(); - } + this.fillDashboard(); } /** @@ -418,32 +375,30 @@ public final class CurrentCockpitEditorBean { * @param display * The display which should be added to the current view. */ - public void addDisplayToView(final MIDisplay display) { - synchronized (this) { - if (this.activeView != null) { - final MIDisplayConnector connector = this.factory.createDisplayConnector(); - connector.setDisplay(display); - connector.setName(UUID.randomUUID().toString()); - this.activeView.getDisplayConnectors().add(connector); - - // Now add it to the dashboard as well - final FacesContext fc = FacesContext.getCurrentInstance(); - final Application application = fc.getApplication(); + public synchronized void addDisplayToView(final MIDisplay display) { + if (this.activeView != null) { + final MIDisplayConnector connector = this.factory.createDisplayConnector(); + connector.setDisplay(display); + connector.setName(UUID.randomUUID().toString()); + this.activeView.getDisplayConnectors().add(connector); - final Panel panel = (Panel) application.createComponent(fc, "org.primefaces.component.Panel", "org.primefaces.component.PanelRenderer"); - panel.setId("displayConnectorPanel_" + (this.dashboard.getChildCount() + 1)); - panel.setHeader(connector.getName()); - panel.setClosable(true); - panel.setToggleable(false); + // Now add it to the dashboard as well + final FacesContext fc = FacesContext.getCurrentInstance(); + final Application application = fc.getApplication(); - this.getDashboard().getChildren().add(panel); - final DashboardColumn column = this.dashboardModel.getColumn(CurrentCockpitEditorBean.NUMBER_COLUMNS - 1); - column.addWidget(panel.getId()); - final HtmlOutputText text = new HtmlOutputText(); - text.setValue("N/A"); + final Panel panel = (Panel) application.createComponent(fc, "org.primefaces.component.Panel", "org.primefaces.component.PanelRenderer"); + panel.setId("displayConnectorPanel_" + (this.dashboard.getChildCount() + 1)); + panel.setHeader(connector.getName()); + panel.setClosable(true); + panel.setToggleable(false); - panel.getChildren().add(text); - } + this.getDashboard().getChildren().add(panel); + final DashboardColumn column = this.dashboardModel.getColumn(CurrentCockpitEditorBean.NUMBER_COLUMNS - 1); + column.addWidget(panel.getId()); + final HtmlOutputText text = new HtmlOutputText(); + text.setValue("N/A"); + + panel.getChildren().add(text); } } @@ -466,23 +421,21 @@ public final class CurrentCockpitEditorBean { * The name to be checked. * @return true iff the name exists already. */ - private boolean existsDisplayConnectorName(final String name) { - synchronized (this) { - // Make sure a view is selected - if (this.activeView == null) { - return false; - } + private synchronized boolean existsDisplayConnectorName(final String name) { + // Make sure a view is selected + if (this.activeView == null) { + return false; + } - // Run through all display connectors and check the name against the given one - for (final MIDisplayConnector connector : this.activeView.getDisplayConnectors()) { - if (connector.getName().equals(name)) { - return true; - } + // Run through all display connectors and check the name against the given one + for (final MIDisplayConnector connector : this.activeView.getDisplayConnectors()) { + if (connector.getName().equals(name)) { + return true; } - - // The name has not been found - return false; } + + // The name has not been found + return false; } /** @@ -495,41 +448,20 @@ public final class CurrentCockpitEditorBean { * @param value * The new value. */ - public void validateDisplayConnectorName(final FacesContext context, final UIComponent toValidate, final Object value) { - synchronized (this) { - if ((value instanceof String) && (toValidate instanceof UIInput)) { - final boolean nameExists = this.existsDisplayConnectorName((String) value); - ((UIInput) toValidate).setValid(!nameExists); - } + public synchronized void validateDisplayConnectorName(final FacesContext context, final UIComponent toValidate, final Object value) { + if ((value instanceof String) && (toValidate instanceof UIInput)) { + final boolean nameExists = this.existsDisplayConnectorName((String) value); + ((UIInput) toValidate).setValid(!nameExists); } } - public Dashboard getDashboard() { + public synchronized Dashboard getDashboard() { return this.dashboard; } - public void setDashboard(final Dashboard dashboard) { + public synchronized void setDashboard(final Dashboard dashboard) { this.dashboard = dashboard; this.dashboard.setModel(this.dashboardModel); } - /** - * The getter for the property {@link CurrentCockpitEditorBean#globalPropertiesBean}. - * - * @return The current value of the property. - */ - public GlobalPropertiesBean getGlobalPropertiesBean() { - return this.globalPropertiesBean; - } - - /** - * The setter for the property {@link CurrentCockpitEditorBean#globalPropertiesBean}. - * - * @param globalPropertiesBean - * The new value of the property. - */ - public void setGlobalPropertiesBean(final GlobalPropertiesBean globalPropertiesBean) { - this.globalPropertiesBean = globalPropertiesBean; - } - } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentControllerBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentControllerBean.java new file mode 100644 index 0000000000000000000000000000000000000000..b037dacb6a28e64fe7dadbcf01136cb69dc2ed54 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentControllerBean.java @@ -0,0 +1,311 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package kieker.webgui.web.beans.view; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.List; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import kieker.analysis.AnalysisController; +import kieker.common.logging.Log; +import kieker.common.logging.LogFactory; +import kieker.webgui.common.exception.AnalysisInitializationException; +import kieker.webgui.common.exception.AnalysisStateException; +import kieker.webgui.common.exception.ProjectNotExistingException; +import kieker.webgui.service.IProjectService; +import kieker.webgui.web.beans.application.ProjectsBean; + +/** + * /** + * The {@link CurrentControllerBean} contains the necessary data behind an instance of the analysis controller. The class is a Spring managed bean with view scope to + * make sure that one user (even in one session) can open multiple projects at a time without causing any problems. + * + * @author Nils Christian Ehmke + */ +@Component +@Scope("view") +public final class CurrentControllerBean { + + private static final Log LOG = LogFactory.getLog(CurrentControllerBean.class); + @Autowired + private IProjectService projectService; + private final List<String> logEntries = new ArrayList<String>(); + + private String projectName; + @Autowired + private ProjectsBean projectsBean; + + /** + * Creates a new instance of this class. <b>Do not use this constructor. This bean is Spring managed.</b> + */ + public CurrentControllerBean() { + // No code necessary + } + + /** + * This method sets the project stored within this bean and returns the new page for the navigation. + * + * @param newName + * The name of the project. + */ + public synchronized void setProjectName(final String newName) { + // Remember the given parameters + this.projectName = newName; + + } + + /** + * This method delivers the project name stored in this bean. + * + * @return The project name for this user. + */ + public synchronized String getProjectName() { + return this.projectName; + } + + /** + * This method starts the current analysis and informs the user about a fail. + */ + public synchronized void startAnalysis() { + this.addLogEntry("Starting Analysis for project '" + this.projectName + "'"); + try { + this.projectService.startAnalysis(this.projectName); + } catch (final AnalysisStateException ex) { + CurrentControllerBean.LOG.info("The analysis has already been started.", ex); + this.addLogEntry(ex); + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + this.addLogEntry(ex); + } + + } + + /** + * This method stops the current analysis and informs the user about a fail. + */ + public synchronized void stopAnalysis() { + try { + this.addLogEntry("Stopping Analysis for project '" + this.projectName + "'"); + synchronized (this) { + this.projectService.stopAnalysis(this.projectName); + } + } catch (final AnalysisStateException ex) { + CurrentControllerBean.LOG.info("The analysis has not been started yet.", ex); + this.addLogEntry(ex); + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + this.addLogEntry(ex); + } + } + + /** + * This method initializes the current analysis and informs the user about a fail. + */ + public synchronized void instantiateAnalysis() { + this.addLogEntry("Instantiating Analysis for project '" + this.projectName + "'"); + try { + this.projectService.initializeAnalysis(this.projectName, this.projectService.getClassLoader(this.projectName, this)); // NOPMD (ClassLoader) + } catch (final AnalysisStateException ex) { + CurrentControllerBean.LOG.error("The analysis has already been instantiated.", ex); + this.addLogEntry(ex); + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + this.addLogEntry(ex); + } catch (final IOException ex) { + CurrentControllerBean.LOG.info("An error occured during the initialization.", ex); + this.addLogEntry(ex); + } catch (final AnalysisInitializationException ex) { + CurrentControllerBean.LOG.info("An error occured during the initialization.", ex); + this.addLogEntry(ex); + } + } + + /** + * This method cleans the current analysis instance. + */ + public synchronized void cleanAnalysis() { + this.addLogEntry("Cleaning Analysis for project '" + this.projectName + "'"); + try { + this.projectService.cleanAnalysis(this.projectName); + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + this.addLogEntry(ex); + } catch (final AnalysisStateException ex) { + CurrentControllerBean.LOG.error("The analysis has not been instantiated yet.", ex); + this.addLogEntry(ex); + + } + } + + /** + * Checks whether the analysis is currently running. + * + * @return true if and only if the analysis is running. + */ + public synchronized boolean isAnalysisRunning() { + try { + return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.RUNNING; + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + return false; + } catch (final NullPointerException ex) { + // This exception can occur, when the projectsBean has not been initialized + CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); + return false; + } + } + + /** + * Checks whether the analysis is currently in the ready state. + * + * @return true if and only if the analysis is ready to be started. + */ + public synchronized boolean isAnalysisReady() { + try { + return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.READY; + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + return false; + } catch (final NullPointerException ex) { + // This exception can occur, when the projectsBean has not been initialized + CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); + return false; + + } + } + + /** + * Checks whether the analysis is not available. + * + * @return true if and only if the analysis is <b>not</b> available. + */ + public synchronized boolean isAnalysisNotAvailable() { + + try { + return this.projectService.getCurrentState(this.projectName) == null; + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + return true; + } catch (final NullPointerException ex) { + // This exception can occur, when the projectsBean has not been initialized + CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); + return true; + } + + } + + /** + * Checks whether the analysis is currently terminated. + * + * @return true if and only if the analysis has been terminated. + */ + public synchronized boolean isAnalysisTerminated() { + + try { + return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.TERMINATED; + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + return false; + } catch (final NullPointerException ex) { + // This exception can occur, when the projectsBean has not been initialized + CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); + return false; + } + + } + + /** + * Checks whether the analysis is currently in the failed state. + * + * @return true if and only if the analysis has failed. + */ + public synchronized boolean isAnalysisFailed() { + + try { + return this.projectService.getCurrentState(this.projectName) == AnalysisController.STATE.FAILED; + } catch (final ProjectNotExistingException ex) { + CurrentControllerBean.LOG.info("The project does not exist.", ex); + return false; + } catch (final NullPointerException ex) { + // This exception can occur, when the projectsBean has not been initialized + CurrentControllerBean.LOG.warn("A null pointer exception occured.", ex); + return false; + } + + } + + /** + * Delivers the available log entries of the current analysis controller instance. + * + * @return The current log entries. + */ + public synchronized Object[] getAnalysisLog() { + try { + return this.projectService.getLogEntries(this.projectName); + } catch (final AnalysisStateException ex) { + // Ignore + return new Object[0]; + } + } + + /** + * Delivers the available log entries of the current view. + * + * @return The current log entries. + */ + public synchronized Collection<String> getViewLog() { + return this.logEntries; + } + + /** + * Adds the element to the log. + * + * @param cause + * The element to be added. + */ + private synchronized void addLogEntry(final Throwable cause) { + final Writer result = new StringWriter(); + final PrintWriter printWriter = new PrintWriter(result); + cause.printStackTrace(printWriter); + this.addLogEntry(result.toString()); + } + + /** + * Adds the element (with the current time) to the log. + * + * @param msg + * The log message. + */ + private synchronized void addLogEntry(final String msg) { + final String finalMsg = new Date().toString() + " : " + msg; + synchronized (this) { + if (this.logEntries.size() > 50) { + this.logEntries.remove(0); + } + this.logEntries.add(finalMsg); + } + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentProjectOverviewBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentProjectOverviewBean.java similarity index 89% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentProjectOverviewBean.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentProjectOverviewBean.java index 6ccfb24974c91a508c24ff5cac37bc99e6b8bfbe..5f56521e468b0c5e3da2a11be8ae6ee4dfe23082 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/CurrentProjectOverviewBean.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentProjectOverviewBean.java @@ -14,12 +14,18 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.beans.view; +package kieker.webgui.web.beans.view; import java.util.ArrayList; import java.util.List; -import kieker.webgui.beans.application.ProjectsBean; +import javax.annotation.PostConstruct; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import kieker.webgui.web.beans.application.ProjectsBean; import org.primefaces.event.SelectEvent; @@ -29,8 +35,10 @@ import org.primefaces.event.SelectEvent; * * @author Nils Christian Ehmke */ +@Component +@Scope("view") public final class CurrentProjectOverviewBean { - + @Autowired private ProjectsBean projectsBean; /** * This list contains all available projects by name. @@ -90,6 +98,7 @@ public final class CurrentProjectOverviewBean { /** * This method should only be called automatically by Spring to update the projects list. */ + @PostConstruct protected void initialialize() { this.updateLists(); } diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentUserManagementBean.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentUserManagementBean.java new file mode 100644 index 0000000000000000000000000000000000000000..64422baff8f1aa778acd8009d296eadc008658f5 --- /dev/null +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/CurrentUserManagementBean.java @@ -0,0 +1,136 @@ +/*************************************************************************** + * Copyright 2012 Kieker Project (http://kieker-monitoring.net) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + ***************************************************************************/ + +package kieker.webgui.web.beans.view; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.PostConstruct; +import javax.faces.application.FacesMessage; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import kieker.webgui.common.exception.DataAccessException; +import kieker.webgui.domain.User; +import kieker.webgui.domain.User.Role; +import kieker.webgui.service.IUserService; +import kieker.webgui.web.beans.application.GlobalPropertiesBean; + +/** + * @author Nils Christian Ehmke + */ +@Component +@Scope("view") +public final class CurrentUserManagementBean { + + @Autowired + private IUserService userService; + + private List<User> availableUses = new ArrayList<User>(); + + /** + * Default constructor. <b>Do not call this constructor manually. It will only be accessed by Spring.</b> + */ + public CurrentUserManagementBean() { + // No code necessary + } + + /** + * This method initializes the bean. <b>Do not call this method manually. It will only be accessed by Spring.</b> + */ + @PostConstruct + protected void initialialize() { + this.updateList(); + } + + /** + * This method adds the given user to the database and informs about success via the growl component. + * + * @param username + * The name of the new user. + * @param password + * The password of the new user. + * @param role + * The role of the new user. + * @param isEnabled + * Determines whether the user is enabled already or not. + */ + public void addUser(final String username, final String password, final Role role, final boolean isEnabled) { + final User user = new User(username, password, role, isEnabled); + + try { + this.userService.addUser(user); + this.availableUses.add(user); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, "Added user to the database."); + } catch (final DataAccessException ex) { + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "Could not add the user to the database."); + } + } + + /** + * This method removed the given user from the database and informs about success via the growl component. + * + * @param user + * The user to be deleted. + */ + public void deleteUser(final User user) { + try { + this.userService.deleteUser(user); + this.availableUses.remove(user); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, "Deleted user from the database."); + } catch (final DataAccessException ex) { + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "Could not deleted the user from the database."); + } + } + + /** + * This method edits the given user within the database and informs about success via the growl component. + * + * @param user + * The user to be modified. + */ + public void editUser(final User user) { + try { + this.userService.editUser(user); + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_INFO, "Modified user within the database."); + } catch (final DataAccessException ex) { + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "Could not modified the user within the database."); + } + } + + /** + * Updates the list containing the available users. + */ + public void updateList() { + try { + this.availableUses = this.userService.getUsers(); + } catch (final DataAccessException ex) { + GlobalPropertiesBean.showMessage(FacesMessage.SEVERITY_ERROR, "An error occured while accessing the database."); + } + } + + /** + * This method delivers all available users. + * + * @return All currently available users. + */ + public List<User> getUsers() { + return this.availableUses; + } +} diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/package-info.java similarity index 95% rename from Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/package-info.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/package-info.java index 1294ccfaea387c1115a5e4fbc6d85776d49071a1..57470cd394f950813f0fb30447ea58441e1e5333 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/beans/view/package-info.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/beans/view/package-info.java @@ -19,5 +19,5 @@ * * @author Nils Christian Ehmke */ -package kieker.webgui.beans.view; +package kieker.webgui.web.beans.view; diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/converter/RoleStringConverter.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/converter/RoleStringConverter.java similarity index 91% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/converter/RoleStringConverter.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/converter/RoleStringConverter.java index 2ddb4906432cea409f9faa3a5fa4c0bb80948b0c..d8e580ff8f878495403302bbee61a5b7f699c193 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/converter/RoleStringConverter.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/converter/RoleStringConverter.java @@ -14,18 +14,22 @@ * limitations under the License. ***************************************************************************/ -package kieker.webgui.common.converter; +package kieker.webgui.web.converter; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import javax.faces.convert.Converter; import javax.faces.convert.FacesConverter; -import kieker.webgui.common.Role; +import kieker.webgui.domain.User.Role; @FacesConverter("roleStringConverter") public class RoleStringConverter implements Converter { + public RoleStringConverter() { + // No code necessary + } + @Override public Object getAsObject(final FacesContext context, final UIComponent comp, final String str) { return Role.valueOf(str); diff --git a/Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/package-info.java b/Kieker.WebGUI/src/main/java/kieker/webgui/web/converter/package-info.java similarity index 95% rename from Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/package-info.java rename to Kieker.WebGUI/src/main/java/kieker/webgui/web/converter/package-info.java index 54cf3cb2fc0edf4f032f6c6df549ea4dbb97ca49..1bfdcb1baeea3329b0bc445c00eb32036b6140c5 100644 --- a/Kieker.WebGUI/src/main/java/kieker/webgui/common/impl/package-info.java +++ b/Kieker.WebGUI/src/main/java/kieker/webgui/web/converter/package-info.java @@ -18,4 +18,4 @@ * @author Nils Christian Ehmke * */ -package kieker.webgui.common.impl; \ No newline at end of file +package kieker.webgui.web.converter; \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/resources/lang/LoginPage_de.properties b/Kieker.WebGUI/src/main/resources/lang/LoginPage_de.properties index beef4292a8be73cc62d7bce5c0264e1b061d4aa6..7ac6e50e76383af558d33b8759b2e585408206f8 100644 --- a/Kieker.WebGUI/src/main/resources/lang/LoginPage_de.properties +++ b/Kieker.WebGUI/src/main/resources/lang/LoginPage_de.properties @@ -1,15 +1,15 @@ #------------------------------------------------------------------------------ # -# Diese Datei beinhaltet sämtliche Nachrichten, Buttonbeschriftungen etc., +# Diese Datei beinhaltet s\u00e4mtliche Nachrichten, Buttonbeschriftungen etc., # welche innerhalb der Anmeldeseite benutzt werden. # #------------------------------------------------------------------------------ msgWelcomeShort = Willkommen bei der Kieker.WebGUI -msgWelcome = Dies ist eine fr\u00fche Beta Version der Kieker Web GUI. Deshalb kann diese noch Bugs enthalten und einige Funktionalit\u00e4ten sind m\u00f6glicherweise noch nicht implementiert. Benutzen sie den Benutzer "Kieker-Team" mit dem Passwort "kieker" um sich anzumelden und fortzufahren. +msgWelcome = Dies ist eine fr\u00fche Beta Version der Kieker Web GUI. Deshalb kann diese noch Bugs enthalten und einige Funktionalit\u00e4ten sind m\u00f6glicherweise noch nicht implementiert. Benutzen sie den Benutzer "Kieker-Administrator" mit dem Passwort "kieker" um sich anzumelden und fortzufahren. username = Benutzername password = Passwort login = Anmelden -hint = Hinweis: Die Kieker.WebGUI benötigt Cookies und JavaScript, um korrekt zu funktionieren. Bitte stellen Sie sicher, dass beides aktiviert ist. \ No newline at end of file +hint = Hinweis: Die Kieker.WebGUI ben\u00f6tigt Cookies und JavaScript, um korrekt zu funktionieren. Bitte stellen Sie sicher, dass beides aktiviert ist. \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/resources/lang/LoginPage_en.properties b/Kieker.WebGUI/src/main/resources/lang/LoginPage_en.properties index 153c8a76c5f95639912deaba73856d347053c0d3..faef1b907c2bbeeeba88542541ef27eb6eb9596f 100644 --- a/Kieker.WebGUI/src/main/resources/lang/LoginPage_en.properties +++ b/Kieker.WebGUI/src/main/resources/lang/LoginPage_en.properties @@ -6,7 +6,7 @@ #------------------------------------------------------------------------------ msgWelcomeShort = Welcome to the Kieker.WebGUI -msgWelcome = This is an early beta version of the Kieker Web GUI. Therefore it may contain bugs and some functionality may have not been implemented yet. Use the user "Kieker-Team" with the password "kieker" to login and continue. +msgWelcome = This is an early beta version of the Kieker Web GUI. Therefore it may contain bugs and some functionality may have not been implemented yet. Use the user "Kieker-Administrator" with the password "kieker" to login and continue. username = Username password = Password diff --git a/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_de.properties b/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_de.properties index dd9d15861ffb82ddf007d2daed82b284be2ba264..f26b740566f94e89239009c6cc6eb437c222de81 100644 --- a/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_de.properties +++ b/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_de.properties @@ -1,7 +1,7 @@ #------------------------------------------------------------------------------ # -# Diese Datei beinhaltet sämtliche Nachrichten, Buttonbeschriftungen etc., -# welche innerhalb der Projektübersichtsseite benutzt werden. +# Diese Datei beinhaltet s\u00e4mtliche Nachrichten, Buttonbeschriftungen etc., +# welche innerhalb der Projekt\u00fcbersichtsseite benutzt werden. # #------------------------------------------------------------------------------ @@ -13,6 +13,7 @@ projectName = Projektname state = Status lastModification = Letzte \u00c4nderung owner = Besitzer +lastEditor = Letzter Bearbeiter copyProject = Projekt Kopieren renameProject = Projekt Umbenennen diff --git a/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_en.properties b/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_en.properties index 7e12607f173be8c911bef14dd0c89625d7443824..b915b322536e735dbe708e374cef169166bb39ab 100644 --- a/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_en.properties +++ b/Kieker.WebGUI/src/main/resources/lang/ProjectOverviewPage_en.properties @@ -13,6 +13,7 @@ projectName = Project Name state = State lastModification = Last Modification owner = Owner +lastEditor = Last Editor copyProject = Copy Project renameProject = Rename Project diff --git a/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_de.properties b/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_de.properties index f5aadf0cfd9875f716c087addc7eaa2e9844c1a2..878f37ba6cf545bb7dce1a6ae0fed80a915d6885 100644 --- a/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_de.properties +++ b/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_de.properties @@ -1,6 +1,6 @@ #------------------------------------------------------------------------------ # -# Diese Datei beinhaltet sämtliche Nachrichten, Buttonbeschriftungen etc., +# Diese Datei beinhaltet s\u00e4mtliche Nachrichten, Buttonbeschriftungen etc., # welche innerhalb der Benutzerverwaltungsseite benutzt werden. # #------------------------------------------------------------------------------ @@ -12,8 +12,8 @@ updateUserList = Benutzerliste Aktualisieren editUser = Benutzer Bearbeiten disableUser = Benutzer Deaktivieren enableUser = Benutzer Aktivieren -deleteUser = Benutzer Löschen +deleteUser = Benutzer L\u00f6schen username = Benutzername -userroles = Benutzerrollen +userrole = Benutzerrolle enabled = Aktiviert \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_en.properties b/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_en.properties index fcca366ae9570d14a04c2cbabeffd28470e6f1ae..f705fdec2d50eef8697cd3d67e374899010f2a10 100644 --- a/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_en.properties +++ b/Kieker.WebGUI/src/main/resources/lang/UserManagementPage_en.properties @@ -15,5 +15,5 @@ enableUser = Enable User deleteUser = Delete User username = Username -userroles = Userroles +userrole = Userrole enabled = Enabled \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/resources/sql/tables.sql b/Kieker.WebGUI/src/main/resources/sql/tables.sql index 1b5b6acd805c0c1dd67d647f8e553b2878b127dc..f2838af0447b2fbc687710c46e6132ca7227c1f9 100644 --- a/Kieker.WebGUI/src/main/resources/sql/tables.sql +++ b/Kieker.WebGUI/src/main/resources/sql/tables.sql @@ -1,3 +1 @@ -CREATE TABLE Roles (ID int NOT NULL PRIMARY KEY, Role varchar(255)); -CREATE TABLE KIEKERUser (name varchar(255) NOT NULL PRIMARY KEY, password varchar(255) NOT NULL, enabled BOOLEAN); -CREATE TABLE Userroles (name varchar(255) NOT NULL, role int NOT NULL , CONSTRAINT key_roles PRIMARY KEY(name, role)); \ No newline at end of file +CREATE TABLE Users (name VARCHAR(255) NOT NULL PRIMARY KEY, password VARCHAR(255) NOT NULL, isGuest BOOLEAN, isUser BOOLEAN, isAdministrator BOOLEAN, isEnabled BOOLEAN, CONSTRAINT checkFlags CHECK ((CASE WHEN isGuest THEN 1 ELSE 0 END)+(CASE WHEN isUser THEN 1 ELSE 0 END)+(CASE WHEN isAdministrator THEN 1 ELSE 0 END)=1)); \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/resources/sql/test-data.sql b/Kieker.WebGUI/src/main/resources/sql/test-data.sql index 1c17b8ef9aeee3b827104badc2df042be937a5a1..5110ea9ca9114f9201f86909fef5dd3fd5eb22cd 100644 --- a/Kieker.WebGUI/src/main/resources/sql/test-data.sql +++ b/Kieker.WebGUI/src/main/resources/sql/test-data.sql @@ -1,3 +1 @@ -INSERT INTO Roles (ID, Role) VALUES (1, 'ROLE_USER'), (2, 'ROLE_ADMIN') -INSERT INTO KIEKERUser (name, password, enabled) VALUES ('Kieker-Team', 'kieker', True), ('Kieker-User', 'kieker', True) -INSERT INTO Userroles (name, role) VALUES ('Kieker-Team', 1), ('Kieker-User', 1), ('Kieker-Team', 2) \ No newline at end of file +INSERT INTO Users (name, password, isGuest, isUser, isAdministrator, isEnabled) VALUES ('Kieker-Administrator', 'kieker', false, false, true, true), ('Kieker-User', 'kieker', false, true, false, true), ('Kieker-Guest', 'kieker', true, false, false, true) \ No newline at end of file diff --git a/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-bean-config.xml b/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-bean-config.xml index dfe8bd88d5c9bc511342610cf966233d809a6012..7397f093037fe3c46c4c00c6b0f47a2c7c241258 100644 --- a/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-bean-config.xml +++ b/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-bean-config.xml @@ -3,23 +3,11 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd - http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd"> + http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd + http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd" xmlns:context="http://www.springframework.org/schema/context"> <!-- The singleton scoped beans. --> - <bean id="pluginFinder" class="kieker.webgui.common.util.PluginFinder" /> - <bean id="fsManager" class="kieker.webgui.common.util.FSManager" init-method="initialize"/> - <bean id="acManager" class="kieker.webgui.common.util.ACManager"> - <property name="fsManager" ref="fsManager" /> - </bean> - <bean id="projectManager" class="kieker.webgui.common.impl.ProjectManagerImpl"> - <property name="fsManager" ref="fsManager" /> - <property name="acManager" ref="acManager" /> - <property name="pluginFinder" ref="pluginFinder" /> - </bean> - <bean id="projectsBean" class="kieker.webgui.beans.application.ProjectsBean" init-method="initialize"> - <property name="projectManagerFacade" ref="projectManager" /> - </bean> - <bean id="globalPropertiesBean" class="kieker.webgui.beans.application.GlobalPropertiesBean"> + <bean id="globalPropertiesBean" class="kieker.webgui.web.beans.application.GlobalPropertiesBean"> <property name="themeCookieName" value="${kieker.webgui.config.lookAndFeel.cookieName}"/> <property name="projectOverviewPage" value="${kieker.webgui.page.projectOverview}"/> <property name="facesContextThemeKey" value="${kieker.webgui.config.lookAndFeel.facesContextKey}"/> @@ -29,7 +17,7 @@ <property name="analysisEditorDefaultGridSize" value="${kieker.webgui.config.analysisEditor.defaultGridSize}"/> <property name="analysisEditorDefaultGridColor" value="${kieker.webgui.config.analysisEditor.defaultGridColor}"/> </bean> - <bean id="themeSwitcherBean" class="kieker.webgui.beans.application.ThemeSwitcherBean"> + <bean id="themeSwitcherBean" class="kieker.webgui.web.beans.application.ThemeSwitcherBean"> <!-- This is the map containing the available themes (look and feels). If one wants to add more themes, this is the correct place to do so. --> <property name="themes"> <map> @@ -66,49 +54,11 @@ </map> </property> </bean> - <bean destroy-method="destroy" init-method="initialize" id="userManager" class="kieker.webgui.common.impl.UserManagerImpl"> - <property name="dataSource" ref="userDataSource" /> - </bean> - - <!-- The session scoped beans. --> - <bean id="userBean" init-method="initialize" class="kieker.webgui.beans.session.UserBean" scope="session"> - <property name="globalPropertiesBean" ref="globalPropertiesBean"/> - </bean> - - <!-- The view scoped beans. --> - <bean id="currentAnalysisEditorBean" class="kieker.webgui.beans.view.CurrentAnalysisEditorBean" scope="view"> - <property name="globalPropertiesBean" ref="globalPropertiesBean"/> - <property name="projectManagerFacade" ref="projectManager" /> - <property name="projectsBean" ref="projectsBean" /> - <property name="currentAnalysisEditorGraphBean" ref="currentAnalysisEditorGraphBean" /> - <property name="userBean" ref="userBean" /> - </bean> - <bean id="currentAnalysisEditorGraphBean" class="kieker.webgui.beans.view.CurrentAnalysisEditorGraphBean" scope="view"/> - <bean id="currentCockpitBean" class="kieker.webgui.beans.view.CurrentCockpitBean" scope="view"> - <property name="projectsBean" ref="projectsBean"/> - <property name="projectManagerFacade" ref="projectManager" /> - </bean> - <bean id="currentCockpitEditorBean" class="kieker.webgui.beans.view.CurrentCockpitEditorBean" scope="view"> - <property name="globalPropertiesBean" ref="globalPropertiesBean"/> - <property name="projectManagerFacade" ref="projectManager" /> - <property name="projectsBean" ref="projectsBean"/> - </bean> - <bean id="currentControllerBean" class="kieker.webgui.beans.view.CurrentControllerBean" scope="view"> - <property name="projectsBean" ref="projectsBean"/> - <property name="projectManagerFacade" ref="projectManager" /> - </bean> - <bean id="currentProjectOverviewBean" class="kieker.webgui.beans.view.CurrentProjectOverviewBean" scope="view" init-method="initialialize"> - <property name="projectsBean" ref="projectsBean"/> - </bean> - <bean id="currentUserManagementBean" class="kieker.webgui.beans.view.CurrentUserManagementBean" init-method="initialialize" scope="view"> - <property name="userManagerFacade" ref="userManager"/> - </bean> - <!-- The request scoped beans. --> - <bean id="stringBean" class="kieker.webgui.beans.request.StringBean" scope="request"/> - <bean id="newUserBean" class="kieker.webgui.beans.request.NewUserBean" scope="request"/> + <context:component-scan base-package="kieker.webgui"/> <!-- The enums. --> - <util:constant id="ROLE_USER" static-field="kieker.webgui.common.Role.ROLE_USER"/> - <util:constant id="ROLE_ADMIN" static-field="kieker.webgui.common.Role.ROLE_ADMIN"/> + <util:constant id="ROLE_GUEST" static-field="kieker.webgui.domain.User.Role.ROLE_GUEST"/> + <util:constant id="ROLE_USER" static-field="kieker.webgui.domain.User.Role.ROLE_USER"/> + <util:constant id="ROLE_ADMIN" static-field="kieker.webgui.domain.User.Role.ROLE_ADMIN"/> </beans> diff --git a/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-common-config.xml b/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-common-config.xml index b3006a954b77fc07e8dff76f300ba10d6da17e6d..3ea303170af8feea4c24f413d8ebb7ca7247673e 100644 --- a/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-common-config.xml +++ b/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-common-config.xml @@ -7,7 +7,7 @@ <property name="scopes"> <map> <entry key="view"> - <bean class="kieker.webgui.common.util.ViewScope"/> + <bean class="kieker.webgui.common.ViewScope"/> </entry> </map> </property> diff --git a/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-security-config.xml b/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-security-config.xml index 990ee3569de60ecc226fcbb2b1e419db3f848afa..7b6d72c9c392233052e738b80869e404eaf22480 100644 --- a/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-security-config.xml +++ b/Kieker.WebGUI/src/main/webapp/WEB-INF/spring-security-config.xml @@ -3,7 +3,7 @@ xmlns:beans="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd - http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> + http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.1.xsd"> <http use-expressions="true" access-denied-page="/accessDenied" > <form-login login-page="/login" default-target-url="/pages/" authentication-failure-url="/login?state=fail"/> @@ -15,12 +15,23 @@ <intercept-url pattern="/templates/**" access="denyAll"/> <!-- The admin area is only accessible by administrators. --> - <intercept-url pattern="/pages/admin/**" access="hasRole('ROLE_ADMIN')"/> - <intercept-url pattern="/faces/pages/admin/**" access="hasRole('ROLE_ADMIN')"/> + <intercept-url pattern="/pages/admin/**" access="hasRole('Administrator')"/> + <intercept-url pattern="/faces/pages/admin/**" access="hasRole('Administrator')"/> + + <!-- The is the guest area. --> + <intercept-url pattern="/pages/analysisEditor" access="isAuthenticated()"/> + <intercept-url pattern="/pages/cockpit" access="isAuthenticated()"/> + <intercept-url pattern="/faces/pages/analysisEditor" access="isAuthenticated()"/> + <intercept-url pattern="/faces/pages/cockpit" access="isAuthenticated()"/> + <intercept-url pattern="/pages/AnalysisEditorPage.xhtml" access="isAuthenticated()"/> + <intercept-url pattern="/pages/CockpitPage.xhtml" access="isAuthenticated()"/> + <intercept-url pattern="/faces/pages/AnalysisEditorPage.xhtml" access="isAuthenticated()"/> + <intercept-url pattern="/faces/pages/CockpitPage.xhtml" access="isAuthenticated()"/> <!-- The is the usual user area. --> - <intercept-url pattern="/pages/**" access="isAuthenticated()"/> - <intercept-url pattern="/faces/pages/**" access="isAuthenticated()"/> + <intercept-url pattern="/pages/**" access="hasAnyRole('User', 'Administrator')"/> + <intercept-url pattern="/faces/pages/**" access="hasAnyRole('User', 'Administrator')"/> + <!-- The root will be redirected to home via prettyfaces. --> <intercept-url pattern="/" access="isAuthenticated()" /> @@ -33,12 +44,10 @@ <authentication-provider> <jdbc-user-service data-source-ref="userDataSource" users-by-username-query=" - select name, password, enabled - from KIEKERUser where name=?" + SELECT name, password, isEnabled + FROM Users WHERE name=?" - authorities-by-username-query=" - select u.name, r.Role from KIEKERUser u, Userroles ur, Roles r - where u.name=ur.name and r.ID = ur.role and u.name=?" + authorities-by-username-query="select name, (case when isGuest then 'Guest' else (case when isUser then 'User' else 'Administrator' end) end) as ROLE from users where users.name = ?" /> </authentication-provider> </authentication-manager> diff --git a/Kieker.WebGUI/src/main/webapp/dialogs/AnalysisEditorPageDialogs.xhtml b/Kieker.WebGUI/src/main/webapp/dialogs/AnalysisEditorPageDialogs.xhtml index 3bb924951b2804fabce08565d5918c6f1e51aacb..1374ef41e89bfdbc985a7364e26f41089b27166d 100644 --- a/Kieker.WebGUI/src/main/webapp/dialogs/AnalysisEditorPageDialogs.xhtml +++ b/Kieker.WebGUI/src/main/webapp/dialogs/AnalysisEditorPageDialogs.xhtml @@ -4,7 +4,7 @@ xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui"> - <p:dialog id="manageLibrariesDlg" header="#{localizedMessages.libraries}" resizable="false" modal="true" widgetVar="manageLibrariesDialog"> + <p:dialog id="manageLibrariesDlg" header="#{localizedAnalysisEditorPageMessages.libraries}" resizable="false" modal="true" widgetVar="manageLibrariesDialog"> <h:form id="dependenciesForm"> <p:dataTable id="currentDependencies" value="#{currentAnalysisEditorBean.libraries}" var="dependency" paginator="true" rows="10" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" > diff --git a/Kieker.WebGUI/src/main/webapp/dialogs/UserManagementDialogs.xhtml b/Kieker.WebGUI/src/main/webapp/dialogs/UserManagementDialogs.xhtml index 2106604ad4feab461ae37820e2955e652920eee0..00a2a4282a9abd797e3e333dd4c8c4880e57cbc6 100644 --- a/Kieker.WebGUI/src/main/webapp/dialogs/UserManagementDialogs.xhtml +++ b/Kieker.WebGUI/src/main/webapp/dialogs/UserManagementDialogs.xhtml @@ -17,16 +17,23 @@ <p:inputText value="#{newUserBean.password}" style="width: 100%" /> - <h:outputText value="Benutzerrollen: " /> - <p:selectManyCheckbox value="#{newUserBean.roles}" layout="pageDirection" converter="roleStringConverter"> + <h:outputText value="Benutzerrolle: " /> + <p:selectOneRadio value="#{newUserBean.role}" converter="roleStringConverter"> + <f:selectItem itemLabel="Gast" itemValue="#{ROLE_GUEST}" /> <f:selectItem itemLabel="Benutzer" itemValue="#{ROLE_USER}" /> <f:selectItem itemLabel="Administrator" itemValue="#{ROLE_ADMIN}" /> - </p:selectManyCheckbox> + </p:selectOneRadio> + + <h:outputText value="Status: " /> + <p:selectOneRadio> + <f:selectItem itemLabel="Aktiviert" itemValue="#{true}" /> + <f:selectItem itemLabel="Deaktiviert" itemValue="#{false}" /> + </p:selectOneRadio> </h:panelGrid> <hr/> <div style="text-align: right"> - <p:commandButton value="#{localizedMessages.ok}" action="#{currentUserManagementBean.addUser(newUserBean.username, newUserBean.password, newUserBean.roles)}" oncomplete="newUserDlg.hide()" update=":usersListForm"/> + <p:commandButton value="#{localizedMessages.ok}" action="#{currentUserManagementBean.addUser(newUserBean.username, newUserBean.password, newUserBean.role, true)}" oncomplete="newUserDlg.hide()" update=":usersListForm"/> </div> </h:form> </p:dialog> diff --git a/Kieker.WebGUI/src/main/webapp/pages/ProjectOverviewPage.xhtml b/Kieker.WebGUI/src/main/webapp/pages/ProjectOverviewPage.xhtml index 18e9b18f249f33733c647a8c3e9e1ead61797771..dec28c8943ccb6b3509bb8df7d5b8ec7b41ab9cf 100644 --- a/Kieker.WebGUI/src/main/webapp/pages/ProjectOverviewPage.xhtml +++ b/Kieker.WebGUI/src/main/webapp/pages/ProjectOverviewPage.xhtml @@ -4,7 +4,8 @@ xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui" - xmlns:f="http://java.sun.com/jsf/core"> + xmlns:f="http://java.sun.com/jsf/core" + xmlns:c="http://java.sun.com/jsp/jstl/core"> <h:head/> @@ -27,9 +28,11 @@ <!-- Those are the menu bar entries left from the help-submenu. --> <ui:define name="furtherMenuBarEntries"> <p:submenu label="#{localizedMessages.file}"> - <p:menuitem styleClass="element-with-whitespace" icon="ui-icon-newProject" value=" #{localizedProjectOverviewMessages.newProject}" onclick="newProjectDialog.show()" ajax="true"/> - <p:menuitem styleClass="element-with-whitespace" icon="ui-icon-importProject" value=" #{localizedProjectOverviewMessages.importProject}" ajax="true" disabled="true"/> - <p:separator/> + <c:if test="#{sec:areAnyGranted('User, Administrator')}"> + <p:menuitem styleClass="element-with-whitespace" icon="ui-icon-newProject" value=" #{localizedProjectOverviewMessages.newProject}" onclick="newProjectDialog.show()" ajax="true"/> + <p:menuitem styleClass="element-with-whitespace" icon="ui-icon-importProject" value=" #{localizedProjectOverviewMessages.importProject}" ajax="true" disabled="true"/> + <p:separator/> + </c:if> <p:menuitem styleClass="element-with-whitespace" icon="ui-icon-reload" value=" #{localizedProjectOverviewMessages.refreshProjectsList}" update=":projectsListForm" action="#{currentProjectOverviewBean.updateLists()}" ajax="true"/> <p:separator/> <p:menuitem styleClass="element-with-whitespace" icon="ui-icon-settings" value=" #{localizedMessages.settings}" onclick="settingsDlg.show()" ajax="true"/> @@ -49,31 +52,41 @@ <p:menuitem icon="ui-icon-analysisEditor" id="openButton" value=" #{localizedMessages.analysisEditor}" styleClass="element-with-whitespace" ajax="false" outcome="analysisEditor"> <f:param name="projectName" value="#{project}"/> </p:menuitem> - <p:menuitem icon="ui-icon-analysis" id="controlAnalysis" styleClass="element-with-whitespace" value=" #{localizedMessages.analysis}" ajax="false" outcome="controller"> - <f:param name="projectName" value="#{project}"/> - </p:menuitem> + <c:if test="#{sec:areAnyGranted('User, Administrator')}"> + <p:menuitem icon="ui-icon-analysis" id="controlAnalysis" styleClass="element-with-whitespace" value=" #{localizedMessages.analysis}" ajax="false" outcome="controller"> + <f:param name="projectName" value="#{project}"/> + </p:menuitem> + </c:if> <p:separator/> - <p:menuitem icon="ui-icon-cockpitEditor" id="editAnalysisViews" styleClass="element-with-whitespace" value=" #{localizedMessages.cockpitEditor}" ajax="false" outcome="cockpitEditor" > - <f:param name="projectName" value="#{project}"/> - </p:menuitem> + <c:if test="#{sec:areAnyGranted('User, Administrator')}"> + <p:menuitem icon="ui-icon-cockpitEditor" id="editAnalysisViews" styleClass="element-with-whitespace" value=" #{localizedMessages.cockpitEditor}" ajax="false" outcome="cockpitEditor" > + <f:param name="projectName" value="#{project}"/> + </p:menuitem> + </c:if> <p:menuitem icon="ui-icon-cockpit" id="showAnalysis" styleClass="element-with-whitespace" value=" #{localizedMessages.cockpit}" ajax="false" outcome="cockpit"> <f:param name="projectName" value="#{project}"/> </p:menuitem> - <p:separator/> - <p:menuitem id="copyButton" icon="ui-icon-copy" styleClass="element-with-whitespace" value=" #{localizedProjectOverviewMessages.copyProject}" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="copyProjectDialog.show()"/> - <p:menuitem id="renameButton" icon="ui-icon-edit" styleClass="element-with-whitespace" value=" #{localizedProjectOverviewMessages.renameProject}" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="renameProjectDialog.show()" disabled="true"/> - <p:menuitem id="deleteButton" icon="ui-icon-delete" styleClass="element-with-whitespace" value=" #{localizedProjectOverviewMessages.deleteProject}" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="deleteProjectDialog.show()" disabled="true"/> + <c:if test="#{sec:areAnyGranted('User, Administrator')}"> + <p:separator/> + <p:menuitem id="copyButton" icon="ui-icon-copy" styleClass="element-with-whitespace" value=" #{localizedProjectOverviewMessages.copyProject}" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="copyProjectDialog.show()"/> + <p:menuitem id="renameButton" icon="ui-icon-edit" styleClass="element-with-whitespace" value=" #{localizedProjectOverviewMessages.renameProject}" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="renameProjectDialog.show()" disabled="true"/> + <p:menuitem id="deleteButton" icon="ui-icon-delete" styleClass="element-with-whitespace" value=" #{localizedProjectOverviewMessages.deleteProject}" action="#{currentProjectOverviewBean.setProjectName(project)}" onclick="deleteProjectDialog.show()" disabled="true"/> + </c:if> </p:menu> </p:column> <p:column headerText="#{localizedProjectOverviewMessages.state}" style="text-align: center" sortBy="#{projectsBean.getAnalysisControllerState(project)}"> <h:outputText value="#{projectsBean.getAnalysisControllerState(project)}"/> </p:column> + <p:column headerText="#{localizedProjectOverviewMessages.owner}" style="text-align: center"> + <h:outputText value="N/A" /> + </p:column> + <p:column headerText="#{localizedProjectOverviewMessages.lastModification}" sortBy="#{projectsBean.getCurrTimeStamp(project)}" style="text-align: center"> <h:outputText value="#{projectsBean.getCurrTimeStamp(project)}" /> </p:column> - <p:column headerText="#{localizedProjectOverviewMessages.owner}" style="text-align: center" rendered="false"> + <p:column headerText="#{localizedProjectOverviewMessages.lastEditor}" style="text-align: center"> <h:outputText value="N/A" /> </p:column> diff --git a/Kieker.WebGUI/src/main/webapp/pages/admin/UserManagementPage.xhtml b/Kieker.WebGUI/src/main/webapp/pages/admin/UserManagementPage.xhtml index b44ced63add34c0e6cf1307409fe478788fce373..249419492bf20f530dd95a666857a8f2e6b8f33e 100644 --- a/Kieker.WebGUI/src/main/webapp/pages/admin/UserManagementPage.xhtml +++ b/Kieker.WebGUI/src/main/webapp/pages/admin/UserManagementPage.xhtml @@ -48,8 +48,8 @@ </p:menu> </p:column> - <p:column headerText="#{localizedUserManagementMessages.userroles}" sortBy="#{user.roles}"> - #{user.roles} + <p:column headerText="#{localizedUserManagementMessages.userrole}" sortBy="#{user.role}"> + #{user.role} </p:column> <p:column headerText="#{localizedUserManagementMessages.enabled}" sortBy="#{user.enabled}" style="text-align: center"> diff --git a/Kieker.WebGUI/src/main/webapp/templates/PagesTemplate.xhtml b/Kieker.WebGUI/src/main/webapp/templates/PagesTemplate.xhtml index 1c09d653f4d0a7ea9e3cad989a6270688c389f21..da0139079fd67133218f876906dcbcfa3a9faa8d 100644 --- a/Kieker.WebGUI/src/main/webapp/templates/PagesTemplate.xhtml +++ b/Kieker.WebGUI/src/main/webapp/templates/PagesTemplate.xhtml @@ -30,17 +30,21 @@ <p:button styleClass="perspective-button" icon="ui-icon-analysisEditor" value="#{localizedMessages.analysisEditor}" outcome="analysisEditor" disabled="#{pagename == 'analysisEditor' or empty projectName}"> <f:param name="projectName" value="#{projectName}" rendered="#{not empty projectName}"/> </p:button> - <p:button styleClass="perspective-button" icon="ui-icon-analysis" value="#{localizedMessages.analysis}" outcome="controller" disabled="#{pagename == 'controller' or empty projectName}"> - <f:param name="projectName" value="#{projectName}" rendered="#{not empty projectName}"/> - </p:button> + <c:if test="#{sec:areAnyGranted('User, Administrator')}"> + <p:button styleClass="perspective-button" icon="ui-icon-analysis" value="#{localizedMessages.analysis}" outcome="controller" disabled="#{pagename == 'controller' or empty projectName}"> + <f:param name="projectName" value="#{projectName}" rendered="#{not empty projectName}"/> + </p:button> + </c:if> <p:separator/> - <p:button styleClass="perspective-button" icon="ui-icon-cockpitEditor" value="#{localizedMessages.cockpitEditor}" outcome="cockpitEditor" disabled="#{pagename == 'cockpitEditor' or empty projectName}"> - <f:param name="projectName" value="#{projectName}" rendered="#{not empty projectName}"/> - </p:button> + <c:if test="#{sec:areAnyGranted('User, Administrator')}"> + <p:button styleClass="perspective-button" icon="ui-icon-cockpitEditor" value="#{localizedMessages.cockpitEditor}" outcome="cockpitEditor" disabled="#{pagename == 'cockpitEditor' or empty projectName}"> + <f:param name="projectName" value="#{projectName}" rendered="#{not empty projectName}"/> + </p:button> + </c:if> <p:button styleClass="perspective-button" icon="ui-icon-cockpit" value="#{localizedMessages.cockpit}" outcome="cockpit" disabled="#{pagename == 'cockpit' or empty projectName}"> <f:param name="projectName" value="#{projectName}" rendered="#{not empty projectName}"/> </p:button> - <c:if test="#{sec:areAnyGranted('ROLE_ADMIN')}"> + <c:if test="#{sec:areAnyGranted('Administrator')}"> <p:separator/> <p:button styleClass="perspective-button" icon="ui-icon-userManagement" value="User Management" outcome="userManagement" disabled="#{pagename == 'userManagement'}" /> </c:if> @@ -57,7 +61,7 @@ <p:menuitem styleClass="element-with-whitespace" icon="ui-icon-about" value=" #{localizedMessages.about}" onclick="aboutDlg.show()" ajax="true"/> </p:submenu> - <p:menuitem styleClass="logOutButton element-with-whitespace" icon="ui-icon-logout" value=" #{userBean.username}" ajax="true" url="#{request.contextPath}/j_spring_security_logout"/> + <p:menuitem styleClass="logOutButton element-with-whitespace" icon="ui-icon-logout" value=" #{userBean.username} (#{userBean.userrole})" ajax="true" url="#{request.contextPath}/j_spring_security_logout"/> </p:menubar> <ui:insert name="furtherMenuBar"/> </h:form>