/*******************************************************************************
* Copyright (c) 2009 Red Hat, Inc.
* Distributed under license by Red Hat, Inc. All rights reserved.
* This program is made available under the terms of the
* Eclipse Public License v1.0 which accompanies this distribution,
* and is available at http://www.eclipse.org/legal/epl-v10.html
*
* Contributor:
* Red Hat, Inc. - initial API and implementation
******************************************************************************/
package org.jboss.tools.hibernate.jpt.core.internal.resource.java;
import java.util.List;
import org.eclipse.jdt.core.dom.CompilationUnit;
import org.eclipse.jpt.common.core.internal.resource.java.source.SourceAnnotation;
import org.eclipse.jpt.common.core.internal.utility.jdt.CombinationIndexedDeclarationAnnotationAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.ConversionDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.ElementIndexedAnnotationAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.EnumDeclarationAnnotationElementAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.ShortCircuitAnnotationElementAdapter;
import org.eclipse.jpt.common.core.internal.utility.jdt.SimpleDeclarationAnnotationAdapter;
import org.eclipse.jpt.common.core.resource.java.JavaResourceModel;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.core.utility.jdt.AnnotatedElement;
import org.eclipse.jpt.common.core.utility.jdt.AnnotationAdapter;
import org.eclipse.jpt.common.core.utility.jdt.AnnotationElementAdapter;
import org.eclipse.jpt.common.core.utility.jdt.DeclarationAnnotationAdapter;
import org.eclipse.jpt.common.core.utility.jdt.DeclarationAnnotationElementAdapter;
import org.eclipse.jpt.common.core.utility.jdt.IndexedAnnotationAdapter;
import org.eclipse.jpt.common.core.utility.jdt.IndexedDeclarationAnnotationAdapter;
import org.eclipse.jpt.common.utility.internal.ObjectTools;
import org.eclipse.jpt.common.utility.internal.iterable.EmptyListIterable;
import org.eclipse.jpt.common.utility.iterable.ListIterable;
import org.eclipse.jpt.jpa.core.resource.java.QueryHintAnnotation;
import org.jboss.tools.hibernate.jpt.core.internal.context.CacheModeType;
import org.jboss.tools.hibernate.jpt.core.internal.context.FlushModeType;
import org.jboss.tools.hibernate.jpt.core.internal.context.basic.Hibernate;
/**
* @author Dmitry Geraskov
*
*/
public class HibernateSourceNamedQueryAnnotation extends SourceAnnotation
implements HibernateNamedQueryAnnotation {
public static final DeclarationAnnotationAdapter DECLARATION_ANNOTATION_ADAPTER = new SimpleDeclarationAnnotationAdapter(ANNOTATION_NAME);
private static final DeclarationAnnotationAdapter CONTAINER_DECLARATION_ANNOTATION_ADAPTER = new SimpleDeclarationAnnotationAdapter(Hibernate.NAMED_QUERIES);
private DeclarationAnnotationElementAdapter<String> nameDeclarationAdapter;
private AnnotationElementAdapter<String> nameAdapter;
private String name;
TextRange nameTextRange;
private DeclarationAnnotationElementAdapter<String> queryDeclarationAdapter;
private AnnotationElementAdapter<String> queryAdapter;
private String query;
List<TextRange> queryTextRanges;
// TextRange queryTextRange;
private DeclarationAnnotationElementAdapter<String> flushModeDeclarationAdapter;
private AnnotationElementAdapter<String> flushModeAdapter;
private FlushModeType flushMode;
TextRange flushModeTextRange;
private DeclarationAnnotationElementAdapter<String> cacheModeDeclarationAdapter;
private AnnotationElementAdapter<String> cacheModeAdapter;
private CacheModeType cacheMode;
TextRange cacheModeTextRange;
private DeclarationAnnotationElementAdapter<Boolean> cacheableDeclarationAdapter;
private AnnotationElementAdapter<Boolean> cacheableAdapter;
private Boolean cacheable;
private DeclarationAnnotationElementAdapter<String> cacheRegionDeclarationAdapter;
private AnnotationElementAdapter<String> cacheRegionAdapter;
private String cacheRegion;
private DeclarationAnnotationElementAdapter<Integer> fetchSizeDeclarationAdapter;
private AnnotationElementAdapter<Integer> fetchSizeAdapter;
private Integer fetchSize;
private DeclarationAnnotationElementAdapter<Integer> timeoutDeclarationAdapter;
private AnnotationElementAdapter<Integer> timeoutAdapter;
private Integer timeout;
private DeclarationAnnotationElementAdapter<String> commentDeclarationAdapter;
private AnnotationElementAdapter<String> commentAdapter;
private String comment;
private DeclarationAnnotationElementAdapter<Boolean> readOnlyDeclarationAdapter;
private AnnotationElementAdapter<Boolean> readOnlyAdapter;
private Boolean readOnly;
private CompilationUnit astRoot;
HibernateSourceNamedQueryAnnotation(JavaResourceModel parent, AnnotatedElement annotatedElement, DeclarationAnnotationAdapter daa, AnnotationAdapter annotationAdapter) {
super(parent, annotatedElement, daa, annotationAdapter);
this.nameDeclarationAdapter = this.buildNameAdapter(daa);
this.nameAdapter = this.buildAdapter(this.nameDeclarationAdapter);
this.queryDeclarationAdapter = this.buildQueryAdapter(daa);
this.queryAdapter = this.buildAdapter(this.queryDeclarationAdapter);
this.flushModeDeclarationAdapter = this.buildFlushModeAdapter(daa);
this.flushModeAdapter = new ShortCircuitAnnotationElementAdapter<String>(annotatedElement, this.flushModeDeclarationAdapter);
this.cacheModeDeclarationAdapter = this.buildCacheModeAdapter(daa);
this.cacheModeAdapter = new ShortCircuitAnnotationElementAdapter<String>(annotatedElement, this.cacheModeDeclarationAdapter);
this.cacheableDeclarationAdapter = this.buildCacheableAdapter(daa);
this.cacheableAdapter = new ShortCircuitAnnotationElementAdapter<Boolean>(annotatedElement, this.cacheableDeclarationAdapter);
this.cacheRegionDeclarationAdapter = this.buildCacheRegionAdapter(daa);
this.cacheRegionAdapter = this.buildAdapter(this.cacheRegionDeclarationAdapter);
this.fetchSizeDeclarationAdapter = this.buildFetchSizeAdapter(daa);
this.fetchSizeAdapter = new ShortCircuitAnnotationElementAdapter<Integer>(annotatedElement, this.fetchSizeDeclarationAdapter);
this.timeoutDeclarationAdapter = this.buildTimeoutAdapter(daa);
this.timeoutAdapter = new ShortCircuitAnnotationElementAdapter<Integer>(annotatedElement, this.timeoutDeclarationAdapter);
this.commentDeclarationAdapter = this.buildCommentAdapter(daa);
this.commentAdapter = new ShortCircuitAnnotationElementAdapter<String>(annotatedElement, this.commentDeclarationAdapter);
this.readOnlyDeclarationAdapter = this.buildReadOnlyAdapter(daa);
this.readOnlyAdapter = new ShortCircuitAnnotationElementAdapter<Boolean>(annotatedElement, this.readOnlyDeclarationAdapter);
}
@Override
public String getAnnotationName() {
return ANNOTATION_NAME;
}
@Override
public void initialize(CompilationUnit astRoot) {
this.astRoot = astRoot;
this.name = this.buildName(astRoot);
this.nameTextRange = this.buildNameTextRange();
this.query = this.buildQuery(astRoot);
this.queryTextRanges = this.buildQueryTextRanges(astRoot);
this.flushMode = this.buildFlushMode(astRoot);
this.flushModeTextRange = this.buildFlushModeTextRange(astRoot);
this.cacheMode = this.buildCacheMode(astRoot);
this.cacheModeTextRange = this.buildCacheModeTextRange(astRoot);
this.cacheable = this.buildCacheable(astRoot);
this.cacheRegion = this.buildCacheRegion(astRoot);
this.fetchSize = this.buildFetchSize(astRoot);
this.timeout = this.buildTimeout(astRoot);
this.comment = this.buildComment(astRoot);
this.readOnly = this.buildReadOnly(astRoot);
}
@Override
public void synchronizeWith(CompilationUnit astRoot) {
this.astRoot = astRoot;
this.syncName(this.buildName(astRoot));
this.nameTextRange = this.buildNameTextRange();
this.syncQuery(this.buildQuery(astRoot));
this.queryTextRanges = this.buildQueryTextRanges(astRoot);
this.syncFlushMode(this.buildFlushMode(astRoot));
this.flushModeTextRange = this.buildFlushModeTextRange(astRoot);
this.syncCacheMode(this.buildCacheMode(astRoot));
this.cacheModeTextRange = this.buildCacheModeTextRange(astRoot);
this.syncCacheable(this.buildCacheable(astRoot));
this.syncCacheRegion(this.buildCacheRegion(astRoot));
this.syncFetchSize(this.buildFetchSize(astRoot));
this.syncTimeout(this.buildTimeout(astRoot));
this.syncComment(this.buildComment(astRoot));
this.syncReadOnly(this.buildReadOnly(astRoot));
}
/**
* convenience method
*/
AnnotationElementAdapter<String> buildAdapter(DeclarationAnnotationElementAdapter<String> daea) {
return new ShortCircuitAnnotationElementAdapter<String>(this.annotatedElement, daea);
}
// ********** BaseNamedQueryAnnotation implementation **********
// ***** name
@Override
public String getName() {
return this.name;
}
@Override
public void setName(String name) {
if (ObjectTools.notEquals(this.name, name)) {
this.name = name;
this.nameAdapter.setValue(name);
}
}
private void syncName(String astName) {
String old = this.name;
this.name = astName;
this.firePropertyChanged(NAME_PROPERTY, old, astName);
}
private String buildName(CompilationUnit astRoot) {
return this.nameAdapter.getValue(astRoot);
}
@Override
public TextRange getNameTextRange() {
return this.nameTextRange;
}
private TextRange buildNameTextRange() {
return this.getElementTextRange(this.nameDeclarationAdapter, getAstAnnotation(astRoot));
}
// ***** query
@Override
public String getQuery() {
return this.query;
}
@Override
public void setQuery(String query) {
if (ObjectTools.notEquals(this.query, query)) {
this.query = query;
this.queryAdapter.setValue(query);
}
}
private void syncQuery(String annotationQuery) {
String old = this.query;
this.query = annotationQuery;
this.firePropertyChanged(QUERY_PROPERTY, old, annotationQuery);
}
private String buildQuery(CompilationUnit astRoot) {
return this.queryAdapter.getValue(astRoot);
}
@Override
public List<TextRange> getQueryTextRanges() {
return this.queryTextRanges;
}
private List<TextRange> buildQueryTextRanges(CompilationUnit astRoot) {
return this.getElementTextRanges(this.queryDeclarationAdapter, getAstAnnotation(astRoot));
}
// ***** hints
@Override
public ListIterable<QueryHintAnnotation> getHints() {
return EmptyListIterable.instance();
}
@Override
public int getHintsSize() {
return 0;
}
@Override
public QueryHintAnnotation hintAt(int index) {
return null;
}
@Override
public QueryHintAnnotation addHint(int index) {
return null;
}
@Override
public void moveHint(int targetIndex, int sourceIndex) {
//nothing to do
}
@Override
public void removeHint(int index) {
//nothing to do
}
// ******************** HibernateNamedQueryAnnotation implementation *************
// ***** flushMode
@Override
public FlushModeType getFlushMode() {
return this.flushMode;
}
@Override
public void setFlushMode(FlushModeType flushMode) {
if (ObjectTools.notEquals(this.flushMode, flushMode)) {
this.flushMode = flushMode;
this.flushModeAdapter.setValue(FlushModeType.toJavaAnnotationValue(flushMode));
}
}
private void syncFlushMode(FlushModeType flushMode) {
FlushModeType old = this.flushMode;
this.flushMode = flushMode;
this.firePropertyChanged(FLUSH_MODE_PROPERTY, old, flushMode);
}
private FlushModeType buildFlushMode(CompilationUnit astRoot) {
return FlushModeType.fromJavaAnnotationValue(this.flushModeAdapter.getValue(astRoot));
}
protected TextRange buildFlushModeTextRange(CompilationUnit astRoot) {
return this.getElementTextRange(this.flushModeDeclarationAdapter, getAstAnnotation(astRoot));
}
@Override
public TextRange getFlushModeTextRange() {
return this.flushModeTextRange;
}
// ***** caheMode
@Override
public CacheModeType getCacheMode() {
return this.cacheMode;
}
@Override
public void setCacheMode(CacheModeType cacheMode) {
if (ObjectTools.notEquals(this.cacheMode, cacheMode)) {
this.cacheMode = cacheMode;
this.cacheModeAdapter.setValue(CacheModeType.toJavaAnnotationValue(cacheMode));
}
}
private void syncCacheMode(CacheModeType cacheMode) {
CacheModeType old = this.cacheMode;
this.cacheMode = cacheMode;
this.firePropertyChanged(CACHE_MODE_PROPERTY, old, cacheMode);
}
private CacheModeType buildCacheMode(CompilationUnit astRoot) {
return CacheModeType.fromJavaAnnotationValue(this.cacheModeAdapter.getValue(astRoot));
}
protected TextRange buildCacheModeTextRange(CompilationUnit astRoot) {
return this.getElementTextRange(this.flushModeDeclarationAdapter, getAstAnnotation(astRoot));
}
@Override
public TextRange getCacheModeTextRange() {
return this.cacheModeTextRange;
}
//************************ cacheable *********************************
@Override
public Boolean isCacheable(){
return this.cacheable;
}
@Override
public void setCacheable(Boolean cacheable){
if (ObjectTools.notEquals(this.cacheable, cacheable)) {
this.cacheable = cacheable;
this.cacheableAdapter.setValue(cacheable);
}
}
private void syncCacheable(Boolean cacheable) {
Boolean old = this.cacheable;
this.cacheable = cacheable;
this.firePropertyChanged(CACHEABLE_PROPERTY, old, cacheable);
}
private Boolean buildCacheable(CompilationUnit astRoot) {
return this.cacheableAdapter.getValue(astRoot);
}
//************************ cacheRegion *********************************
@Override
public String getCacheRegion(){
return this.cacheRegion;
}
@Override
public void setCacheRegion(String cacheRegion){
if (ObjectTools.notEquals(this.cacheRegion, cacheRegion)) {
this.cacheRegion = cacheRegion;
this.cacheRegionAdapter.setValue(cacheRegion);
}
}
private void syncCacheRegion(String cacheRegion) {
String old = this.cacheRegion;
this.cacheRegion = cacheRegion;
this.firePropertyChanged(CACHE_REGION_PROPERTY, old, cacheRegion);
}
private String buildCacheRegion(CompilationUnit astRoot) {
return this.cacheRegionAdapter.getValue(astRoot);
}
//************************ fetchSize *********************************
@Override
public Integer getFetchSize(){
return this.fetchSize;
}
@Override
public void setFetchSize(Integer fetchSize){
if (ObjectTools.notEquals(this.fetchSize, fetchSize)) {
this.fetchSize = fetchSize;
this.fetchSizeAdapter.setValue(fetchSize);
}
}
private void syncFetchSize(Integer fetchSize) {
Integer old = this.fetchSize;
this.fetchSize = fetchSize;
this.firePropertyChanged(FETCH_SIZE_PROPERTY, old, fetchSize);
}
private Integer buildFetchSize(CompilationUnit astRoot) {
return this.fetchSizeAdapter.getValue(astRoot);
}
//************************ timeout *********************************
@Override
public Integer getTimeout(){
return this.timeout;
}
@Override
public void setTimeout(Integer timeout){
if (ObjectTools.notEquals(this.timeout, timeout)) {
this.timeout = timeout;
this.timeoutAdapter.setValue(timeout);
}
}
private void syncTimeout(Integer timeout) {
Integer old = this.timeout;
this.timeout = timeout;
this.firePropertyChanged(TIMEOUT_PROPERTY, old, timeout);
}
private Integer buildTimeout(CompilationUnit astRoot) {
return this.timeoutAdapter.getValue(astRoot);
}
//************************ comment *********************************
@Override
public String getComment(){
return this.comment;
}
@Override
public void setComment(String comment){
if (ObjectTools.notEquals(this.comment, comment)) {
this.comment = comment;
this.commentAdapter.setValue(comment);
}
}
private void syncComment(String comment) {
String old = this.comment;
this.comment = comment;
this.firePropertyChanged(COMMENT_PROPERTY, old, comment);
}
private String buildComment(CompilationUnit astRoot) {
return this.commentAdapter.getValue(astRoot);
}
//************************ readOnly *********************************
@Override
public Boolean isReadOnly(){
return this.readOnly;
}
@Override
public void setReadOnly(Boolean readOnly){
if (ObjectTools.notEquals(this.readOnly, readOnly)) {
this.readOnly = readOnly;
this.readOnlyAdapter.setValue(readOnly);
}
}
private void syncReadOnly(Boolean readOnly) {
Boolean old = this.readOnly;
this.readOnly = readOnly;
this.firePropertyChanged(READ_ONLY_PROPERTY, old, readOnly);
}
private Boolean buildReadOnly(CompilationUnit astRoot) {
return this.readOnlyAdapter.getValue(astRoot);
}
// ********** NestableAnnotation implementation **********
@Override
public boolean isUnset() {
return super.isUnset() &&
(this.name == null) &&
(this.query == null) &&
(this.flushMode == null) &&
(this.cacheMode == null) &&
(this.cacheable == null) &&
(this.cacheRegion == null) &&
(this.fetchSize == null) &&
(this.comment == null) &&
(this.readOnly == null);
}
/**
* convenience implementation of method from NestableAnnotation interface
* for subclasses
*/
@Override
public void moveAnnotation(int newIndex) {
this.getIndexedAnnotationAdapter().moveAnnotation(newIndex);
}
private IndexedAnnotationAdapter getIndexedAnnotationAdapter() {
return (IndexedAnnotationAdapter) this.annotationAdapter;
}
public static HibernateNamedQueryAnnotation createNamedQuery(JavaResourceModel parent, AnnotatedElement annotatedElement, int index) {
IndexedDeclarationAnnotationAdapter idaa = buildNamedQueryDeclarationAnnotationAdapter(index);
IndexedAnnotationAdapter iaa = buildNamedQueryAnnotationAdapter(annotatedElement, idaa);
return new HibernateSourceNamedQueryAnnotation(
parent,
annotatedElement,
idaa,
iaa);
}
protected DeclarationAnnotationElementAdapter<String> buildNameAdapter(DeclarationAnnotationAdapter daAdapter) {
return ConversionDeclarationAnnotationElementAdapter.forStrings(daAdapter, Hibernate.NAMED_QUERY__NAME);
}
protected DeclarationAnnotationElementAdapter<String> buildQueryAdapter(DeclarationAnnotationAdapter daAdapter) {
return ConversionDeclarationAnnotationElementAdapter.forStrings(daAdapter, Hibernate.NAMED_QUERY__QUERY);
}
protected DeclarationAnnotationElementAdapter<String> buildFlushModeAdapter(DeclarationAnnotationAdapter daAdapter) {
return new EnumDeclarationAnnotationElementAdapter(daAdapter, Hibernate.NAMED_QUERY__FLUSH_MODE);
}
protected DeclarationAnnotationElementAdapter<String> buildCacheModeAdapter(DeclarationAnnotationAdapter daAdapter) {
return new EnumDeclarationAnnotationElementAdapter(daAdapter, Hibernate.NAMED_QUERY__CACHE_MODE);
}
protected DeclarationAnnotationElementAdapter<Boolean> buildCacheableAdapter(DeclarationAnnotationAdapter daAdapter) {
return ConversionDeclarationAnnotationElementAdapter.forBooleans(daAdapter, Hibernate.NAMED_QUERY__CACHEABLE);
}
protected DeclarationAnnotationElementAdapter<String> buildCacheRegionAdapter(DeclarationAnnotationAdapter daAdapter){
return ConversionDeclarationAnnotationElementAdapter.forStrings(daAdapter, Hibernate.NAMED_QUERY__CACHE_REGION);
}
protected DeclarationAnnotationElementAdapter<Integer> buildFetchSizeAdapter(DeclarationAnnotationAdapter daAdapter){
return ConversionDeclarationAnnotationElementAdapter.forNumbers(daAdapter, Hibernate.NAMED_QUERY__FETCH_SIZE);
}
protected DeclarationAnnotationElementAdapter<Integer> buildTimeoutAdapter(DeclarationAnnotationAdapter daAdapter){
return ConversionDeclarationAnnotationElementAdapter.forNumbers(daAdapter, Hibernate.NAMED_QUERY__TIMEOUT);
}
protected DeclarationAnnotationElementAdapter<String> buildCommentAdapter(DeclarationAnnotationAdapter daAdapter){
return ConversionDeclarationAnnotationElementAdapter.forStrings(daAdapter, Hibernate.NAMED_QUERY__COMMENT);
}
protected DeclarationAnnotationElementAdapter<Boolean> buildReadOnlyAdapter(DeclarationAnnotationAdapter daAdapter) {
return ConversionDeclarationAnnotationElementAdapter.forBooleans(daAdapter, Hibernate.NAMED_QUERY__READ_ONLY);
}
@Override
public void toString(StringBuilder sb) {
sb.append(this.name);
}
// ********** static methods **********
protected static IndexedAnnotationAdapter buildNamedQueryAnnotationAdapter(AnnotatedElement annotatedElement, IndexedDeclarationAnnotationAdapter idaa) {
return new ElementIndexedAnnotationAdapter(annotatedElement, idaa);
}
private static IndexedDeclarationAnnotationAdapter buildNamedQueryDeclarationAnnotationAdapter(int index) {
IndexedDeclarationAnnotationAdapter idaa =
new CombinationIndexedDeclarationAnnotationAdapter(
DECLARATION_ANNOTATION_ADAPTER,
CONTAINER_DECLARATION_ANNOTATION_ADAPTER,
index,
ANNOTATION_NAME);
return idaa;
}
}