Instruction:
作为 Java 安全专家，检测此代码中的安全漏洞：
## 内容1
### 文件路径：
dhis-2/dhis-api/src/main/java/org/hisp/dhis/common/IdentifiableObjectManager.java
### 代码内容：
package org.hisp.dhis.common;

import java.util.Collection;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.hisp.dhis.attribute.Attribute;
import org.hisp.dhis.attribute.AttributeValue;
import org.hisp.dhis.translation.Translation;
import org.hisp.dhis.user.User;
import org.hisp.dhis.user.UserInfo;

/**
 * @author Lars Helge Overland
 */
public interface IdentifiableObjectManager
{
    String ID = IdentifiableObjectManager.class.getName();

    void save( IdentifiableObject object );

    void save( IdentifiableObject object, boolean clearSharing );

    void save( List<IdentifiableObject> objects );

    void update( IdentifiableObject object );

    void update( IdentifiableObject object, User user );

    void update( List<IdentifiableObject> objects );

    void update( List<IdentifiableObject> objects, User user );

    void delete( IdentifiableObject object );

    void delete( IdentifiableObject object, User user );

    <T extends IdentifiableObject> T get( String uid );

    <T extends IdentifiableObject> T get( Class<T> clazz, long id );

    <T extends IdentifiableObject> T get( Class<T> clazz, String uid );

    <T extends IdentifiableObject> boolean exists( Class<T> clazz, String uid );

    <T extends IdentifiableObject> T get( Collection<Class<? extends IdentifiableObject>> classes, String uid );

    <T extends IdentifiableObject> T get( Collection<Class<? extends IdentifiableObject>> classes, IdScheme idScheme,
        String value );

    <T extends IdentifiableObject> T getByCode( Class<T> clazz, String code );

    <T extends IdentifiableObject> List<T> getByCode( Class<T> clazz, Collection<String> codes );

    <T extends IdentifiableObject> T getByName( Class<T> clazz, String name );

    <T extends IdentifiableObject> T getByUniqueAttributeValue( Class<T> clazz, Attribute attribute, String value );

    <T extends IdentifiableObject> T getByUniqueAttributeValue( Class<T> clazz, Attribute attribute, String value,
        UserInfo userInfo );

    <T extends IdentifiableObject> T search( Class<T> clazz, String query );

    <T extends IdentifiableObject> List<T> filter( Class<T> clazz, String query );

    <T extends IdentifiableObject> List<T> getAll( Class<T> clazz );

    <T extends IdentifiableObject> List<T> getDataWriteAll( Class<T> clazz );

    <T extends IdentifiableObject> List<T> getDataReadAll( Class<T> clazz );

    <T extends IdentifiableObject> List<T> getAllSorted( Class<T> clazz );

    <T extends IdentifiableObject> List<T> getAllByAttributes( Class<T> klass, List<Attribute> attributes );

    <T extends IdentifiableObject> List<AttributeValue> getAllValuesByAttributes( Class<T> klass,
        List<Attribute> attributes );

    <T extends IdentifiableObject> long countAllValuesByAttributes( Class<T> klass, List<Attribute> attributes );

    <T extends IdentifiableObject> List<T> getByUid( Class<T> clazz, Collection<String> uids );

    <T extends IdentifiableObject> List<T> getByUid( Collection<Class<? extends IdentifiableObject>> classes,
        Collection<String> uids );

    <T extends IdentifiableObject> List<T> getById( Class<T> clazz, Collection<Long> ids );

    <T extends IdentifiableObject> List<T> getOrdered( Class<T> clazz, IdScheme idScheme, Collection<String> values );

    <T extends IdentifiableObject> List<T> getByUidOrdered( Class<T> clazz, List<String> uids );

    <T extends IdentifiableObject> List<T> getLikeName( Class<T> clazz, String name );

    <T extends IdentifiableObject> List<T> getLikeName( Class<T> clazz, String name, boolean caseSensitive );

    <T extends IdentifiableObject> List<T> getBetweenSorted( Class<T> clazz, int first, int max );

    <T extends IdentifiableObject> List<T> getBetweenLikeName( Class<T> clazz, Set<String> words, int first, int max );

    <T extends IdentifiableObject> Date getLastUpdated( Class<T> clazz );

    <T extends IdentifiableObject> Map<String, T> getIdMap( Class<T> clazz, IdentifiableProperty property );

    <T extends IdentifiableObject> Map<String, T> getIdMap( Class<T> clazz, IdScheme idScheme );

    <T extends IdentifiableObject> Map<String, T> getIdMapNoAcl( Class<T> clazz, IdentifiableProperty property );

    <T extends IdentifiableObject> Map<String, T> getIdMapNoAcl( Class<T> clazz, IdScheme idScheme );

    <T extends IdentifiableObject> List<T> getObjects( Class<T> clazz, IdentifiableProperty property,
        Collection<String> identifiers );

    <T extends IdentifiableObject> List<T> getObjects( Class<T> clazz, Collection<Long> identifiers );

    <T extends IdentifiableObject> T getObject( Class<T> clazz, IdentifiableProperty property, String value );

    <T extends IdentifiableObject> T getObject( Class<T> clazz, IdScheme idScheme, String value );

    IdentifiableObject getObject( String uid, String simpleClassName );

    IdentifiableObject getObject( long id, String simpleClassName );

    <T extends IdentifiableObject> int getCount( Class<T> clazz );

    <T extends IdentifiableObject> int getCountByCreated( Class<T> clazz, Date created );

    <T extends IdentifiableObject> int getCountByLastUpdated( Class<T> clazz, Date lastUpdated );

    <T extends DimensionalObject> List<T> getDataDimensions( Class<T> clazz );

    <T extends DimensionalObject> List<T> getDataDimensionsNoAcl( Class<T> clazz );

    void refresh( Object object );

    /**
     * Resets all properties that are not owned by the object type.
     *
     * @param object object to reset
     */
    void resetNonOwnerProperties( Object object );

    void flush();

    void clear();

    void evict( Object object );

    <T extends IdentifiableObject> List<T> getByAttributeAndValue( Class<T> klass, Attribute attribute, String value );

    <T extends IdentifiableObject> boolean isAttributeValueUnique( Class<? extends IdentifiableObject> klass, T object,
        AttributeValue attributeValue );

    <T extends IdentifiableObject> boolean isAttributeValueUnique( Class<? extends IdentifiableObject> klass, T object,
        Attribute attribute, String value );

    List<? extends IdentifiableObject> getAllByAttributeAndValues( Class<? extends IdentifiableObject> klass,
        Attribute attribute, List<String> values );

    Map<Class<? extends IdentifiableObject>, IdentifiableObject> getDefaults();

    void updateTranslations( IdentifiableObject persistedObject, Set<Translation> translations );

    <T extends IdentifiableObject> List<T> getNoAcl( Class<T> clazz, Collection<String> uids );

    boolean isDefault( IdentifiableObject object );

    List<String> getUidsCreatedBefore( Class<? extends IdentifiableObject> klass, Date date );

    /**
     * Remove given UserGroup UID from all sharing records in database
     */
    void removeUserGroupFromSharing( String userGroupUid );

    // -------------------------------------------------------------------------
    // NO ACL
    // -------------------------------------------------------------------------

    <T extends IdentifiableObject> T getNoAcl( Class<T> clazz, String uid );

    <T extends IdentifiableObject> void updateNoAcl( T object );

    <T extends IdentifiableObject> List<T> getAllNoAcl( Class<T> clazz );
}

## 内容2
### 文件路径：
dhis-2/dhis-api/src/main/java/org/hisp/dhis/feedback/ErrorCode.java
### 代码内容：
package org.hisp.dhis.feedback;

/**
 * @author Morten Olav Hansen <mortenoh@gmail.com>
 */
public enum ErrorCode
{
    /* General */
    E1000( "API query must be specified" ),
    E1001( "API query contains an illegal string" ),
    E1002( "API version is invalid" ),

    /* Basic metadata */
    E1100( "Data element not found or not accessible: `{0}`" ),
    E1101( "Period is invalid: `{0}`" ),
    E1102( "Organisation unit not found or not accessible: `{0}`" ),
    E1103( "Category option combo not found or not accessible: `{0}`" ),
    E1104( "Attribute option combo not found or not accessible: `{0}`" ),
    E1105( "Data set not found or not accessible: `{0}`" ),
    E1106( "There are duplicate translation record for property `{0}` and locale `{1}`" ),
    E1107( "Object type `{0}` is not translatable." ),

    /* Org unit merge */
    E1500( "At least two source orgs unit must be specified" ),
    E1501( "Target org unit must be specified" ),
    E1502( "Target org unit cannot be a source org unit" ),
    E1503( "Source org unit does not exist: `{0}`" ),
    E1504( "Target org unit cannot be a descendant of a source org unit" ),

    /* Org unit split */
    E1510( "Source org unit must be specified" ),
    E1511( "At least two target org units must be specified" ),
    E1512( "Source org unit cannot be a target org unit" ),
    E1513( "Primary target must be specified" ),
    E1514( "Primary target must be a target org unit" ),
    E1515( "Target org unit does not exist: `{0}`" ),
    E1516( "Target org unit cannot be a descendant of the source org unit: `{0}`" ),

    /* Org unit move */
    E1520( "User `{0}` is not allowed to move organisation units" ),
    E1521( "User `{0}` is not allowed to move organisation `{1}`" ),
    E1522( "User `{0}` is not allowed to move organisation `{1}` unit from parent `{2}`" ),
    E1523( "User `{0}` is not allowed to move organisation `{1}` unit to parent `{2}`" ),

    /* Data */
    E2000( "Query parameters cannot be null" ),
    E2001( "At least one data element, data set or data element group must be specified" ),
    E2002( "At least one period, start/end dates, last updated or last updated duration must be specified" ),
    E2003( "Both periods and start/end date cannot be specified" ),
    E2004( "Start date must be before end date" ),
    E2005( "Duration is not valid: `{0}`" ),
    E2006( "At least one organisation unit or organisation unit group must be specified" ),
    E2007( "Organisation unit children cannot be included for organisation unit groups" ),
    E2008( "At least one organisation unit must be specified when children are included" ),
    E2009( "Limit cannot be less than zero: `{0}`" ),
    E2010( "User is not allowed to read data for data set: `{0}`" ),
    E2011( "User is not allowed to read data for attribute option combo: `{0}`" ),
    E2012( "User is not allowed to view org unit: `{0}`" ),
    E2013( "At least one data set must be specified" ),
    E2014( "Unable to parse filter `{0}`" ),
    E2015( "Unable to parse order param: `{0}`" ),
    E2016( "Unable to parse element `{0}` on filter `{1}`. The values available are: {2}" ),
    E2017( "Data set is locked" ),
    E2018( "Category option combo is required but not specified" ),
    E2019( "Organisation unit is closed for the selected period: `{0}`" ),
    E2020( "Organisation unit is not in the hierarchy of the current user: `{0}`" ),
    E2021( "Data set: `{0}` does not contain data element: `{1}`" ),
    E2022( "Period: `{0}` is after latest open future period: `{1}` for data element: `{2}`" ),
    E2023( "Period: `{0}` is before start date: {1} for attribute option: `{2}`" ),
    E2024( "Period: `{0}` is after start date: {1} for attribute option: `{2}`" ),
    E2025( "Period: `{0}` is not open for data set: `{1}`" ),
    E2026( "File resource already assigned or linked to a data value" ),
    E2027( "File resource is invalid: `{0}`" ),
    E2028( "Comment is invalid: `{0}`" ),
    E2029( "Data value is not a valid option of the data element option set: `{0}`" ),
    E2030( "Data value must match data element value type: `{0}`" ),
    E2031( "User does not have write access to category option combo: `{0}`" ),
    E2032( "Data value does not exist" ),
    E2033( "Follow-up must be specified" ),
    E2034( "Filter not supported: `{0}`" ),
    E2035( "Operator not supported: `{0}`" ),
    E2036( "Combination not supported: `{0}`" ),
    E2037( "Order not supported: `{0}`" ),
    E2038( "Field not supported: `{0}`" ),

    /* Outlier detection */
    E2200( "At least one data element must be specified" ),
    E2201( "Start date and end date must be specified" ),
    E2202( "Start date must be before end date" ),
    E2203( "At least one organisation unit must be specified" ),
    E2204( "Threshold must be a positive number" ),
    E2205( "Max results must be a positive number" ),
    E2206( "Max results exceeds the allowed max limit: `{0}`" ),
    E2207( "Data start date must be before data end date" ),
    E2208( "Non-numeric data values encountered during outlier value detection" ),

    /* Followup analysis */
    E2300( "At least one data element or data set must be specified" ),
    E2301( "Start date and end date must be specified directly or indirectly by specifying a period" ),

    /* Security */
    E3000( "User `{0}` is not allowed to create objects of type {1}." ),
    E3001( "User `{0}` is not allowed to update object `{1}`." ),
    E3002( "User `{0}` is not allowed to delete object `{1}`." ),
    E3003( "User `{0}` is not allowed to grant users access to user role `{1}`." ),
    E3004( "User `{0}` is not allowed to grant users access to user groups." ),
    E3005( "User `{0}` is not allowed to grant users access to user group `{1}`." ),
    E3006( "User `{0}` is not allowed to externalize objects of type `{1}`." ),
    E3008( "User `{0}` is not allowed to make public objects of type `{1}`." ),
    E3009( "User `{0}` is not allowed to make private objects of type `{1}`." ),
    E3010( "Invalid access string `{0}`." ),
    E3011( "Data sharing is not enabled for type `{0}`, but access strings contain data sharing read or write." ),
    E3012( "User `{0}` does not have read access for object `{1}`." ),
    E3013( "Sharing settings of system default metadata object of type `{0}` cannot be modified." ),
    E3014( "You do not have manage access to this object." ),
    E3015( "Invalid public access string: `{0}`" ),
    E3016( "Data sharing is not enabled for this object" ),
    E3017( "Invalid user group access string: `{0}`" ),
    E3018( "Invalid user access string: `{0}`" ),

    /* Metadata Validation */
    E4000( "Missing required property `{0}`." ),
    E4001( "Maximum length of property `{0}`is {1}, but given length was {2}." ),
    E4002( "Allowed length range for property `{0}` is [{1} to {2}], but given length was {3}." ),
    E4003( "Property `{0}` requires a valid email address, was given `{1}`." ),
    E4004( "Property `{0}` requires a valid URL, was given `{1}`." ),
    E4005( "Property `{0}` requires a valid password, was given `{1}`." ),
    E4006( "Property `{0}` requires a valid HEX color, was given `{1}`." ),
    E4007( "Allowed size range for collection property `{0}` is [{1} to {2}], but size given was {3}." ),
    E4008( "Allowed range for numeric property `{0}` is [{1} to {2}], but number given was {3}." ),
    E4009( "Attribute `{0}` is unique, and value `{1}` already exist." ),
    E4010( "Attribute `{0}` is not supported for type `{1}`." ),
    E4011( "Attribute `{0}` is required, but no value was found." ),
    E4012( "Attribute `{0}` contains elements of different period type than the data set it was added to" ),
    E4013( "Invalid Closing date `{0}`, must be after Opening date `{1}`" ),
    E4014( "Invalid UID `{0}` for property `{1}`" ),
    E4015( "Property `{0}` refers to an object that does not exist, could not find `{1}`" ),
    E4016( "Object referenced by the `{0}` property is already associated with another object, value: `{1}`" ),
    E4017( "RenderingType `{0}` is not supported for ValueType `{1}`" ),
    E4018( "Property `{0}` must be set when property `{1}` is `{2}`" ),
    E4019( "Failed to parse pattern `{0}`. {1}" ),
    E4020( "The value `{0}` does not conform to the attribute pattern `{1}`" ),
    E4021( "ID-pattern is required to have 1 generated segment (RANDOM or SEQUENTIAL)." ),
    E4022( "Pattern `{0}` does not conform to the value type `{1}`." ),
    E4023( "Property `{0}` can not be set when property `{1}` is `{2}`. " ),
    E4024( "Property `{0}` must be set when property `{1}` is `{2}`. " ),
    E4025( "Properties `{0}` and `{1}` are mutually exclusive and cannot be used together." ),
    E4026( "One of the properties `{0}` and `{1}` is required when property `{2}` is `{3}`." ),
    E4027( "Value `{0}` is not a valid for property `{1}`" ),
    E4028( "Option set `{0}` already contains option `{1}`" ),
    E4029( "Job parameters cannot be null for job type: {0}" ),
    E4030( "Object could not be deleted because it is associated with another object: {0}" ),

    /* ProgramRuleAction validation */
    E4033( "A program rule action of type `{0}` associated with program rule name `{1}` is invalid" ),
    E4034( "ProgramNotificationTemplate `{0}` associated with program rule name `{1}` does not exist" ),
    E4035( "ProgramNotificationTemplate cannot be null for program rule name `{0}`" ),
    E4036( "ProgramStageSection cannot be null for program rule `{0}`" ),
    E4037( "ProgramStageSection `{0}` associated with program rule `{1}` does not exist" ),
    E4038( "ProgramStage cannot be null for program rule `{0}`" ),
    E4039( "ProgramStage `{0}` associated with program rule `{1}` does not exist" ),
    E4040( "Option cannot be null for program rule `{0}`" ),
    E4041( "Option `{0}` associated with program rule `{1}` does not exist" ),
    E4042( "OptionGroup cannot be null for program rule `{0}`" ),
    E4043( "OptionGroup `{0}` associated with program rule `{1}` does not exist" ),
    E4044( "DataElement or TrackedEntityAttribute cannot be null for program rule `{0}`" ),
    E4045( "DataElement `{0}` associated with program rule `{1}` does not exist" ),
    E4046( "TrackedEntityAttribute `{0}` associated with program rule `{1}` does not exist" ),
    E4047( "DataElement `{0}` is not linked to any ProgramStageDataElement for program rule `{1}`" ),
    E4048( "TrackedEntityAttribute `{0}` is not linked to ProgramTrackedEntityAttribute for program rule `{1}`" ),
    E4049( "Property `{0}` requires a valid username, was given `{1}`." ),
    E4050(
        "One of the parameters DataElement, TrackedEntityAttribute or ProgramRuleVariable is required for program rule `{0}`" ),

    /* ProgramRuleVariable validation */
    E4051( "A program rule variable with name `{0}` and program uid `{1}` already exists" ),
    E4052( "For program rule variable with name `{0}` following keywords are forbidden : and , or , not" ),
    E4053( "Program stage `{0}` must reference a program." ),

    /* SQL views */
    E4300( "SQL query is null" ),
    E4301( "SQL query must be a select query" ),
    E4302( "SQL query can only contain a single semi-colon at the end of the query" ),
    E4303( "Variables contain null key" ),
    E4304( "Variables contain null value" ),
    E4305( "Variable params are invalid: `{0}`" ),
    E4306( "Variables are invalid: `{0}`" ),
    E4307( "SQL query contains variables not provided in request: `{0}`" ),
    E4308( "Criteria params are invalid: `{0}`" ),
    E4309( "Criteria values are invalid: `{0}`" ),
    E4310( "SQL query contains references to protected tables" ),
    E4311( "SQL query contains illegal keywords" ),
    E4312( "Current user is not authorised to read data from SQL view: `{0}`" ),
    E4313( "SQL query contains variable names that are invalid: `{0}`" ),

    /* Preheat */
    E5000( "Found matching object for reference, but import mode is CREATE. Identifier was {0}, and object was {1}." ),
    E5001( "No matching object for reference. Identifier was {0}, and object was {1}." ),
    E5002( "Invalid reference {0} on object {1} for association `{2}`." ),
    E5003( "Property `{0}` with value `{1}` on object {2} already exists on object {3}." ),
    E5004( "Id `{0}` for type `{1}` exists on more than 1 object in the payload, removing all but the first found." ),
    E5005( "Properties `{0}` in objects `{1}` must be unique within the payload" ),
    E5006(
        "Non owner reference {0} on object {1} for association `{2}` is not allowed within payload for ERRORS_NOT_OWNER" ),

    /* Metadata import */
    E6000( "Program `{0}` has more than one Program Instances" ),
    E6001( "ProgramStage `{0}` has invalid next event scheduling property `{1}`. " +
        "This property need to be data element of value type date and belong the program stage." ),

    /* File resource */
    E6100( "Filename not present" ),
    E6101( "File type not allowed" ),

    /* Users */
    E6200( "Feedback message recipients user group not defined" ),

    /* Scheduling */
    E7000( "Job of same type already scheduled with cron expression: `{0}`" ),
    E7003( "Only interval property can be configured for non configurable job type: `{0}`" ),
    E7004( "Cron expression must be not null for job with scheduling type CRON: `{0}`" ),
    E7005( "Cron expression is invalid for job: `{0}` " ),
    E7006( "Failed to execute job: `{0}`." ),
    E7007( "Delay must be not null for job with scheduling type FIXED_DELAY: `{0}`" ),
    E7010( "Failed to validate job runtime: `{0}`" ),

    /* Aggregate analytics */
    E7100( "Query parameters cannot be null" ),
    E7101( "At least one dimension must be specified" ),
    E7102( "At least one data dimension item or data element group set dimension item must be specified" ),
    E7103( "Dimensions cannot be specified as dimension and filter simultaneously: `{0}`" ),
    E7104( "At least one period as dimension or filter, or start and dates, must be specified" ),
    E7105( "Periods and start and end dates cannot be specified simultaneously" ),
    E7106( "Start date cannot be after end date" ),
    E7107( "Start and end dates cannot be specified for reporting rates" ),
    E7108( "Only a single indicator can be specified as filter" ),
    E7109( "Only a single reporting rate can be specified as filter" ),
    E7110( "Category option combos cannot be specified as filter" ),
    E7111( "Dimensions cannot be specified more than once: `{0}`" ),
    E7112( "Reporting rates can only be specified together with dimensions of type: `{0}`" ),
    E7113( "Assigned categories cannot be specified when data elements are not specified" ),
    E7114( "Assigned categories can only be specified together with data elements" ),
    E7115( "Data elements must be of a value and aggregation type that allow aggregation: `{0}`" ),
    E7116( "Indicator expressions cannot contain cyclic references: `{0}`" ),
    E7117( "A data dimension 'dx' must be specified when output format is DATA_VALUE_SET" ),
    E7118( "A period dimension 'pe' must be specified when output format is DATA_VALUE_SET" ),
    E7119( "An organisation unit dimension 'ou' must be specified when output format is DATA_VALUE_SET" ),
    E7120( "User: `{0}` is not allowed to view org unit: `{1}`" ),
    E7121( "User: `{0}` is not allowed to read data for `{1}`: `{2}`" ),
    E7122( "Data approval level does not exist: `{0}`" ),
    E7123( "Current user is constrained by a dimension but has access to no dimension items: `{0}`" ),
    E7124( "Dimension is present in query without any valid dimension options: `{0}`" ),
    E7125( "Dimension identifier does not reference any dimension: `{0}`" ),
    E7126( "Column must be present as dimension in query: `{0}`" ),
    E7127( "Row must be present as dimension in query: `{0}`" ),
    E7128( "Query result set exceeded max limit: `{0}`" ),
    E7129( "Program is specified but does not exist: `{0}`" ),
    E7130( "Program stage is specified but does not exist: `{0}`" ),
    E7131( "Query failed, likely because the query timed out" ),
    E7132( "An indicator expression caused division by zero operation" ),
    E7133( "Query cannot be executed, possibly because of invalid types or invalid operation" ),

    /* Event analytics */
    E7200( "At least one organisation unit must be specified" ),
    E7201( "Dimensions cannot be specified more than once: `{0}`" ),
    E7202( "Query items cannot be specified more than once: `{0}`" ),
    E7203( "Value dimension cannot also be specified as an item or item filter" ),
    E7204( "Value dimension or aggregate data must be specified when aggregation type is specified" ),
    E7205( "Start and end date or at least one period must be specified" ),
    E7206( "Start date is after end date: `{0}`, `{1}`" ),
    E7207( "Page number must be a positive number: `{0}`" ),
    E7208( "Page size must be zero or a positive number: `{0}`" ),
    E7209( "Limit is larger than max limit: `{0}`, `{1}`" ),
    E7210( "Time field is invalid: `{0}`" ),
    E7211( "Org unit field is invalid: `{0}`" ),
    E7212( "Cluster size must be a positive number: `{0}`" ),
    E7213( "Bbox is invalid, must be on format: 'min-lng,min-lat,max-lng,max-lat': `{0}`" ),
    E7214( "Cluster field must be specified when bbox or cluster size are specified" ),
    E7215( "Query item cannot specify both legend set and option set: `{0}`" ),
    E7216( "Query item must be aggregateable when used in aggregate query: `{0}`" ),
    E7217( "User is not allowed to view event analytics data: `{0}`" ),
    E7218( "Spatial database support is not enabled" ),
    E7219( "Data element must be of value type coordinate or org unit to be used as coordinate field: `{0}`" ),
    E7220( "Attribute must be of value type coordinate or org unit to be used as coordinate field: `{0}`" ),
    E7221( "Coordinate field is invalid: `{0}`" ),
    E7222( "Query item or filter is invalid: `{0}`" ),
    E7223( "Value does not refer to a data element or attribute which are numeric and part of the program: `{0}`" ),
    E7224( "Item identifier does not reference any data element, attribute or indicator part of the program: `{0}`" ),
    E7225( "Program stage is mandatory for data element dimensions in enrollment analytics queries: `{0}`" ),
    E7226( "Dimension is not a valid query item: `{0}`" ),
    E7227( "Relationship entity type not supported: `{0}`" ),
    E7228( "Fallback coordinate field is invalid: `{0}` " ),
    E7229( "Operator '{0}' does not allow missing value" ),

    /* Org unit analytics */
    E7300( "At least one organisation unit must be specified" ),
    E7301( "At least one organisation unit group set must be specified" ),

    /* Debug analytics */
    E7400( "Debug query must contain at least one data element, one period and one organisation unit" ),

    /* Validation Results API */
    E7500( "Organisation unit does not exist: `{0}`" ),
    E7501( "Validation rule does not exist: `{0}`" ),
    E7502( "Filter for period is not valid: `{0}`" ),
    E7503( "Filter for created date period is not valid: `{0}`" ),

    /* Data import validation */
    // Data Set validation
    E7600( "Data set not found or not accessible: `{0}`" ),
    E7601( "User does not have write access for DataSet: `{0}`" ),
    E7602( "A valid dataset is required" ),
    E7603( "Org unit not found or not accessible: `{0}`" ),
    E7604( "Attribute option combo not found or not accessible: `{0}`" ),
    // Data Value validation
    E7610( "Data element not found or not accessible: `{0}`" ),
    E7611( "Period not valid: `{0}`" ),
    E7612( "Organisation unit not found or not accessible: `{0}`" ),
    E7613( "Category option combo not found or not accessible for writing data: `{0}`" ),
    E7614( "Category option combo: `{0}` option not accessible: `{1}`" ),
    E7615( "Attribute option combo not found or not accessible for writing data: `{0}`" ),
    E7616( "Attribute option combo: `{0}` option not accessible: `{1}`" ),
    E7617( "Organisation unit: `{0}` not in hierarchy of current user: `{1}`" ),
    E7618( "Data value or comment not specified for data element: `{0}`" ),
    E7619( "Value must match data element''s `{0}` type constraints: {1}" ),
    E7620( "Invalid comment: {0}" ),
    E7621( "Data value is not a valid option of the data element option set: `{0}`" ),
    // Data Value constraints
    E7630( "Category option combo is required but is not specified" ),
    E7631( "Attribute option combo is required but is not specified" ),
    E7632( "Period type of period: `{0}` not valid for data element: `{1}`" ),
    E7633( "Data element: `{0}` is not part of dataset: `{1}`" ),
    E7634( "Category option combo: `{0}` must be part of category combo of data element: `{1}`" ),
    E7635( "Attribute option combo: `{0}` must be part of category combo of data sets of data element: `{1}`" ),
    E7636( "Data element: `{1}` must be assigned through data sets to organisation unit: `{0}`" ),
    E7637( "Invalid storedBy: {0}" ),
    E7638( "Period: `{0}` is not within date range of attribute option combo: `{1}`" ),
    E7639( "Organisation unit: `{0}` is not valid for attribute option combo: `{1}`" ),
    E7640( "Current date is past expiry days for period: `{0}`  and data set: `{1}`" ),
    E7641( "Period: `{0}` is after latest open future period: `{2}` for data element: `{1}`" ),
    E7642(
        "Data is already approved for data set: `{3}` period: `{1}` organisation unit: `{0}` attribute option combo: `{2}`" ),
    E7643( "Period: `{0}` is not open for this data set at this time: `{1}`" ),
    E7644( "Period: `{0}` does not conform to the open periods of associated data sets" ),
    E7645( "No data value for file resource exist for the given combination for data element: `{0}`" );

    private String message;

    ErrorCode( String message )
    {
        this.message = message;
    }

    public String getMessage()
    {
        return message;
    }
}

## 内容3
### 文件路径：
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/association/AbstractOrganisationUnitAssociationsQueryBuilder.java
### 代码内容：
package org.hisp.dhis.association;

import static java.util.stream.Collectors.joining;
import static org.hisp.dhis.hibernate.jsonb.type.JsonbFunctions.CHECK_USER_ACCESS;
import static org.hisp.dhis.hibernate.jsonb.type.JsonbFunctions.CHECK_USER_GROUPS_ACCESS;
import static org.hisp.dhis.hibernate.jsonb.type.JsonbFunctions.EXTRACT_PATH_TEXT;
import static org.hisp.dhis.hibernate.jsonb.type.JsonbFunctions.HAS_USER_GROUP_IDS;
import static org.hisp.dhis.hibernate.jsonb.type.JsonbFunctions.HAS_USER_ID;
import static org.hisp.dhis.security.acl.AclService.LIKE_READ_METADATA;

import java.util.Arrays;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Stream;

import lombok.RequiredArgsConstructor;

import org.hisp.dhis.commons.collection.CollectionUtils;
import org.hisp.dhis.user.CurrentUserGroupInfo;
import org.hisp.dhis.user.CurrentUserService;
import org.hisp.dhis.user.User;

@RequiredArgsConstructor
public abstract class AbstractOrganisationUnitAssociationsQueryBuilder
{

    private final CurrentUserService currentUserService;

    private static final String SHARING_OUTER_QUERY_BEGIN = "select " +
        "    inner_query_alias.uid, " +
        "    inner_query_alias.agg_ou_uid " +
        "from (";

    private static final String SHARING_OUTER_QUERY_END = ") as inner_query_alias";

    private static final String REL_TABLE_ALIAS = "relationship_table_alias";

    private static final String T_ALIAS = "base_table_alias";

    private static final String INNER_QUERY_GROUPING_BY = "group by " + T_ALIAS + ".uid, " + T_ALIAS
        + ".sharing";

    private String getInnerQuerySql()
    {
        return "select " +
            T_ALIAS + ".uid, " +
            T_ALIAS + ".sharing, " +
            "array_agg(ou.uid) agg_ou_uid " +
            "from " + getBaseTableName() + " " + T_ALIAS +
            " left join " + getRelationshipTableName() + " " + REL_TABLE_ALIAS +
            " on " + T_ALIAS + "." + getJoinColumnName() + " = " + REL_TABLE_ALIAS + "." + getJoinColumnName() +
            " left join organisationunit ou " +
            " on " + REL_TABLE_ALIAS + ".organisationunitid = ou.organisationunitid " +
            "where";
    }

    protected abstract String getRelationshipTableName();

    protected abstract String getJoinColumnName();

    protected abstract String getBaseTableName();

    public String buildSqlQuery( Set<String> uids, Set<String> userOrgUnitPaths, User currentUser )
    {
        Stream<String> queryParts = Stream.of(
            SHARING_OUTER_QUERY_BEGIN,
            innerQueryProvider( uids, userOrgUnitPaths, currentUser ),
            SHARING_OUTER_QUERY_END );

        if ( nonSuperUser( currentUser ) )
        {
            queryParts = Stream.concat(
                queryParts,
                Stream.of(
                    "where",
                    getSharingConditions( LIKE_READ_METADATA ) ) );
        }
        return queryParts.collect( joining( " " ) );
    }

    public String buildSqlQueryForRawAssociation( Set<String> uids )
    {
        Stream<String> queryParts = Stream.of(
            SHARING_OUTER_QUERY_BEGIN,
            innerQueryProvider( uids, null, null ),
            SHARING_OUTER_QUERY_END );

        return queryParts.collect( joining( " " ) );
    }

    private String innerQueryProvider( Set<String> uids, Set<String> userOrgUnitPaths, User currentUser )
    {
        Stream<String> queryParts = Stream.of(
            getInnerQuerySql(),
            getUidsFilter( uids ) );

        if ( nonSuperUser( currentUser ) )
        {
            queryParts = Stream.concat( queryParts,
                Stream.of(
                    "and",
                    getUserOrgUnitPathsFilter( userOrgUnitPaths ) ) );
        }

        queryParts = Stream.concat( queryParts, Stream.of( INNER_QUERY_GROUPING_BY ) );

        return queryParts.collect( joining( " " ) );
    }

    private String getSharingConditions( String access )
    {
        CurrentUserGroupInfo currentUserGroupInfo = currentUserService.getCurrentUserGroupsInfo();
        return String.join( " or ",
            getOwnerCondition( currentUserGroupInfo ),
            getPublicSharingCondition( access ),
            getUserGroupAccessCondition( currentUserGroupInfo, access ),
            getUserAccessCondition( currentUserGroupInfo, access ) );
    }

    private String getOwnerCondition( CurrentUserGroupInfo currentUserGroupInfo )
    {
        return String.join( " or ",
            jsonbFunction( EXTRACT_PATH_TEXT, "owner" ) + " = " + withQuotes( currentUserGroupInfo.getUserUID() ),
            jsonbFunction( EXTRACT_PATH_TEXT, "owner" ) + " is null" );
    }

    private String getPublicSharingCondition( String access )
    {
        return String.join( " or ",
            jsonbFunction( EXTRACT_PATH_TEXT, "public" ) + " like " + withQuotes( access ),
            jsonbFunction( EXTRACT_PATH_TEXT, "public" ) + " is null" );
    }

    private String getUserAccessCondition( CurrentUserGroupInfo currentUserGroupInfo, String access )
    {
        String userUid = currentUserGroupInfo.getUserUID();
        return Stream.of(
            jsonbFunction( HAS_USER_ID, userUid ),
            jsonbFunction( CHECK_USER_ACCESS, userUid, access ) )
            .collect( joining( " and ", "(", ")" ) );
    }

    private String getUserGroupAccessCondition( CurrentUserGroupInfo currentUserGroupInfo, String access )
    {
        if ( CollectionUtils.isEmpty( currentUserGroupInfo.getUserGroupUIDs() ) )
        {
            return "1=0";
        }
        String groupUids = "{" + String.join( ",", currentUserGroupInfo.getUserGroupUIDs() ) + "}";
        return Stream.of(
            jsonbFunction( HAS_USER_GROUP_IDS, groupUids ),
            jsonbFunction( CHECK_USER_GROUPS_ACCESS, access, groupUids ) )
            .collect( joining( " and ", "(", ")" ) );
    }

    private String jsonbFunction( String functionName, String... params )
    {
        return String.join( "",
            functionName,
            "(",
            String.join( ",", "inner_query_alias.sharing",
                Arrays.stream( params )
                    .map( this::withQuotes )
                    .collect( joining( "," ) ) ),
            ")" );
    }

    private boolean nonSuperUser( User currentUser )
    {
        return Objects.nonNull( currentUser ) && !currentUser.isSuper();
    }

    private String getUidsFilter( Set<String> uids )
    {
        return T_ALIAS + ".uid in (" +
            uids.stream()
                .map( this::withQuotes )
                .collect( joining( "," ) )
            + ")";
    }

    private String withQuotes( String uid )
    {
        return String.join( "", "'", uid, "'" );
    }

    private String getUserOrgUnitPathsFilter( Set<String> userOrgUnitPaths )
    {
        return Stream.concat(
            Stream.of( "ou.organisationUnitId is null" ),
            userOrgUnitPaths.stream()
                .map( userOrgUnitPath -> "ou.path like '" + userOrgUnitPath + "%'" ) )
            .collect( joining( " or ", "(", ")" ) );
    }

}

## 内容4
### 文件路径：
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/common/DefaultIdentifiableObjectManager.java
### 代码内容：
package org.hisp.dhis.common;

import static com.google.common.base.Preconditions.checkNotNull;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hisp.dhis.attribute.Attribute;
import org.hisp.dhis.attribute.AttributeValue;
import org.hisp.dhis.cache.Cache;
import org.hisp.dhis.cache.CacheProvider;
import org.hisp.dhis.category.Category;
import org.hisp.dhis.category.CategoryCombo;
import org.hisp.dhis.category.CategoryOption;
import org.hisp.dhis.category.CategoryOptionCombo;
import org.hisp.dhis.common.exception.InvalidIdentifierReferenceException;
import org.hisp.dhis.hibernate.HibernateProxyUtils;
import org.hisp.dhis.schema.Schema;
import org.hisp.dhis.schema.SchemaService;
import org.hisp.dhis.system.util.ReflectionUtils;
import org.hisp.dhis.translation.Translation;
import org.hisp.dhis.user.CurrentUserService;
import org.hisp.dhis.user.User;
import org.hisp.dhis.user.UserCredentials;
import org.hisp.dhis.user.UserGroup;
import org.hisp.dhis.user.UserInfo;
import org.hisp.dhis.util.SharingUtils;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.google.api.client.util.Lists;
import com.google.common.base.Defaults;
import com.google.common.collect.ImmutableMap;
import com.google.gson.internal.Primitives;

/**
 * Note that it is required for nameable object stores to have concrete
 * implementation classes, not rely on the HibernateIdentifiableObjectStore
 * class, in order to be injected as nameable object stores.
 *
 * @author Lars Helge Overland
 */
@Slf4j
@Component( "org.hisp.dhis.common.IdentifiableObjectManager" )
public class DefaultIdentifiableObjectManager
    implements IdentifiableObjectManager
{
    public static final String DEFAULT = "default";

    /**
     * Cache for default category objects. Disabled during test phase.
     */
    private final Cache<IdentifiableObject> defaultObjectCache;

    private final Set<IdentifiableObjectStore<? extends IdentifiableObject>> identifiableObjectStores;

    private final Set<GenericDimensionalObjectStore<? extends DimensionalObject>> dimensionalObjectStores;

    private final SessionFactory sessionFactory;

    private final CurrentUserService currentUserService;

    protected final SchemaService schemaService;

    private Map<Class<? extends IdentifiableObject>, IdentifiableObjectStore<? extends IdentifiableObject>> identifiableObjectStoreMap;

    private Map<Class<? extends DimensionalObject>, GenericDimensionalObjectStore<? extends DimensionalObject>> dimensionalObjectStoreMap;

    public DefaultIdentifiableObjectManager(
        Set<IdentifiableObjectStore<? extends IdentifiableObject>> identifiableObjectStores,
        Set<GenericDimensionalObjectStore<? extends DimensionalObject>> dimensionalObjectStores,
        SessionFactory sessionFactory, CurrentUserService currentUserService, SchemaService schemaService,
        CacheProvider cacheProvider )
    {
        checkNotNull( identifiableObjectStores );
        checkNotNull( dimensionalObjectStores );
        checkNotNull( sessionFactory );
        checkNotNull( currentUserService );
        checkNotNull( schemaService );
        checkNotNull( cacheProvider );

        this.identifiableObjectStores = identifiableObjectStores;
        this.dimensionalObjectStores = dimensionalObjectStores;
        this.sessionFactory = sessionFactory;
        this.currentUserService = currentUserService;
        this.schemaService = schemaService;
        this.defaultObjectCache = cacheProvider.createDefaultObjectCache();
    }

    // --------------------------------------------------------------------------
    // IdentifiableObjectManager implementation
    // --------------------------------------------------------------------------

    @Override
    @Transactional
    public void save( IdentifiableObject object )
    {
        save( object, true );
    }

    @Override
    @Transactional
    @SuppressWarnings( "unchecked" )
    public void save( IdentifiableObject object, boolean clearSharing )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore(
            HibernateProxyUtils.getRealClass( object ) );

        if ( store != null )
        {
            store.save( object, clearSharing );
        }
    }

    @Override
    @Transactional
    public void save( List<IdentifiableObject> objects )
    {
        objects.forEach( o -> save( o, true ) );
    }

    @Override
    @Transactional
    public void update( IdentifiableObject object )
    {
        update( object, currentUserService.getCurrentUser() );
    }

    @Override
    @Transactional
    @SuppressWarnings( "unchecked" )
    public void update( IdentifiableObject object, User user )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore(
            HibernateProxyUtils.getRealClass( object ) );

        if ( store != null )
        {
            store.update( object, user );
        }
    }

    @Override
    @Transactional
    public void update( List<IdentifiableObject> objects )
    {
        update( objects, currentUserService.getCurrentUser() );
    }

    @Override
    @Transactional
    public void update( List<IdentifiableObject> objects, User user )
    {
        if ( objects == null || objects.isEmpty() )
        {
            return;
        }

        for ( IdentifiableObject object : objects )
        {
            update( object, user );
        }
    }

    @Override
    @Transactional
    public void updateTranslations( IdentifiableObject persistedObject, Set<Translation> translations )
    {
        Session session = sessionFactory.getCurrentSession();

        BaseIdentifiableObject translatedObject = (BaseIdentifiableObject) persistedObject;

        translatedObject.setTranslations(
            translations.stream()
                .filter( t -> !StringUtils.isEmpty( t.getValue() ) )
                .collect( Collectors.toSet() ) );

        translatedObject.setLastUpdated( new Date() );
        translatedObject.setLastUpdatedBy( currentUserService.getCurrentUser() );

        session.update( translatedObject );
    }

    @Override
    @Transactional
    public void delete( IdentifiableObject object )
    {
        delete( object, currentUserService.getCurrentUser() );
    }

    @Override
    @Transactional
    @SuppressWarnings( "unchecked" )
    public void delete( IdentifiableObject object, User user )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore(
            HibernateProxyUtils.getRealClass( object ) );

        if ( store != null )
        {
            store.delete( object, user );
        }
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T get( String uid )
    {
        for ( IdentifiableObjectStore<? extends IdentifiableObject> store : identifiableObjectStores )
        {
            T object = (T) store.getByUid( uid );

            if ( object != null )
            {
                return object;
            }
        }

        return null;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T get( Class<T> clazz, long id )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (T) store.get( id );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T get( Class<T> clazz, String uid )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (T) store.getByUid( uid );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> boolean exists( Class<T> clazz, String uid )
    {
        return get( clazz, uid ) != null;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T get( Collection<Class<? extends IdentifiableObject>> classes, String uid )
    {
        for ( Class<? extends IdentifiableObject> clazz : classes )
        {
            T object = (T) get( clazz, uid );

            if ( object != null )
            {
                return object;
            }
        }

        return null;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T get( Collection<Class<? extends IdentifiableObject>> classes,
        IdScheme idScheme, String identifier )
    {
        for ( Class<? extends IdentifiableObject> clazz : classes )
        {
            T object = (T) getObject( clazz, idScheme, identifier );

            if ( object != null )
            {
                return object;
            }
        }

        return null;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getNoAcl( Class<T> clazz, Collection<String> uids )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (List<T>) store.getByUidNoAcl( uids );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T getByCode( Class<T> clazz, String code )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (T) store.getByCode( code );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T getByName( Class<T> clazz, String name )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (T) store.getByName( name );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> T getByUniqueAttributeValue( Class<T> clazz, Attribute attribute,
        String value )
    {
        return getByUniqueAttributeValue( clazz, attribute, value, currentUserService.getCurrentUserInfo() );
    }

    @SuppressWarnings( "unchecked" )
    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> T getByUniqueAttributeValue( Class<T> clazz, Attribute attribute,
        String value, UserInfo userInfo )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (T) store.getByUniqueAttributeValue( attribute, value, userInfo );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> T search( Class<T> clazz, String query )
    {
        T object = get( clazz, query );

        if ( object == null )
        {
            object = getByCode( clazz, query );
        }

        if ( object == null )
        {
            object = getByName( clazz, query );
        }

        return object;
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> List<T> filter( Class<T> clazz, String query )
    {
        Set<T> uniqueObjects = new HashSet<>();

        T uidObject = get( clazz, query );

        if ( uidObject != null )
        {
            uniqueObjects.add( uidObject );
        }

        T codeObject = getByCode( clazz, query );

        if ( codeObject != null )
        {
            uniqueObjects.add( codeObject );
        }

        uniqueObjects.addAll( getLikeName( clazz, query, false ) );

        List<T> objects = new ArrayList<>( uniqueObjects );

        Collections.sort( objects );

        return objects;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getAll( Class<T> clazz )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAll();
    }

    @Override
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getDataWriteAll( Class<T> clazz )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getDataWriteAll();
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getDataReadAll( Class<T> clazz )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getDataReadAll();
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getAllSorted( Class<T> clazz )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAllOrderedName();
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getAllByAttributes( Class<T> klass, List<Attribute> attributes )
    {
        Schema schema = schemaService.getDynamicSchema( klass );

        if ( schema == null || !schema.havePersistedProperty( "attributeValues" ) || attributes.isEmpty() )
        {
            return new ArrayList<>();
        }

        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAllByAttributes( attributes );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> List<AttributeValue> getAllValuesByAttributes( Class<T> klass,
        List<Attribute> attributes )
    {
        Schema schema = schemaService.getDynamicSchema( klass );

        if ( schema == null || !schema.havePersistedProperty( "attributeValues" ) || attributes.isEmpty() )
        {
            return new ArrayList<>();
        }

        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return store.getAllValuesByAttributes( attributes );
    }

    @Override
    public <T extends IdentifiableObject> long countAllValuesByAttributes( Class<T> klass, List<Attribute> attributes )
    {
        Schema schema = schemaService.getDynamicSchema( klass );

        if ( schema == null || !schema.havePersistedProperty( "attributeValues" ) || attributes.isEmpty() )
        {
            return 0;
        }

        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );

        if ( store == null )
        {
            return 0;
        }

        return store.countAllValuesByAttributes( attributes );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getByUid( Class<T> clazz, Collection<String> uids )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getByUid( uids );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getByUid( Collection<Class<? extends IdentifiableObject>> classes,
        Collection<String> uids )
    {
        List<T> list = new ArrayList<>();

        for ( Class<? extends IdentifiableObject> clazz : classes )
        {
            list.addAll( (List<T>) getByUid( clazz, uids ) );
        }

        return list;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getById( Class<T> clazz, Collection<Long> ids )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (List<T>) store.getById( ids );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getByCode( Class<T> clazz, Collection<String> codes )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getByCode( codes );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> List<T> getOrdered( Class<T> clazz, IdScheme idScheme,
        Collection<String> values )
    {
        if ( values == null )
        {
            return new ArrayList<>();
        }

        List<T> list = new ArrayList<>();

        for ( String value : values )
        {
            T object = getObject( clazz, idScheme, value );

            if ( object != null )
            {
                list.add( object );
            }
        }

        return list;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getByUidOrdered( Class<T> clazz, List<String> uids )
    {
        IdentifiableObjectStore<T> store = (IdentifiableObjectStore<T>) getIdentifiableObjectStore( clazz );

        if ( store == null || uids == null )
        {
            return new ArrayList<>();
        }

        List<T> list = new ArrayList<>();

        for ( String uid : uids )
        {
            T object = store.getByUid( uid );

            if ( object != null )
            {
                list.add( object );
            }
        }

        return list;
    }

    @Override
    @Transactional
    public <T extends IdentifiableObject> int getCount( Class<T> clazz )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store != null )
        {
            return store.getCount();
        }

        return 0;
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> int getCountByCreated( Class<T> clazz, Date created )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store != null )
        {
            return store.getCountGeCreated( created );
        }

        return 0;
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> int getCountByLastUpdated( Class<T> clazz, Date lastUpdated )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store != null )
        {
            return store.getCountGeLastUpdated( lastUpdated );
        }

        return 0;
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getLikeName( Class<T> clazz, String name )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAllLikeName( name );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getLikeName( Class<T> clazz, String name, boolean caseSensitive )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAllLikeName( name, caseSensitive );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getBetweenSorted( Class<T> clazz, int first, int max )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAllOrderedName( first, max );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getBetweenLikeName( Class<T> clazz, Set<String> words, int first,
        int max )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAllLikeName( words, first, max );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> Date getLastUpdated( Class<T> clazz )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return store.getLastUpdated();
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> Map<String, T> getIdMap( Class<T> clazz, IdentifiableProperty property )
    {
        return getIdMap( clazz, IdScheme.from( property ) );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> Map<String, T> getIdMap( Class<T> clazz, IdScheme idScheme )
    {
        IdentifiableObjectStore<T> store = (IdentifiableObjectStore<T>) getIdentifiableObjectStore( clazz );

        Map<String, T> map = new HashMap<>();

        if ( store == null )
        {
            return map;
        }

        List<T> objects = store.getAll();

        return IdentifiableObjectUtils.getIdMap( objects, idScheme );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> Map<String, T> getIdMapNoAcl( Class<T> clazz, IdentifiableProperty property )
    {
        return getIdMapNoAcl( clazz, IdScheme.from( property ) );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> Map<String, T> getIdMapNoAcl( Class<T> clazz, IdScheme idScheme )
    {
        IdentifiableObjectStore<T> store = (IdentifiableObjectStore<T>) getIdentifiableObjectStore( clazz );

        Map<String, T> map = new HashMap<>();

        if ( store == null )
        {
            return map;
        }

        List<T> objects = store.getAllNoAcl();

        return IdentifiableObjectUtils.getIdMap( objects, idScheme );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getObjects( Class<T> clazz, IdentifiableProperty property,
        Collection<String> identifiers )
    {
        IdentifiableObjectStore<T> store = (IdentifiableObjectStore<T>) getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        if ( identifiers != null && !identifiers.isEmpty() )
        {
            if ( property == null || IdentifiableProperty.UID.equals( property ) )
            {
                return store.getByUid( identifiers );
            }
            else if ( IdentifiableProperty.CODE.equals( property ) )
            {
                return store.getByCode( identifiers );
            }
            else if ( IdentifiableProperty.NAME.equals( property ) )
            {
                return store.getByName( identifiers );
            }

            throw new InvalidIdentifierReferenceException(
                "Invalid identifiable property / class combination: " + property );
        }

        return new ArrayList<>();
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getObjects( Class<T> clazz, Collection<Long> identifiers )
    {
        IdentifiableObjectStore<T> store = (IdentifiableObjectStore<T>) getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return store.getById( identifiers );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> T getObject( Class<T> clazz, IdentifiableProperty property, String value )
    {
        return getObject( clazz, IdScheme.from( property ), value );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T getObject( Class<T> clazz, IdScheme idScheme, String value )
    {
        IdentifiableObjectStore<T> store = (IdentifiableObjectStore<T>) getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        if ( !StringUtils.isEmpty( value ) )
        {
            if ( idScheme.isNull() || idScheme.is( IdentifiableProperty.UID ) )
            {
                return store.getByUid( value );
            }
            else if ( idScheme.is( IdentifiableProperty.CODE ) )
            {
                return store.getByCode( value );
            }
            else if ( idScheme.is( IdentifiableProperty.NAME ) )
            {
                return store.getByName( value );
            }
            else if ( idScheme.is( IdentifiableProperty.ATTRIBUTE ) )
            {
                Attribute attribute = get( Attribute.class, idScheme.getAttribute() );
                return store.getByUniqueAttributeValue( attribute, value );
            }
            else if ( idScheme.is( IdentifiableProperty.ID ) )
            {
                if ( Integer.valueOf( value ) > 0 )
                {
                    return store.get( Integer.valueOf( value ) );
                }
            }

            throw new InvalidIdentifierReferenceException(
                "Invalid identifiable property / class combination: " + idScheme );
        }

        return null;
    }

    @Override
    @Transactional( readOnly = true )
    public IdentifiableObject getObject( String uid, String simpleClassName )
    {
        for ( IdentifiableObjectStore<? extends IdentifiableObject> objectStore : identifiableObjectStores )
        {
            if ( simpleClassName.equals( objectStore.getClazz().getSimpleName() ) )
            {
                return objectStore.getByUid( uid );
            }
        }

        return null;
    }

    @Override
    @Transactional( readOnly = true )
    public IdentifiableObject getObject( long id, String simpleClassName )
    {
        for ( IdentifiableObjectStore<? extends IdentifiableObject> objectStore : identifiableObjectStores )
        {
            if ( simpleClassName.equals( objectStore.getClazz().getSimpleName() ) )
            {
                return objectStore.get( id );
            }
        }

        return null;
    }

    @Override
    @Transactional
    public void refresh( Object object )
    {
        sessionFactory.getCurrentSession().refresh( object );
    }

    @Override
    public void resetNonOwnerProperties( Object object )
    {
        if ( object == null )
        {
            return;
        }

        Schema schema = schemaService.getDynamicSchema( object.getClass() );

        schema.getProperties()
            .stream()
            .filter( p -> !p.isOwner() && p.getSetterMethod() != null && !SharingUtils.isLegacySharingProperty( p ) )
            .forEach( p -> {
                Class<?> parameterType = p.getSetterMethod().getParameterTypes()[0];

                if ( p.isCollection() )
                {
                    Collection<?> targetObject = ReflectionUtils.newCollectionInstance( parameterType );
                    ReflectionUtils.invokeMethod( object, p.getSetterMethod(), targetObject );
                }
                else
                {
                    if ( Primitives.isPrimitive( parameterType ) )
                    {
                        ReflectionUtils.invokeMethod( object, p.getSetterMethod(),
                            Defaults.defaultValue( parameterType ) );
                    }
                    else
                    {
                        ReflectionUtils.invokeMethod( object, p.getSetterMethod(), (Object) null );
                    }
                }
            } );
    }

    @Override
    @Transactional
    public void flush()
    {
        sessionFactory.getCurrentSession().flush();
    }

    @Override
    @Transactional
    public void clear()
    {
        sessionFactory.getCurrentSession().clear();
    }

    @Override
    @Transactional
    public void evict( Object object )
    {
        sessionFactory.getCurrentSession().evict( object );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> T getNoAcl( Class<T> clazz, String uid )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return null;
        }

        return (T) store.getByUidNoAcl( uid );
    }

    @Override
    @Transactional
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> void updateNoAcl( T object )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore(
            HibernateProxyUtils.getRealClass( object ) );

        if ( store != null )
        {
            store.updateNoAcl( object );
        }
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getAllNoAcl( Class<T> clazz )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getAllNoAcl();
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends DimensionalObject> List<T> getDataDimensions( Class<T> clazz )
    {
        GenericDimensionalObjectStore<DimensionalObject> store = getDimensionalObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getByDataDimension( true );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends DimensionalObject> List<T> getDataDimensionsNoAcl( Class<T> clazz )
    {
        GenericDimensionalObjectStore<DimensionalObject> store = getDimensionalObjectStore( clazz );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return (List<T>) store.getByDataDimensionNoAcl( true );
    }

    @Override
    @Transactional( readOnly = true )
    @SuppressWarnings( "unchecked" )
    public <T extends IdentifiableObject> List<T> getByAttributeAndValue( Class<T> klass, Attribute attribute,
        String value )
    {
        Schema schema = schemaService.getDynamicSchema( klass );

        if ( schema == null || !schema.havePersistedProperty( "attributeValues" ) )
        {
            return null;
        }

        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );

        if ( store == null )
        {
            return null;
        }

        return (List<T>) store.getByAttributeAndValue( attribute, value );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> boolean isAttributeValueUnique( Class<? extends IdentifiableObject> klass,
        T object, AttributeValue attributeValue )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );
        return store != null && store.isAttributeValueUnique( object, attributeValue );
    }

    @Override
    @Transactional( readOnly = true )
    public <T extends IdentifiableObject> boolean isAttributeValueUnique( Class<? extends IdentifiableObject> klass,
        T object, Attribute attribute, String value )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );
        return store != null && store.isAttributeValueUnique( object, attribute, value );
    }

    @Override
    @Transactional( readOnly = true )
    public List<? extends IdentifiableObject> getAllByAttributeAndValues( Class<? extends IdentifiableObject> klass,
        Attribute attribute, List<String> values )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );
        return store != null ? store.getAllByAttributeAndValues( attribute, values ) : Lists.newArrayList();
    }

    @Override
    @Transactional( readOnly = true )
    public Map<Class<? extends IdentifiableObject>, IdentifiableObject> getDefaults()
    {
        Optional<IdentifiableObject> categoryObjects = defaultObjectCache.get( Category.class.getName(),
            key -> HibernateProxyUtils.unproxy( getByName( Category.class, DEFAULT ) ) );
        Optional<IdentifiableObject> categoryComboObjects = defaultObjectCache.get( CategoryCombo.class.getName(),
            key -> HibernateProxyUtils.unproxy( getByName( CategoryCombo.class, DEFAULT ) ) );
        Optional<IdentifiableObject> categoryOptionObjects = defaultObjectCache.get( CategoryOption.class.getName(),
            key -> HibernateProxyUtils.unproxy( getByName( CategoryOption.class, DEFAULT ) ) );
        Optional<IdentifiableObject> categoryOptionCombo = defaultObjectCache.get(
            CategoryOptionCombo.class.getName(),
            key -> HibernateProxyUtils.unproxy( getByName( CategoryOptionCombo.class, DEFAULT ) ) );

        return new ImmutableMap.Builder<Class<? extends IdentifiableObject>, IdentifiableObject>()
            .put( Category.class, Objects.requireNonNull( categoryObjects.orElse( null ) ) )
            .put( CategoryCombo.class, Objects.requireNonNull( categoryComboObjects.orElse( null ) ) )
            .put( CategoryOption.class, Objects.requireNonNull( categoryOptionObjects.orElse( null ) ) )
            .put( CategoryOptionCombo.class, Objects.requireNonNull( categoryOptionCombo.orElse( null ) ) )
            .build();
    }

    @Override
    @Transactional( readOnly = true )
    public List<String> getUidsCreatedBefore( Class<? extends IdentifiableObject> klass, Date date )
    {
        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( klass );

        if ( store == null )
        {
            return new ArrayList<>();
        }

        return store.getUidsCreatedBefore( date );
    }

    // --------------------------------------------------------------------------
    // Supportive methods
    // --------------------------------------------------------------------------

    @Override
    @Transactional( readOnly = true )
    public boolean isDefault( IdentifiableObject object )
    {
        Map<Class<? extends IdentifiableObject>, IdentifiableObject> defaults = getDefaults();

        if ( object == null )
        {
            return false;
        }

        Class<?> realClass = HibernateProxyUtils.getRealClass( object );

        if ( !defaults.containsKey( realClass ) )
        {
            return false;
        }

        IdentifiableObject defaultObject = defaults.get( realClass );

        return defaultObject != null && defaultObject.getUid().equals( object.getUid() );
    }

    @Override
    @Transactional
    public void removeUserGroupFromSharing( String userGroupUid )
    {
        List<Schema> schemas = schemaService.getSchemas().stream().filter( s -> s.isShareable() ).collect(
            Collectors.toList() );

        IdentifiableObjectStore<IdentifiableObject> store = getIdentifiableObjectStore( UserGroup.class );
        schemas.forEach( schema -> store.removeUserGroupFromSharing( userGroupUid, schema.getTableName() ) );
    }

    @SuppressWarnings( "unchecked" )
    private <T extends IdentifiableObject> IdentifiableObjectStore<IdentifiableObject> getIdentifiableObjectStore(
        Class<T> clazz )
    {
        initMaps();

        IdentifiableObjectStore<? extends IdentifiableObject> store = identifiableObjectStoreMap.get( clazz );

        if ( store == null )
        {
            store = identifiableObjectStoreMap.get( clazz.getSuperclass() );

            if ( store == null && !UserCredentials.class.isAssignableFrom( clazz ) )
            {
                log.debug( "No IdentifiableObjectStore found for class: " + clazz );
            }
        }

        return (IdentifiableObjectStore<IdentifiableObject>) store;
    }

    @SuppressWarnings( "unchecked" )
    private <T extends DimensionalObject> GenericDimensionalObjectStore<DimensionalObject> getDimensionalObjectStore(
        Class<T> clazz )
    {
        initMaps();

        GenericDimensionalObjectStore<? extends DimensionalObject> store = dimensionalObjectStoreMap.get( clazz );

        if ( store == null )
        {
            store = dimensionalObjectStoreMap.get( clazz.getSuperclass() );

            if ( store == null )
            {
                log.debug( "No DimensionalObjectStore found for class: " + clazz );
            }
        }

        return (GenericDimensionalObjectStore<DimensionalObject>) store;
    }

    private void initMaps()
    {
        if ( identifiableObjectStoreMap != null )
        {
            return; // Already initialized
        }

        identifiableObjectStoreMap = new HashMap<>();

        for ( IdentifiableObjectStore<? extends IdentifiableObject> store : identifiableObjectStores )
        {
            identifiableObjectStoreMap.put( store.getClazz(), store );
        }

        dimensionalObjectStoreMap = new HashMap<>();

        for ( GenericDimensionalObjectStore<? extends DimensionalObject> store : dimensionalObjectStores )
        {
            dimensionalObjectStoreMap.put( store.getClazz(), store );
        }
    }
}

## 内容5
### 文件路径：
dhis-2/dhis-services/dhis-service-core/src/main/java/org/hisp/dhis/program/DefaultProgramService.java
### 代码内容：
package org.hisp.dhis.program;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import lombok.RequiredArgsConstructor;

import org.apache.commons.collections4.SetValuedMap;
import org.hisp.dhis.dataelement.DataElement;
import org.hisp.dhis.dataentryform.DataEntryForm;
import org.hisp.dhis.organisationunit.OrganisationUnit;
import org.hisp.dhis.program.jdbc.JdbcOrgUnitAssociationsStore;
import org.hisp.dhis.trackedentity.TrackedEntityType;
import org.hisp.dhis.user.CurrentUserService;
import org.hisp.dhis.user.User;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;

/**
 * @author Abyot Asalefew
 */
@RequiredArgsConstructor
@Service( "org.hisp.dhis.program.ProgramService" )
public class DefaultProgramService
    implements ProgramService
{
    // -------------------------------------------------------------------------
    // Dependencies
    // -------------------------------------------------------------------------

    private final ProgramStore programStore;

    private final CurrentUserService currentUserService;

    @Qualifier( "jdbcProgramOrgUnitAssociationsStore" )
    private final JdbcOrgUnitAssociationsStore jdbcOrgUnitAssociationsStore;

    // -------------------------------------------------------------------------
    // Implementation methods
    // -------------------------------------------------------------------------

    @Override
    @Transactional
    public long addProgram( Program program )
    {
        programStore.save( program );
        return program.getId();
    }

    @Override
    @Transactional
    public void updateProgram( Program program )
    {
        programStore.update( program );
    }

    @Override
    @Transactional
    public void deleteProgram( Program program )
    {
        programStore.delete( program );
    }

    @Override
    @Transactional( readOnly = true )
    public List<Program> getAllPrograms()
    {
        return programStore.getAll();
    }

    @Override
    @Transactional( readOnly = true )
    public Program getProgram( long id )
    {
        return programStore.get( id );
    }

    @Override
    @Transactional( readOnly = true )
    public Collection<Program> getPrograms( Collection<String> uids )
    {
        return programStore.getByUid( uids );
    }

    @Override
    @Transactional( readOnly = true )
    public List<Program> getPrograms( OrganisationUnit organisationUnit )
    {
        return programStore.get( organisationUnit );
    }

    @Override
    @Transactional( readOnly = true )
    public Program getProgram( String uid )
    {
        return programStore.getByUid( uid );
    }

    @Override
    @Transactional( readOnly = true )
    public List<Program> getProgramsByTrackedEntityType( TrackedEntityType trackedEntityType )
    {
        return programStore.getByTrackedEntityType( trackedEntityType );
    }

    @Override
    @Transactional( readOnly = true )
    public List<Program> getProgramsByDataEntryForm( DataEntryForm dataEntryForm )
    {
        return programStore.getByDataEntryForm( dataEntryForm );
    }

    @Override
    @Transactional( readOnly = true )
    public List<Program> getUserPrograms()
    {
        return getUserPrograms( currentUserService.getCurrentUser() );
    }

    @Override
    @Transactional( readOnly = true )
    public List<Program> getUserPrograms( User user )
    {
        if ( user == null || user.isSuper() )
        {
            return getAllPrograms();
        }

        return programStore.getDataReadAll( user );
    }

    // -------------------------------------------------------------------------
    // ProgramDataElement
    // -------------------------------------------------------------------------

    @Override
    @Transactional( readOnly = true )
    public List<ProgramDataElementDimensionItem> getGeneratedProgramDataElements( String programUid )
    {
        Program program = getProgram( programUid );

        List<ProgramDataElementDimensionItem> programDataElements = Lists.newArrayList();

        if ( program == null )
        {
            return programDataElements;
        }

        for ( DataElement element : program.getDataElements() )
        {
            programDataElements.add( new ProgramDataElementDimensionItem( program, element ) );
        }

        Collections.sort( programDataElements );

        return programDataElements;
    }

    @Override
    public boolean hasOrgUnit( Program program, OrganisationUnit organisationUnit )
    {
        return this.programStore.hasOrgUnit( program, organisationUnit );
    }

    @Override
    public SetValuedMap<String, String> getProgramOrganisationUnitsAssociationsForCurrentUser(
        Set<String> programUids )
    {
        return jdbcOrgUnitAssociationsStore.getOrganisationUnitsAssociationsForCurrentUser( programUids );
    }

    @Override
    public SetValuedMap<String, String> getProgramOrganisationUnitsAssociations( Set<String> programUids )
    {
        return jdbcOrgUnitAssociationsStore.getOrganisationUnitsAssociations( programUids );
    }

}

## 内容6
### 文件路径：
dhis-2/dhis-support/dhis-support-commons/src/main/java/org/hisp/dhis/commons/collection/CollectionUtils.java
### 代码内容：
package org.hisp.dhis.commons.collection;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Objects;
import java.util.Set;
import java.util.function.Consumer;

/**
 * Utility methods for operations on various collections.
 *
 * @author Morten Olav Hansen
 */
public class CollectionUtils
{
    public static final String[] STRING_ARR = new String[0];

    /**
     * Returns the intersection of the given Collections.
     *
     * @param c1 the first Collection.
     * @param c2 the second Collection.
     * @param <T> the type.
     * @return the intersection of the Collections.
     */
    public static <T> Collection<T> intersection( Collection<T> c1, Collection<T> c2 )
    {
        Set<T> set1 = new HashSet<>( c1 );
        set1.retainAll( new HashSet<>( c2 ) );
        return set1;
    }

    /**
     * Searches for and returns the first string which starts with the given
     * prefix. Removes the match from the collection.
     *
     * @param collection the collection.
     * @param prefix the string prefix.
     * @return a string, or null if no matches.
     */
    public static String popStartsWith( Collection<String> collection, String prefix )
    {
        Iterator<String> iterator = collection.iterator();

        while ( iterator.hasNext() )
        {
            String element = iterator.next();

            if ( element != null && element.startsWith( prefix ) )
            {
                iterator.remove();
                return element;
            }
        }

        return null;
    }

    /**
     * Applies the given consumer to each item in the given collection after
     * filtering out null items.
     *
     * @param collection the collection.
     * @param consumer the consumer.
     */
    public static <E> void nullSafeForEach( Collection<E> collection, Consumer<E> consumer )
    {
        collection.stream()
            .filter( Objects::nonNull )
            .forEach( consumer );
    }

    /**
     * Returns an empty set if the given set is null, if not returns the set.
     *
     * @param set the set.
     * @return a non-null set.
     */
    public static <T> Set<T> emptyIfNull( Set<T> set )
    {
        return set != null ? set : new HashSet<>();
    }

    /**
     * Adds all items not already present in the target collection
     *
     * @param collection collection to add items to.
     * @param items collection of items to add.
     */
    public static <E> void addAllUnique( Collection<E> collection, Collection<E> items )
    {
        items.stream()
            .filter( item -> !collection.contains( item ) )
            .forEach( item -> collection.add( item ) );
    }

    public static boolean isEmpty( Collection collection )
    {
        return collection == null || collection.isEmpty();
    }
}

Output:
【漏洞类型】SQL注入漏洞
【严重性】Medium
【漏洞摘要】此代码中的`AbstractOrganisationUnitAssociationsQueryBuilder`类在构建SQL查询时，使用了用户输入的数据（如`uids`），而没有对其进行适当的验证或参数化。具体表现为在`getInnerQuerySql`方法中，将`uids`直接拼接到SQL语句中，形成了SQL注入的条件。例如，`withQuotes`方法简单地在字符串两端添加单引号，这并不能防止恶意用户通过构造特定的`uids`值来执行任意SQL查询。
【关键代码模式】
- `innerQueryProvider`方法中的`getUidsFilter`函数，将`uids`直接拼接到SQL语句中。
- `withQuotes`方法，用于将字符串包裹在单引号中，但未能有效防止SQL注入。
- `getUserOrgUnitPathsFilter`方法，将用户输入的`path`拼接到SQL语句中。
【修复方法说明】通过添加`getAndValidateByUid`方法，对传入的`uids`进行验证，确保所有`uid`都存在于数据库中，从而防止SQL注入。使用`SqlUtils::singleQuote`函数替代`withQuotes`方法，确保SQL语句中字符串的正确引用。


Instruction:
作为 Java 安全专家，检测此代码中的安全漏洞：
## 内容1
### 文件路径：
ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/SysProfileController.java
### 代码内容：
package com.ruoyi.web.controller.system;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.ShiroUtils;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.framework.shiro.service.SysPasswordService;
import com.ruoyi.system.service.ISysUserService;

/**
 * 个人信息 业务处理
 *
 * @author ruoyi
 */
@Controller
@RequestMapping("/system/user/profile")
public class SysProfileController extends BaseController
{
    private static final Logger log = LoggerFactory.getLogger(SysProfileController.class);

    private String prefix = "system/user/profile";

    @Autowired
    private ISysUserService userService;

    @Autowired
    private SysPasswordService passwordService;

    /**
     * 个人信息
     */
    @GetMapping()
    public String profile(ModelMap mmap)
    {
        SysUser user = getSysUser();
        mmap.put("user", user);
        mmap.put("roleGroup", userService.selectUserRoleGroup(user.getUserId()));
        mmap.put("postGroup", userService.selectUserPostGroup(user.getUserId()));
        return prefix + "/profile";
    }

    @GetMapping("/checkPassword")
    @ResponseBody
    public boolean checkPassword(String password)
    {
        SysUser user = getSysUser();
        if (passwordService.matches(user, password))
        {
            return true;
        }
        return false;
    }

    @GetMapping("/resetPwd")
    public String resetPwd(ModelMap mmap)
    {
        SysUser user = getSysUser();
        mmap.put("user", userService.selectUserById(user.getUserId()));
        return prefix + "/resetPwd";
    }

    @Log(title = "重置密码", businessType = BusinessType.UPDATE)
    @PostMapping("/resetPwd")
    @ResponseBody
    public AjaxResult resetPwd(String oldPassword, String newPassword)
    {
        SysUser user = getSysUser();
        if (!passwordService.matches(user, oldPassword))
        {
            return error("修改密码失败，旧密码错误");
        }
        if (passwordService.matches(user, newPassword))
        {
            return error("新密码不能与旧密码相同");
        }
        user.setSalt(ShiroUtils.randomSalt());
        user.setPassword(passwordService.encryptPassword(user.getLoginName(), newPassword, user.getSalt()));
        user.setPwdUpdateDate(DateUtils.getNowDate());
        if (userService.resetUserPwd(user) > 0)
        {
            setSysUser(userService.selectUserById(user.getUserId()));
            return success();
        }
        return error("修改密码异常，请联系管理员");
    }

    /**
     * 修改用户
     */
    @GetMapping("/edit")
    public String edit(ModelMap mmap)
    {
        SysUser user = getSysUser();
        mmap.put("user", userService.selectUserById(user.getUserId()));
        return prefix + "/edit";
    }

    /**
     * 修改头像
     */
    @GetMapping("/avatar")
    public String avatar(ModelMap mmap)
    {
        SysUser user = getSysUser();
        mmap.put("user", userService.selectUserById(user.getUserId()));
        return prefix + "/avatar";
    }

    /**
     * 修改用户
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PostMapping("/update")
    @ResponseBody
    public AjaxResult update(SysUser user)
    {
        SysUser currentUser = getSysUser();
        currentUser.setUserName(user.getUserName());
        currentUser.setEmail(user.getEmail());
        currentUser.setPhonenumber(user.getPhonenumber());
        currentUser.setSex(user.getSex());
        if (StringUtils.isNotEmpty(user.getPhonenumber())
                && UserConstants.USER_PHONE_NOT_UNIQUE.equals(userService.checkPhoneUnique(currentUser)))
        {
            return error("修改用户'" + currentUser.getLoginName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail())
                && UserConstants.USER_EMAIL_NOT_UNIQUE.equals(userService.checkEmailUnique(currentUser)))
        {
            return error("修改用户'" + currentUser.getLoginName() + "'失败，邮箱账号已存在");
        }
        if (userService.updateUserInfo(currentUser) > 0)
        {
            setSysUser(userService.selectUserById(currentUser.getUserId()));
            return success();
        }
        return error();
    }

    /**
     * 保存头像
     */
    @Log(title = "个人信息", businessType = BusinessType.UPDATE)
    @PostMapping("/updateAvatar")
    @ResponseBody
    public AjaxResult updateAvatar(@RequestParam("avatarfile") MultipartFile file)
    {
        SysUser currentUser = getSysUser();
        try
        {
            if (!file.isEmpty())
            {
                String avatar = FileUploadUtils.upload(RuoYiConfig.getAvatarPath(), file);
                currentUser.setAvatar(avatar);
                if (userService.updateUserInfo(currentUser) > 0)
                {
                    setSysUser(userService.selectUserById(currentUser.getUserId()));
                    return success();
                }
            }
            return error();
        }
        catch (Exception e)
        {
            log.error("修改头像失败！", e);
            return error(e.getMessage());
        }
    }
}

## 内容2
### 文件路径：
ruoyi-common/src/main/java/com/ruoyi/common/exception/file/InvalidExtensionException.java
### 代码内容：
package com.ruoyi.common.exception.file;

import java.util.Arrays;
import org.apache.commons.fileupload.FileUploadException;

/**
 * 文件上传 误异常类
 *
 * @author ruoyi
 */
public class InvalidExtensionException extends FileUploadException
{
    private static final long serialVersionUID = 1L;

    private String[] allowedExtension;
    private String extension;
    private String filename;

    public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
    {
        super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
        this.allowedExtension = allowedExtension;
        this.extension = extension;
        this.filename = filename;
    }

    public String[] getAllowedExtension()
    {
        return allowedExtension;
    }

    public String getExtension()
    {
        return extension;
    }

    public String getFilename()
    {
        return filename;
    }

    public static class InvalidImageExtensionException extends InvalidExtensionException
    {
        private static final long serialVersionUID = 1L;

        public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
        {
            super(allowedExtension, extension, filename);
        }
    }

    public static class InvalidFlashExtensionException extends InvalidExtensionException
    {
        private static final long serialVersionUID = 1L;

        public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
        {
            super(allowedExtension, extension, filename);
        }
    }

    public static class InvalidMediaExtensionException extends InvalidExtensionException
    {
        private static final long serialVersionUID = 1L;

        public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
        {
            super(allowedExtension, extension, filename);
        }
    }

    public static class InvalidVideoExtensionException extends InvalidExtensionException
    {
        private static final long serialVersionUID = 1L;

        public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
        {
            super(allowedExtension, extension, filename);
        }
    }
}

Output:
【漏洞类型】文件上传格式限制漏洞
【严重性】Medium
【漏洞摘要】原始代码中，`SysProfileController`类的`updateAvatar`方法在处理用户头像上传时，未对上传文件的扩展名进行验证。攻击者可以上传任意类型的文件，包括恶意脚本或可执行文件，这可能导致服务器被恶意利用。具体问题在于调用`FileUploadUtils.upload`方法时没有指定允许的文件扩展名。
【关键代码模式】
- `FileUploadUtils.upload`方法
- `SysProfileController.updateAvatar`方法
- `MultipartFile`对象
- 未验证的用户输入
【修复方法说明】修复方法通过在调用`FileUploadUtils.upload`方法时指定允许的文件扩展名（即`MimeTypeUtils.IMAGE_EXTENSION`）来解决此问题。这确保了只有图像文件可以被上传，从而减轻了服务器被恶意利用的风险。最佳实践是始终对用户上传的文件进行严格的格式和类型验证，并限制允许上传的文件类型。