001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019: package org.apache.openjpa.persistence;
020:
021: import java.lang.reflect.Method;
022: import java.util.Collection;
023:
024: import org.apache.openjpa.event.LifecycleCallbacks;
025: import org.apache.openjpa.event.LifecycleEvent;
026: import org.apache.openjpa.event.MethodLifecycleCallbacks;
027: import org.apache.openjpa.lib.log.Log;
028: import org.apache.openjpa.lib.util.Localizer;
029: import org.apache.openjpa.meta.MetaDataDefaults;
030: import org.apache.openjpa.util.UserException;
031:
032: /**
033: * Common utilities for persistence metadata parsers.
034: *
035: * @author Abe White
036: */
037: class MetaDataParsers {
038:
039: private static final Localizer _loc = Localizer
040: .forPackage(MetaDataParsers.class);
041:
042: /**
043: * Return the event type constants for the given tag, or null if none.
044: */
045: public static int[] getEventTypes(MetaDataTag tag) {
046: switch (tag) {
047: case PRE_PERSIST:
048: return new int[] { LifecycleEvent.BEFORE_PERSIST };
049: case POST_PERSIST:
050: return new int[] { LifecycleEvent.AFTER_PERSIST_PERFORMED };
051: case PRE_REMOVE:
052: return new int[] { LifecycleEvent.BEFORE_DELETE };
053: case POST_REMOVE:
054: return new int[] { LifecycleEvent.AFTER_DELETE_PERFORMED };
055: case PRE_UPDATE:
056: return new int[] { LifecycleEvent.BEFORE_UPDATE };
057: case POST_UPDATE:
058: return new int[] { LifecycleEvent.AFTER_UPDATE_PERFORMED };
059: case POST_LOAD:
060: return new int[] { LifecycleEvent.AFTER_LOAD,
061: LifecycleEvent.AFTER_REFRESH };
062: default:
063: return null;
064: }
065: }
066:
067: /**
068: * Validate that the given listener class does not have multiple methods
069: * listening for the same lifecycle event, which is forbidden by the spec.
070: */
071: public static void validateMethodsForSameCallback(Class cls,
072: Collection<LifecycleCallbacks> callbacks, Method method,
073: MetaDataTag tag, MetaDataDefaults def, Log log) {
074: if (callbacks == null || callbacks.isEmpty())
075: return;
076:
077: for (LifecycleCallbacks lc : callbacks) {
078: if (!(lc instanceof MethodLifecycleCallbacks))
079: continue;
080: Method exists = ((MethodLifecycleCallbacks) lc)
081: .getCallbackMethod();
082: if (!exists.getDeclaringClass().equals(
083: method.getDeclaringClass()))
084: continue;
085:
086: PersistenceMetaDataDefaults defaults = getPersistenceDefaults(def);
087: Localizer.Message msg = _loc.get(
088: "multiple-methods-on-callback", new Object[] {
089: method.getDeclaringClass().getName(),
090: method.getName(), exists.getName(),
091: tag.toString() });
092: if (defaults == null
093: || defaults
094: .getAllowsMultipleMethodsForSameCallback())
095: log.warn(msg);
096: else
097: throw new UserException(msg);
098: }
099: }
100:
101: /**
102: * Return the {@link PersistenceMetaDataDefaults} in use, or null if not
103: * using JPA defaults.
104: */
105: private static PersistenceMetaDataDefaults getPersistenceDefaults(
106: MetaDataDefaults def) {
107: if (def instanceof PersistenceMetaDataDefaults)
108: return (PersistenceMetaDataDefaults) def;
109: return null;
110: }
111: }
|