blob: 06aa7ab5827cb207d37c76a7d1266f582ba244db [file] [log] [blame]
/*
* Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0,
* or the Eclipse Distribution License v. 1.0 which is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
*/
// Contributors:
// mmacivor - Feb 06/2009 - Initial implementation
package org.eclipse.persistence.internal.oxm.accessor;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import org.eclipse.persistence.core.mappings.CoreAttributeAccessor;
import org.eclipse.persistence.descriptors.changetracking.ChangeTracker;
import org.eclipse.persistence.indirection.ValueHolder;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.indirection.WeavedAttributeValueHolderInterface;
import org.eclipse.persistence.mappings.AttributeAccessor;
/**
* INTERNAL:
* A custom AttriuteAccessor to be used when the same object is mapped in both
* OXM and ORM. This will bridge the gap between the two for attributes that use
* ValueHolders. Specifically for JPA weaving.
* @author matt.macivor
*
*/
public class OrmAttributeAccessor extends AttributeAccessor {
private AttributeAccessor ormAccessor;
private CoreAttributeAccessor oxmAccessor;
private boolean isValueHolderProperty;
private boolean isChangeTracking;
public OrmAttributeAccessor(AttributeAccessor ormAccessor, CoreAttributeAccessor oxmAccessor) {
this.ormAccessor = ormAccessor;
this.oxmAccessor = oxmAccessor;
}
public void setValueHolderProperty(boolean isValueHolder) {
isValueHolderProperty = isValueHolder;
}
public void setChangeTracking(boolean changeTracking) {
this.isChangeTracking = changeTracking;
}
public boolean isValueHolderProperty() {
return this.isValueHolderProperty;
}
public boolean isChangeTracking() {
return this.isChangeTracking;
}
@Override
public Object getAttributeValueFromObject(Object object) {
if(isValueHolderProperty) {
ValueHolderInterface<?> vh = (ValueHolderInterface<?>)ormAccessor.getAttributeValueFromObject(object);
if(vh != null && !vh.isInstantiated()) {
Object value = vh.getValue();
oxmAccessor.setAttributeValueInObject(object, value);
if(vh instanceof WeavedAttributeValueHolderInterface) {
((WeavedAttributeValueHolderInterface<?>)vh).setIsCoordinatedWithProperty(true);
}
}
}
return oxmAccessor.getAttributeValueFromObject(object);
}
@Override
public void setAttributeValueInObject(Object object, Object value) {
if(isChangeTracking) {
Object oldValue = getAttributeValueFromObject(object);
PropertyChangeListener listener = ((ChangeTracker)object)._persistence_getPropertyChangeListener();
if(listener != null) {
listener.propertyChange(new PropertyChangeEvent(object, oxmAccessor.getAttributeName(), value, oldValue));
}
}
if(isValueHolderProperty) {
@SuppressWarnings({"unchecked"})
ValueHolderInterface<Object> vh = (ValueHolderInterface<Object>)ormAccessor.getAttributeValueFromObject(object);
if(vh == null) {
vh = new ValueHolder<>();
((ValueHolder<?>)vh).setIsNewlyWeavedValueHolder(true);
}
vh.setValue(value);
ormAccessor.setAttributeValueInObject(object, vh);
}
oxmAccessor.setAttributeValueInObject(object, value);
}
public AttributeAccessor getOrmAccessor() {
return this.ormAccessor;
}
public CoreAttributeAccessor getOxmAccessor() {
return this.oxmAccessor;
}
public void setOrmAccessor(AttributeAccessor accessor) {
this.ormAccessor = accessor;
}
public void setOxmAccessor(AttributeAccessor accessor) {
this.oxmAccessor = accessor;
}
@Override
public Class<?> getAttributeClass() {
return oxmAccessor.getAttributeClass();
}
@Override
public boolean isMethodAttributeAccessor() {
return oxmAccessor.isMethodAttributeAccessor();
}
@Override
public String getAttributeName() {
return oxmAccessor.getAttributeName();
}
}