| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.jdt.internal.formatter.comment; |
| |
| import java.util.LinkedList; |
| |
| /** |
| * General comment line in a comment region. |
| * |
| * @since 3.0 |
| */ |
| public abstract class CommentLine implements IBorderAttributes { |
| |
| /** Prefix of non-formattable comment lines */ |
| protected static final String NON_FORMAT_START_PREFIX= "/*-"; //$NON-NLS-1$ |
| |
| /** The attributes of this line */ |
| private int fAttributes= 0; |
| |
| /** The parent region of this line */ |
| private final CommentRegion fParent; |
| |
| /** The comment ranges in this line */ |
| private final LinkedList fRanges= new LinkedList(); |
| |
| /** |
| * Creates a new comment line. |
| * |
| * @param parent comment region to create the comment line for |
| */ |
| protected CommentLine(final CommentRegion parent) { |
| fParent= parent; |
| } |
| |
| /** |
| * Adapts the line attributes from the previous line in the comment |
| * region. |
| * |
| * @param previous the previous comment line in the comment region |
| */ |
| protected abstract void adapt(final CommentLine previous); |
| |
| /** |
| * Appends the specified comment range to this comment line. |
| * |
| * @param range comment range to append to this line |
| */ |
| protected void append(final CommentRange range) { |
| fRanges.add(range); |
| } |
| |
| /** |
| * Formats this comment line as content line. |
| * |
| * @param predecessor the predecessor comment line in the comment region |
| * @param last the most recently processed comment range |
| * @param indentation the indentation of the comment region |
| * @param line the index of this comment line in the comment region |
| * @return the first comment range in this comment line |
| */ |
| protected CommentRange formatLine(final CommentLine predecessor, final CommentRange last, final String indentation, final int line) { |
| |
| int offset= 0; |
| int length= 0; |
| |
| CommentRange next= last; |
| CommentRange previous= null; |
| |
| final int stop= fRanges.size() - 1; |
| final int end= fParent.getSize() - 1; |
| |
| for (int index= stop; index >= 0; index--) { |
| |
| previous= next; |
| next= (CommentRange)fRanges.get(index); |
| |
| if (fParent.canFormat(previous, next)) { |
| |
| offset= next.getOffset() + next.getLength(); |
| length= previous.getOffset() - offset; |
| |
| if (index == stop && line != end) |
| fParent.logEdit(fParent.getDelimiter(predecessor, this, previous, next, indentation), offset, length); |
| else |
| fParent.logEdit(fParent.getDelimiter(previous, next), offset, length); |
| } |
| } |
| return next; |
| } |
| |
| /** |
| * Formats this comment line as end line having a lower border |
| * consisting of content line prefixes. |
| * |
| * @param range last comment range of the last comment line in the |
| * comment region |
| * @param indentation the indentation of the comment region |
| * @param length the maximal length of text in this comment region |
| * measured in average character widths |
| */ |
| protected void formatLowerBorder(final CommentRange range, final String indentation, final int length) { |
| |
| final int offset= range.getOffset() + range.getLength(); |
| |
| final StringBuffer buffer= new StringBuffer(length); |
| final String end= getEndingPrefix(); |
| final String delimiter= fParent.getDelimiter(); |
| |
| if (fParent.isSingleLine() && fParent.getSize() == 1) |
| buffer.append(end); |
| else { |
| |
| final String filler= getContentPrefix().trim(); |
| |
| buffer.append(delimiter); |
| buffer.append(indentation); |
| |
| if (fParent.hasBorder(BORDER_LOWER)) { |
| |
| buffer.append(' '); |
| for (int character= 0; character < length; character++) |
| buffer.append(filler); |
| |
| buffer.append(end.trim()); |
| |
| } else |
| buffer.append(end); |
| } |
| fParent.logEdit(buffer.toString(), offset, fParent.getLength() - offset); |
| } |
| |
| /** |
| * Formats this comment line as start line having an upper border |
| * consisting of content line prefixes. |
| * |
| * @param range the first comment range in the comment region |
| * @param indentation the indentation of the comment region |
| * @param length the maximal length of text in this comment region |
| * measured in average character widths |
| */ |
| protected void formatUpperBorder(final CommentRange range, final String indentation, final int length) { |
| |
| final StringBuffer buffer= new StringBuffer(length); |
| final String start= getStartingPrefix(); |
| final String content= getContentPrefix(); |
| |
| if (fParent.isSingleLine() && fParent.getSize() == 1) |
| buffer.append(start); |
| else { |
| |
| final String trimmed= start.trim(); |
| final String filler= content.trim(); |
| |
| buffer.append(trimmed); |
| |
| if (fParent.hasBorder(BORDER_UPPER)) { |
| |
| for (int character= 0; character < length - trimmed.length() + start.length(); character++) |
| buffer.append(filler); |
| } |
| |
| buffer.append(fParent.getDelimiter()); |
| buffer.append(indentation); |
| buffer.append(content); |
| } |
| fParent.logEdit(buffer.toString(), 0, range.getOffset()); |
| } |
| |
| /** |
| * Returns the line prefix of content lines. |
| * |
| * @return line prefix of content lines |
| */ |
| protected abstract String getContentPrefix(); |
| |
| /** |
| * Returns the line prefix of end lines. |
| * |
| * @return line prefix of end lines |
| */ |
| protected abstract String getEndingPrefix(); |
| |
| /** |
| * Returns the first comment range in this comment line. |
| * |
| * @return the first comment range |
| */ |
| protected final CommentRange getFirst() { |
| return (CommentRange)fRanges.getFirst(); |
| } |
| |
| /** |
| * Returns the indentation reference string for this line. |
| * |
| * @return the indentation reference string for this line |
| */ |
| protected String getIndentationReference() { |
| return ""; //$NON-NLS-1$ |
| } |
| |
| /** |
| * Returns the last comment range in this comment line. |
| * |
| * @return the last comment range |
| */ |
| protected final CommentRange getLast() { |
| return (CommentRange)fRanges.getLast(); |
| } |
| |
| /** |
| * Returns the parent comment region of this comment line. |
| * |
| * @return the parent comment region |
| */ |
| protected final CommentRegion getParent() { |
| return fParent; |
| } |
| |
| /** |
| * Returns the number of comment ranges in this comment line. |
| * |
| * @return the number of ranges in this line |
| */ |
| protected final int getSize() { |
| return fRanges.size(); |
| } |
| |
| /** |
| * Returns the line prefix of start lines. |
| * |
| * @return line prefix of start lines |
| */ |
| protected abstract String getStartingPrefix(); |
| |
| /** |
| * Is the attribute <code>attribute</code> true? |
| * |
| * @param attribute the attribute to get. |
| * @return <code>true</code> iff this attribute is <code>true</code>, |
| * <code>false</code> otherwise. |
| */ |
| protected final boolean hasAttribute(final int attribute) { |
| return (fAttributes & attribute) == attribute; |
| } |
| |
| /** |
| * Scans this comment line for comment range boundaries. |
| * |
| * @param line the index of this line in the comment region |
| */ |
| protected abstract void scanLine(final int line); |
| |
| /** |
| * Set the attribute <code>attribute</code> to true. |
| * |
| * @param attribute the attribute to set. |
| */ |
| protected final void setAttribute(final int attribute) { |
| fAttributes |= attribute; |
| } |
| |
| /** |
| * Tokenizes this comment line into comment ranges |
| * |
| * @param line the index of this line in the comment region |
| */ |
| protected void tokenizeLine(final int line) { |
| |
| int offset= 0; |
| int index= offset; |
| |
| final CommentRange range= (CommentRange)fRanges.get(0); |
| final int begin= range.getOffset(); |
| |
| final String content= fParent.getText(begin, range.getLength()); |
| final int length= content.length(); |
| |
| while (offset < length) { |
| |
| while (offset < length && Character.isWhitespace(content.charAt(offset))) |
| offset++; |
| |
| index= offset; |
| |
| while (index < length && !Character.isWhitespace(content.charAt(index))) |
| index++; |
| |
| if (index - offset > 0) { |
| fParent.append(new CommentRange(begin + offset, index - offset)); |
| |
| offset= index; |
| } |
| } |
| } |
| } |