mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
ACS-8843 Investigate Java 21 compatibility (#2960)
* [ACS-8843] Delegate creation of proxy to one place Co-authored-by: Kacper Magdziarz <kacper.magdziarz@hyland.com>
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -28,13 +28,11 @@ package org.alfresco.repo.security.permissions;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.aop.IntroductionAdvisor;
|
import org.springframework.aop.IntroductionAdvisor;
|
||||||
import org.springframework.aop.framework.ProxyFactory;
|
|
||||||
import org.springframework.aop.support.DefaultIntroductionAdvisor;
|
import org.springframework.aop.support.DefaultIntroductionAdvisor;
|
||||||
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for collection-based results that describe permission filtering
|
* Interface for collection-based results that describe permission filtering behaviour around cut-off limits.
|
||||||
* behaviour around cut-off limits.
|
|
||||||
*
|
*
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
@@ -42,16 +40,15 @@ import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
|||||||
public interface PermissionCheckCollection<T>
|
public interface PermissionCheckCollection<T>
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get the desired number of results. Permission checks can stop once the number of
|
* Get the desired number of results. Permission checks can stop once the number of return objects reaches this number.
|
||||||
* return objects reaches this number.
|
|
||||||
*
|
*
|
||||||
* @return the number of results desired
|
* @return the number of results desired
|
||||||
*/
|
*/
|
||||||
int getTargetResultCount();
|
int getTargetResultCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the maximum time for permission checks to execute before cutting the results off.
|
* Get the maximum time for permission checks to execute before cutting the results off. <br/>
|
||||||
* <br/>Zero: Ignore this value.
|
* Zero: Ignore this value.
|
||||||
*
|
*
|
||||||
* @return the time allowed for permission checks before cutoff
|
* @return the time allowed for permission checks before cutoff
|
||||||
*/
|
*/
|
||||||
@@ -65,16 +62,16 @@ public interface PermissionCheckCollection<T>
|
|||||||
int getCutOffAfterCount();
|
int getCutOffAfterCount();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper 'introduction' to allow simple addition of the {@link PermissionCheckCollection} interface to
|
* Helper 'introduction' to allow simple addition of the {@link PermissionCheckCollection} interface to existing collections.
|
||||||
* existing collections.
|
|
||||||
*
|
*
|
||||||
* @param <T> the type of the <code>Collection</code> in use
|
* @param <T>
|
||||||
|
* the type of the <code>Collection</code> in use
|
||||||
*
|
*
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public static class PermissionCheckCollectionMixin<T> extends DelegatingIntroductionInterceptor implements PermissionCheckCollection<T>
|
class PermissionCheckCollectionMixin<T> extends DelegatingIntroductionInterceptor implements PermissionCheckCollection<T>
|
||||||
{
|
{
|
||||||
private final int targetResultCount;
|
private final int targetResultCount;
|
||||||
private final long cutOffAfterTimeMs;
|
private final long cutOffAfterTimeMs;
|
||||||
@@ -117,18 +114,20 @@ public interface PermissionCheckCollection<T>
|
|||||||
/**
|
/**
|
||||||
* Helper method to create a {@link PermissionCheckCollection} from an existing <code>Collection</code>
|
* Helper method to create a {@link PermissionCheckCollection} from an existing <code>Collection</code>
|
||||||
*
|
*
|
||||||
* @param <TT> the type of the <code>Collection</code>
|
* @param <TT>
|
||||||
* @param collection the <code>Collection</code> to proxy
|
* the type of the <code>Collection</code>
|
||||||
* @param targetResultCount the desired number of results or default to the collection size
|
* @param collection
|
||||||
* @param cutOffAfterTimeMs the number of milliseconds to wait before cut-off or zero to use the system default
|
* the <code>Collection</code> to proxy
|
||||||
* time-based cut-off.
|
* @param targetResultCount
|
||||||
* @param cutOffAfterCount the number of permission checks to process before cut-off or zero to use the system default
|
* the desired number of results or default to the collection size
|
||||||
* count-based cut-off.
|
* @param cutOffAfterTimeMs
|
||||||
* @return a <code>Collection</code> of the same type but including the
|
* the number of milliseconds to wait before cut-off or zero to use the system default time-based cut-off.
|
||||||
* {@link PermissionCheckCollection} interface
|
* @param cutOffAfterCount
|
||||||
|
* the number of permission checks to process before cut-off or zero to use the system default count-based cut-off.
|
||||||
|
* @return a <code>Collection</code> of the same type but including the {@link PermissionCheckCollection} interface
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static final <TT> Collection<TT> create(
|
public static <TT> Collection<TT> create(
|
||||||
Collection<TT> collection,
|
Collection<TT> collection,
|
||||||
int targetResultCount, long cutOffAfterTimeMs, int cutOffAfterCount)
|
int targetResultCount, long cutOffAfterTimeMs, int cutOffAfterCount)
|
||||||
{
|
{
|
||||||
@@ -137,19 +136,14 @@ public interface PermissionCheckCollection<T>
|
|||||||
targetResultCount = collection.size();
|
targetResultCount = collection.size();
|
||||||
}
|
}
|
||||||
// Create the mixin
|
// Create the mixin
|
||||||
DelegatingIntroductionInterceptor mixin = new PermissionCheckCollectionMixin<Integer>(
|
DelegatingIntroductionInterceptor mixin = new PermissionCheckCollectionMixin<>(
|
||||||
targetResultCount,
|
targetResultCount,
|
||||||
cutOffAfterTimeMs,
|
cutOffAfterTimeMs,
|
||||||
cutOffAfterCount);
|
cutOffAfterCount);
|
||||||
// Create the advisor
|
// Create the advisor
|
||||||
IntroductionAdvisor advisor = new DefaultIntroductionAdvisor(mixin, PermissionCheckCollection.class);
|
IntroductionAdvisor advisor = new DefaultIntroductionAdvisor(mixin, PermissionCheckCollection.class);
|
||||||
// Proxy
|
// Create Proxy
|
||||||
ProxyFactory pf = new ProxyFactory(collection);
|
return (Collection<TT>) ProxyFactoryUtils.createProxy(collection, advisor);
|
||||||
pf.addAdvisor(advisor);
|
|
||||||
Object proxiedObject = pf.getProxy();
|
|
||||||
|
|
||||||
// Done
|
|
||||||
return (Collection<TT>) proxiedObject;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -2,7 +2,7 @@
|
|||||||
* #%L
|
* #%L
|
||||||
* Alfresco Repository
|
* Alfresco Repository
|
||||||
* %%
|
* %%
|
||||||
* Copyright (C) 2005 - 2016 Alfresco Software Limited
|
* Copyright (C) 2005 - 2024 Alfresco Software Limited
|
||||||
* %%
|
* %%
|
||||||
* This file is part of the Alfresco software.
|
* This file is part of the Alfresco software.
|
||||||
* If the software was purchased under a paid Alfresco license, the terms of
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
@@ -28,13 +28,11 @@ package org.alfresco.repo.security.permissions;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
import org.springframework.aop.IntroductionAdvisor;
|
import org.springframework.aop.IntroductionAdvisor;
|
||||||
import org.springframework.aop.framework.ProxyFactory;
|
|
||||||
import org.springframework.aop.support.DefaultIntroductionAdvisor;
|
import org.springframework.aop.support.DefaultIntroductionAdvisor;
|
||||||
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
import org.springframework.aop.support.DelegatingIntroductionInterceptor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for collection-based results that carry extra information
|
* Interface for collection-based results that carry extra information about the state of permission cut-offs.
|
||||||
* about the state of permission cut-offs.
|
|
||||||
*
|
*
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
@@ -44,14 +42,12 @@ public interface PermissionCheckedCollection<T>
|
|||||||
/**
|
/**
|
||||||
* Check if the results have been truncated by permission check limits.
|
* Check if the results have been truncated by permission check limits.
|
||||||
*
|
*
|
||||||
* @return <tt>true</tt> - if the results (usually a collection) have been
|
* @return <tt>true</tt> - if the results (usually a collection) have been cut off by permission check limits
|
||||||
* cut off by permission check limits
|
|
||||||
*/
|
*/
|
||||||
boolean isCutOff();
|
boolean isCutOff();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the number of objects in the original (unfiltered) collection that did
|
* Get the number of objects in the original (unfiltered) collection that did <b>not</b> have any permission checks.
|
||||||
* <b>not</b> have any permission checks.
|
|
||||||
*
|
*
|
||||||
* @return number of entries from the original collection that were not checked
|
* @return number of entries from the original collection that were not checked
|
||||||
*/
|
*/
|
||||||
@@ -65,20 +61,21 @@ public interface PermissionCheckedCollection<T>
|
|||||||
int sizeOriginal();
|
int sizeOriginal();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper 'introduction' to allow simple addition of the {@link PermissionCheckedCollection} interface to
|
* Helper 'introduction' to allow simple addition of the {@link PermissionCheckedCollection} interface to existing collections.
|
||||||
* existing collections.
|
|
||||||
*
|
*
|
||||||
* @param <T> the type of the <code>Collection</code> in use
|
* @param <T>
|
||||||
|
* the type of the <code>Collection</code> in use
|
||||||
*
|
*
|
||||||
* @author Derek Hulley
|
* @author Derek Hulley
|
||||||
* @since 4.0
|
* @since 4.0
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("serial")
|
@SuppressWarnings("serial")
|
||||||
public static class PermissionCheckedCollectionMixin<T> extends DelegatingIntroductionInterceptor implements PermissionCheckedCollection<T>
|
class PermissionCheckedCollectionMixin<T> extends DelegatingIntroductionInterceptor implements PermissionCheckedCollection<T>
|
||||||
{
|
{
|
||||||
private final boolean isCutOff;
|
private final boolean isCutOff;
|
||||||
private final int sizeUnchecked;
|
private final int sizeUnchecked;
|
||||||
private final int sizeOriginal;
|
private final int sizeOriginal;
|
||||||
|
|
||||||
private PermissionCheckedCollectionMixin(boolean isCutOff, int sizeUnchecked, int sizeOriginal)
|
private PermissionCheckedCollectionMixin(boolean isCutOff, int sizeUnchecked, int sizeOriginal)
|
||||||
{
|
{
|
||||||
super();
|
super();
|
||||||
@@ -86,34 +83,37 @@ public interface PermissionCheckedCollection<T>
|
|||||||
this.sizeUnchecked = sizeUnchecked;
|
this.sizeUnchecked = sizeUnchecked;
|
||||||
this.sizeOriginal = sizeOriginal;
|
this.sizeOriginal = sizeOriginal;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isCutOff()
|
public boolean isCutOff()
|
||||||
{
|
{
|
||||||
return isCutOff;
|
return isCutOff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int sizeUnchecked()
|
public int sizeUnchecked()
|
||||||
{
|
{
|
||||||
return sizeUnchecked;
|
return sizeUnchecked;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int sizeOriginal()
|
public int sizeOriginal()
|
||||||
{
|
{
|
||||||
return sizeOriginal;
|
return sizeOriginal;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to create a {@link PermissionCheckedCollection} from an existing <code>Collection</code>
|
* Helper method to create a {@link PermissionCheckedCollection} from an existing <code>Collection</code> by applying the same values as present on a potentially permission-checked source. If the existing checked source is <b>NOT</b> permission-checked, then the collection will not be decorated.
|
||||||
* by applying the same values as present on a potentially permission-checked source. If the
|
|
||||||
* existing checked source is <b>NOT</b> permission-checked, then the collection will not be
|
|
||||||
* decorated.
|
|
||||||
*
|
*
|
||||||
* @param <TT> the type of the <code>Collection</code>
|
* @param <TT>
|
||||||
* @param collection the <code>Collection</code> to proxy
|
* the type of the <code>Collection</code>
|
||||||
* @param checkedSource a collection that might implement {@link PermissionCheckedCollection}
|
* @param collection
|
||||||
* @return a <code>Collection</code> of the same type but including the
|
* the <code>Collection</code> to proxy
|
||||||
* {@link PermissionCheckedCollection} interface
|
* @param checkedSource
|
||||||
|
* a collection that might implement {@link PermissionCheckedCollection}
|
||||||
|
* @return a <code>Collection</code> of the same type but including the {@link PermissionCheckedCollection} interface
|
||||||
*/
|
*/
|
||||||
public static final <TT> Collection<TT> create(
|
public static <TT> Collection<TT> create(
|
||||||
Collection<TT> collection, Collection<?> checkedSource)
|
Collection<TT> collection, Collection<?> checkedSource)
|
||||||
{
|
{
|
||||||
if (checkedSource instanceof PermissionCheckedCollection)
|
if (checkedSource instanceof PermissionCheckedCollection)
|
||||||
@@ -126,37 +126,36 @@ public interface PermissionCheckedCollection<T>
|
|||||||
return collection;
|
return collection;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Helper method to create a {@link PermissionCheckedCollection} from an existing <code>Collection</code>
|
* Helper method to create a {@link PermissionCheckedCollection} from an existing <code>Collection</code>
|
||||||
*
|
*
|
||||||
* @param <TT> the type of the <code>Collection</code>
|
* @param <TT>
|
||||||
* @param collection the <code>Collection</code> to proxy
|
* the type of the <code>Collection</code>
|
||||||
* @param isCutOff <tt>true</tt> if permission checking was cut off before completion
|
* @param collection
|
||||||
* @param sizeUnchecked number of entries from the original collection that were not checked
|
* the <code>Collection</code> to proxy
|
||||||
* @param sizeOriginal number of entries in the original, pre-checked collection
|
* @param isCutOff
|
||||||
* @return a <code>Collection</code> of the same type but including the
|
* <tt>true</tt> if permission checking was cut off before completion
|
||||||
* {@link PermissionCheckedCollection} interface
|
* @param sizeUnchecked
|
||||||
|
* number of entries from the original collection that were not checked
|
||||||
|
* @param sizeOriginal
|
||||||
|
* number of entries in the original, pre-checked collection
|
||||||
|
* @return a <code>Collection</code> of the same type but including the {@link PermissionCheckedCollection} interface
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public static final <TT> Collection<TT> create(
|
public static <TT> Collection<TT> create(
|
||||||
Collection<TT> collection,
|
Collection<TT> collection,
|
||||||
boolean isCutOff, int sizeUnchecked, int sizeOriginal)
|
boolean isCutOff, int sizeUnchecked, int sizeOriginal)
|
||||||
{
|
{
|
||||||
// Create the mixin
|
// Create the mixin
|
||||||
DelegatingIntroductionInterceptor mixin = new PermissionCheckedCollectionMixin<Integer>(
|
DelegatingIntroductionInterceptor mixin = new PermissionCheckedCollectionMixin<>(
|
||||||
isCutOff,
|
isCutOff,
|
||||||
sizeUnchecked,
|
sizeUnchecked,
|
||||||
sizeOriginal
|
sizeOriginal);
|
||||||
);
|
|
||||||
// Create the advisor
|
// Create the advisor
|
||||||
IntroductionAdvisor advisor = new DefaultIntroductionAdvisor(mixin, PermissionCheckedCollection.class);
|
IntroductionAdvisor advisor = new DefaultIntroductionAdvisor(mixin, PermissionCheckedCollection.class);
|
||||||
// Proxy
|
// Create Proxy
|
||||||
ProxyFactory pf = new ProxyFactory(collection);
|
return (Collection<TT>) ProxyFactoryUtils.createProxy(collection, advisor);
|
||||||
pf.addAdvisor(advisor);
|
|
||||||
Object proxiedObject = pf.getProxy();
|
|
||||||
|
|
||||||
// Done
|
|
||||||
return (Collection<TT>) proxiedObject;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* #%L
|
||||||
|
* Alfresco Repository
|
||||||
|
* %%
|
||||||
|
* Copyright (C) 2024 Alfresco Software Limited
|
||||||
|
* %%
|
||||||
|
* This file is part of the Alfresco software.
|
||||||
|
* If the software was purchased under a paid Alfresco license, the terms of
|
||||||
|
* the paid license agreement will prevail. Otherwise, the software is
|
||||||
|
* provided under the following open source license terms:
|
||||||
|
*
|
||||||
|
* Alfresco is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Alfresco is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
* #L%
|
||||||
|
*/
|
||||||
|
package org.alfresco.repo.security.permissions;
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.Deque;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.aop.IntroductionAdvisor;
|
||||||
|
import org.springframework.aop.framework.ProxyFactory;
|
||||||
|
|
||||||
|
class ProxyFactoryUtils
|
||||||
|
{
|
||||||
|
private ProxyFactoryUtils()
|
||||||
|
{}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delegate creation of {@link ProxyFactory} and proxy to have control over it in one place.
|
||||||
|
*
|
||||||
|
* @param collection
|
||||||
|
* given collection for ProxyFactory.
|
||||||
|
* @param advisor
|
||||||
|
* given advisor for ProxyFactory.
|
||||||
|
* @return the proxy object.
|
||||||
|
*/
|
||||||
|
protected static Object createProxy(Collection<?> collection, IntroductionAdvisor advisor)
|
||||||
|
{
|
||||||
|
ProxyFactory pf = new ProxyFactory(collection);
|
||||||
|
pf.addAdvisor(advisor);
|
||||||
|
if (pf.isInterfaceProxied(List.class) && pf.isInterfaceProxied(Deque.class))
|
||||||
|
{
|
||||||
|
pf.removeInterface(Deque.class);
|
||||||
|
}
|
||||||
|
return pf.getProxy();
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user