// Path: repository/src/main/java/de/acosix/alfresco/mtsupport/repo/sync/TenantAwareChainingUserRegistrySynchronizer.java
// @FunctionalInterface
// public static interface ComponentLookupCallback
// {
// 
//     /**
//      * Retrieves the matching component from an enclosing {@link TenantAwareChainingUserRegistrySynchronizer} instance.
//      *
//      * @param name
//      *            the name of the component
//      * @return the component
//      * @throws IllegalStateException
//      *             if the requested component is not available
//      */
// 
//     Object getComponent(String name);
// 
//     /**
//      * Retrieves the matching component from an enclosing {@link TenantAwareChainingUserRegistrySynchronizer} instance.
//      *
//      * @param <T>
//      *            the expected base type of the component
//      * @param name
//      *            the name of the component
//      * @param iface
//      *            the interface of the component
//      * @return the service
//      * @throws IllegalStateException
//      *             if the requested component is not available
//      */
//     default <T> T getComponent(final String name, final Class<T> iface)
//     {
//         final Object service = this.getComponent(name);
//         return iface.cast(service);
//     }
// }


import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicLong;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.dictionary.constraint.NameChecker;
import org.alfresco.repo.security.sync.NodeDescription;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.EqualsHelper;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.acosix.alfresco.mtsupport.repo.sync.TenantAwareChainingUserRegistrySynchronizer.ComponentLookupCallback;
/*
 * Copyright 2016 Acosix GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.acosix.alfresco.mtsupport.repo.sync;




/**
 * @author Axel Faust, <a href="http://acosix.de">Acosix GmbH</a>
 */
public class PersonWorkerImpl extends AbstractZonedSyncBatchWorker<NodeDescription> implements PersonWorker
{

    private static final Logger LOGGER = LoggerFactory.getLogger(PersonWorkerImpl.class);

    // non-model QName used to map a default mimetype for avatar
    private static final QName PROP_AVATAR_DEFAULT_MIMETPYE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
            "avatarDefaultMimetype");

    protected final NameChecker nameChecker;

    protected final AtomicLong latestModified = new AtomicLong(-1l);

    protected UserAccountInterpreter accountInterpreter;

    protected NodeService nodeService;

    protected ContentService contentService;

    public PersonWorkerImpl(final String id, final String zoneId, final Set<String> targetZoneIds, final Collection<String> visitedIds,
            final Collection<String> allIds, final boolean allowDeletions, final UserAccountInterpreter accountInterpreter,
// Path: repository/src/main/java/de/acosix/alfresco/mtsupport/repo/sync/TenantAwareChainingUserRegistrySynchronizer.java
// @FunctionalInterface
// public static interface ComponentLookupCallback
// {
// 
//     /**
//      * Retrieves the matching component from an enclosing {@link TenantAwareChainingUserRegistrySynchronizer} instance.
//      *
//      * @param name
//      *            the name of the component
//      * @return the component
//      * @throws IllegalStateException
//      *             if the requested component is not available
//      */
// 
//     Object getComponent(String name);
// 
//     /**
//      * Retrieves the matching component from an enclosing {@link TenantAwareChainingUserRegistrySynchronizer} instance.
//      *
//      * @param <T>
//      *            the expected base type of the component
//      * @param name
//      *            the name of the component
//      * @param iface
//      *            the interface of the component
//      * @return the service
//      * @throws IllegalStateException
//      *             if the requested component is not available
//      */
//     default <T> T getComponent(final String name, final Class<T> iface)
//     {
//         final Object service = this.getComponent(name);
//         return iface.cast(service);
//     }
// }


// Path: repository/src/main/java/de/acosix/alfresco/mtsupport/repo/sync/PersonWorkerImpl.java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.concurrent.atomic.AtomicLong;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.dictionary.constraint.NameChecker;
import org.alfresco.repo.security.sync.NodeDescription;
import org.alfresco.service.cmr.repository.AssociationRef;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.security.AuthorityService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.alfresco.util.EqualsHelper;
import org.apache.commons.codec.binary.Hex;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import de.acosix.alfresco.mtsupport.repo.sync.TenantAwareChainingUserRegistrySynchronizer.ComponentLookupCallback;

/*
 * Copyright 2016 Acosix GmbH
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package de.acosix.alfresco.mtsupport.repo.sync;




/**
 * @author Axel Faust, <a href="http://acosix.de">Acosix GmbH</a>
 */
public class PersonWorkerImpl extends AbstractZonedSyncBatchWorker<NodeDescription> implements PersonWorker
{

    private static final Logger LOGGER = LoggerFactory.getLogger(PersonWorkerImpl.class);

    // non-model QName used to map a default mimetype for avatar
    private static final QName PROP_AVATAR_DEFAULT_MIMETPYE = QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI,
            "avatarDefaultMimetype");

    protected final NameChecker nameChecker;

    protected final AtomicLong latestModified = new AtomicLong(-1l);

    protected UserAccountInterpreter accountInterpreter;

    protected NodeService nodeService;

    protected ContentService contentService;

    public PersonWorkerImpl(final String id, final String zoneId, final Set<String> targetZoneIds, final Collection<String> visitedIds,
            final Collection<String> allIds, final boolean allowDeletions, final UserAccountInterpreter accountInterpreter,
            final ComponentLookupCallback componentLookup)