001/* 002 * (C) Copyright 2006-2007 Nuxeo SAS (http://nuxeo.com/) and contributors. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the GNU Lesser General Public License 006 * (LGPL) version 2.1 which accompanies this distribution, and is available at 007 * http://www.gnu.org/licenses/lgpl.html 008 * 009 * This library is distributed in the hope that it will be useful, 010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 012 * Lesser General Public License for more details. 013 * 014 * Contributors: 015 * Nuxeo - initial API and implementation 016 * 017 * $Id: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $ 018 */ 019 020package org.nuxeo.ecm.directory; 021 022import java.util.List; 023 024import org.nuxeo.common.xmap.annotation.XNode; 025import org.nuxeo.common.xmap.annotation.XObject; 026 027/** 028 * Reference that uses the matching reference of the target directory to actually do the job. 029 * 030 * @author ogrisel 031 */ 032@XObject(value = "inverseReference") 033public class InverseReference extends AbstractReference { 034 035 /** 036 * Indicates if the target directory can be updated from the current reference 037 * 038 * @since 5.7 039 */ 040 protected boolean readOnly = false; 041 042 @XNode("@dualReferenceField") 043 protected String dualReferenceName; 044 045 protected Reference dualReference; 046 047 @XNode("@field") 048 public void setFieldName(String fieldName) { 049 this.fieldName = fieldName; 050 } 051 052 @Override 053 @XNode("@directory") 054 public void setTargetDirectoryName(String targetDirectoryName) { 055 this.targetDirectoryName = targetDirectoryName; 056 } 057 058 @XNode("@readOnly") 059 public void setReadOnly(boolean readOnly) { 060 this.readOnly = readOnly; 061 } 062 063 public boolean isReadOnly() { 064 return readOnly; 065 } 066 067 protected void checkDualReference() throws DirectoryException { 068 if (dualReference == null) { 069 List<Reference> references = getTargetDirectory().getReferences(dualReferenceName); 070 if (references.size() == 0) { 071 dualReference = null; 072 } else if (references.size() == 1) { 073 dualReference = references.get(0); 074 } else { 075 for (Reference ref : references) { 076 if (ref instanceof InverseReference) { 077 continue; 078 } else if (sourceDirectoryName.equals(ref.getTargetDirectory().getName()) 079 && targetDirectoryName.equals(ref.getSourceDirectory().getName())) { 080 if (dualReference == null) { 081 dualReference = ref; 082 } else { 083 throw new DirectoryException( 084 "More than one reference: could not find reference " + dualReferenceName); 085 } 086 } 087 } 088 } 089 } 090 if (dualReference == null) { 091 throw new DirectoryException("could not find reference " + dualReferenceName); 092 } 093 if (dualReference instanceof InverseReference) { 094 throw new DirectoryException(String.format("InverseReference %s cannot refer to InverseReference %s", 095 getFieldName(), dualReferenceName)); 096 } 097 } 098 099 public void addLinks(String sourceId, List<String> targetIds) throws DirectoryException { 100 if (readOnly) { 101 return; 102 } 103 checkDualReference(); 104 dualReference.addLinks(targetIds, sourceId); 105 } 106 107 public void addLinks(List<String> sourceIds, String targetId) throws DirectoryException { 108 if (readOnly) { 109 return; 110 } 111 checkDualReference(); 112 dualReference.addLinks(targetId, sourceIds); 113 } 114 115 public void removeLinksForTarget(String targetId) throws DirectoryException { 116 if (readOnly) { 117 return; 118 } 119 checkDualReference(); 120 dualReference.removeLinksForSource(targetId); 121 } 122 123 public void removeLinksForSource(String sourceId) throws DirectoryException { 124 if (readOnly) { 125 return; 126 } 127 checkDualReference(); 128 dualReference.removeLinksForTarget(sourceId); 129 } 130 131 public List<String> getSourceIdsForTarget(String targetId) throws DirectoryException { 132 checkDualReference(); 133 return dualReference.getTargetIdsForSource(targetId); 134 } 135 136 public List<String> getTargetIdsForSource(String sourceId) throws DirectoryException { 137 checkDualReference(); 138 return dualReference.getSourceIdsForTarget(sourceId); 139 } 140 141 public void setTargetIdsForSource(String sourceId, List<String> targetIds) throws DirectoryException { 142 if (readOnly) { 143 return; 144 } 145 checkDualReference(); 146 dualReference.setSourceIdsForTarget(sourceId, targetIds); 147 } 148 149 public void setSourceIdsForTarget(String targetId, List<String> sourceIds) throws DirectoryException { 150 if (readOnly) { 151 return; 152 } 153 checkDualReference(); 154 dualReference.setTargetIdsForSource(targetId, sourceIds); 155 } 156 157 @Override 158 protected AbstractReference newInstance() { 159 return new InverseReference(); 160 } 161 162 public InverseReference clone() { 163 InverseReference clone = (InverseReference) super.clone(); 164 clone.dualReferenceName = dualReferenceName; 165 return clone; 166 } 167}