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 public void addLinks(String sourceId, List<String> targetIds) throws DirectoryException { 102 if (readOnly) { 103 return; 104 } 105 checkDualReference(); 106 dualReference.addLinks(targetIds, sourceId); 107 } 108 109 public void addLinks(List<String> sourceIds, String targetId) throws DirectoryException { 110 if (readOnly) { 111 return; 112 } 113 checkDualReference(); 114 dualReference.addLinks(targetId, sourceIds); 115 } 116 117 public void removeLinksForTarget(String targetId) throws DirectoryException { 118 if (readOnly) { 119 return; 120 } 121 checkDualReference(); 122 dualReference.removeLinksForSource(targetId); 123 } 124 125 public void removeLinksForSource(String sourceId) throws DirectoryException { 126 if (readOnly) { 127 return; 128 } 129 checkDualReference(); 130 dualReference.removeLinksForTarget(sourceId); 131 } 132 133 public List<String> getSourceIdsForTarget(String targetId) throws DirectoryException { 134 checkDualReference(); 135 return dualReference.getTargetIdsForSource(targetId); 136 } 137 138 public List<String> getTargetIdsForSource(String sourceId) throws DirectoryException { 139 checkDualReference(); 140 return dualReference.getSourceIdsForTarget(sourceId); 141 } 142 143 public void setTargetIdsForSource(String sourceId, List<String> targetIds) throws DirectoryException { 144 if (readOnly) { 145 return; 146 } 147 checkDualReference(); 148 dualReference.setSourceIdsForTarget(sourceId, targetIds); 149 } 150 151 public void setSourceIdsForTarget(String targetId, List<String> sourceIds) throws DirectoryException { 152 if (readOnly) { 153 return; 154 } 155 checkDualReference(); 156 dualReference.setTargetIdsForSource(targetId, sourceIds); 157 } 158 159 @Override 160 protected AbstractReference newInstance() { 161 return new InverseReference(); 162 } 163 164 public InverseReference clone() { 165 InverseReference clone = (InverseReference) super.clone(); 166 clone.dualReferenceName = dualReferenceName; 167 return clone; 168 } 169}