Merge pull request #3448 from yo-h/java-qldoc-add

Java: improve QLDoc completeness
This commit is contained in:
Anders Schack-Mulligen
2020-05-13 08:26:02 +02:00
committed by GitHub
20 changed files with 731 additions and 22 deletions

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates related to Javadoc conventions. */
import java
/** Holds if the given `Javadoc` contains a minimum of a few characters of text. */
@@ -29,6 +31,7 @@ class DocuRefType extends RefType {
this.isPublic()
}
/** Holds if the Javadoc for this type contains a minimum of a few characters of text. */
predicate hasAcceptableDocText() { acceptableDocText(this.getDoc().getJavadoc()) }
}
@@ -46,8 +49,10 @@ class DocuCallable extends Callable {
not this.getLocation() = this.getDeclaringType().getLocation()
}
/** Holds if the Javadoc for this callable contains a minimum of a few characters of text. */
predicate hasAcceptableDocText() { acceptableDocText(this.getDoc().getJavadoc()) }
/** Gets a string to identify whether this callable is a "method" or a "constructor". */
string toMethodOrConstructorString() {
this instanceof Method and result = "method"
or

View File

@@ -1,5 +1,8 @@
/** Provides classes and predicates related to Java naming conventions. */
import java
/** A field that is both `static` and `final`. */
class ConstantField extends Field {
ConstantField() {
this.isStatic() and

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates for working with Maven dependencies. */
import java
import semmle.code.xml.MavenPom

View File

@@ -1,3 +1,7 @@
/**
* Provides predicates for identifying unsupported JDK-internal APIs.
*/
/**
* Provides a QL encoding of the list of unsupported JDK-internal APIs at:
*

View File

@@ -1,3 +1,7 @@
/**
* Provides predicates for identifying suggested replacements for unsupported JDK-internal APIs.
*/
/**
* Provides a QL encoding of the suggested replacements for unsupported JDK-internal APIs listed at:
*

View File

@@ -1 +1,3 @@
/** DEPRECATED: use `java.qll` instead. */
import java

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates for working with Clover reports. */
import java
/**
@@ -18,6 +20,7 @@ class CloverCoverage extends XMLElement {
this.getName() = "coverage"
}
/** Gets a project for this `coverage` element. */
CloverProject getAProject() { result = this.getAChild() }
}
@@ -27,6 +30,7 @@ class CloverCoverage extends XMLElement {
* all subclasses of this class, to share code.
*/
abstract class CloverMetricsContainer extends XMLElement {
/** Gets the Clover `metrics` child element for this element. */
CloverMetrics getMetrics() { result = this.getAChild() }
}
@@ -44,42 +48,61 @@ class CloverMetrics extends XMLElement {
private float ratio(string name) { result = attr("covered" + name) / attr(name).(float) }
/** Gets the value of the `conditionals` attribute. */
int getNumConditionals() { result = attr("conditionals") }
/** Gets the value of the `coveredconditionals` attribute. */
int getNumCoveredConditionals() { result = attr("coveredconditionals") }
/** Gets the value of the `statements` attribute. */
int getNumStatements() { result = attr("statements") }
/** Gets the value of the `coveredstatements` attribute. */
int getNumCoveredStatements() { result = attr("coveredstatements") }
/** Gets the value of the `elements` attribute. */
int getNumElements() { result = attr("elements") }
/** Gets the value of the `coveredelements` attribute. */
int getNumCoveredElements() { result = attr("coveredelements") }
/** Gets the value of the `methods` attribute. */
int getNumMethods() { result = attr("methods") }
/** Gets the value of the `coveredmethods` attribute. */
int getNumCoveredMethods() { result = attr("coveredmethods") }
/** Gets the value of the `loc` attribute. */
int getNumLoC() { result = attr("loc") }
/** Gets the value of the `ncloc` attribute. */
int getNumNonCommentedLoC() { result = attr("ncloc") }
/** Gets the value of the `packages` attribute. */
int getNumPackages() { result = attr("packages") }
/** Gets the value of the `files` attribute. */
int getNumFiles() { result = attr("files") }
/** Gets the value of the `classes` attribute. */
int getNumClasses() { result = attr("classes") }
/** Gets the value of the `complexity` attribute. */
int getCloverComplexity() { result = attr("complexity") }
/** Gets the ratio of the `coveredconditionals` attribute over the `conditionals` attribute. */
float getConditionalCoverage() { result = ratio("conditionals") }
/** Gets the ratio of the `coveredstatements` attribute over the `statements` attribute. */
float getStatementCoverage() { result = ratio("statements") }
/** Gets the ratio of the `coveredelements` attribute over the `elements` attribute. */
float getElementCoverage() { result = ratio("elements") }
/** Gets the ratio of the `coveredmethods` attribute over the `methods` attribute. */
float getMethodCoverage() { result = ratio("methods") }
/** Gets the ratio of the `ncloc` attribute over the `loc` attribute. */
float getNonCommentedLoCRatio() { result = attr("ncloc") / attr("loc") }
}
@@ -100,6 +123,7 @@ class CloverPackage extends CloverMetricsContainer {
this.getName() = "package"
}
/** Gets the Java package for this Clover package. */
Package getRealPackage() { result.hasName(getAttribute("name").getValue()) }
}
@@ -122,8 +146,10 @@ class CloverClass extends CloverMetricsContainer {
this.getName() = "class"
}
/** Gets the Clover package for this Clover class. */
CloverPackage getPackage() { result = getParent().(CloverFile).getParent() }
/** Gets the Java type for this Clover class. */
RefType getRealClass() {
result
.hasQualifiedName(getPackage().getAttribute("name").getValue(),

View File

@@ -1,31 +1,50 @@
/**
* Provides classes and predicates for working with annotations in the `javax` package.
*/
import java
/*
* javax.annotation annotations
* Annotations in the package `javax.annotation`.
*/
/**
* A `@javax.annotation.Generated` annotation.
*/
class GeneratedAnnotation extends Annotation {
GeneratedAnnotation() { this.getType().hasQualifiedName("javax.annotation", "Generated") }
}
/**
* A `@javax.annotation.PostConstruct` annotation.
*/
class PostConstructAnnotation extends Annotation {
PostConstructAnnotation() { this.getType().hasQualifiedName("javax.annotation", "PostConstruct") }
}
/**
* A `@javax.annotation.PreDestroy` annotation.
*/
class PreDestroyAnnotation extends Annotation {
PreDestroyAnnotation() { this.getType().hasQualifiedName("javax.annotation", "PreDestroy") }
}
/**
* A `@javax.annotation.Resource` annotation.
*/
class ResourceAnnotation extends Annotation {
ResourceAnnotation() { this.getType().hasQualifiedName("javax.annotation", "Resource") }
}
/**
* A `@javax.annotation.Resources` annotation.
*/
class ResourcesAnnotation extends Annotation {
ResourcesAnnotation() { this.getType().hasQualifiedName("javax.annotation", "Resources") }
}
/**
* A javax.annotation.ManagedBean annotation.
* A `@javax.annotation.ManagedBean` annotation.
*/
class JavaxManagedBeanAnnotation extends Annotation {
JavaxManagedBeanAnnotation() {
@@ -34,71 +53,104 @@ class JavaxManagedBeanAnnotation extends Annotation {
}
/*
* javax.annotation.security annotations
* Annotations in the package `javax.annotation.security`.
*/
/**
* A `@javax.annotation.security.DeclareRoles` annotation.
*/
class DeclareRolesAnnotation extends Annotation {
DeclareRolesAnnotation() {
this.getType().hasQualifiedName("javax.annotation.security", "DeclareRoles")
}
}
/**
* A `@javax.annotation.security.DenyAll` annotation.
*/
class DenyAllAnnotation extends Annotation {
DenyAllAnnotation() { this.getType().hasQualifiedName("javax.annotation.security", "DenyAll") }
}
/**
* A `@javax.annotation.security.PermitAll` annotation.
*/
class PermitAllAnnotation extends Annotation {
PermitAllAnnotation() {
this.getType().hasQualifiedName("javax.annotation.security", "PermitAll")
}
}
/**
* A `@javax.annotation.security.RolesAllowed` annotation.
*/
class RolesAllowedAnnotation extends Annotation {
RolesAllowedAnnotation() {
this.getType().hasQualifiedName("javax.annotation.security", "RolesAllowed")
}
}
/**
* A `@javax.annotation.security.RunAs` annotation.
*/
class RunAsAnnotation extends Annotation {
RunAsAnnotation() { this.getType().hasQualifiedName("javax.annotation.security", "RunAs") }
}
/*
* javax.interceptor annotations
* Annotations in the package `javax.interceptor`.
*/
/**
* A `@javax.interceptor.AroundInvoke` annotation.
*/
class AroundInvokeAnnotation extends Annotation {
AroundInvokeAnnotation() { this.getType().hasQualifiedName("javax.interceptor", "AroundInvoke") }
}
/**
* A `@javax.interceptor.ExcludeClassInterceptors` annotation.
*/
class ExcludeClassInterceptorsAnnotation extends Annotation {
ExcludeClassInterceptorsAnnotation() {
this.getType().hasQualifiedName("javax.interceptor", "ExcludeClassInterceptors")
}
}
/**
* A `@javax.interceptor.ExcludeDefaultInterceptors` annotation.
*/
class ExcludeDefaultInterceptorsAnnotation extends Annotation {
ExcludeDefaultInterceptorsAnnotation() {
this.getType().hasQualifiedName("javax.interceptor", "ExcludeDefaultInterceptors")
}
}
/**
* A `@javax.interceptor.Interceptors` annotation.
*/
class InterceptorsAnnotation extends Annotation {
InterceptorsAnnotation() { this.getType().hasQualifiedName("javax.interceptor", "Interceptors") }
}
/*
* javax.jws annotations
* Annotations in the package `javax.jws`.
*/
/**
* A `@javax.jws.WebService` annotation.
*/
class WebServiceAnnotation extends Annotation {
WebServiceAnnotation() { this.getType().hasQualifiedName("javax.jws", "WebService") }
}
/*
* javax.xml.ws annotations
* Annotations in the package `javax.xml.ws`.
*/
/**
* A `@javax.xml.ws.WebServiceRef` annotation.
*/
class WebServiceRefAnnotation extends Annotation {
WebServiceRefAnnotation() { this.getType().hasQualifiedName("javax.xml.ws", "WebServiceRef") }
}

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates for working with the GWT framework. */
import java
import GwtXml
import GwtUiBinder

View File

@@ -8,26 +8,44 @@
import java
import GwtUiBinderXml
/**
* An annotation in the package `com.google.gwt.uibinder.client`.
*/
class GwtUiBinderClientAnnotation extends Annotation {
GwtUiBinderClientAnnotation() { getType().getPackage().hasName("com.google.gwt.uibinder.client") }
}
/**
* A `@com.google.gwt.uibinder.client.UiHandler` annotation.
*/
class GwtUiHandlerAnnotation extends GwtUiBinderClientAnnotation {
GwtUiHandlerAnnotation() { getType().hasName("UiHandler") }
}
/**
* A `@com.google.gwt.uibinder.client.UiField` annotation.
*/
class GwtUiFieldAnnotation extends GwtUiBinderClientAnnotation {
GwtUiFieldAnnotation() { getType().hasName("UiField") }
}
/**
* A `@com.google.gwt.uibinder.client.UiTemplate` annotation.
*/
class GwtUiTemplateAnnotation extends GwtUiBinderClientAnnotation {
GwtUiTemplateAnnotation() { getType().hasName("UiTemplate") }
}
/**
* A `@com.google.gwt.uibinder.client.UiFactory` annotation.
*/
class GwtUiFactoryAnnotation extends GwtUiBinderClientAnnotation {
GwtUiFactoryAnnotation() { getType().hasName("UiFactory") }
}
/**
* A `@com.google.gwt.uibinder.client.UiConstructor` annotation.
*/
class GwtUiConstructorAnnotation extends GwtUiBinderClientAnnotation {
GwtUiConstructorAnnotation() { getType().hasName("UiConstructor") }
}

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates for working with `*.gwt.xml` files. */
import semmle.code.xml.XML
/**

View File

@@ -1,3 +1,7 @@
/**
* Provides classes and predicates for working with OCNI (Objective-C Native Interface).
*/
import java
/**

View File

@@ -9,6 +9,9 @@ import semmle.code.java.Reflection
import semmle.code.java.dataflow.DataFlow
import semmle.code.java.dataflow.DataFlow5
/**
* A `@com.fasterxml.jackson.annotation.JsonIgnore` annoation.
*/
class JacksonJSONIgnoreAnnotation extends NonReflectiveAnnotation {
JacksonJSONIgnoreAnnotation() {
exists(AnnotationType anntp | anntp = this.getType() |
@@ -17,6 +20,7 @@ class JacksonJSONIgnoreAnnotation extends NonReflectiveAnnotation {
}
}
/** A type whose values may be serialized using the Jackson JSON framework. */
abstract class JacksonSerializableType extends Type { }
/**
@@ -34,6 +38,7 @@ library class JacksonWriteValueMethod extends Method {
}
}
/** A type whose values are explicitly serialized in a call to a Jackson method. */
library class ExplicitlyWrittenJacksonSerializableType extends JacksonSerializableType {
ExplicitlyWrittenJacksonSerializableType() {
exists(MethodAccess ma |
@@ -45,12 +50,14 @@ library class ExplicitlyWrittenJacksonSerializableType extends JacksonSerializab
}
}
/** A type used in a `JacksonSerializableField` declaration. */
library class FieldReferencedJacksonSerializableType extends JacksonSerializableType {
FieldReferencedJacksonSerializableType() {
exists(JacksonSerializableField f | usesType(f.getType(), this))
}
}
/** A type whose values may be deserialized by the Jackson JSON framework. */
abstract class JacksonDeserializableType extends Type { }
private class TypeLiteralToJacksonDatabindFlowConfiguration extends DataFlow5::Configuration {
@@ -76,6 +83,7 @@ private class TypeLiteralToJacksonDatabindFlowConfiguration extends DataFlow5::C
TypeLiteral getSourceWithFlowToJacksonDatabind() { hasFlow(DataFlow::exprNode(result), _) }
}
/** A type whose values are explicitly deserialized in a call to a Jackson method. */
library class ExplicitlyReadJacksonDeserializableType extends JacksonDeserializableType {
ExplicitlyReadJacksonDeserializableType() {
exists(TypeLiteralToJacksonDatabindFlowConfiguration conf |
@@ -84,12 +92,14 @@ library class ExplicitlyReadJacksonDeserializableType extends JacksonDeserializa
}
}
/** A type used in a `JacksonDeserializableField` declaration. */
library class FieldReferencedJacksonDeSerializableType extends JacksonDeserializableType {
FieldReferencedJacksonDeSerializableType() {
exists(JacksonDeserializableField f | usesType(f.getType(), this))
}
}
/** A field that may be serialized using the Jackson JSON framework. */
class JacksonSerializableField extends SerializableField {
JacksonSerializableField() {
exists(JacksonSerializableType superType |
@@ -101,6 +111,7 @@ class JacksonSerializableField extends SerializableField {
}
}
/** A field that may be deserialized using the Jackson JSON framework. */
class JacksonDeserializableField extends DeserializableField {
JacksonDeserializableField() {
exists(JacksonDeserializableType superType |
@@ -183,6 +194,7 @@ class JacksonMixinType extends ClassOrInterface {
}
}
/** A callable used as a Jackson mixin callable. */
class JacksonMixedInCallable extends Callable {
JacksonMixedInCallable() {
exists(JacksonMixinType mixinType | this = mixinType.getAMixedInCallable())

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates for working with Java Server Faces. */
import default
import semmle.code.java.frameworks.javaee.jsf.JSFAnnotations
import semmle.code.java.frameworks.javaee.jsf.JSFFacesContextXML
@@ -42,6 +44,7 @@ class FacesAccessibleType extends RefType {
)
}
/** Gets a method declared on this type that is visible to JSF. */
FacesVisibleMethod getAnAccessibleMethod() { result = getAMethod() }
}

View File

@@ -1,3 +1,7 @@
/**
* Provides classes and predicates for working with the JavaEE Persistence API.
*/
import java
/**
@@ -29,7 +33,7 @@ class PersistentEntity extends RefType {
}
/**
* If there is an annotation on this class defining the access type, then this is the type.
* Gets the access type for this entity as defined by a `@javax.persistence.Access` annotation, if any.
*/
string getAccessTypeFromAnnotation() {
exists(AccessAnnotation accessType | accessType = getAnAnnotation() |
@@ -43,376 +47,607 @@ class PersistentEntity extends RefType {
* Annotations in the `javax.persistence` package.
*/
/**
* A `@javax.persistence.Access` annotation.
*/
class AccessAnnotation extends Annotation {
AccessAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Access") }
}
/**
* A `@javax.persistence.AccessType` annotation.
*/
class AccessTypeAnnotation extends Annotation {
AccessTypeAnnotation() { this.getType().hasQualifiedName("javax.persistence", "AccessType") }
}
/**
* A `@javax.persistence.AssociationOverride` annotation.
*/
class AssociationOverrideAnnotation extends Annotation {
AssociationOverrideAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "AssociationOverride")
}
}
/**
* A `@javax.persistence.AssociationOverrides` annotation.
*/
class AssociationOverridesAnnotation extends Annotation {
AssociationOverridesAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "AssociationOverrides")
}
}
/**
* A `@javax.persistence.AttributeOverride` annotation.
*/
class AttributeOverrideAnnotation extends Annotation {
AttributeOverrideAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "AttributeOverride")
}
}
/**
* A `@javax.persistence.AttributeOverrides` annotation.
*/
class AttributeOverridesAnnotation extends Annotation {
AttributeOverridesAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "AttributeOverrides")
}
}
/**
* A `@javax.persistence.Basic` annotation.
*/
class BasicAnnotation extends Annotation {
BasicAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Basic") }
}
/**
* A `@javax.persistence.Cacheable` annotation.
*/
class CacheableAnnotation extends Annotation {
CacheableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Cacheable") }
}
/**
* A `@javax.persistence.CollectionTable` annotation.
*/
class CollectionTableAnnotation extends Annotation {
CollectionTableAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "CollectionTable")
}
}
/**
* A `@javax.persistence.Column` annotation.
*/
class ColumnAnnotation extends Annotation {
ColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Column") }
}
/**
* A `@javax.persistence.ColumnResult` annotation.
*/
class ColumnResultAnnotation extends Annotation {
ColumnResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "ColumnResult") }
}
/**
* A `@javax.persistence.DiscriminatorColumn` annotation.
*/
class DiscriminatorColumnAnnotation extends Annotation {
DiscriminatorColumnAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "DiscriminatorColumn")
}
}
/**
* A `@javax.persistence.DiscriminatorValue` annotation.
*/
class DiscriminatorValueAnnotation extends Annotation {
DiscriminatorValueAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "DiscriminatorValue")
}
}
/**
* A `@javax.persistence.ElementCollection` annotation.
*/
class ElementCollectionAnnotation extends Annotation {
ElementCollectionAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "ElementCollection")
}
}
/**
* A `@javax.persistence.Embeddable` annotation.
*/
class EmbeddableAnnotation extends Annotation {
EmbeddableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Embeddable") }
}
/**
* A `@javax.persistence.Embedded` annotation.
*/
class EmbeddedAnnotation extends Annotation {
EmbeddedAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Embedded") }
}
/**
* A `@javax.persistence.EmbeddedId` annotation.
*/
class EmbeddedIdAnnotation extends Annotation {
EmbeddedIdAnnotation() { this.getType().hasQualifiedName("javax.persistence", "EmbeddedId") }
}
/**
* A `@javax.persistence.Entity` annotation.
*/
class EntityAnnotation extends Annotation {
EntityAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Entity") }
}
/**
* A `@javax.persistence.EntityListeners` annotation.
*/
class EntityListenersAnnotation extends Annotation {
EntityListenersAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "EntityListeners")
}
}
/**
* A `@javax.persistence.EntityResult` annotation.
*/
class EntityResultAnnotation extends Annotation {
EntityResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "EntityResult") }
}
/**
* A `@javax.persistence.Enumerated` annotation.
*/
class EnumeratedAnnotation extends Annotation {
EnumeratedAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Enumerated") }
}
/**
* A `@javax.persistence.ExcludeDefaultListeners` annotation.
*/
class ExcludeDefaultListenersAnnotation extends Annotation {
ExcludeDefaultListenersAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "ExcludeDefaultListeners")
}
}
/**
* A `@javax.persistence.ExcludeSuperclassListeners` annotation.
*/
class ExcludeSuperclassListenersAnnotation extends Annotation {
ExcludeSuperclassListenersAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "ExcludeSuperclassListeners")
}
}
/**
* A `@javax.persistence.FieldResult` annotation.
*/
class FieldResultAnnotation extends Annotation {
FieldResultAnnotation() { this.getType().hasQualifiedName("javax.persistence", "FieldResult") }
}
/**
* A `@javax.persistence.GeneratedValue` annotation.
*/
class GeneratedValueAnnotation extends Annotation {
GeneratedValueAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "GeneratedValue")
}
}
/**
* A `@javax.persistence.Id` annotation.
*/
class IdAnnotation extends Annotation {
IdAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Id") }
}
/**
* A `@javax.persistence.IdClass` annotation.
*/
class IdClassAnnotation extends Annotation {
IdClassAnnotation() { this.getType().hasQualifiedName("javax.persistence", "IdClass") }
}
/**
* A `@javax.persistence.Inheritance` annotation.
*/
class InheritanceAnnotation extends Annotation {
InheritanceAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Inheritance") }
}
/**
* A `@javax.persistence.JoinColumn` annotation.
*/
class JoinColumnAnnotation extends Annotation {
JoinColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "JoinColumn") }
}
/**
* A `@javax.persistence.JoinColumns` annotation.
*/
class JoinColumnsAnnotation extends Annotation {
JoinColumnsAnnotation() { this.getType().hasQualifiedName("javax.persistence", "JoinColumns") }
}
/**
* A `@javax.persistence.JoinTable` annotation.
*/
class JoinTableAnnotation extends Annotation {
JoinTableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "JoinTable") }
}
/**
* A `@javax.persistence.Lob` annotation.
*/
class LobAnnotation extends Annotation {
LobAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Lob") }
}
/**
* A `@javax.persistence.ManyToMany` annotation.
*/
class ManyToManyAnnotation extends Annotation {
ManyToManyAnnotation() { this.getType().hasQualifiedName("javax.persistence", "ManyToMany") }
}
/**
* A `@javax.persistence.ManyToOne` annotation.
*/
class ManyToOneAnnotation extends Annotation {
ManyToOneAnnotation() { this.getType().hasQualifiedName("javax.persistence", "ManyToOne") }
}
/**
* A `@javax.persistence.MapKey` annotation.
*/
class MapKeyAnnotation extends Annotation {
MapKeyAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapKey") }
}
/**
* A `@javax.persistence.MapKeyClass` annotation.
*/
class MapKeyClassAnnotation extends Annotation {
MapKeyClassAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapKeyClass") }
}
/**
* A `@javax.persistence.MapKeyColumn` annotation.
*/
class MapKeyColumnAnnotation extends Annotation {
MapKeyColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapKeyColumn") }
}
/**
* A `@javax.persistence.MapKeyEnumerated` annotation.
*/
class MapKeyEnumeratedAnnotation extends Annotation {
MapKeyEnumeratedAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "MapKeyEnumerated")
}
}
/**
* A `@javax.persistence.MapKeyJoinColumn` annotation.
*/
class MapKeyJoinColumnAnnotation extends Annotation {
MapKeyJoinColumnAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "MapKeyJoinColumn")
}
}
/**
* A `@javax.persistence.MapKeyJoinColumns` annotation.
*/
class MapKeyJoinColumnsAnnotation extends Annotation {
MapKeyJoinColumnsAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "MapKeyJoinColumns")
}
}
/**
* A `@javax.persistence.MapKeyTemporal` annotation.
*/
class MapKeyTemporalAnnotation extends Annotation {
MapKeyTemporalAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "MapKeyTemporal")
}
}
/**
* A `@javax.persistence.MappedSuperclass` annotation.
*/
class MappedSuperclassAnnotation extends Annotation {
MappedSuperclassAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "MappedSuperclass")
}
}
/**
* A `@javax.persistence.MapsId` annotation.
*/
class MapsIdAnnotation extends Annotation {
MapsIdAnnotation() { this.getType().hasQualifiedName("javax.persistence", "MapsId") }
}
/**
* A `@javax.persistence.NamedNativeQueries` annotation.
*/
class NamedNativeQueriesAnnotation extends Annotation {
NamedNativeQueriesAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "NamedNativeQueries")
}
}
/**
* A `@javax.persistence.NamedNativeQuery` annotation.
*/
class NamedNativeQueryAnnotation extends Annotation {
NamedNativeQueryAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "NamedNativeQuery")
}
}
/**
* A `@javax.persistence.NamedQueries` annotation.
*/
class NamedQueriesAnnotation extends Annotation {
NamedQueriesAnnotation() { this.getType().hasQualifiedName("javax.persistence", "NamedQueries") }
}
/**
* A `@javax.persistence.NamedQuery` annotation.
*/
class NamedQueryAnnotation extends Annotation {
NamedQueryAnnotation() { this.getType().hasQualifiedName("javax.persistence", "NamedQuery") }
}
/**
* A `@javax.persistence.OneToMany` annotation.
*/
class OneToManyAnnotation extends Annotation {
OneToManyAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OneToMany") }
}
/**
* A `@javax.persistence.OneToOne` annotation.
*/
class OneToOneAnnotation extends Annotation {
OneToOneAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OneToOne") }
}
/**
* A `@javax.persistence.OrderBy` annotation.
*/
class OrderByAnnotation extends Annotation {
OrderByAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OrderBy") }
}
/**
* A `@javax.persistence.OrderColumn` annotation.
*/
class OrderColumnAnnotation extends Annotation {
OrderColumnAnnotation() { this.getType().hasQualifiedName("javax.persistence", "OrderColumn") }
}
/**
* A `@javax.persistence.PersistenceContext` annotation.
*/
class PersistenceContextAnnotation extends Annotation {
PersistenceContextAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "PersistenceContext")
}
}
/**
* A `@javax.persistence.PersistenceContexts` annotation.
*/
class PersistenceContextsAnnotation extends Annotation {
PersistenceContextsAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "PersistenceContexts")
}
}
/**
* A `@javax.persistence.PersistenceProperty` annotation.
*/
class PersistencePropertyAnnotation extends Annotation {
PersistencePropertyAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "PersistenceProperty")
}
}
/**
* A `@javax.persistence.PersistenceUnit` annotation.
*/
class PersistenceUnitAnnotation extends Annotation {
PersistenceUnitAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "PersistenceUnit")
}
}
/**
* A `@javax.persistence.PersistenceUnits` annotation.
*/
class PersistenceUnitsAnnotation extends Annotation {
PersistenceUnitsAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "PersistenceUnits")
}
}
/**
* A `@javax.persistence.PostLoad` annotation.
*/
class PostLoadAnnotation extends Annotation {
PostLoadAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostLoad") }
}
/**
* A `@javax.persistence.PostPersist` annotation.
*/
class PostPersistAnnotation extends Annotation {
PostPersistAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostPersist") }
}
/**
* A `@javax.persistence.PostRemove` annotation.
*/
class PostRemoveAnnotation extends Annotation {
PostRemoveAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostRemove") }
}
/**
* A `@javax.persistence.PostUpdate` annotation.
*/
class PostUpdateAnnotation extends Annotation {
PostUpdateAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PostUpdate") }
}
/**
* A `@javax.persistence.PrePersist` annotation.
*/
class PrePersistAnnotation extends Annotation {
PrePersistAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PrePersist") }
}
/**
* A `@javax.persistence.PreRemove` annotation.
*/
class PreRemoveAnnotation extends Annotation {
PreRemoveAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PreRemove") }
}
/**
* A `@javax.persistence.PreUpdate` annotation.
*/
class PreUpdateAnnotation extends Annotation {
PreUpdateAnnotation() { this.getType().hasQualifiedName("javax.persistence", "PreUpdate") }
}
/**
* A `@javax.persistence.PrimaryKeyJoinColumn` annotation.
*/
class PrimaryKeyJoinColumnAnnotation extends Annotation {
PrimaryKeyJoinColumnAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "PrimaryKeyJoinColumn")
}
}
/**
* A `@javax.persistence.PrimaryKeyJoinColumns` annotation.
*/
class PrimaryKeyJoinColumnsAnnotation extends Annotation {
PrimaryKeyJoinColumnsAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "PrimaryKeyJoinColumns")
}
}
/**
* A `@javax.persistence.QueryHint` annotation.
*/
class QueryHintAnnotation extends Annotation {
QueryHintAnnotation() { this.getType().hasQualifiedName("javax.persistence", "QueryHint") }
}
/**
* A `@javax.persistence.SecondaryTable` annotation.
*/
class SecondaryTableAnnotation extends Annotation {
SecondaryTableAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "SecondaryTable")
}
}
/**
* A `@javax.persistence.SecondaryTables` annotation.
*/
class SecondaryTablesAnnotation extends Annotation {
SecondaryTablesAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "SecondaryTables")
}
}
/**
* A `@javax.persistence.SequenceGenerator` annotation.
*/
class SequenceGeneratorAnnotation extends Annotation {
SequenceGeneratorAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "SequenceGenerator")
}
}
/**
* A `@javax.persistence.SqlResultSetMapping` annotation.
*/
class SqlResultSetMappingAnnotation extends Annotation {
SqlResultSetMappingAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "SqlResultSetMapping")
}
}
/**
* A `@javax.persistence.SqlResultSetMappings` annotation.
*/
class SqlResultSetMappingsAnnotation extends Annotation {
SqlResultSetMappingsAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "SqlResultSetMappings")
}
}
/**
* A `@javax.persistence.Table` annotation.
*/
class TableAnnotation extends Annotation {
TableAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Table") }
}
/**
* A `@javax.persistence.TableGenerator` annotation.
*/
class TableGeneratorAnnotation extends Annotation {
TableGeneratorAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "TableGenerator")
}
}
/**
* A `@javax.persistence.Temporal` annotation.
*/
class TemporalAnnotation extends Annotation {
TemporalAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Temporal") }
}
/**
* A `@javax.persistence.Transient` annotation.
*/
class TransientAnnotation extends Annotation {
TransientAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Transient") }
}
/**
* A `@javax.persistence.UniqueConstraint` annotation.
*/
class UniqueConstraintAnnotation extends Annotation {
UniqueConstraintAnnotation() {
this.getType().hasQualifiedName("javax.persistence", "UniqueConstraint")
}
}
/**
* A `@javax.persistence.Version` annotation.
*/
class VersionAnnotation extends Annotation {
VersionAnnotation() { this.getType().hasQualifiedName("javax.persistence", "Version") }
}

View File

@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for working with JavaEE
* persistence configuration XML files (`persistence.xml`).
*/
import java
/**
@@ -6,66 +11,94 @@ import java
class PersistenceXMLFile extends XMLFile {
PersistenceXMLFile() { this.getStem() = "persistence" }
/** Gets the root XML element in this `persistence.xml` file. */
PersistenceXmlRoot getRoot() { result = this.getAChild() }
// convenience methods
/** Gets a `shared-cache-mode` XML element nested within this `persistence.xml` file. */
SharedCacheModeElement getASharedCacheModeElement() {
result = this.getRoot().getAPersistenceUnitElement().getASharedCacheModeElement()
}
/** Gets a `property` XML element nested within this `persistence.xml` file. */
PersistencePropertyElement getAPropertyElement() {
result =
this.getRoot().getAPersistenceUnitElement().getAPropertiesElement().getAPropertyElement()
}
}
/** The root `persistence` XML element in a `persistence.xml` file. */
class PersistenceXmlRoot extends XMLElement {
PersistenceXmlRoot() {
this.getParent() instanceof PersistenceXMLFile and
this.getName() = "persistence"
}
/** Gets a `persistence-unit` child XML element of this `persistence` XML element. */
PersistenceUnitElement getAPersistenceUnitElement() { result = this.getAChild() }
}
/**
* A `persistence-unit` child XML element of the root
* `persistence` XML element in a `persistence.xml` file.
*/
class PersistenceUnitElement extends XMLElement {
PersistenceUnitElement() {
this.getParent() instanceof PersistenceXmlRoot and
this.getName() = "persistence-unit"
}
/** Gets a `shared-cache-mode` child XML element of this `persistence-unit` XML element. */
SharedCacheModeElement getASharedCacheModeElement() { result = this.getAChild() }
/** Gets a `properties` child XML element of this `persistence-unit` XML element. */
PersistencePropertiesElement getAPropertiesElement() { result = this.getAChild() }
}
/**
* A `shared-cache-mode` child XML element of a `persistence-unit`
* XML element in a `persistence.xml` file.
*/
class SharedCacheModeElement extends XMLElement {
SharedCacheModeElement() {
this.getParent() instanceof PersistenceUnitElement and
this.getName() = "shared-cache-mode"
}
/** Gets the value of this `shared-cache-mode` XML element. */
string getValue() { result = this.getACharactersSet().getCharacters() }
/** Holds if this `shared-cache-mode` XML element has the value "NONE". */
predicate isDisabled() { this.getValue() = "NONE" }
}
/**
* A `properties` child XML element of a `persistence-unit`
* XML element in a `persistence.xml` file.
*/
class PersistencePropertiesElement extends XMLElement {
PersistencePropertiesElement() {
this.getParent() instanceof PersistenceUnitElement and
this.getName() = "properties"
}
/** Gets a `property` child XML element of this `properties` XML element. */
PersistencePropertyElement getAPropertyElement() { result = this.getAChild() }
}
/**
* A `property` child XML element of a `properties`
* XML element in a `persistence.xml` file.
*/
class PersistencePropertyElement extends XMLElement {
PersistencePropertyElement() {
this.getParent() instanceof PersistencePropertiesElement and
this.getName() = "property"
}
/** see http://wiki.eclipse.org/EclipseLink/Examples/JPA/Caching */
/**
* Holds if this `property` XML element of a `persistence.xml` file
* disables the EclipseLink shared cache.
*/
predicate disablesEclipseLinkSharedCache() {
getAttribute("name").getValue() = "eclipselink.cache.shared.default" and
getAttribute("value").getValue() = "false"

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates for working with Enterprise Java Beans. */
import java
import EJBJarXML
@@ -322,10 +324,17 @@ class LocalAnnotatedBusinessInterface extends AnnotatedBusinessInterface {
* Init and create methods for session beans.
*/
/**
* A `@javax.ejb.Init` annotation.
*/
class InitAnnotation extends Annotation {
InitAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Init") }
}
/**
* A method annotated with a `@javax.ejb.Init` annotation
* that is declared in or inherited by a session EJB.
*/
class EjbAnnotatedInitMethod extends Method {
EjbAnnotatedInitMethod() {
this.getAnAnnotation() instanceof InitAnnotation and
@@ -333,21 +342,31 @@ class EjbAnnotatedInitMethod extends Method {
}
}
/**
* A method whose name starts with `ejbCreate` that is
* declared in or inherited by a session EJB.
*/
class EjbCreateMethod extends Method {
EjbCreateMethod() {
this.getName().matches("ejbCreate%") and
exists(SessionEJB ejb | ejb.inherits(this))
}
/** Gets the suffix of the method name without the `ejbCreate` prefix. */
string getMethodSuffix() { result = this.getName().substring(9, this.getName().length()) }
}
/**
* A method whose name starts with `create` that is
* declared in or inherited by a legacy EJB home interface.
*/
class EjbInterfaceCreateMethod extends Method {
EjbInterfaceCreateMethod() {
this.getName().matches("create%") and
exists(LegacyEjbHomeInterface i | i.inherits(this))
}
/** Gets the suffix of the method name without the `create` prefix. */
string getMethodSuffix() { result = this.getName().substring(6, this.getName().length()) }
}
@@ -398,6 +417,10 @@ class XmlSpecifiedRemoteInterface extends LegacyEjbRemoteInterface {
)
}
/**
* Gets a session EJB specified in the XML deployment descriptor
* for this legacy EJB remote interface.
*/
SessionEJB getAnEJB() {
exists(EjbJarXMLFile f, EjbJarSessionElement se |
se = f.getASessionElement() and
@@ -423,6 +446,7 @@ class AnnotatedRemoteHomeInterface extends LegacyEjbRemoteHomeInterface {
/** Gets an EJB to which this interface belongs. */
SessionEJB getAnEJB() { result.getAnAnnotation().(RemoteHomeAnnotation).getANamedType() = this }
/** Gets a remote interface associated with this legacy remote home interface. */
Interface getAnAssociatedRemoteInterface() { result = getACreateMethod().getReturnType() }
}
@@ -486,6 +510,7 @@ class AnnotatedLocalHomeInterface extends LegacyEjbLocalHomeInterface {
/** Gets an EJB to which this interface belongs. */
SessionEJB getAnEJB() { result.getAnAnnotation().(LocalHomeAnnotation).getANamedType() = this }
/** Gets a local interface associated with this legacy local home interface. */
Interface getAnAssociatedLocalInterface() { result = getACreateMethod().getReturnType() }
}
@@ -535,6 +560,7 @@ class RemoteInterface extends Interface {
*/
Method getARemoteMethod() { this.inherits(result) }
/** Gets a remote method implementation for this remote interface. */
Method getARemoteMethodImplementation() {
result = getARemoteMethodImplementationChecked() or
result = getARemoteMethodImplementationUnchecked()
@@ -716,127 +742,209 @@ Type inheritsMatchingCreateMethodExceptThrows(StatefulSessionEJB ejb, EjbInterfa
* Annotations in the `javax.ejb package`.
*/
/**
* A `@javax.ejb.AccessTimeout` annotation.
*/
class AccessTimeoutAnnotation extends Annotation {
AccessTimeoutAnnotation() { this.getType().hasQualifiedName("javax.ejb", "AccessTimeout") }
}
/**
* A `@javax.ejb.ActivationConfigProperty` annotation.
*/
class ActivationConfigPropertyAnnotation extends Annotation {
ActivationConfigPropertyAnnotation() {
this.getType().hasQualifiedName("javax.ejb", "ActivationConfigProperty")
}
}
/**
* A `@javax.ejb.AfterBegin` annotation.
*/
class AfterBeginAnnotation extends Annotation {
AfterBeginAnnotation() { this.getType().hasQualifiedName("javax.ejb", "AfterBegin") }
}
/**
* A `@javax.ejb.AfterCompletion` annotation.
*/
class AfterCompletionAnnotation extends Annotation {
AfterCompletionAnnotation() { this.getType().hasQualifiedName("javax.ejb", "AfterCompletion") }
}
/**
* A `@javax.ejb.ApplicationException` annotation.
*/
class ApplicationExceptionAnnotation extends Annotation {
ApplicationExceptionAnnotation() {
this.getType().hasQualifiedName("javax.ejb", "ApplicationException")
}
}
/**
* A `@javax.ejb.Asynchronous` annotation.
*/
class AsynchronousAnnotation extends Annotation {
AsynchronousAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Asynchronous") }
}
/**
* A `@javax.ejb.BeforeCompletion` annotation.
*/
class BeforeCompletionAnnotation extends Annotation {
BeforeCompletionAnnotation() { this.getType().hasQualifiedName("javax.ejb", "BeforeCompletion") }
}
/**
* A `@javax.ejb.ConcurrencyManagement` annotation.
*/
class ConcurrencyManagementAnnotation extends Annotation {
ConcurrencyManagementAnnotation() {
this.getType().hasQualifiedName("javax.ejb", "ConcurrencyManagement")
}
}
/**
* A `@javax.ejb.DependsOn` annotation.
*/
class DependsOnAnnotation extends Annotation {
DependsOnAnnotation() { this.getType().hasQualifiedName("javax.ejb", "DependsOn") }
}
/**
* A `@javax.ejb.EJB` annotation.
*/
class EJBAnnotation extends Annotation {
EJBAnnotation() { this.getType().hasQualifiedName("javax.ejb", "EJB") }
}
/**
* A `@javax.ejb.EJBs` annotation.
*/
class EJBsAnnotation extends Annotation {
EJBsAnnotation() { this.getType().hasQualifiedName("javax.ejb", "EJBs") }
}
// See above for `@Init`, `@Local`.
/**
* A `@javax.ejb.LocalBean` annotation.
*/
class LocalBeanAnnotation extends Annotation {
LocalBeanAnnotation() { this.getType().hasQualifiedName("javax.ejb", "LocalBean") }
}
// See above for `@LocalHome`.
/**
* A `@javax.ejb.Lock` annotation.
*/
class LockAnnotation extends Annotation {
LockAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Lock") }
}
/**
* A `@javax.ejb.MessageDriven` annotation.
*/
class MessageDrivenAnnotation extends Annotation {
MessageDrivenAnnotation() { this.getType().hasQualifiedName("javax.ejb", "MessageDriven") }
}
/**
* A `@javax.ejb.PostActivate` annotation.
*/
class PostActivateAnnotation extends Annotation {
PostActivateAnnotation() { this.getType().hasQualifiedName("javax.ejb", "PostActivate") }
}
/**
* A `@javax.ejb.PrePassivate` annotation.
*/
class PrePassivateAnnotation extends Annotation {
PrePassivateAnnotation() { this.getType().hasQualifiedName("javax.ejb", "PrePassivate") }
}
// See above for `@Remote`, `@RemoteHome`.
/**
* A `@javax.ejb.Remove` annotation.
*/
class RemoveAnnotation extends Annotation {
RemoveAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Remove") }
}
/**
* A `@javax.ejb.Schedule` annotation.
*/
class ScheduleAnnotation extends Annotation {
ScheduleAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Schedule") }
}
/**
* A `@javax.ejb.Schedules` annotation.
*/
class SchedulesAnnotation extends Annotation {
SchedulesAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Schedules") }
}
/**
* A `@javax.ejb.Singleton` annotation.
*/
class SingletonAnnotation extends Annotation {
SingletonAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Singleton") }
}
/**
* A `@javax.ejb.Startup` annotation.
*/
class StartupAnnotation extends Annotation {
StartupAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Startup") }
}
/**
* A `@javax.ejb.Stateful` annotation.
*/
class StatefulAnnotation extends Annotation {
StatefulAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Stateful") }
}
/**
* A `@javax.ejb.StatefulTimeout` annotation.
*/
class StatefulTimeoutAnnotation extends Annotation {
StatefulTimeoutAnnotation() { this.getType().hasQualifiedName("javax.ejb", "StatefulTimeout") }
}
/**
* A `@javax.ejb.Stateless` annotation.
*/
class StatelessAnnotation extends Annotation {
StatelessAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Stateless") }
}
/**
* A `@javax.ejb.Timeout` annotation.
*/
class TimeoutAnnotation extends Annotation {
TimeoutAnnotation() { this.getType().hasQualifiedName("javax.ejb", "Timeout") }
}
/**
* A `@javax.ejb.TransactionAttribute` annotation.
*/
class TransactionAttributeAnnotation extends Annotation {
TransactionAttributeAnnotation() {
this.getType().hasQualifiedName("javax.ejb", "TransactionAttribute")
}
}
/**
* A `@javax.ejb.TransactionManagement` annotation.
*/
class TransactionManagementAnnotation extends Annotation {
TransactionManagementAnnotation() {
this.getType().hasQualifiedName("javax.ejb", "TransactionManagement")
}
}
/**
* A `@javax.ejb.TransactionAttribute` annotation with the
* transaction attribute type set to `REQUIRED`.
*/
class RequiredTransactionAttributeAnnotation extends TransactionAttributeAnnotation {
RequiredTransactionAttributeAnnotation() {
exists(FieldRead fr |
@@ -847,6 +955,10 @@ class RequiredTransactionAttributeAnnotation extends TransactionAttributeAnnotat
}
}
/**
* A `@javax.ejb.TransactionAttribute` annotation with the
* transaction attribute type set to `REQUIRES_NEW`.
*/
class RequiresNewTransactionAttributeAnnotation extends TransactionAttributeAnnotation {
RequiresNewTransactionAttributeAnnotation() {
exists(FieldRead fr |
@@ -861,6 +973,9 @@ class RequiresNewTransactionAttributeAnnotation extends TransactionAttributeAnno
* Convenience methods.
*/
/**
* Gets the innermost `@javax.ejb.TransactionAttribute` annotation for method `m`.
*/
TransactionAttributeAnnotation getInnermostTransactionAttributeAnnotation(Method m) {
// A `TransactionAttribute` annotation can either be on the method itself,
// in which case it supersedes any such annotation on the declaring class...
@@ -876,6 +991,10 @@ TransactionAttributeAnnotation getInnermostTransactionAttributeAnnotation(Method
* Methods in the `javax.ejb package`.
*/
/**
* A method named `setRollbackOnly` declared on the
* interface `javax.ejb.EJBContext` or a subtype thereof.
*/
class SetRollbackOnlyMethod extends Method {
SetRollbackOnlyMethod() {
this.getDeclaringType().getASupertype*().hasQualifiedName("javax.ejb", "EJBContext") and

View File

@@ -1,3 +1,8 @@
/**
* Provides classes and predicates for working with
* EJB deployment descriptor XML files (`ejb-jar.xml`).
*/
import java
/**
@@ -6,161 +11,222 @@ import java
class EjbJarXMLFile extends XMLFile {
EjbJarXMLFile() { this.getStem() = "ejb-jar" }
/** Gets the root `ejb-jar` XML element of this `ejb-jar.xml` file. */
EjbJarRootElement getRoot() { result = this.getAChild() }
// Convenience methods.
/** Gets an `enterprise-beans` XML element nested within this `ejb-jar.xml` file. */
EjbJarEnterpriseBeansElement getAnEnterpriseBeansElement() {
result = this.getRoot().getAnEnterpriseBeansElement()
}
/** Gets a `session` XML element nested within this `ejb-jar.xml` file. */
EjbJarSessionElement getASessionElement() {
result = this.getAnEnterpriseBeansElement().getASessionElement()
}
/** Gets a `message-driven` XML element nested within this `ejb-jar.xml` file. */
EjbJarMessageDrivenElement getAMessageDrivenElement() {
result = this.getAnEnterpriseBeansElement().getAMessageDrivenElement()
}
/** Gets an `entity` XML element nested within this `ejb-jar.xml` file. */
EjbJarEntityElement getAnEntityElement() {
result = this.getAnEnterpriseBeansElement().getAnEntityElement()
}
}
/** The root `ejb-jar` XML element in an `ejb-jar.xml` file. */
class EjbJarRootElement extends XMLElement {
EjbJarRootElement() {
this.getParent() instanceof EjbJarXMLFile and
this.getName() = "ejb-jar"
}
/** Gets an `enterprise-beans` child XML element of this root `ejb-jar` XML element. */
EjbJarEnterpriseBeansElement getAnEnterpriseBeansElement() { result = this.getAChild() }
}
/**
* An `enterprise-beans` child XML element of the root
* `ejb-jar` XML element in an `ejb-jar.xml` file.
*/
class EjbJarEnterpriseBeansElement extends XMLElement {
EjbJarEnterpriseBeansElement() {
this.getParent() instanceof EjbJarRootElement and
this.getName() = "enterprise-beans"
}
/** Gets a `session` child XML element of this `enterprise-beans` XML element. */
EjbJarSessionElement getASessionElement() {
result = this.getAChild() and
result.getName() = "session"
}
/** Gets a `message-driven` child XML element of this `enterprise-beans` XML element. */
EjbJarMessageDrivenElement getAMessageDrivenElement() {
result = this.getAChild() and
result.getName() = "message-driven"
}
/** Gets an `entity` child XML element of this `enterprise-beans` XML element. */
EjbJarEntityElement getAnEntityElement() {
result = this.getAChild() and
result.getName() = "entity"
}
}
/**
* A child XML element of an `enterprise-beans` XML element within an `ejb-jar.xml` file.
*
* This is either a `message-driven` element, a `session` element, or an `entity` element.
*/
abstract class EjbJarBeanTypeElement extends XMLElement {
EjbJarBeanTypeElement() { this.getParent() instanceof EjbJarEnterpriseBeansElement }
/** Gets an `ejb-class` child XML element of this bean type element. */
XMLElement getAnEjbClassElement() {
result = this.getAChild() and
result.getName() = "ejb-class"
}
}
/**
* A `session` child XML element of a bean type element in an `ejb-jar.xml` file.
*/
class EjbJarSessionElement extends EjbJarBeanTypeElement {
EjbJarSessionElement() { this.getName() = "session" }
/** Gets a `business-local` child XML element of this `session` XML element. */
XMLElement getABusinessLocalElement() {
result = this.getAChild() and
result.getName() = "business-local"
}
/** Gets a `business-remote` child XML element of this `session` XML element. */
XMLElement getABusinessRemoteElement() {
result = this.getAChild() and
result.getName() = "business-remote"
}
/**
* Gets a business child XML element of this `session` XML element.
*
* This is either a `business-local` or `business-remote` element.
*/
XMLElement getABusinessElement() {
result = getABusinessLocalElement() or
result = getABusinessRemoteElement()
}
/** Gets a `remote` child XML element of this `session` XML element. */
XMLElement getARemoteElement() {
result = this.getAChild() and
result.getName() = "remote"
}
/** Gets a `home` child XML element of this `session` XML element. */
XMLElement getARemoteHomeElement() {
result = this.getAChild() and
result.getName() = "home"
}
/** Gets a `local` child XML element of this `session` XML element. */
XMLElement getALocalElement() {
result = this.getAChild() and
result.getName() = "local"
}
/** Gets a `local-home` child XML element of this `session` XML element. */
XMLElement getALocalHomeElement() {
result = this.getAChild() and
result.getName() = "local-home"
}
/** Gets a `session-type` child XML element of this `session` XML element. */
EjbJarSessionTypeElement getASessionTypeElement() { result = this.getAChild() }
/** Gets an `init-method` child XML element of this `session` XML element. */
EjbJarInitMethodElement getAnInitMethodElement() { result = this.getAChild() }
// Convenience methods.
/**
* Gets a `method-name` child XML element of a `create-method`
* XML element nested within this `session` XML element.
*/
XMLElement getACreateMethodNameElement() {
result = getAnInitMethodElement().getACreateMethodElement().getAMethodNameElement()
}
/**
* Gets a `method-name` child XML element of a `bean-method`
* XML element nested within this `session` XML element.
*/
XMLElement getABeanMethodNameElement() {
result = getAnInitMethodElement().getABeanMethodElement().getAMethodNameElement()
}
}
/**
* A `message-driven` child XML element of a bean type element in an `ejb-jar.xml` file.
*/
class EjbJarMessageDrivenElement extends EjbJarBeanTypeElement {
EjbJarMessageDrivenElement() { this.getName() = "message-driven" }
}
/**
* An `entity` child XML element of a bean type element in an `ejb-jar.xml` file.
*/
class EjbJarEntityElement extends EjbJarBeanTypeElement {
EjbJarEntityElement() { this.getName() = "entity" }
}
/** A `session-type` child XML element of a `session` element in an `ejb-jar.xml` file. */
class EjbJarSessionTypeElement extends XMLElement {
EjbJarSessionTypeElement() {
this.getParent() instanceof EjbJarSessionElement and
this.getName() = "session-type"
}
/** Holds if the value of this `session-type` XML element is "Stateful". */
predicate isStateful() { this.getACharactersSet().getCharacters() = "Stateful" }
/** Holds if the value of this `session-type` XML element is "Stateless". */
predicate isStateless() { this.getACharactersSet().getCharacters() = "Stateless" }
}
/** An `init-method` child XML element of a `session` element in an `ejb-jar.xml` file. */
class EjbJarInitMethodElement extends XMLElement {
EjbJarInitMethodElement() {
this.getParent() instanceof EjbJarSessionElement and
this.getName() = "init-method"
}
/** Gets a `create-method` child XML element of this `init-method` XML element. */
EjbJarCreateMethodElement getACreateMethodElement() {
result = this.getAChild() and
result.getName() = "create-method"
}
/** Gets a `bean-method` child XML element of this `init-method` XML element. */
EjbJarBeanMethodElement getABeanMethodElement() {
result = this.getAChild() and
result.getName() = "bean-method"
}
}
/**
* A child XML element of an `init-method` element in an `ejb-jar.xml` file.
*
* This is either a `create-method` element, or a `bean-method` element.
*/
abstract class EjbJarInitMethodChildElement extends XMLElement {
/** Gets a `method-name` child XML element of this `create-method` or `bean-method` XML element. */
XMLElement getAMethodNameElement() {
result = this.getAChild() and
result.getName() = "method-name"
}
}
/** A `create-method` child XML element of an `init-method` element in an `ejb-jar.xml` file. */
class EjbJarCreateMethodElement extends EjbJarInitMethodChildElement {
EjbJarCreateMethodElement() {
this.getParent() instanceof EjbJarInitMethodElement and
@@ -168,6 +234,7 @@ class EjbJarCreateMethodElement extends EjbJarInitMethodChildElement {
}
}
/** A `bean-method` child XML element of an `init-method` element in an `ejb-jar.xml` file. */
class EjbJarBeanMethodElement extends EjbJarInitMethodChildElement {
EjbJarBeanMethodElement() {
this.getParent() instanceof EjbJarInitMethodElement and

View File

@@ -1,10 +1,12 @@
import java
import EJB
/*
/**
* Provides classes and predicates for modeling
* EJB Programming Restrictions (see EJB 3.0 specification, section 21.1.2).
*/
import java
import EJB
/** A method or constructor that may not be called from an EJB. */
abstract class ForbiddenCallable extends Callable { }
/**
@@ -47,6 +49,7 @@ predicate ejbCalls(Callable origin, ForbiddenCallable target, Call call) {
* Specification of "forbidden callables".
*/
/** A method or constructor that may not be called by an EJB due to container interference. */
class ForbiddenContainerInterferenceCallable extends ForbiddenCallable {
ForbiddenContainerInterferenceCallable() {
this.getDeclaringType().getASupertype*().getSourceDeclaration() instanceof ClassLoaderClass or
@@ -55,18 +58,21 @@ class ForbiddenContainerInterferenceCallable extends ForbiddenCallable {
}
}
/** A method or constructor involving file input or output that may not be called by an EJB. */
class ForbiddenFileCallable extends ForbiddenCallable {
ForbiddenFileCallable() {
this.getDeclaringType().getASupertype*().getSourceDeclaration() instanceof FileInputOutputClass
}
}
/** A method or constructor involving graphics operations that may not be called by an EJB. */
class ForbiddenGraphicsCallable extends ForbiddenCallable {
ForbiddenGraphicsCallable() {
this.getDeclaringType().getASupertype*().getPackage() instanceof GraphicsPackage
}
}
/** A method or constructor involving native code that may not be called by an EJB. */
class ForbiddenNativeCallable extends ForbiddenCallable {
ForbiddenNativeCallable() {
this.isNative() or
@@ -74,32 +80,38 @@ class ForbiddenNativeCallable extends ForbiddenCallable {
}
}
/** A method or constructor involving reflection that may not be called by and EJB. */
class ForbiddenReflectionCallable extends ForbiddenCallable {
ForbiddenReflectionCallable() {
this.getDeclaringType().getASupertype*().getPackage() instanceof ReflectionPackage
}
}
/** A method or constructor involving security configuration that may not be called by an EJB. */
class ForbiddenSecurityConfigurationCallable extends ForbiddenCallable {
ForbiddenSecurityConfigurationCallable() {
this.getDeclaringType().getASupertype*().getSourceDeclaration() instanceof SecurityConfigClass
}
}
/** A method or constructor involving serialization that may not be called by an EJB. */
class ForbiddenSerializationCallable extends ForbiddenCallable {
ForbiddenSerializationCallable() { this instanceof ForbiddenSerializationMethod }
}
/** A method or constructor involving network factory operations that may not be called by an EJB. */
class ForbiddenSetFactoryCallable extends ForbiddenCallable {
ForbiddenSetFactoryCallable() { this instanceof ForbiddenSetFactoryMethod }
}
/** A method or constructor involving server socket operations that may not be called by an EJB. */
class ForbiddenServerSocketCallable extends ForbiddenCallable {
ForbiddenServerSocketCallable() {
this.getDeclaringType().getASupertype*().getSourceDeclaration() instanceof ServerSocketsClass
}
}
/** A method or constructor involving synchronization that may not be called by an EJB. */
class ForbiddenSynchronizationCallable extends ForbiddenCallable {
ForbiddenSynchronizationCallable() {
this.isSynchronized()
@@ -112,26 +124,37 @@ class ForbiddenSynchronizationCallable extends ForbiddenCallable {
}
}
/** A method or constructor involving static field access that may not be called by an EJB. */
class ForbiddenStaticFieldCallable extends ForbiddenCallable {
ForbiddenStaticFieldCallable() { exists(forbiddenStaticFieldUse(this)) }
}
/**
* Gets an access to a non-final static field in callable `c`
* that is disallowed by the EJB specification.
*/
FieldAccess forbiddenStaticFieldUse(Callable c) {
result.getEnclosingCallable() = c and
result.getField().isStatic() and
not result.getField().isFinal()
}
/** A method or constructor involving thread operations that may not be called by an EJB. */
class ForbiddenThreadingCallable extends ForbiddenCallable {
ForbiddenThreadingCallable() {
this.getDeclaringType().getASupertype*().getSourceDeclaration() instanceof ThreadingClass
}
}
/** A method or constructor referencing `this` that may not be called by an EJB. */
class ForbiddenThisCallable extends ForbiddenCallable {
ForbiddenThisCallable() { exists(forbiddenThisUse(this)) }
}
/**
* Gets an access to `this` in callable `c`
* that is disallowed by the EJB specification.
*/
ThisAccess forbiddenThisUse(Callable c) {
result.getEnclosingCallable() = c and
(
@@ -144,6 +167,7 @@ ThisAccess forbiddenThisUse(Callable c) {
* Specification of "forbidden packages".
*/
/** The package `java.lang.reflect` or a subpackage thereof. */
class ReflectionPackage extends Package {
ReflectionPackage() {
this.getName() = "java.lang.reflect" or
@@ -151,6 +175,7 @@ class ReflectionPackage extends Package {
}
}
/** The package `java.awt` or `javax.swing` or a subpackage thereof. */
class GraphicsPackage extends Package {
GraphicsPackage() {
this.getName() = "java.awt" or
@@ -160,6 +185,7 @@ class GraphicsPackage extends Package {
}
}
/** The package `java.util.concurrent` or a subpackage thereof. */
class ConcurrentPackage extends Package {
ConcurrentPackage() {
this.getName() = "java.util.concurrent" or
@@ -171,6 +197,7 @@ class ConcurrentPackage extends Package {
* Specification of "forbidden classes".
*/
/** The class `java.lang.Thread` or `java.lang.ThreadGroup`. */
class ThreadingClass extends Class {
ThreadingClass() {
this.hasQualifiedName("java.lang", "Thread") or
@@ -178,6 +205,10 @@ class ThreadingClass extends Class {
}
}
/**
* The class `java.net.ServerSocket`, `java.net.MulticastSocket`
* or `java.nio.channels.ServerSocketChannel`.
*/
class ServerSocketsClass extends Class {
ServerSocketsClass() {
this.hasQualifiedName("java.net", "ServerSocket") or
@@ -186,6 +217,10 @@ class ServerSocketsClass extends Class {
}
}
/**
* A class in the package `java.security` named `Policy`,
* `Security`, `Provider`, `Signer` or `Identity`.
*/
class SecurityConfigClass extends Class {
SecurityConfigClass() {
this.hasQualifiedName("java.security", "Policy") or
@@ -196,14 +231,17 @@ class SecurityConfigClass extends Class {
}
}
/** The class `java.lang.ClassLoader`. */
class ClassLoaderClass extends Class {
ClassLoaderClass() { this.hasQualifiedName("java.lang", "ClassLoader") }
}
/** The class `java.lang.SecurityManager`. */
class SecurityManagerClass extends Class {
SecurityManagerClass() { this.hasQualifiedName("java.lang", "SecurityManager") }
}
/** A class involving file input or output. */
class FileInputOutputClass extends Class {
FileInputOutputClass() {
this.hasQualifiedName("java.io", "File") or
@@ -222,7 +260,7 @@ class FileInputOutputClass extends Class {
* Specification of "forbidden methods".
*/
// Forbidden container interference.
/** A method that may cause EJB container interference. */
class ForbiddenContainerInterferenceMethod extends Method {
ForbiddenContainerInterferenceMethod() {
this instanceof SystemExitMethod or
@@ -236,6 +274,10 @@ class ForbiddenContainerInterferenceMethod extends Method {
}
}
/**
* A method named `exit` declared in
* the class `java.lang.System`.
*/
class SystemExitMethod extends Method {
SystemExitMethod() {
this.hasName("exit") and
@@ -249,6 +291,10 @@ class SystemExitMethod extends Method {
}
}
/**
* A method named `exit` or `halt` declared in
* the class `java.lang.Runtime` or a subclass thereof.
*/
class RuntimeExitOrHaltMethod extends Method {
RuntimeExitOrHaltMethod() {
(this.hasName("exit") or this.hasName("halt")) and
@@ -262,6 +308,10 @@ class RuntimeExitOrHaltMethod extends Method {
}
}
/**
* A method named `addShutdownHook` or `removeShutdownHook` declared in
* the class `java.lang.Runtime` or a subclass thereof.
*/
class RuntimeAddOrRemoveShutdownHookMethod extends Method {
RuntimeAddOrRemoveShutdownHookMethod() {
(this.hasName("addShutdownHook") or this.hasName("removeShutdownHook")) and
@@ -275,6 +325,10 @@ class RuntimeAddOrRemoveShutdownHookMethod extends Method {
}
}
/**
* A method named `setErr` or `setOut` declared in
* the class `java.lang.System`.
*/
class SystemSetPrintStreamMethod extends Method {
SystemSetPrintStreamMethod() {
(this.hasName("setErr") or this.hasName("setOut")) and
@@ -288,6 +342,10 @@ class SystemSetPrintStreamMethod extends Method {
}
}
/**
* A method named `setIn` declared in
* the class `java.lang.System`.
*/
class SystemSetInputStreamMethod extends Method {
SystemSetInputStreamMethod() {
this.hasName("setIn") and
@@ -301,6 +359,10 @@ class SystemSetInputStreamMethod extends Method {
}
}
/**
* A method named `getSecurityManager` declared in
* the class `java.lang.System`.
*/
class SystemGetSecurityManagerMethod extends Method {
SystemGetSecurityManagerMethod() {
this.hasName("getSecurityManager") and
@@ -313,6 +375,10 @@ class SystemGetSecurityManagerMethod extends Method {
}
}
/**
* A method named `setSecurityManager` declared in
* the class `java.lang.System`.
*/
class SystemSetSecurityManagerMethod extends Method {
SystemSetSecurityManagerMethod() {
this.hasName("setSecurityManager") and
@@ -326,6 +392,10 @@ class SystemSetSecurityManagerMethod extends Method {
}
}
/**
* A method named `inheritedChannel` declared in
* the class `java.lang.System`.
*/
class SystemInheritedChannelMethod extends Method {
SystemInheritedChannelMethod() {
this.hasName("inheritedChannel") and
@@ -338,7 +408,7 @@ class SystemInheritedChannelMethod extends Method {
}
}
// Forbidden serialization.
/** A method involving serialization that may not be called from an EJB. */
class ForbiddenSerializationMethod extends Method {
ForbiddenSerializationMethod() {
this instanceof EnableReplaceObjectMethod or
@@ -350,6 +420,10 @@ class ForbiddenSerializationMethod extends Method {
}
}
/**
* A method named `enableReplaceObject` declared in
* the class `java.io.ObjectInputStream` or a subclass thereof.
*/
class EnableReplaceObjectMethod extends Method {
EnableReplaceObjectMethod() {
this.hasName("enableReplaceObject") and
@@ -363,6 +437,10 @@ class EnableReplaceObjectMethod extends Method {
}
}
/**
* A method named `replaceObject` declared in
* the class `java.io.ObjectInputStream` or a subclass thereof.
*/
class ReplaceObjectMethod extends Method {
ReplaceObjectMethod() {
this.hasName("replaceObject") and
@@ -376,6 +454,10 @@ class ReplaceObjectMethod extends Method {
}
}
/**
* A method named `enableResolveObject` declared in
* the class `java.io.ObjectInputStream` or a subclass thereof.
*/
class EnableResolveObjectMethod extends Method {
EnableResolveObjectMethod() {
this.hasName("enableResolveObject") and
@@ -389,6 +471,10 @@ class EnableResolveObjectMethod extends Method {
}
}
/**
* A method named `resolveObject` declared in
* the class `java.io.ObjectInputStream` or a subclass thereof.
*/
class ResolveObjectMethod extends Method {
ResolveObjectMethod() {
this.hasName("resolveObject") and
@@ -402,6 +488,10 @@ class ResolveObjectMethod extends Method {
}
}
/**
* A method named `resolveClass` declared in
* the class `java.io.ObjectInputStream` or a subclass thereof.
*/
class ResolveClassMethod extends Method {
ResolveClassMethod() {
this.hasName("resolveClass") and
@@ -415,6 +505,10 @@ class ResolveClassMethod extends Method {
}
}
/**
* A method named `resolveProxyClass` declared in
* the class `java.io.ObjectInputStream` or a subclass thereof.
*/
class ResolveProxyClassMethod extends Method {
ResolveProxyClassMethod() {
this.hasName("resolveProxyClass") and
@@ -434,7 +528,7 @@ class ResolveProxyClassMethod extends Method {
}
}
// Forbidden "set factory" methods.
/** A method involving network factory operations that may not be called from an EJB. */
class ForbiddenSetFactoryMethod extends Method {
ForbiddenSetFactoryMethod() {
this instanceof SetSocketFactoryMethod or
@@ -443,6 +537,10 @@ class ForbiddenSetFactoryMethod extends Method {
}
}
/**
* A method named `setSocketFactory` declared in
* the class `java.net.ServerSocket` or a subclass thereof.
*/
class SetSocketFactoryMethod extends Method {
SetSocketFactoryMethod() {
this.hasName("setSocketFactory") and
@@ -461,6 +559,10 @@ class SetSocketFactoryMethod extends Method {
}
}
/**
* A method named `setSocketImplFactory` declared in
* the class `java.net.Socket` or a subclass thereof.
*/
class SetSocketImplFactoryMethod extends Method {
SetSocketImplFactoryMethod() {
this.hasName("setSocketImplFactory") and
@@ -479,6 +581,10 @@ class SetSocketImplFactoryMethod extends Method {
}
}
/**
* A method named `setURLStreamHandlerFactory` declared in
* the class `java.net.URL` or a subclass thereof.
*/
class SetUrlStreamHandlerFactoryMethod extends Method {
SetUrlStreamHandlerFactoryMethod() {
this.hasName("setURLStreamHandlerFactory") and
@@ -497,7 +603,7 @@ class SetUrlStreamHandlerFactoryMethod extends Method {
}
}
// Forbidden native code methods.
/** A method involving native code that may not be called by an EJB. */
class ForbiddenNativeCodeMethod extends Method {
ForbiddenNativeCodeMethod() {
this instanceof SystemOrRuntimeLoadLibraryMethod or
@@ -505,6 +611,10 @@ class ForbiddenNativeCodeMethod extends Method {
}
}
/**
* A method named `load` or `loadLibrary` declared in the class
* `java.lang.System` or `java.lang.Runtime` or a subclass thereof.
*/
class SystemOrRuntimeLoadLibraryMethod extends Method {
SystemOrRuntimeLoadLibraryMethod() {
(this.hasName("load") or this.hasName("loadLibrary")) and
@@ -525,6 +635,10 @@ class SystemOrRuntimeLoadLibraryMethod extends Method {
}
}
/**
* A method named `exec` declared in the class
* `java.lang.Runtime` or in a subclass thereof.
*/
class RuntimeExecMethod extends Method {
RuntimeExecMethod() {
this.hasName("exec") and

View File

@@ -1,3 +1,5 @@
/** Provides classes and predicates for working with Java Server Faces annotations. */
import default
/**