| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed 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 com.intellij.openapi.diff; |
| |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.diff.impl.string.DiffString; |
| import com.intellij.openapi.editor.Document; |
| import com.intellij.openapi.editor.EditorFactory; |
| import com.intellij.openapi.fileEditor.OpenFileDescriptor; |
| import com.intellij.openapi.fileTypes.FileType; |
| import com.intellij.openapi.fileTypes.FileTypeManager; |
| import com.intellij.openapi.vfs.CharsetToolkit; |
| import com.intellij.openapi.vfs.VirtualFile; |
| import com.intellij.util.LineSeparator; |
| import com.intellij.util.SystemProperties; |
| import org.jetbrains.annotations.NotNull; |
| import org.jetbrains.annotations.Nullable; |
| |
| import java.io.*; |
| import java.nio.ByteBuffer; |
| import java.nio.charset.Charset; |
| |
| /** |
| * Allows to compare some text not associated with file or document. |
| * |
| * @see #getText() |
| * @see #setReadOnly(boolean) |
| */ |
| public class SimpleContent extends DiffContent { |
| private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.SimpleContent"); |
| |
| private final byte[] myOriginalBytes; |
| private final String myOriginalText; |
| private final LineSeparators myLineSeparators = new LineSeparators(); |
| private final Document myDocument; |
| private final FileType myType; |
| private Charset myCharset; |
| private byte[] myBOM; |
| |
| /** |
| * Constructs content with given text and null type |
| */ |
| public SimpleContent(String text) { |
| this(text, null); |
| } |
| |
| public SimpleContent(@NotNull String text, @Nullable FileType type) { |
| this(text, type, EditorFactory.getInstance()); |
| } |
| |
| public SimpleContent(@NotNull String text, FileType type, EditorFactory f) { |
| myOriginalBytes = text.getBytes(); |
| myOriginalText = myLineSeparators.correctText(text); |
| myDocument = f.createDocument(myOriginalText); |
| setReadOnly(true); |
| myType = type; |
| } |
| |
| public static SimpleContent createEmpty() { |
| final SimpleContent content = new SimpleContent(""); |
| content.setIsEmpty(true); |
| return content; |
| } |
| |
| /** |
| * Make this content editable or not. By default SimpleContent isn't editable. |
| */ |
| public void setReadOnly(boolean readOnly) { |
| myDocument.setReadOnly(readOnly); |
| } |
| |
| /** |
| * @return modified text. |
| * @see #setReadOnly(boolean) |
| */ |
| public String getText() { |
| return myLineSeparators.restoreText(myDocument.getText()); |
| } |
| |
| @Override |
| public Document getDocument() { |
| return myDocument; |
| } |
| |
| /** |
| * @return null |
| */ |
| @Override |
| public OpenFileDescriptor getOpenFileDescriptor(int offset) { |
| return null; |
| } |
| |
| /** |
| * @return null |
| */ |
| @Override |
| public VirtualFile getFile() { |
| return null; |
| } |
| |
| @Override |
| @Nullable |
| public FileType getContentType() { |
| return myType; |
| } |
| |
| /** |
| * @return Encodes using default encoding |
| */ |
| @Override |
| public byte[] getBytes() { |
| String currentText = getText(); |
| if (myOriginalText.equals(myDocument.getText()) && myCharset == null) { |
| return myOriginalBytes; |
| } |
| else if (myCharset != null) { |
| final ByteBuffer buffer = myCharset.encode(currentText).compact(); |
| int bomLength = myBOM != null ? myBOM.length : 0; |
| final int encodedLength = buffer.position(); |
| byte[] result = new byte[encodedLength + bomLength]; |
| if (bomLength > 0) { |
| System.arraycopy(myBOM, 0, result, 0, bomLength); |
| } |
| buffer.position(0); |
| buffer.get(result, bomLength, encodedLength); |
| return result; |
| } |
| return currentText.getBytes(); |
| } |
| |
| @NotNull |
| @Override |
| public LineSeparator getLineSeparator() { |
| return LineSeparator.fromString(myLineSeparators.mySeparator); |
| } |
| |
| public Charset getCharset() { |
| return myCharset; |
| } |
| |
| public void setCharset(final Charset charset) { |
| myCharset = charset; |
| } |
| |
| /** |
| * @param text text of content |
| * @param fileName used to determine content type |
| */ |
| public static SimpleContent forFileContent(String text, String fileName) { |
| FileType fileType; |
| if (fileName != null) { |
| fileType = FileTypeManager.getInstance().getFileTypeByFileName(fileName); |
| } |
| else { |
| fileType = null; |
| } |
| return new SimpleContent(text, fileType); |
| } |
| |
| /** |
| * @param bytes binary text representaion |
| * @param charset name of charset. If null IDE default charset will be used |
| * @param fileType content type. If null file name will be used to select file type |
| * @return content representing bytes as text |
| * @throws UnsupportedEncodingException |
| */ |
| public static SimpleContent fromBytes(byte[] bytes, String charset, FileType fileType) throws UnsupportedEncodingException { |
| if (charset == null) charset = CharsetToolkit.getDefaultSystemCharset().name(); |
| return new SimpleContent(new String(bytes, charset), fileType); |
| } |
| |
| /** |
| * @param file should exist and not to be a directory |
| * @param charset name of file charset. If null IDE default charset will be used |
| * @param fileType content type. If null file name will be used to select file type |
| * @return Content representing text in file |
| * @throws IOException |
| */ |
| public static DiffContent fromIoFile(File file, String charset, FileType fileType) throws IOException { |
| if (file.isDirectory()) throw new IllegalArgumentException(file.toString()); |
| if (fileType == null) fileType = FileTypeManager.getInstance().getFileTypeByFileName(file.getName()); |
| BufferedInputStream stream = new BufferedInputStream(new FileInputStream(file)); |
| try { |
| byte[] bytes = new byte[(int)file.length()]; |
| int bytesRead = stream.read(bytes, 0, bytes.length); |
| LOG.assertTrue(file.length() == bytesRead); |
| return fromBytes(bytes, charset, fileType); |
| } |
| finally { |
| stream.close(); |
| } |
| } |
| |
| public void setBOM(final byte[] BOM) { |
| myBOM = BOM; |
| } |
| |
| private static class LineSeparators { |
| private String mySeparator; |
| |
| @NotNull |
| public String correctText(@NotNull String text) { |
| DiffString.LineTokenizer lineTokenizer = new DiffString.LineTokenizer(DiffString.create(text)); |
| DiffString[] lines = lineTokenizer.execute(); |
| mySeparator = lineTokenizer.getLineSeparator(); |
| LOG.assertTrue(mySeparator == null || !mySeparator.isEmpty()); |
| if (mySeparator == null) mySeparator = SystemProperties.getLineSeparator(); |
| return DiffString.concatenate(lines).toString(); |
| } |
| |
| @NotNull |
| public String restoreText(@NotNull String text) { |
| if (mySeparator == null) throw new NullPointerException(); |
| return text.replaceAll("\n", mySeparator); |
| } |
| } |
| } |