1 /**
2 * Copyright 2005-2014 The Kuali Foundation
3 *
4 * Licensed under the Educational Community License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.opensource.org/licenses/ecl2.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 package org.kuali.rice.krad.util;
17
18 import org.kuali.rice.kew.api.KewApiServiceLocator;
19 import org.kuali.rice.krad.UserSession;
20 import org.kuali.rice.krad.data.KradDataServiceLocator;
21 import org.kuali.rice.krad.datadictionary.DocumentEntry;
22 import org.kuali.rice.krad.service.KRADServiceLocatorWeb;
23
24 import java.util.concurrent.Callable;
25
26 /**
27 * Exposes legacy detection functionality statically.
28 *
29 * @author Kuali Rice Team (rice.collab@kuali.org)
30 */
31 public final class LegacyUtils {
32
33 private static LegacyDetector ld = new LegacyDetector(KradDataServiceLocator.getMetadataRepository(),
34 KRADServiceLocatorWeb.getDataDictionaryService());
35
36 private LegacyUtils() {
37 throw new UnsupportedOperationException(LegacyUtils.class + " should not be constructed");
38 }
39
40 /**
41 * Indicates whether the given type is managed by the legacy data framework. Note that it's possible for a given
42 * type to managed by both the legacy and the non-legacy data framework, in which case this method will return true
43 * as well.
44 *
45 * @param type the type to check
46 * @return true if managed by the legacy framework, false otherwise
47 */
48 public static boolean isLegacyManaged(Class<?> type) {
49 return ld.isLegacyManaged(type);
50 }
51
52 /**
53 * Indicates whether the given type is managed by the non-legacy data framework. Note that it's possible for a given
54 * type to managed by both the legacy and the non-legacy data framework, in which case this method will return true
55 * as well.
56 *
57 * @param type the type to check
58 * @return true if managed by the non-legacy krad-data framework, false otherwise
59 */
60 public static boolean isKradDataManaged(Class<?> type) {
61 return ld.isKradDataManaged(type);
62 }
63
64 /**
65 * Indicates whether or not the given DocumentEntry represents a legacy KNS document entry.
66 *
67 * @param documentEntry the document entry to check
68 * @return true if the given entry is a KNS entry, false otherwise
69 */
70 public static boolean isKnsDocumentEntry(DocumentEntry documentEntry) {
71 return "org.kuali.rice.kns.datadictionary".equals(documentEntry.getClass().getPackage().getName());
72 }
73
74 public static boolean isKnsEnabled() {
75 return ld.isKnsEnabled();
76 }
77
78 /**
79 * Return whether the legacy data framework is enabled
80 * @return whether the legacy data framework is enabled
81 */
82 public static boolean isLegacyDataFrameworkEnabled() {
83 return ld.isLegacyDataFrameworkEnabled();
84 }
85
86 /**
87 * Return whether objects of the given class should be handled via the legacy data framework
88 * @param dataObjectClass the data object class
89 * @return whether objects of the given class should be handled via the legacy data framework
90 */
91 public static boolean useLegacy(Class<?> dataObjectClass) {
92 return ld.useLegacy(dataObjectClass);
93 }
94
95 /**
96 * Return whether the object should be handled via the legacy data framework
97 * @param dataObject the data object
98 * @return whether the object should be handled via the legacy data framework
99 */
100 public static boolean useLegacyForObject(Object dataObject) {
101 return ld.useLegacyForObject(dataObject);
102 }
103
104 /**
105 * @return whether we are currently in a legacy calling context
106 */
107 public static boolean isInLegacyContext() {
108 return ld.isInLegacyContext();
109 }
110
111 public static void beginLegacyContext() {
112 ld.beginLegacyContext();
113 }
114
115 public static void endLegacyContext() {
116 ld.endLegacyContext();
117 }
118
119 /**
120 * Performs the specified {@link Callable} inside of the legacy context.
121 *
122 * @param callable the method to call inside of the new contexts
123 * @param <T> the return type of the callable
124 * @return the result of the callable
125 * @throws Exception any exception thrown during the execution of the context
126 */
127 public static <T> T doInLegacyContext(Callable<T> callable) throws Exception {
128 beginLegacyContext();
129 try {
130 return callable.call();
131 } finally {
132 endLegacyContext();
133 }
134 }
135
136 /**
137 * Performs the specified {@link Callable} inside of both the legacy context (if necessary as dependent on the
138 * {@code documentId}) and in new {@link GlobalVariables} as specified by the given {@code userSession}.
139 *
140 * @param documentId id of the document for which to establish the data context
141 * @param userSession the new user session to establish
142 * @param callable the method to call inside of the new contexts
143 * @param <T> the return type of the callable
144 * @return the result of the callable
145 * @throws Exception any exception thrown during the execution of the context
146 */
147 public static <T> T doInLegacyContext(String documentId, UserSession userSession, Callable<T> callable) throws Exception {
148 boolean inLegacyContext = establishLegacyDataContextIfNecessary(documentId);
149 try {
150 return GlobalVariables.doInNewGlobalVariables(userSession, callable);
151 } finally {
152 clearLegacyDataContextIfExists(inLegacyContext);
153 }
154 }
155
156 /**
157 * Establish a legacy data context if it deems that it's necessary to do so for the document being processed.
158 * Unfortunately for us here, there is really no easy way to tell if the original document was submitted from a
159 * legacy context (i.e. KNS + OJB) or if it was submitted from a non-legacy context.
160 *
161 * <p>This is really only a problem for us if the data object happens to be mapped and configured in both the legacy
162 * and non-legacy data frameworks (which may be the case while a conversion is in-progress). In the case that the
163 * document or the maintainable happens to be configured for both legacy and non-legacy data frameworks, the best we
164 * can do is use the non-legacy framework by default. We will, however, ensure that the document entry is not one of
165 * the KNS subclasses, as that will tell us that they have, in fact, converted the document over from KNS to KRAD.
166 * </p>
167 *
168 * @param documentId id of the document for which to establish the data context
169 * @return true if a legacy data context was established, false otherwise
170 */
171 private static boolean establishLegacyDataContextIfNecessary(String documentId) {
172 String documentTypeName = KewApiServiceLocator.getWorkflowDocumentService().getDocumentTypeName(documentId);
173 DocumentEntry documentEntry = KRADServiceLocatorWeb.getDocumentDictionaryService().getDocumentEntry(documentTypeName);
174
175 if (isKnsDocumentEntry(documentEntry)) {
176 beginLegacyContext();
177
178 return true;
179 }
180
181 return false;
182 }
183
184 /**
185 * If the given boolean is true, will end any existing legacy data context.
186 *
187 * @param inLegacyContext whether or not the legacy data context has been established
188 */
189 private static void clearLegacyDataContextIfExists(boolean inLegacyContext) {
190 if (inLegacyContext) {
191 endLegacyContext();
192 }
193 }
194
195 }