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 }