/* ****************************************************************************** * Copyright (c) 2006-2016 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ /** * */ package org.xmind.ui.internal.editor; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import org.xmind.core.Core; import org.xmind.core.CoreException; import org.xmind.core.IEntryStreamNormalizer; import org.xmind.core.IFileEntry; import org.xmind.core.IWorkbook; import org.xmind.core.event.CoreEvent; import org.xmind.core.event.ICoreEventSource; import org.xmind.core.internal.security.PasswordProtectedNormalizer; import org.xmind.ui.internal.MindMapUIPlugin; /** * @author Frank Shaka * @since 3.6.50 */ public class WorkbookRefEncryptable implements IEncryptable { private static class LazyPasswordBasedEncryptor implements IEntryStreamNormalizer { private final AbstractWorkbookRef workbookRef; private IEntryStreamNormalizer delegate; /** * */ public LazyPasswordBasedEncryptor(AbstractWorkbookRef workbookRef) { this.workbookRef = workbookRef; this.delegate = IEntryStreamNormalizer.NULL; } /** * @return the delegate */ public IEntryStreamNormalizer getDelegate() { return delegate; } /* * (non-Javadoc) * @see * org.xmind.core.IEntryStreamNormalizer#normalizeOutputStream(java.io. * OutputStream, org.xmind.core.IFileEntry) */ @Override public OutputStream normalizeOutputStream(OutputStream stream, IFileEntry fileEntry) throws IOException, CoreException { return delegate.normalizeOutputStream(stream, fileEntry); } /* * (non-Javadoc) * @see * org.xmind.core.IEntryStreamNormalizer#normalizeInputStream(java.io. * InputStream, org.xmind.core.IFileEntry) */ @Override public InputStream normalizeInputStream(InputStream stream, IFileEntry fileEntry) throws IOException, CoreException { if (fileEntry.getEncryptionData() != null && delegate == IEntryStreamNormalizer.NULL) { /// encrypted, should ask for password IPasswordProvider passwordProvider = workbookRef .getService(IPasswordProvider.class); if (passwordProvider != null) { String password = passwordProvider .askForPassword(workbookRef, null); if (password == null) throw new CoreException(Core.ERROR_CANCELLATION); delegate = createEncryptor(password); } } return delegate.normalizeInputStream(stream, fileEntry); } /* * (non-Javadoc) * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj == this) return true; if (obj == null || !(obj instanceof LazyPasswordBasedEncryptor)) return false; LazyPasswordBasedEncryptor that = (LazyPasswordBasedEncryptor) obj; return this.delegate.equals(that.delegate); } /* * (non-Javadoc) * @see java.lang.Object#hashCode() */ @Override public int hashCode() { return 37 ^ delegate.hashCode(); } } private final AbstractWorkbookRef workbookRef; private IEntryStreamNormalizer encryptor; private String password; private String passwordHint; /** * */ public WorkbookRefEncryptable(AbstractWorkbookRef workbookRef) { super(); this.workbookRef = workbookRef; this.encryptor = new LazyPasswordBasedEncryptor(workbookRef); } /* * (non-Javadoc) * @see * org.xmind.ui.internal.editor.IEncryptable#setPassword(java.lang.String) */ @Override public void setPassword(String newPassword) { MindMapUIPlugin.getDefault().getUsageDataCollector() .increase("TrigSetPasswordCount"); //$NON-NLS-1$ IEntryStreamNormalizer oldEncryptor = this.encryptor; IEntryStreamNormalizer newEncryptor = createEncryptor(newPassword); if (encryptorEquals(oldEncryptor, newEncryptor)) return; this.encryptor = newEncryptor; IWorkbook workbook = workbookRef.getWorkbook(); if (workbook != null && workbook instanceof ICoreEventSource) { ICoreEventSource eventSource = (ICoreEventSource) workbook; eventSource.getCoreEventSupport().dispatch(eventSource, new CoreEvent(eventSource, Core.PasswordChange, null)); } this.password = newPassword; } public String getPassword() { return password; } @Override public void setPasswordHint(String passwordHint) { MindMapUIPlugin.getDefault().getUsageDataCollector() .increase("TrigSetPasswordHintCount"); //$NON-NLS-1$ this.passwordHint = passwordHint; } public String getPasswordHint() { MindMapUIPlugin.getDefault().getUsageDataCollector() .increase("TrigGetPasswordHintCount"); //$NON-NLS-1$ return passwordHint; } /* * (non-Javadoc) * @see * org.xmind.ui.internal.editor.IEncryptable#isPasswordCorrect(java.lang. * String) */ @Override public boolean testsPassword(String passwordToTest) { IEntryStreamNormalizer oldEncryptor = this.encryptor; IEntryStreamNormalizer newEncryptor = createEncryptor(passwordToTest); return encryptorEquals(oldEncryptor, newEncryptor); } private static boolean encryptorEquals(IEntryStreamNormalizer oldEncryptor, IEntryStreamNormalizer newEncryptor) { return oldEncryptor.equals(newEncryptor); } /* * (non-Javadoc) * @see org.xmind.ui.internal.editor.IEncryptable#hasPassword() */ @Override public boolean hasPassword() { IEntryStreamNormalizer e = this.encryptor; while (e instanceof LazyPasswordBasedEncryptor) { e = ((LazyPasswordBasedEncryptor) e).getDelegate(); } return e != IEntryStreamNormalizer.NULL; } /** * @return the encryptor */ public IEntryStreamNormalizer getEncryptor() { return encryptor; } protected void setEncryptor(IEntryStreamNormalizer encryptor) { this.encryptor = encryptor; } public void reset() { this.encryptor = new LazyPasswordBasedEncryptor(workbookRef); } /** * @param password * @return */ private static IEntryStreamNormalizer createEncryptor(String password) { return password == null ? IEntryStreamNormalizer.NULL : new PasswordProtectedNormalizer(password); } }