001/*
002 * (C) Copyright 2006-2009 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 * $Id$
020 */
021
022package org.nuxeo.ecm.directory.multi;
023
024import java.util.ArrayList;
025import java.util.HashSet;
026import java.util.List;
027import java.util.Set;
028
029import org.apache.commons.logging.Log;
030import org.apache.commons.logging.LogFactory;
031import org.nuxeo.ecm.directory.AbstractReference;
032import org.nuxeo.ecm.directory.Directory;
033import org.nuxeo.ecm.directory.DirectoryEntryNotFoundException;
034import org.nuxeo.ecm.directory.Reference;
035import org.nuxeo.ecm.directory.Session;
036import org.nuxeo.ecm.directory.api.DirectoryService;
037import org.nuxeo.runtime.api.Framework;
038
039public class MultiReference extends AbstractReference implements Cloneable {
040
041    private static final Log log = LogFactory.getLog(MultiReference.class);
042
043    final MultiDirectory dir;
044
045    MultiReference(MultiDirectory dir, String fieldName) {
046        super(fieldName, null);
047        this.dir = dir;
048    }
049
050    @Override
051    public void addLinks(String sourceId, List<String> targetIds) {
052        throw new UnsupportedOperationException();
053    }
054
055    @Override
056    public void addLinks(String sourceId, List<String> targetIds, Session session) {
057        throw new UnsupportedOperationException();
058    }
059
060    @Override
061    public void addLinks(List<String> sourceIds, String targetId, Session session) {
062        throw new UnsupportedOperationException();
063    }
064
065    @Override
066    public void addLinks(List<String> sourceIds, String targetId) {
067        throw new UnsupportedOperationException();
068    }
069
070    protected interface Collector {
071        List<String> collect(List<Reference> dir);
072    }
073
074    protected List<String> doCollect(Collector extractor) {
075        DirectoryService dirService = Framework.getService(DirectoryService.class);
076        Set<String> ids = new HashSet<>();
077        for (SourceDescriptor src : dir.getDescriptor().sources) {
078            for (SubDirectoryDescriptor sub : src.subDirectories) {
079                Directory dir = dirService.getDirectory(sub.name);
080                if (dir == null) {
081                    continue;
082                }
083                List<Reference> ref = dir.getReferences(fieldName);
084                if (ref == null) {
085                    continue;
086                }
087                try {
088                    ids.addAll(extractor.collect(ref));
089                } catch (DirectoryEntryNotFoundException e) {
090                    log.debug(e.getMessage());
091                }
092            }
093        }
094        List<String> x = new ArrayList<>(ids.size());
095        x.addAll(ids);
096        return x;
097    }
098
099    @Override
100    public List<String> getSourceIdsForTarget(final String targetId) {
101        return doCollect(refs -> {
102            List<String> sourceIds = new ArrayList<>(1);
103            for (Reference ref : refs) {
104                sourceIds.addAll(ref.getSourceIdsForTarget(targetId));
105            }
106            return sourceIds;
107        });
108    }
109
110    @Override
111    public List<String> getTargetIdsForSource(final String sourceId) {
112        return doCollect(refs -> {
113            List<String> targetIds = new ArrayList<>(1);
114            for (Reference ref : refs) {
115                targetIds.addAll(ref.getSourceIdsForTarget(sourceId));
116            }
117            return targetIds;
118        });
119    }
120
121    @Override
122    public void removeLinksForSource(String sourceId) {
123        throw new UnsupportedOperationException();
124    }
125
126    @Override
127    public void removeLinksForSource(String sourceId, Session session) {
128        throw new UnsupportedOperationException();
129    }
130
131    @Override
132    public void removeLinksForTarget(String targetId) {
133        throw new UnsupportedOperationException();
134    }
135
136    @Override
137    public void removeLinksForTarget(String targetId, Session session) {
138        throw new UnsupportedOperationException();
139    }
140
141    @Override
142    public void setSourceIdsForTarget(String targetId, List<String> sourceIds) {
143        throw new UnsupportedOperationException();
144    }
145
146    @Override
147    public void setSourceIdsForTarget(String targetId, List<String> sourceIds, Session session) {
148        throw new UnsupportedOperationException();
149    }
150
151    @Override
152    public void setTargetIdsForSource(String sourceId, List<String> targetIds) {
153        throw new UnsupportedOperationException();
154    }
155
156    @Override
157    public void setTargetIdsForSource(String sourceId, List<String> targetIds, Session session) {
158        throw new UnsupportedOperationException();
159    }
160
161    /**
162     * @since 5.6
163     */
164    @Override
165    public MultiReference clone() {
166        // basic fields are already copied by super.clone()
167        try {
168            return (MultiReference) super.clone();
169        } catch (CloneNotSupportedException e) {
170            throw new AssertionError(e);
171        }
172    }
173}