001 /* 002 * JBoss, Home of Professional Open Source. 003 * Copyright 2008, Red Hat Middleware LLC, and individual contributors 004 * as indicated by the @author tags. See the copyright.txt file in the 005 * distribution for a full listing of individual contributors. 006 * 007 * This is free software; you can redistribute it and/or modify it 008 * under the terms of the GNU Lesser General Public License as 009 * published by the Free Software Foundation; either version 2.1 of 010 * the License, or (at your option) any later version. 011 * 012 * This software is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * You should have received a copy of the GNU Lesser General Public 018 * License along with this software; if not, write to the Free 019 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 020 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 021 */ 022 package org.jboss.dna.connector.federation.merge.strategy; 023 024 import java.util.Iterator; 025 import java.util.List; 026 import java.util.Map; 027 import java.util.UUID; 028 import net.jcip.annotations.ThreadSafe; 029 import org.jboss.dna.connector.federation.contribution.Contribution; 030 import org.jboss.dna.connector.federation.merge.FederatedNode; 031 import org.jboss.dna.connector.federation.merge.MergePlan; 032 import org.jboss.dna.graph.DnaLexicon; 033 import org.jboss.dna.graph.ExecutionContext; 034 import org.jboss.dna.graph.properties.Name; 035 import org.jboss.dna.graph.properties.Property; 036 import org.jboss.dna.graph.properties.UuidFactory; 037 import org.jboss.dna.graph.properties.ValueFormatException; 038 import org.jboss.dna.graph.properties.Path.Segment; 039 040 /** 041 * A merge strategy that is optimized for merging when there is a single contribution. 042 * 043 * @author Randall Hauch 044 */ 045 @ThreadSafe 046 public class OneContributionMergeStrategy implements MergeStrategy { 047 048 public static final boolean DEFAULT_REUSE_UUID_FROM_CONTRIBUTION = true; 049 050 private boolean useUuidFromContribution = DEFAULT_REUSE_UUID_FROM_CONTRIBUTION; 051 052 /** 053 * @return reuseUuidFromContribution 054 */ 055 public boolean isContributionUuidUsedForFederatedNode() { 056 return useUuidFromContribution; 057 } 058 059 /** 060 * @param useUuidFromContribution Sets useUuidFromContribution to the specified value. 061 */ 062 public void setContributionUuidUsedForFederatedNode( boolean useUuidFromContribution ) { 063 this.useUuidFromContribution = useUuidFromContribution; 064 } 065 066 /** 067 * {@inheritDoc} 068 * <p> 069 * This method only uses the one and only one non-null {@link Contribution} in the <code>contributions</code>. 070 * </p> 071 * 072 * @see org.jboss.dna.connector.federation.merge.strategy.MergeStrategy#merge(org.jboss.dna.connector.federation.merge.FederatedNode, 073 * java.util.List, org.jboss.dna.graph.ExecutionContext) 074 */ 075 public void merge( FederatedNode federatedNode, 076 List<Contribution> contributions, 077 ExecutionContext context ) { 078 assert federatedNode != null; 079 assert context != null; 080 assert contributions != null; 081 assert contributions.size() > 0; 082 Contribution contribution = contributions.get(0); 083 assert contribution != null; 084 final boolean findUuid = isContributionUuidUsedForFederatedNode(); 085 // Copy the children ... 086 List<Segment> children = federatedNode.getChildren(); 087 children.clear(); 088 Iterator<Segment> childIterator = contribution.getChildren(); 089 while (childIterator.hasNext()) { 090 Segment child = childIterator.next(); 091 children.add(child); 092 } 093 // Copy the properties ... 094 Map<Name, Property> properties = federatedNode.getPropertiesByName(); 095 properties.clear(); 096 UUID uuid = null; 097 UuidFactory uuidFactory = null; 098 Iterator<Property> propertyIterator = contribution.getProperties(); 099 while (propertyIterator.hasNext()) { 100 Property property = propertyIterator.next(); 101 if (findUuid && uuid == null && property.getName().getLocalName().equals("uuid")) { 102 if (property.isSingle()) { 103 if (uuidFactory == null) uuidFactory = context.getValueFactories().getUuidFactory(); 104 try { 105 uuid = uuidFactory.create(property.getValues().next()); 106 } catch (ValueFormatException e) { 107 // Ignore conversion exceptions 108 } 109 } 110 } else { 111 properties.put(property.getName(), property); 112 } 113 } 114 // If we found a single "uuid" property whose value is a valid UUID .. 115 if (uuid != null) { 116 // then set the UUID on the federated node ... 117 federatedNode.setUuid(uuid); 118 } 119 // Set the UUID as a property ... 120 Property uuidProperty = context.getPropertyFactory().create(DnaLexicon.UUID, federatedNode.getUuid()); 121 properties.put(uuidProperty.getName(), uuidProperty); 122 123 // Assign the merge plan ... 124 MergePlan mergePlan = MergePlan.create(contributions); 125 federatedNode.setMergePlan(mergePlan); 126 } 127 128 }