1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19 package org.apache.openjpa.slice;
20
21 import org.apache.openjpa.kernel.FinalizingBrokerImpl;
22 import org.apache.openjpa.kernel.OpCallbacks;
23 import org.apache.openjpa.kernel.OpenJPAStateManager;
24 import org.apache.openjpa.lib.util.Localizer;
25 import org.apache.openjpa.util.UserException;
26
27 /**
28 * A specialized Broker to associate slice identifiers with the StateManagers as
29 * they are persisted in a cascade. This intervention helps the user to define
30 * distribution policy only for root instances i.e. the instances that are
31 * explicit argument to persist() call. The cascaded instances are assigned the
32 * same slice to honor collocation constraint.
33 *
34 * @author Pinaki Poddar
35 *
36 */
37 @SuppressWarnings("serial")
38 public class DistributedBrokerImpl extends FinalizingBrokerImpl {
39 private transient String slice;
40
41 private static final Localizer _loc =
42 Localizer.forPackage(DistributedBrokerImpl.class);
43
44 /**
45 * Assigns slice identifier to the resultant StateManager as initialized by
46 * the super class implementation. The slice identifier is decided by
47 * {@link DistributionPolicy} for given <code>pc</code> if it is a root
48 * instance i.e. the argument of the user application's persist() call. The
49 * cascaded instances are detected by non-empty status of the current
50 * operating set. The slice is assigned only if a StateManager has never
51 * been assigned before.
52 */
53 @Override
54 public OpenJPAStateManager persist(Object pc, Object id, boolean explicit,
55 OpCallbacks call) {
56 OpenJPAStateManager sm = getStateManager(pc);
57 if (getOperatingSet().isEmpty()
58 && (sm == null || sm.getImplData() == null)) {
59 slice = getSlice(pc);
60 }
61 sm = super.persist(pc, id, explicit, call);
62 if (sm.getImplData() == null)
63 sm.setImplData(slice, true);
64
65 return sm;
66 }
67
68 /**
69 * Gets the slice by the user-defined distribution policy.
70 */
71 String getSlice(Object pc) {
72 DistributedConfiguration conf =
73 (DistributedConfiguration) getConfiguration();
74 String slice =
75 (conf.getDistributionPolicyInstance().distribute(pc, conf
76 .getActiveSliceNames(), this));
77 if (!conf.getActiveSliceNames().contains(slice))
78 throw new UserException(_loc.get("bad-policy-slice", new Object[] {
79 conf.getDistributionPolicyInstance().getClass().getName(),
80 slice, pc, conf.getActiveSliceNames() }));
81 return slice;
82 }
83
84 @Override
85 public boolean endOperation() {
86 try {
87 return super.endOperation();
88 } catch (Exception ex) {
89
90 }
91 return true;
92 }
93 }