blob: 1e9083278b2b7136342b2df3d072ff2e7d5e85ff [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2007, 2011 Oracle. All rights reserved.
* This program and the accompanying materials are 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.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.jpa.core.internal.jpa1.context.persistence;
import java.util.List;
import org.eclipse.jpt.common.core.utility.TextRange;
import org.eclipse.jpt.common.utility.internal.iterables.EmptyListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.ListIterable;
import org.eclipse.jpt.common.utility.internal.iterables.SingleElementListIterable;
import org.eclipse.jpt.jpa.core.JpaStructureNode;
import org.eclipse.jpt.jpa.core.JptJpaCorePlugin;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceStructureNodes;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceXml;
import org.eclipse.jpt.jpa.core.internal.context.persistence.AbstractPersistenceXmlContextNode;
import org.eclipse.jpt.jpa.core.internal.validation.DefaultJpaValidationMessages;
import org.eclipse.jpt.jpa.core.internal.validation.JpaValidationMessages;
import org.eclipse.jpt.jpa.core.jpa2.context.persistence.Persistence2_0;
import org.eclipse.jpt.jpa.core.jpa2.context.persistence.PersistenceUnit2_0;
import org.eclipse.jpt.jpa.core.resource.persistence.PersistenceFactory;
import org.eclipse.jpt.jpa.core.resource.persistence.XmlPersistence;
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;
/**
* <code>persistence.xml</code> file
* <br>
* <code>persistence</code> element
*/
public class GenericPersistence
extends AbstractPersistenceXmlContextNode
implements Persistence2_0
{
protected final XmlPersistence xmlPersistence;
// The implementation here is a single persistence unit, although the API
// is for a list. We want to support multiple persistence units someday....
protected PersistenceUnit persistenceUnit;
public GenericPersistence(PersistenceXml parent, XmlPersistence xmlPersistence) {
super(parent);
this.xmlPersistence = xmlPersistence;
this.initializePersistenceUnits();
}
// ********** synchronize/update **********
@Override
public void synchronizeWithResourceModel() {
super.synchronizeWithResourceModel();
this.syncPersistenceUnits();
}
@Override
public void update() {
super.update();
this.updateNodes(this.getPersistenceUnits());
}
// ********** persistence units **********
public ListIterable<PersistenceUnit> getPersistenceUnits() {
return (this.persistenceUnit == null) ? EmptyListIterable.<PersistenceUnit>instance() : this.getPersistenceUnits_();
}
protected ListIterable<PersistenceUnit> getPersistenceUnits_() {
return new SingleElementListIterable<PersistenceUnit>(this.persistenceUnit);
}
public int getPersistenceUnitsSize() {
return (this.persistenceUnit == null) ? 0 : 1;
}
public PersistenceUnit addPersistenceUnit() {
return this.addPersistenceUnit(this.getPersistenceUnitsSize());
}
public PersistenceUnit addPersistenceUnit(int index) {
if ((index > 0) || (this.persistenceUnit != null)) {
throw new IllegalStateException("This implementation does not support multiple persistence units."); //$NON-NLS-1$
}
XmlPersistenceUnit xmlPersistenceUnit = PersistenceFactory.eINSTANCE.createXmlPersistenceUnit();
this.persistenceUnit = this.buildPersistenceUnit(xmlPersistenceUnit);
this.xmlPersistence.getPersistenceUnits().add(xmlPersistenceUnit);
this.fireItemAdded(PERSISTENCE_UNITS_LIST, index, this.persistenceUnit);
return this.persistenceUnit;
}
public void removePersistenceUnit(PersistenceUnit pu) {
if (pu != this.persistenceUnit) {
throw new IllegalArgumentException("Invalid persistence unit: " + pu); //$NON-NLS-1$
}
this.removePersistenceUnit(0);
}
public void removePersistenceUnit(int index) {
if ((index > 0) || (this.persistenceUnit == null)) {
throw new IndexOutOfBoundsException("index: " + index); //$NON-NLS-1$
}
PersistenceUnit old = this.persistenceUnit;
this.persistenceUnit.dispose();
this.persistenceUnit = null;
this.xmlPersistence.getPersistenceUnits().remove(index);
this.fireItemRemoved(PERSISTENCE_UNITS_LIST, index, old);
}
// only building one here, until we support multiple persistence units...
protected void initializePersistenceUnits() {
XmlPersistenceUnit xmlPersistenceUnit = this.getXmlPersistenceUnit();
if (xmlPersistenceUnit != null) {
this.persistenceUnit = this.buildPersistenceUnit(xmlPersistenceUnit);
}
}
protected void syncPersistenceUnits() {
XmlPersistenceUnit xmlPersistenceUnit = this.getXmlPersistenceUnit();
if (this.persistenceUnit == null) {
if (xmlPersistenceUnit != null) {
this.addPersistenceUnit_(this.buildPersistenceUnit(xmlPersistenceUnit));
}
} else {
if (xmlPersistenceUnit == null) {
this.removePersistenceUnit_();
} else {
if (this.persistenceUnit.getXmlPersistenceUnit() == xmlPersistenceUnit) {
this.persistenceUnit.synchronizeWithResourceModel();
} else {
this.removePersistenceUnit_();
this.addPersistenceUnit_(this.buildPersistenceUnit(xmlPersistenceUnit));
}
}
}
}
protected XmlPersistenceUnit getXmlPersistenceUnit() {
List<XmlPersistenceUnit> xmlPersistenceUnits = this.xmlPersistence.getPersistenceUnits();
return xmlPersistenceUnits.isEmpty() ? null : xmlPersistenceUnits.get(0);
}
protected void addPersistenceUnit_(PersistenceUnit pu) {
this.persistenceUnit = pu;
this.fireItemAdded(PERSISTENCE_UNITS_LIST, 0, pu);
}
protected void removePersistenceUnit_() {
PersistenceUnit old = this.persistenceUnit;
this.persistenceUnit = null;
old.dispose();
this.fireItemRemoved(PERSISTENCE_UNITS_LIST, 0, old);
}
protected PersistenceUnit buildPersistenceUnit(XmlPersistenceUnit xmlPersistenceUnit) {
return this.getContextNodeFactory().buildPersistenceUnit(this, xmlPersistenceUnit);
}
// ********** metamodel **********
public void initializeMetamodel() {
for (PersistenceUnit pu : this.getPersistenceUnits()) {
((PersistenceUnit2_0) pu).initializeMetamodel();
}
}
public void synchronizeMetamodel() {
for (PersistenceUnit pu : this.getPersistenceUnits()) {
((PersistenceUnit2_0) pu).synchronizeMetamodel();
}
}
public void disposeMetamodel() {
for (PersistenceUnit pu : this.getPersistenceUnits()) {
((PersistenceUnit2_0) pu).disposeMetamodel();
}
}
// ********** Persistence implementation **********
public XmlPersistence getXmlPersistence() {
return this.xmlPersistence;
}
public boolean containsOffset(int textOffset) {
return (this.xmlPersistence == null) ? false : this.xmlPersistence.containsOffset(textOffset);
}
// ********** XmlContextNode implementation **********
@Override
public PersistenceXml getParent() {
return (PersistenceXml) super.getParent();
}
protected PersistenceXml getPersistenceXml() {
return this.getParent();
}
public TextRange getValidationTextRange() {
TextRange textRange = this.xmlPersistence.getValidationTextRange();
return (textRange != null) ? textRange : this.getPersistenceXml().getValidationTextRange();
}
// ********** JpaStructureNode implementation **********
public String getId() {
return PersistenceStructureNodes.PERSISTENCE_ID;
}
public JpaStructureNode getStructureNode(int textOffset) {
for (PersistenceUnit pu : this.getPersistenceUnits()) {
if (pu.containsOffset(textOffset)) {
return pu.getStructureNode(textOffset);
}
}
return this;
}
public TextRange getSelectionTextRange() {
return this.xmlPersistence.getSelectionTextRange();
}
public void dispose() {
for (PersistenceUnit pu : this.getPersistenceUnits()) {
pu.dispose();
}
}
// ********** validation **********
@Override
public void validate(List<IMessage> messages, IReporter reporter) {
super.validate(messages, reporter);
this.validateVersion(messages);
this.checkForMultiplePersistenceUnits(messages);
this.validatePersistenceUnit(messages, reporter);
}
protected void validateVersion(List<IMessage> messages) {
if (! this.getLatestDocumentVersion().equals(this.xmlPersistence.getVersion())) {
messages.add(
DefaultJpaValidationMessages.buildMessage(
IMessage.LOW_SEVERITY,
JpaValidationMessages.XML_VERSION_NOT_LATEST,
this,
this.xmlPersistence.getVersionTextRange()));
}
}
protected String getLatestDocumentVersion() {
return this.getJpaPlatform().getMostRecentSupportedResourceType(
JptJpaCorePlugin.PERSISTENCE_XML_CONTENT_TYPE).getVersion();
}
/**
* extraneous persistence units can be
* accessed through the XmlPersistence resource object
*/
protected void checkForMultiplePersistenceUnits(List<IMessage> messages) {
if (this.xmlPersistence.getPersistenceUnits().size() > 1) {
messages.add(
DefaultJpaValidationMessages.buildMessage(
IMessage.NORMAL_SEVERITY,
JpaValidationMessages.PERSISTENCE_MULTIPLE_PERSISTENCE_UNITS,
this,
this.getValidationTextRange()
)
);
}
}
protected void validatePersistenceUnit(List<IMessage> messages, IReporter reporter) {
if (this.persistenceUnit == null) {
messages.add(
DefaultJpaValidationMessages.buildMessage(
IMessage.HIGH_SEVERITY,
JpaValidationMessages.PERSISTENCE_NO_PERSISTENCE_UNIT,
this,
this.getValidationTextRange()
)
);
return;
}
this.persistenceUnit.validate(messages, reporter);
}
}