/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. * */ package org.apache.directory.studio.ldifparser.model; import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; import org.apache.directory.studio.ldifparser.LdifFormatParameters; import org.apache.directory.studio.ldifparser.model.container.LdifChangeRecord; import org.apache.directory.studio.ldifparser.model.container.LdifContainer; import org.apache.directory.studio.ldifparser.model.container.LdifModSpec; import org.apache.directory.studio.ldifparser.model.container.LdifRecord; /** * A LDIF file, as we manipulate it in Studio. It's a list of LdifContainer. * * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> */ public class LdifFile implements Serializable { /** The serialVersionUID */ private static final long serialVersionUID = 846864138240517008L; /** The list of container constituting this LDIF file */ private List<LdifContainer> containerList = new ArrayList<LdifContainer>(); /** A flag which is set if a LdifChange is added into the LdifFile */ private boolean hasChanges = false; /** * Create an instance of a LdifFile. */ public LdifFile() { } /** * Tells if the LDIF file is a Content LDIF (there will be no changes) * * @return true if the LDIF file does not contain any change */ public boolean isContentType() { return !hasChanges; } /** * Tells if the LDIF file is a Change LDIF (there will be no changes) * * @return true if the LDIF file is a Change LDIF */ public boolean isChangeType() { return hasChanges; } /** * Add a new LdifContainer to the LdifFile * * @param container The added LdifContainer */ public void addContainer( LdifContainer container ) { containerList.add( container ); if ( container instanceof LdifChangeRecord ) { hasChanges = true; } } /** * @return A list of LdifContainers, including version, comments, records and unknown */ public List<LdifContainer> getContainers() { return containerList; } /** * @return An array of LdifRecords (even invalid), no LdifVersion, LdifComments, or LdifUnknown */ public LdifRecord[] getRecords() { List<LdifRecord> recordList = new ArrayList<LdifRecord>(); for ( LdifContainer container : containerList ) { if ( container instanceof LdifRecord ) { recordList.add( ( LdifRecord ) container ); } } return recordList.toArray( new LdifRecord[recordList.size()] ); } /** * @return the last LdifContainer, or null */ public LdifContainer getLastContainer() { if ( containerList.isEmpty() ) { return null; } else { return containerList.get( containerList.size() - 1 ); } } public String toRawString() { StringBuilder sb = new StringBuilder(); for ( LdifContainer container : containerList ) { sb.append( container.toRawString() ); } return sb.toString(); } public String toFormattedString( LdifFormatParameters formatParameters ) { StringBuilder sb = new StringBuilder(); for ( LdifContainer ldifContainer : containerList ) { sb.append( ldifContainer.toFormattedString( formatParameters ) ); } return sb.toString(); } public String toString() { StringBuilder sb = new StringBuilder(); for ( LdifContainer ldifContainer : containerList ) { sb.append( ldifContainer ); } return sb.toString(); } /** * Retrieve the container at the given offset * * @param model The Ldif file containing the containers * @param offset The position in the file * @return The container if we found one */ public static LdifContainer getContainer( LdifFile model, int offset ) { if ( ( model == null ) || ( offset < 0 ) ) { return null; } List<LdifContainer> containers = model.getContainers(); if ( containers.size() > 0 ) { for ( LdifContainer ldifContainer : containers ) { if ( ( ldifContainer.getOffset() <= offset ) && ( offset < ldifContainer.getOffset() + ldifContainer.getLength() ) ) { return ldifContainer; } } } return null; } public static LdifModSpec getInnerContainer( LdifContainer container, int offset ) { if ( ( container == null ) || ( offset < container.getOffset() ) || ( offset > container.getOffset() + container.getLength() ) ) { return null; } LdifModSpec innerContainer = null; LdifPart[] parts = container.getParts(); if ( parts.length > 0 ) { for ( LdifPart ldifPart : parts ) { int start = ldifPart.getOffset(); int end = ldifPart.getOffset() + ldifPart.getLength(); if ( ( start <= offset ) && ( offset < end ) && ( ldifPart instanceof LdifModSpec ) ) { innerContainer = ( LdifModSpec ) ldifPart; break; } } } return innerContainer; } public static LdifContainer[] getContainers( LdifFile model, int offset, int length ) { if ( ( model == null ) || ( offset < 0 ) ) { return null; } List<LdifContainer> containerList = new ArrayList<LdifContainer>(); List<LdifContainer> containers = model.getContainers(); if ( containers.size() > 0 ) { for ( LdifContainer container : containers ) { int containerOffset = container.getOffset(); if ( ( offset < containerOffset + container.getLength() ) && ( offset + length > containerOffset ) ) { containerList.add( container ); } } } return containerList.toArray( new LdifContainer[containerList.size()] ); } public static LdifPart[] getParts( LdifFile model, int offset, int length ) { if ( ( model == null ) || ( offset < 0 ) ) { return null; } List<LdifContainer> containers = model.getContainers(); return getParts( containers, offset, length ); } public static LdifPart[] getParts( List<LdifContainer> containers, int offset, int length ) { if ( ( containers == null ) || ( offset < 0 ) ) { return null; } List<LdifPart> partList = new ArrayList<LdifPart>(); for ( LdifContainer ldifContainer : containers ) { int ldifContainerOffset = ldifContainer.getOffset(); if ( ( offset < ldifContainerOffset + ldifContainer.getLength() ) && ( offset + length >= ldifContainerOffset ) ) { LdifPart[] ldifParts = ldifContainer.getParts(); LdifPart previousLdifPart = null; for ( LdifPart ldifPart : ldifParts ) { int ldifPartOffset = ldifPart.getOffset(); if ( ( offset < ldifPartOffset + ldifPart.getLength() ) && ( offset + length >= ldifPartOffset ) ) { if ( ldifPart instanceof LdifModSpec ) { LdifModSpec spec = ( LdifModSpec ) ldifPart; List<LdifContainer> newLdifContainer = new ArrayList<LdifContainer>(); newLdifContainer.add( spec ); partList.addAll( Arrays.asList( getParts( newLdifContainer, offset, length ) ) ); } else { if ( ( ldifPart instanceof LdifInvalidPart ) && ( previousLdifPart != null ) ) { ldifPart = previousLdifPart; } partList.add( ldifPart ); } previousLdifPart = ldifPart; } } } } return partList.toArray( new LdifPart[partList.size()] ); } public static LdifPart getContainerContent( LdifContainer container, int offset ) { int containerOffset = container.getOffset(); if ( ( container == null ) || ( offset < containerOffset ) || ( offset > containerOffset + container.getLength() ) ) { return null; } LdifPart part = null; LdifPart[] parts = container.getParts(); if ( parts.length > 0 ) { for ( LdifPart ldifPart : parts ) { int start = ldifPart.getOffset(); int end = ldifPart.getOffset() + ldifPart.getLength(); if ( ( start <= offset ) && ( offset < end ) ) { if ( ldifPart instanceof LdifModSpec ) { part = getContainerContent( ( LdifModSpec ) ldifPart, offset ); } break; } } } return part; } public void replace( LdifContainer[] oldContainers, List<LdifContainer> newContainers ) { // find index int index = 0; if ( oldContainers.length > 0 ) { index = containerList.indexOf( oldContainers[0] ); } // remove old containers int removeLength = 0; int removeOffset = 0; if ( oldContainers.length > 0 ) { removeOffset = oldContainers[0].getOffset(); for ( int i = 0; i < oldContainers.length; i++ ) { containerList.remove( index ); removeLength += oldContainers[i].getLength(); } } // add new containers int insertLength = 0; int pos = 0; for ( LdifContainer ldifContainer : newContainers ) { ldifContainer.adjustOffset( removeOffset ); insertLength += ldifContainer.getLength(); containerList.add( index + pos, ldifContainer ); pos++; } // adjust offset of following containers int adjust = insertLength - removeLength; for ( int i = index + newContainers.size(); i < containerList.size(); i++ ) { LdifContainer container = containerList.get( i ); container.adjustOffset( adjust ); } } }