001/* 002 * (C) Copyright 2006-2007 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: JOOoConvertPluginImpl.java 18651 2007-05-13 20:28:53Z sfermigier $ 020 */ 021 022package org.nuxeo.ecm.directory; 023 024import java.util.List; 025 026import org.nuxeo.common.xmap.annotation.XNode; 027import org.nuxeo.common.xmap.annotation.XObject; 028 029/** 030 * Reference that uses the matching reference of the target directory to actually do the job. 031 * 032 * @author ogrisel 033 */ 034@XObject(value = "inverseReference") 035public class InverseReference extends AbstractReference { 036 037 /** 038 * Indicates if the target directory can be updated from the current reference 039 * 040 * @since 5.7 041 */ 042 protected boolean readOnly = false; 043 044 @XNode("@dualReferenceField") 045 protected String dualReferenceName; 046 047 protected Reference dualReference; 048 049 @XNode("@field") 050 public void setFieldName(String fieldName) { 051 this.fieldName = fieldName; 052 } 053 054 @Override 055 @XNode("@directory") 056 public void setTargetDirectoryName(String targetDirectoryName) { 057 this.targetDirectoryName = targetDirectoryName; 058 } 059 060 @XNode("@readOnly") 061 public void setReadOnly(boolean readOnly) { 062 this.readOnly = readOnly; 063 } 064 065 public boolean isReadOnly() { 066 return readOnly; 067 } 068 069 protected void checkDualReference() throws DirectoryException { 070 if (dualReference == null) { 071 List<Reference> references = getTargetDirectory().getReferences(dualReferenceName); 072 if (references.size() == 0) { 073 dualReference = null; 074 } else if (references.size() == 1) { 075 dualReference = references.get(0); 076 } else { 077 for (Reference ref : references) { 078 if (ref instanceof InverseReference) { 079 continue; 080 } else if (sourceDirectoryName.equals(ref.getTargetDirectory().getName()) 081 && targetDirectoryName.equals(ref.getSourceDirectory().getName())) { 082 if (dualReference == null) { 083 dualReference = ref; 084 } else { 085 throw new DirectoryException( 086 "More than one reference: could not find reference " + dualReferenceName); 087 } 088 } 089 } 090 } 091 } 092 if (dualReference == null) { 093 throw new DirectoryException("could not find reference " + dualReferenceName); 094 } 095 if (dualReference instanceof InverseReference) { 096 throw new DirectoryException(String.format("InverseReference %s cannot refer to InverseReference %s", 097 getFieldName(), dualReferenceName)); 098 } 099 } 100 101 @Override 102 public void addLinks(String sourceId, List<String> targetIds) throws DirectoryException { 103 if (readOnly) { 104 return; 105 } 106 checkDualReference(); 107 dualReference.addLinks(targetIds, sourceId); 108 } 109 110 @Override 111 public void addLinks(List<String> sourceIds, String targetId) throws DirectoryException { 112 if (readOnly) { 113 return; 114 } 115 checkDualReference(); 116 dualReference.addLinks(targetId, sourceIds); 117 } 118 119 @Override 120 public void removeLinksForTarget(String targetId) throws DirectoryException { 121 if (readOnly) { 122 return; 123 } 124 checkDualReference(); 125 dualReference.removeLinksForSource(targetId); 126 } 127 128 @Override 129 public void removeLinksForSource(String sourceId) throws DirectoryException { 130 if (readOnly) { 131 return; 132 } 133 checkDualReference(); 134 dualReference.removeLinksForTarget(sourceId); 135 } 136 137 @Override 138 public List<String> getSourceIdsForTarget(String targetId) throws DirectoryException { 139 checkDualReference(); 140 return dualReference.getTargetIdsForSource(targetId); 141 } 142 143 @Override 144 public List<String> getTargetIdsForSource(String sourceId) throws DirectoryException { 145 checkDualReference(); 146 return dualReference.getSourceIdsForTarget(sourceId); 147 } 148 149 @Override 150 public void setTargetIdsForSource(String sourceId, List<String> targetIds) throws DirectoryException { 151 if (readOnly) { 152 return; 153 } 154 checkDualReference(); 155 dualReference.setSourceIdsForTarget(sourceId, targetIds); 156 } 157 158 @Override 159 public void setSourceIdsForTarget(String targetId, List<String> sourceIds) throws DirectoryException { 160 if (readOnly) { 161 return; 162 } 163 checkDualReference(); 164 dualReference.setTargetIdsForSource(targetId, sourceIds); 165 } 166 167 @Override 168 public InverseReference clone() { 169 InverseReference clone = (InverseReference) super.clone(); 170 // basic fields are already copied by super.clone() 171 return clone; 172 } 173}