001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2014-2016 ForgeRock AS. 015 */ 016package org.opends.server.replication.server.changelog.file; 017 018import org.opends.server.replication.protocol.UpdateMsg; 019import org.opends.server.replication.server.changelog.api.ChangelogException; 020import org.opends.server.replication.server.changelog.api.DBCursor; 021import org.forgerock.opendj.ldap.DN; 022 023import java.util.ArrayList; 024import java.util.List; 025 026/** 027 * Multi domain DB cursor that only returns updates for the domains which have 028 * been enabled for the external changelog. 029 */ 030public final class ECLMultiDomainDBCursor implements DBCursor<UpdateMsg> 031{ 032 private final ECLEnabledDomainPredicate predicate; 033 private final MultiDomainDBCursor cursor; 034 private final List<DN> eclDisabledDomains = new ArrayList<>(); 035 036 /** 037 * Builds an instance of this class filtering updates from the provided cursor. 038 * 039 * @param predicate 040 * tells whether a domain is enabled for the external changelog 041 * @param cursor 042 * the cursor whose updates will be filtered 043 */ 044 public ECLMultiDomainDBCursor(ECLEnabledDomainPredicate predicate, MultiDomainDBCursor cursor) 045 { 046 this.predicate = predicate; 047 this.cursor = cursor; 048 } 049 050 /** {@inheritDoc} */ 051 @Override 052 public UpdateMsg getRecord() 053 { 054 return cursor.getRecord(); 055 } 056 057 /** 058 * Returns the data associated to the cursor that returned the current record. 059 * 060 * @return the data associated to the cursor that returned the current record. 061 */ 062 public DN getData() 063 { 064 return cursor.getData(); 065 } 066 067 /** 068 * Removes a replication domain from this cursor and stops iterating over it. 069 * Removed cursors will be effectively removed on the next call to 070 * {@link #next()}. 071 * 072 * @param baseDN 073 * the replication domain's baseDN 074 */ 075 public void removeDomain(DN baseDN) 076 { 077 cursor.removeDomain(baseDN); 078 } 079 080 /** 081 * Returns whether the cursor should be reinitialized because a domain became re-enabled. 082 * 083 * @return whether the cursor should be reinitialized 084 */ 085 public boolean shouldReInitialize() 086 { 087 for (DN domainDN : eclDisabledDomains) 088 { 089 if (predicate.isECLEnabledDomain(domainDN)) 090 { 091 eclDisabledDomains.clear(); 092 return true; 093 } 094 } 095 return false; 096 } 097 098 @Override 099 public boolean next() throws ChangelogException 100 { 101 if (!cursor.next()) 102 { 103 return false; 104 } 105 // discard updates from non ECL enabled domains by removing the disabled domains from the cursor 106 DN domain = cursor.getData(); 107 while (domain != null && !predicate.isECLEnabledDomain(domain)) 108 { 109 cursor.removeDomain(domain); 110 eclDisabledDomains.add(domain); 111 domain = cursor.getData(); 112 } 113 return domain != null; 114 } 115 116 @Override 117 public void close() 118 { 119 cursor.close(); 120 } 121 122 @Override 123 public String toString() 124 { 125 return getClass().getSimpleName() + " cursor=[" + cursor + ']'; 126 } 127}