001: /* ====================================================================
002: Licensed to the Apache Software Foundation (ASF) under one or more
003: contributor license agreements. See the NOTICE file distributed with
004: this work for additional information regarding copyright ownership.
005: The ASF licenses this file to You under the Apache License, Version 2.0
006: (the "License"); you may not use this file except in compliance with
007: the License. You may obtain a copy of the License at
008:
009: http://www.apache.org/licenses/LICENSE-2.0
010:
011: Unless required by applicable law or agreed to in writing, software
012: distributed under the License is distributed on an "AS IS" BASIS,
013: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: See the License for the specific language governing permissions and
015: limitations under the License.
016: ==================================================================== */
017:
018: package org.apache.poi.hwpf.model;
019:
020: import java.util.Arrays;
021:
022: /**
023: * Represents a lightweight node in the Trees used to store content
024: * properties.
025: *
026: * @author Ryan Ackley
027: */
028: public abstract class PropertyNode implements Comparable, Cloneable {
029: protected Object _buf;
030: private int _cpStart;
031: private int _cpEnd;
032:
033: /**
034: * @param fcStart The start of the text for this property.
035: * @param fcEnd The end of the text for this property.
036: * @param buf FIXME: Old documentation is: "grpprl The property description in compressed form."
037: */
038: protected PropertyNode(int fcStart, int fcEnd, Object buf) {
039: _cpStart = fcStart;
040: _cpEnd = fcEnd;
041: _buf = buf;
042:
043: }
044:
045: /**
046: * @return The offset of this property's text.
047: */
048: public int getStart() {
049: return _cpStart;
050: }
051:
052: public void setStart(int start) {
053: _cpStart = start;
054: }
055:
056: /**
057: * @return The offset of the end of this property's text.
058: */
059: public int getEnd() {
060: return _cpEnd;
061: }
062:
063: public void setEnd(int end) {
064: _cpEnd = end;
065: }
066:
067: /**
068: * Adjust for a deletion that can span multiple PropertyNodes.
069: * @param start
070: * @param length
071: */
072: public void adjustForDelete(int start, int length) {
073: int end = start + length;
074:
075: if (_cpEnd > start) {
076: if (_cpStart < end) {
077: _cpEnd = end >= _cpEnd ? start : _cpEnd - length;
078: _cpStart = Math.min(start, _cpStart);
079: } else {
080: _cpEnd -= length;
081: _cpStart -= length;
082: }
083: }
084: }
085:
086: protected boolean limitsAreEqual(Object o) {
087: return ((PropertyNode) o).getStart() == _cpStart
088: && ((PropertyNode) o).getEnd() == _cpEnd;
089:
090: }
091:
092: public boolean equals(Object o) {
093: if (limitsAreEqual(o)) {
094: Object testBuf = ((PropertyNode) o)._buf;
095: if (testBuf instanceof byte[] && _buf instanceof byte[]) {
096: return Arrays.equals((byte[]) testBuf, (byte[]) _buf);
097: }
098: return _buf.equals(testBuf);
099: }
100: return false;
101: }
102:
103: public Object clone() throws CloneNotSupportedException {
104: return super .clone();
105: }
106:
107: /**
108: * Used for sorting in collections.
109: */
110: public int compareTo(Object o) {
111: int cpEnd = ((PropertyNode) o).getEnd();
112: if (_cpEnd == cpEnd) {
113: return 0;
114: } else if (_cpEnd < cpEnd) {
115: return -1;
116: } else {
117: return 1;
118: }
119: }
120:
121: }
|