/* | |
* Licensed to the Apache Software Foundation (ASF) under one | |
* or more contributor license agreements. See the NOTICE file | |
* distributed with this work for additional information | |
* regarding copyright ownership. The ASF licenses this file | |
* to you under the Apache License, Version 2.0 (the | |
* "License"); you may not use this file except in compliance | |
* with the License. You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, | |
* software distributed under the License is distributed on an | |
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY | |
* KIND, either express or implied. See the License for the | |
* specific language governing permissions and limitations | |
* under the License. | |
*/ | |
package org.apache.openjpa.slice; | |
import org.apache.openjpa.kernel.FinalizingBrokerImpl; | |
import org.apache.openjpa.kernel.OpCallbacks; | |
import org.apache.openjpa.kernel.OpenJPAStateManager; | |
import org.apache.openjpa.lib.util.Localizer; | |
import org.apache.openjpa.util.UserException; | |
/** | |
* A specialized Broker to associate slice identifiers with the StateManagers as | |
* they are persisted in a cascade. This intervention helps the user to define | |
* distribution policy only for root instances i.e. the instances that are | |
* explicit argument to persist() call. The cascaded instances are assigned the | |
* same slice to honor collocation constraint. | |
* | |
* @author Pinaki Poddar | |
* | |
*/ | |
@SuppressWarnings("serial") | |
public class DistributedBrokerImpl extends FinalizingBrokerImpl { | |
private transient String slice; | |
private static final Localizer _loc = | |
Localizer.forPackage(DistributedBrokerImpl.class); | |
/** | |
* Assigns slice identifier to the resultant StateManager as initialized by | |
* the super class implementation. The slice identifier is decided by | |
* {@link DistributionPolicy} for given <code>pc</code> if it is a root | |
* instance i.e. the argument of the user application's persist() call. The | |
* cascaded instances are detected by non-empty status of the current | |
* operating set. The slice is assigned only if a StateManager has never | |
* been assigned before. | |
*/ | |
@Override | |
public OpenJPAStateManager persist(Object pc, Object id, boolean explicit, | |
OpCallbacks call) { | |
OpenJPAStateManager sm = getStateManager(pc); | |
if (getOperatingSet().isEmpty() | |
&& (sm == null || sm.getImplData() == null)) { | |
slice = getSlice(pc); | |
} | |
sm = super.persist(pc, id, explicit, call); | |
if (sm.getImplData() == null) | |
sm.setImplData(slice, true); | |
return sm; | |
} | |
/** | |
* Gets the slice by the user-defined distribution policy. | |
*/ | |
String getSlice(Object pc) { | |
DistributedConfiguration conf = | |
(DistributedConfiguration) getConfiguration(); | |
String slice = | |
(conf.getDistributionPolicyInstance().distribute(pc, conf | |
.getActiveSliceNames(), this)); | |
if (!conf.getActiveSliceNames().contains(slice)) | |
throw new UserException(_loc.get("bad-policy-slice", new Object[] { | |
conf.getDistributionPolicyInstance().getClass().getName(), | |
slice, pc, conf.getActiveSliceNames() })); | |
return slice; | |
} | |
@Override | |
public boolean endOperation() { | |
try { | |
return super.endOperation(); | |
} catch (Exception ex) { | |
} | |
return true; | |
} | |
} |