11/*
2- * Copyright 2009-2023 the original author or authors.
2+ * Copyright 2009-2024 the original author or authors.
33 *
44 * Licensed under the Apache License, Version 2.0 (the "License");
55 * you may not use this file except in compliance with the License.
2626import java .util .Properties ;
2727import java .util .Set ;
2828import java .util .concurrent .ConcurrentHashMap ;
29+ import java .util .concurrent .locks .ReentrantLock ;
2930import java .util .function .BiFunction ;
3031
3132import org .apache .ibatis .binding .MapperRegistry ;
9596import org .apache .ibatis .type .TypeAliasRegistry ;
9697import org .apache .ibatis .type .TypeHandler ;
9798import org .apache .ibatis .type .TypeHandlerRegistry ;
98- import org .apache .ibatis .util .LockKit ;
9999
100100/**
101101 * @author Clinton Begin
@@ -172,6 +172,11 @@ public class Configuration {
172172 protected final Collection <ResultMapResolver > incompleteResultMaps = new LinkedList <>();
173173 protected final Collection <MethodResolver > incompleteMethods = new LinkedList <>();
174174
175+ private final ReentrantLock incompleteResultMapsLock = new ReentrantLock ();
176+ private final ReentrantLock incompleteCacheRefsLock = new ReentrantLock ();
177+ private final ReentrantLock incompleteStatementsLock = new ReentrantLock ();
178+ private final ReentrantLock incompleteMethodsLock = new ReentrantLock ();
179+
175180 /*
176181 * A map holds cache-ref relationship. The key is the namespace that references a cache bound to another namespace and
177182 * the value is the namespace which the actual cache is bound to.
@@ -832,34 +837,70 @@ public Collection<MappedStatement> getMappedStatements() {
832837 return mappedStatements .values ();
833838 }
834839
840+ /**
841+ * @deprecated call {@link #parsePendingStatements(boolean)}
842+ */
843+ @ Deprecated
835844 public Collection <XMLStatementBuilder > getIncompleteStatements () {
836845 return incompleteStatements ;
837846 }
838847
839848 public void addIncompleteStatement (XMLStatementBuilder incompleteStatement ) {
840- incompleteStatements .add (incompleteStatement );
849+ incompleteStatementsLock .lock ();
850+ try {
851+ incompleteStatements .add (incompleteStatement );
852+ } finally {
853+ incompleteStatementsLock .unlock ();
854+ }
841855 }
842856
857+ /**
858+ * @deprecated call {@link #parsePendingCacheRefs(boolean)}
859+ */
860+ @ Deprecated
843861 public Collection <CacheRefResolver > getIncompleteCacheRefs () {
844862 return incompleteCacheRefs ;
845863 }
846864
847865 public void addIncompleteCacheRef (CacheRefResolver incompleteCacheRef ) {
848- incompleteCacheRefs .add (incompleteCacheRef );
866+ incompleteCacheRefsLock .lock ();
867+ try {
868+ incompleteCacheRefs .add (incompleteCacheRef );
869+ } finally {
870+ incompleteCacheRefsLock .unlock ();
871+ }
849872 }
850873
874+ /**
875+ * @deprecated call {@link #parsePendingResultMaps(boolean)}
876+ */
877+ @ Deprecated
851878 public Collection <ResultMapResolver > getIncompleteResultMaps () {
852879 return incompleteResultMaps ;
853880 }
854881
855882 public void addIncompleteResultMap (ResultMapResolver resultMapResolver ) {
856- incompleteResultMaps .add (resultMapResolver );
883+ incompleteResultMapsLock .lock ();
884+ try {
885+ incompleteResultMaps .add (resultMapResolver );
886+ } finally {
887+ incompleteResultMapsLock .unlock ();
888+ }
857889 }
858890
859891 public void addIncompleteMethod (MethodResolver builder ) {
860- incompleteMethods .add (builder );
892+ incompleteMethodsLock .lock ();
893+ try {
894+ incompleteMethods .add (builder );
895+ } finally {
896+ incompleteMethodsLock .unlock ();
897+ }
861898 }
862899
900+ /**
901+ * @deprecated call {@link #parsePendingMethods(boolean)}
902+ */
903+ @ Deprecated
863904 public Collection <MethodResolver > getIncompleteMethods () {
864905 return incompleteMethods ;
865906 }
@@ -923,48 +964,71 @@ public void addCacheRef(String namespace, String referencedNamespace) {
923964 * are added as it provides fail-fast statement validation.
924965 */
925966 protected void buildAllStatements () {
926- parsePendingResultMaps ();
927- if (!incompleteCacheRefs .isEmpty ()) {
928- LockKit .ReentrantLock lock = LockKit .obtainLock (incompleteCacheRefs );
929- lock .lock ();
930- try {
931- incompleteCacheRefs .removeIf (x -> x .resolveCacheRef () != null );
932- } finally {
933- lock .unlock ();
967+ parsePendingResultMaps (true );
968+ parsePendingCacheRefs (true );
969+ parsePendingStatements (true );
970+ parsePendingMethods (true );
971+ }
972+
973+ public void parsePendingMethods (boolean reportUnresolved ) {
974+ if (incompleteMethods .isEmpty ()) {
975+ return ;
976+ }
977+ incompleteMethodsLock .lock ();
978+ try {
979+ incompleteMethods .removeIf (x -> {
980+ x .resolve ();
981+ return true ;
982+ });
983+ } catch (IncompleteElementException e ) {
984+ if (reportUnresolved ) {
985+ throw e ;
934986 }
987+ } finally {
988+ incompleteMethodsLock .unlock ();
935989 }
936- if (!incompleteStatements .isEmpty ()) {
937- LockKit .ReentrantLock lock = LockKit .obtainLock (incompleteStatements );
938- lock .lock ();
939- try {
940- incompleteStatements .removeIf (x -> {
941- x .parseStatementNode ();
942- return true ;
943- });
944- } finally {
945- lock .unlock ();
990+ }
991+
992+ public void parsePendingStatements (boolean reportUnresolved ) {
993+ if (incompleteStatements .isEmpty ()) {
994+ return ;
995+ }
996+ incompleteStatementsLock .lock ();
997+ try {
998+ incompleteStatements .removeIf (x -> {
999+ x .parseStatementNode ();
1000+ return true ;
1001+ });
1002+ } catch (IncompleteElementException e ) {
1003+ if (reportUnresolved ) {
1004+ throw e ;
9461005 }
1006+ } finally {
1007+ incompleteStatementsLock .unlock ();
1008+ }
1009+ }
1010+
1011+ public void parsePendingCacheRefs (boolean reportUnresolved ) {
1012+ if (incompleteCacheRefs .isEmpty ()) {
1013+ return ;
9471014 }
948- if (!incompleteMethods .isEmpty ()) {
949- LockKit .ReentrantLock lock = LockKit .obtainLock (incompleteMethods );
950- lock .lock ();
951- try {
952- incompleteMethods .removeIf (x -> {
953- x .resolve ();
954- return true ;
955- });
956- } finally {
957- lock .unlock ();
1015+ incompleteCacheRefsLock .lock ();
1016+ try {
1017+ incompleteCacheRefs .removeIf (x -> x .resolveCacheRef () != null );
1018+ } catch (IncompleteElementException e ) {
1019+ if (reportUnresolved ) {
1020+ throw e ;
9581021 }
1022+ } finally {
1023+ incompleteCacheRefsLock .unlock ();
9591024 }
9601025 }
9611026
962- private void parsePendingResultMaps () {
1027+ public void parsePendingResultMaps (boolean reportUnresolved ) {
9631028 if (incompleteResultMaps .isEmpty ()) {
9641029 return ;
9651030 }
966- LockKit .ReentrantLock lock = LockKit .obtainLock (incompleteResultMaps );
967- lock .lock ();
1031+ incompleteResultMapsLock .lock ();
9681032 try {
9691033 boolean resolved ;
9701034 IncompleteElementException ex = null ;
@@ -981,12 +1045,12 @@ private void parsePendingResultMaps() {
9811045 }
9821046 }
9831047 } while (resolved );
984- if (!incompleteResultMaps .isEmpty () && ex != null ) {
1048+ if (reportUnresolved && !incompleteResultMaps .isEmpty () && ex != null ) {
9851049 // At least one result map is unresolvable.
9861050 throw ex ;
9871051 }
9881052 } finally {
989- lock .unlock ();
1053+ incompleteResultMapsLock .unlock ();
9901054 }
9911055 }
9921056
0 commit comments