/*******************************************************************************
* Copyright (c) 2008-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.context;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Set;
import java.util.Vector;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaModelException;
import org.eclipse.jpt.common.utility.internal.iterable.CompositeIterable;
import org.eclipse.jpt.common.utility.internal.iterable.FilteringIterable;
import org.eclipse.jpt.common.utility.internal.iterable.IterableTools;
import org.eclipse.jpt.common.utility.internal.iterable.SubIterableWrapper;
import org.eclipse.jpt.common.utility.internal.iterable.TransformationIterable;
import org.eclipse.jpt.common.utility.internal.iterator.CloneListIterator;
import org.eclipse.jpt.common.utility.internal.predicate.PredicateTools;
import org.eclipse.jpt.common.utility.transformer.Transformer;
import org.eclipse.jpt.jpa.core.context.Generator;
import org.eclipse.jpt.jpa.core.context.java.JavaGenerator;
import org.eclipse.jpt.jpa.core.context.persistence.ClassRef;
import org.eclipse.jpt.jpa.core.context.persistence.Persistence;
import org.eclipse.jpt.jpa.core.internal.GenericJpaJpqlQueryHelper;
import org.eclipse.jpt.jpa.core.internal.context.persistence.AbstractPersistenceUnit;
import org.eclipse.jpt.jpa.core.internal.jpa1.context.persistence.GenericClassRef;
import org.eclipse.jpt.jpa.core.jpql.JpaJpqlQueryHelper;
import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistenceUnit;
import org.eclipse.wst.validation.internal.provisional.core.IMessage;
import org.eclipse.wst.validation.internal.provisional.core.IReporter;
import org.jboss.tools.hibernate.jpt.core.internal.HibernateJpaProject;
import org.jboss.tools.hibernate.jpt.core.internal.HibernateJptPlugin;
import org.jboss.tools.hibernate.jpt.core.internal.context.basic.BasicHibernateProperties;
import org.jboss.tools.hibernate.jpt.core.internal.context.basic.Hibernate;
import org.jboss.tools.hibernate.jpt.core.internal.context.basic.HibernatePersistenceUnitProperties;
import org.jboss.tools.hibernate.jpt.core.internal.context.java.HibernatePackageInfo;
import org.jboss.tools.hibernate.jpt.core.internal.context.java.JavaTypeDef;
import org.jboss.tools.hibernate.jpt.core.internal.context.persistence.HibernateClassRef;
import org.jboss.tools.hibernate.jpt.core.internal.context.persistence.HibernatePersistenceUnitPropertiesBuilder;
import org.jboss.tools.hibernate.jpt.core.internal.validation.HibernateJpaValidationMessage;
/**
* @author Dmitry Geraskov
*
*/
public class HibernatePersistenceUnit extends AbstractPersistenceUnit
implements Messages, Hibernate {
public String TYPE_DEF_LIST = "typeDefs"; //$NON-NLS-1$
private HibernatePersistenceUnitProperties hibernateProperties;
/* global type def definitions, defined elsewhere in model */
protected final Vector<JavaTypeDef> typeDefs = new Vector<JavaTypeDef>();
/**
* @param parent
* @param persistenceUnit
*/
public HibernatePersistenceUnit(Persistence parent,
XmlPersistenceUnit persistenceUnit) {
super(parent, persistenceUnit);
}
@Override
public HibernateJpaProject getJpaProject() {
return (HibernateJpaProject)super.getJpaProject();
}
@Override
protected void addNonUpdateAspectNamesTo(Set<String> nonUpdateAspectNames) {
super.addNonUpdateAspectNamesTo(nonUpdateAspectNames);
nonUpdateAspectNames.add(this.TYPE_DEF_LIST);
}
@Override
public void update(IProgressMonitor monitor) {
this.typeDefs.clear();
super.update(monitor);
this.fireListChanged(this.TYPE_DEF_LIST, this.typeDefs);
}
@Override
protected void initializeProperties() {
super.initializeProperties();
this.hibernateProperties = ((HibernatePersistenceUnitPropertiesBuilder)this.getContextModelFactory())
.buildHibernatePersistenceUnitProperties(this);
}
@Override
public void propertyRemoved(String propertyName) {
super.propertyRemoved(propertyName);
this.hibernateProperties.propertyRemoved(propertyName);
}
@Override
public void propertyValueChanged(String propertyName, String newValue) {
super.propertyValueChanged(propertyName, newValue);
this.hibernateProperties.propertyValueChanged(propertyName, newValue);
}
// ******** Behavior *********
public BasicHibernateProperties getHibernatePersistenceUnitProperties() {
return this.hibernateProperties;
}
// ******** Type Def *********
public ListIterator<JavaTypeDef> typeDefs() {
return new CloneListIterator<JavaTypeDef>(this.typeDefs,CloneListIterator.Adapter.ReadOnly.<JavaTypeDef>instance());
}
public int typeDefsSize() {
return this.typeDefs.size();
}
public void addTypeDef(JavaTypeDef typeDef) {
this.typeDefs.add(typeDef);
}
public String[] uniqueTypeDefNames() {
HashSet<String> names = new HashSet<String>(this.typeDefs.size());
this.addNonNullTypeDefNamesTo(names);
return names.toArray(new String[names.size()]);
}
public boolean hasTypeDef(String name) {
for (Iterator<JavaTypeDef> stream = this.typeDefs(); stream.hasNext(); ) {
String typeDefName = stream.next().getName();
if (name.equals(typeDefName)) {
return true;
}
}
return false;
}
protected void addNonNullTypeDefNamesTo(Set<String> names) {
for (Iterator<JavaTypeDef> stream = this.typeDefs(); stream.hasNext(); ) {
String typeDefName = stream.next().getName();
if (typeDefName != null) {
names.add(typeDefName);
}
}
}
/**
* Return the names of all the Java classes and packages in the JPA project that are
* mapped (i.e. have the appropriate annotation etc.) but not specified
* in the persistence unit.
*/
// FIXME Find what was changed related to this function
// @SuppressWarnings("unchecked")
// @Override
// protected Iterable<String> getImpliedClassNames_() {
// return new CompositeIterable<String>(super.getImpliedClassNames_(),
// new FilteringIterable<String>(this.getJpaProject().getMappedJavaSourcePackagesNames()) {
// @Override
// protected boolean accept(String mappedPackageName) {
// return !HibernatePersistenceUnit.this.specifiedPackageInfo(mappedPackageName);
// }
// }
// );
// }
/**
* Ignore implied class refs and jar files.
*/
public boolean specifiedPackageInfo(String typeName) {
for (ClassRef classRef : this.getSpecifiedClassRefs()) {
if (classRef.isFor(typeName)) {
return true;
}
}
return false;
}
/**
* Ignore implied class refs and jar files.
*/
public boolean impliedPackageInfo(String typeName) {
for (ClassRef classRef : this.getImpliedClassRefs()) {
if (classRef.isFor(typeName)) {
return true;
}
}
return false;
}
// ********** Validation ***********************************************
@Override
protected void validateProperties(List<IMessage> messages, IReporter reporter) {
String configFile = this.hibernateProperties.getConfigurationFile();
if (configFile != null && configFile.length() > 0){
IPath path = new Path(configFile);
try {
IJavaProject jp = getJpaProject().getJavaProject();
IPackageFragmentRoot[] pfrs = jp.getPackageFragmentRoots();
for (int i = 0; i < pfrs.length; i++) {
if (pfrs[i].isArchive()) continue;
if (((IContainer)pfrs[i].getResource()).findMember(path) != null){
return;
}
}
} catch (JavaModelException e) {
HibernateJptPlugin.logException(e);
}
IJavaProject jProject = getJpaProject().getJavaProject();
IResource res = null;
if (jProject != null){
try {
IPackageFragmentRoot[] allPackageFragmentRoots = jProject.getAllPackageFragmentRoots();
for (IPackageFragmentRoot iPackageFragmentRoot : allPackageFragmentRoots) {
if (!iPackageFragmentRoot.isArchive()){
IResource sourceFolder = iPackageFragmentRoot.getResource();
if (sourceFolder instanceof IContainer) {
IContainer folder = (IContainer) sourceFolder;
if ((res = folder.findMember(path)) != null){
break;
}
}
}
}
} catch (JavaModelException e) {
//ignore
}
}
if (res != null) {
int resType= res.getType();
if (resType != IResource.FILE) {
Property prop = getProperty(BasicHibernateProperties.HIBERNATE_CONFIG_FILE);
IMessage message = HibernateJpaValidationMessage.buildMessage(IMessage.HIGH_SEVERITY,
NOT_A_FILE, new String[]{configFile}, getResource());
message.setLineNo(prop.getValidationTextRange().getLineNumber());
messages.add(message);
}
} else {
Property prop = getProperty(BasicHibernateProperties.HIBERNATE_CONFIG_FILE);
IMessage message = HibernateJpaValidationMessage.buildMessage(IMessage.HIGH_SEVERITY,
CONFIG_FILE_NOT_FOUND, new String[]{configFile}, getResource());
message.setLineNo(prop.getValidationTextRange().getLineNumber());
messages.add(message);
}
}
}
@Override
public JpaJpqlQueryHelper createJpqlQueryHelper() {
return new GenericJpaJpqlQueryHelper(this.getJpaPlatform().getJpqlGrammar());
}
@SuppressWarnings("unchecked")
protected Iterable<Generator> getAllJavaGenerators() {
return IterableTools.concatenate(
IterableTools.concatenate(super.getAllJavaGenerators()),
new CompositeIterable<JavaGenerator>(this.getAllPackageInfoMappingGeneratorLists()));
}
/**
* @return
*/
protected Iterable<Iterable<JavaGenerator>> getAllPackageInfoMappingGeneratorLists() {
return new TransformationIterable<HibernatePackageInfo, Iterable<JavaGenerator>>(
this.getClassRefPackageInfos_(),
new Transformer<HibernatePackageInfo, Iterable<JavaGenerator>>() {
@Override
public Iterable<JavaGenerator> transform(HibernatePackageInfo o) {
return new SubIterableWrapper<Generator, JavaGenerator>(this.transform_(o));
}
protected Iterable<Generator> transform_(HibernatePackageInfo o) {
return o.getGeneratorContainer().getGenerators();
}
}
);
}
protected Iterable<HibernatePackageInfo> getClassRefPackageInfos_() {
return new FilteringIterable<HibernatePackageInfo>(
new TransformationIterable<HibernateClassRef, HibernatePackageInfo>(
new SubIterableWrapper<ClassRef,HibernateClassRef>(this.getClassRefs()),
new Transformer<GenericClassRef, HibernatePackageInfo>() {
@Override
public HibernatePackageInfo transform(GenericClassRef classRef) {
if (classRef instanceof HibernateClassRef) {
return ((HibernateClassRef)classRef).getJavaPackageInfo();
}
return null;
}
}
),
PredicateTools.isNotNull()
);
}
}