/*
* Copyright (C) 2012-2016 NS Solutions Corporation
*
* 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.htmlhifive.tools.wizard.download;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Enumeration;
import java.util.Set;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.eclipse.core.net.proxy.IProxyService;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.OperationCanceledException;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.TreeNode;
import org.osgi.util.tracker.ServiceTracker;
import com.htmlhifive.tools.wizard.H5WizardPlugin;
import com.htmlhifive.tools.wizard.PluginConstant;
import com.htmlhifive.tools.wizard.library.LibraryState;
import com.htmlhifive.tools.wizard.library.xml.BaseProject;
import com.htmlhifive.tools.wizard.library.xml.Category;
import com.htmlhifive.tools.wizard.library.xml.Library;
import com.htmlhifive.tools.wizard.library.xml.Site;
import com.htmlhifive.tools.wizard.log.ResultStatus;
import com.htmlhifive.tools.wizard.log.messages.Messages;
import com.htmlhifive.tools.wizard.ui.UIMessages;
import com.htmlhifive.tools.wizard.ui.page.tree.CategoryNode;
import com.htmlhifive.tools.wizard.ui.page.tree.LibraryNode;
import com.htmlhifive.tools.wizard.ui.page.tree.RootNode;
import com.htmlhifive.tools.wizard.utils.H5IOUtils;
/**
* <H3>ライブラリダウンロード用モジュール.</H3>
*
* @author fkubo
*/
public class DownloadModule {
/** 外部接続用ProxyTracker. */
//private final ServiceTracker<IProxyService, Object> proxyTracker; // eclipse3.6対応.
private final ServiceTracker proxyTracker;
/** defaultOverwriteMode. */
private int defaultOverwriteMode = 0;
/** lastDownloadStatus. */
private boolean lastDownloadStatus = false;
/**
* デフォルトコンストラクタ.
*
* @param shell シェル
*/
public DownloadModule() {
//this.proxyTracker = new ServiceTracker<IProxyService, Object>(H5WizardPlugin.getInstance().getBundle()
//.getBundleContext(), IProxyService.class, null); // eclipse3.6対応.
this.proxyTracker = new ServiceTracker(H5WizardPlugin.getInstance().getBundle()
.getBundleContext(), IProxyService.class.getName(), null);
proxyTracker.open();
}
/**
* <H3>ファイルコンテンツ出力用ハンドラー.</H3>
*
* @author fkubo
*/
static abstract class FileContentsHandler {
abstract InputStream getInputStream() throws IOException;
}
/**
* <H3>Zipファイルコンテンツ出力用ハンドラー.</H3>
*
* @author fkubo
*/
static class ZipFileContentsHandler implements IFileContentsHandler {
private final ZipEntry zipEntry;
private final ZipFile zipFile;
ZipFileContentsHandler(ZipFile zipFile, ZipEntry zipEntry) {
this.zipFile = zipFile;
this.zipEntry = zipEntry;
}
@Override
public InputStream getInputStream() throws IOException {
return zipFile.getInputStream(zipEntry);
}
}
/**
* closeする.
*/
public void close() {
proxyTracker.close();
}
/**
* 1つのファイルを保存する.
*
* @param monitor モニター
* @param totalWork タスク数
* @param iFile ファイル
* @param fileContentsHandler ファイルコンテンツハンドラ
* @throws IOException IO例外
* @return 結果
*/
private boolean updateFile(IProgressMonitor monitor, int totalWork, ResultStatus logger, IFile iFile,
IFileContentsHandler fileContentsHandler) throws IOException {
// PI0112=INFO,[{0}]を更新中...
monitor.subTask(Messages.PI0112.format(iFile.getFullPath()));
int ret = 0;
InputStream is = null;
try {
if (iFile.exists()) {
// 既に存在している.
if (defaultOverwriteMode != 0) {
ret = defaultOverwriteMode;
} else {
MessageDialog dialog = new MessageDialog(null, Messages.SE0113.format(),
Dialog.getImage(Dialog.DLG_IMG_MESSAGE_INFO), Messages.SE0114.format(iFile.getRawLocation()
.toString()), MessageDialog.QUESTION, new String[] { UIMessages.Dialog_OVERWRITE,
UIMessages.Dialog_ALL_OVERWRITE, UIMessages.Dialog_IGNORE,
UIMessages.Dialog_ALL_IGNORE }, 0);
ret = dialog.open();
}
switch (ret) {
case 1:
defaultOverwriteMode = ret;
case 0:
// 上書きする.
logger.log(Messages.SE0097, iFile.getFullPath());
is = fileContentsHandler.getInputStream();
iFile.setContents(is, true, true, null);
logger.log(Messages.SE0098, iFile.getFullPath());
break;
case 3:
defaultOverwriteMode = ret;
case 2:
// 無視する.
break;
}
} else {
if (!iFile.getParent().exists()) {
// フォルダの作成.
H5IOUtils.createParentFolder(iFile.getParent(), null);
}
is = fileContentsHandler.getInputStream();
logger.log(Messages.SE0091, iFile.getFullPath());
iFile.create(is, true, null);
logger.log(Messages.SE0092, iFile.getFullPath());
}
return true;
} catch (CoreException e) {
// SE0024=ERROR,({0})を操作中に入出力例外が発生しました。
logger.log(e, Messages.SE0024, iFile.getFullPath().toString());
} finally {
IOUtils.closeQuietly(is);
}
return false;
}
/**
* 1つのファイルをダウンロードする.
*
* @param monitor モニター
* @param totalWork タスク数
* @param file ファイル
* @param uri URI
* @throws CoreException コア例外
*/
private ZipFile download(final IProgressMonitor monitor, final int totalWork, ResultStatus logger, IFile file,
final String urlStr) throws CoreException {
// PI0111=INFO,[{0}]をダウンロード中...
monitor.subTask(Messages.PI0111.format(urlStr));
lastDownloadStatus = false;
int ret = 0;
while (ret == 0) {
try {
if (file != null) {
// 通常のファイル生成.
IConnectMethod method = ConnectMethodFactory.getMethod(urlStr, true);
method.setConnectionTimeout(PluginConstant.URL_LIBRARY_CONNECTION_TIMEOUT);
method.setProxy(getProxyService());
method.getInputStream();
boolean updateResult = updateFile(monitor, 0, logger, file, method);
if (updateResult) {
lastDownloadStatus = true;
}
monitor.worked(totalWork);
} else {
// fileがnullの時は一時ファイルを作成し、ZipFileを返す仕様とする.
BufferedInputStream bufferIs = null;
OutputStream os = null;
try {
IConnectMethod method = ConnectMethodFactory.getMethod(urlStr, true);
method.setConnectionTimeout(PluginConstant.URL_LIBRARY_CONNECTION_TIMEOUT);
method.setProxy(getProxyService());
if (!method.connect()) {
// SE0101=ERROR,リソース({0})のダウンロードに失敗しました。URL={1}, File={2}
logger.log(Messages.SE0101, urlStr, file != null ? file.toString() : "");
return null;
}
final int contentLength = method.getContentLength();
// final int perWork;
// if (contentLength > 0) {
// perWork = Math.max(1, totalWork * DEFAULT_BUFFER_SIZE / 8 / contentLength);
// }else{
// perWork = totalWork;
// }
InputStream is = method.getInputStream();
// if (H5IOUtils.isClassResources(urlStr)) {
// // urlがnullの時は、クラスパスから取得する.
// is = DownloadModule.class.getResourceAsStream(urlStr);
// } else {
// // 通常のURL
// HttpMethod method = DownloadModule.this.connect(urlStr,
// PluginResource.URL_LIBRARY_CONNECTION_TIMEOUT);
// if (method == null) {
// return null;
// }
//
// // サイズが取得で切れば取得する.
// Header header = method.getResponseHeader("Content-Length");
// if (header != null) {
// contentLength = Integer.valueOf(header.getValue());
// }
// if (contentLength > 0) {
// perWork = Math.max(1, perWork * DEFAULT_BUFFER_SIZE / contentLength);
// }
// is = method.getResponseBodyAsStream();
// }
if (is == null) {
// SE0101=ERROR,リソース({0})のダウンロードに失敗しました。URL={1}, File={2}
logger.log(Messages.SE0101, urlStr, file != null ? file.toString() : "");
return null;
}
bufferIs = new BufferedInputStream(is) {
private int current = 0;
private final int perWork = Math.max(1, totalWork * buf.length / 8 / contentLength);
@Override
public synchronized int read() throws IOException {
int result = super.read();
current += result * 16;
monitor.subTask(Messages.PI0143.format(current, contentLength, urlStr));
//monitor.worked(result * 16);
monitor.worked(perWork);
return result;
}
};
// SE0093=INFO,{0}をダウンロードします。
logger.log(Messages.SE0093, urlStr);
// ZIP対応.
File tempFile = File.createTempFile(H5WizardPlugin.getId(), "tmp");
// VM終了時に削除されるようにセット.
tempFile.deleteOnExit();
// 保存する.
os = FileUtils.openOutputStream(tempFile);
IOUtils.copy(bufferIs, os);
// byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
// int n = 0;
// while (-1 != (n = is.read(buffer))) {
// os.write(buffer, 0, n);
// if (contentLength > 0) {
// monitor.worked(perWork);
// }
// }
if (contentLength == 0) {
monitor.worked(totalWork);
}
// SE0094=INFO,{0}をダウンロードしました。
logger.log(Messages.SE0094, urlStr);
lastDownloadStatus = true;
return new ZipFile(tempFile);
} finally {
IOUtils.closeQuietly(bufferIs);
IOUtils.closeQuietly(os);
}
}
ret = 1;
} catch (IOException e) {
// SE0101=ERROR,リソース({0})のダウンロードに失敗しました。URL={1}, File={2}
logger.log(e, Messages.SE0101, urlStr, file != null ? file.toString() : "");
// つながりません.
MessageDialog dialog = new MessageDialog(null, Messages.SE0115.format(),
Dialog.getImage(Dialog.DLG_IMG_MESSAGE_WARNING), Messages.SE0116.format(urlStr),
MessageDialog.QUESTION, new String[] { UIMessages.Dialog_RETRY, UIMessages.Dialog_IGNORE,
UIMessages.Dialog_STOP }, 0);
ret = dialog.open();
if (ret == 2) {
// 中断
throw new OperationCanceledException(Messages.SE0101.format(urlStr, file != null ? file.toString()
: ""));
}
}
}
return null;
}
/**
* プロジェクト構造をダウンロードする.
*
* @param monitor モニター
* @param totalTask タスク数
* @param logger ロガー
* @param baseProject ベースプロジェクト
* @param proj 対象プロジェクト
* @throws CoreException コア例外
*/
public void downloadProject(IProgressMonitor monitor, int totalTask, ResultStatus logger, BaseProject baseProject,
IProject proj) throws CoreException {
// 全てで400work.
int perLibWork = totalTask;
// SE0063=INFO,プロジェクト用ZIPファイルをダウンロードします。
logger.log(Messages.SE0063);
// 直接ファイルを展開するよう修正
// 先に全上書きフラグは立てておく.
defaultOverwriteMode = 1;
String siteUrl = baseProject.getUrl();
String path = H5IOUtils.getURLPath(siteUrl);
if (path == null) {
logger.log(Messages.SE0082, baseProject.getUrl());
logger.setSuccess(false);
throw new CoreException(new Status(IStatus.ERROR, H5WizardPlugin.getId(),
Messages.SE0082.format(baseProject.getUrl())));
}
final ZipFile zipFile;
//try {
//URI uri = new URI(baseProject.getUrl());
zipFile = download(monitor, totalTask, logger, null, siteUrl);
//} catch (URISyntaxException e) {
//throw new CoreException(new Status(IStatus.ERROR, H5WizardPlugin.getId(), Messages.SE0013.format(), e));
//}
perLibWork = perLibWork - 100;
if (!lastDownloadStatus) {
// ダウンロードエラー.
logger.log(Messages.SE0068);
logger.setSuccess(false);
throw new CoreException(new Status(IStatus.ERROR, H5WizardPlugin.getId(), Messages.SE0068.format()));
}
// SE0064=INFO,プロジェクト用ZIPファイルをダウンロードしました。
logger.log(Messages.SE0064);
// 更新.
//proj.refreshLocal(IResource.DEPTH_ONE, monitor);
//logger.log(Messages.SE0101);
// プロジェクト構造の追加
int perExtractWork = Math.max(1, perLibWork / zipFile.size());
for (Enumeration<? extends ZipEntry> enumeration = zipFile.entries(); enumeration.hasMoreElements();) {
final ZipEntry zipEntry = enumeration.nextElement();
// PI0113=INFO,[{0}]を展開中...
monitor.subTask(Messages.PI0113.format(zipEntry.getName()));
if (zipEntry.isDirectory()) {
// フォルダ
IFolder iFolder = proj.getFolder(zipEntry.getName());
if (!iFolder.exists()) {
logger.log(Messages.SE0091, iFolder.getFullPath());
H5IOUtils.createParentFolder(iFolder, null);
logger.log(Messages.SE0092, iFolder.getFullPath());
}
} else {
// ファイル
IFile iFile = proj.getFile(zipEntry.getName());
// ファイル保存.
try {
updateFile(monitor, 0, logger, iFile, new ZipFileContentsHandler(zipFile, zipEntry));
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, H5WizardPlugin.getId(), Messages.SE0068.format(),
e));
}
}
monitor.worked(perExtractWork);
}
// // エラー ZIPに含まれていない.
// H5StringUtils.log(getShell(), null, Messages.SE0043,
// Messages.SE0045.format(site.getFile()));
// 元に戻す.
defaultOverwriteMode = 0;
logger.log(Messages.SE0070);
}
/**
* ライブラリをダウンロードする.
*
* @param monitor モニター
* @param totalWork タスク数
* @param logger ロガー
* @param selectedLibrarySet 選択済ライブラリ
* @param projectRoot プロジェクトルートフォルダ
* @return 処理が成功したかどうか
*/
public boolean downloadLibrary(IProgressMonitor monitor, int totalWork, ResultStatus logger,
Set<LibraryNode> selectedLibrarySet, IContainer projectRoot) {
if (H5WizardPlugin.getInstance().getSelectedLibrarySet().size() == 0) {
return true;
}
// 全てで900work.
int perLibWork = Math.max(1, totalWork / H5WizardPlugin.getInstance().getSelectedLibrarySet().size());
// タスクを開始.
// PI0102=INFO,ライブラリをダウンロード中...
// monitor.beginTask(Messages.PI0102.format(), H5WizardPlugin.getInstance().getSelectedLibrarySet()
// .size()); // ライブラリの数分登録.
defaultOverwriteMode = 0;
for (LibraryNode libraryNode : selectedLibrarySet) {
if (libraryNode.isSelected()) {
try {
// 追加処理.
CategoryNode categoryNode = libraryNode.getParent();
Category category = categoryNode.getValue();
// PI0114=INFO,ライブラリ[{0}{1}]を更新中...
monitor.subTask(Messages.PI0114.format(category.getName(), libraryNode.getLabel()));
// SE0073=INFO,ライブラリ{0}{1}の更新処理を開始します。
logger.log(Messages.SE0073, category.getName(), libraryNode.getLabel());
// 処理フォルダ.
IContainer folder = categoryNode.getInstallFullPath(); // projectRoot.getFolder();
if (libraryNode.getState() == LibraryState.REMOVE) {
// 削除処理.
// 全てで900work.
int perLibFileWork = perLibWork;
if (libraryNode.getFileList().length > 0) {
perLibFileWork = Math.max(1, perLibWork / libraryNode.getFileList().length);
for (String fileName : libraryNode.getFileList()) {
IFile iFile = folder.getFile(Path.fromOSString(fileName));
if (iFile.exists()) {
// 他で利用されているかどうかチェック.
if (isOtherLibraryResources(libraryNode, folder, fileName)) {
logger.log(Messages.SE0102, iFile.getFullPath());
} else {
// 削除.
logger.log(Messages.SE0095, iFile.getFullPath());
iFile.delete(true, true, monitor);
logger.log(Messages.SE0096, iFile.getFullPath());
// フォルダが空なら削除.
IContainer parentFolder = iFile.getParent();
while (parentFolder.exists() && parentFolder.members().length == 0) {
// 削除.
logger.log(Messages.SE0095, parentFolder.getFullPath());
((IFolder) parentFolder).delete(true, true, monitor);
logger.log(Messages.SE0096, parentFolder.getFullPath());
parentFolder = parentFolder.getParent();
}
}
}
monitor.worked(perLibFileWork);
}
} else {
monitor.worked(perLibWork);
}
} else if (libraryNode.isAddable()) {
// 追加処理.
if (!downloadZip(libraryNode, perLibWork, folder, monitor, logger)) {
// 1つ以上ダウンロードに失敗した場合.
logger.setSuccess(false);
}
}
// SE0074=INFO,ライブラリ{0}{1}の更新処理が完了しました。
logger.log(Messages.SE0074, category.getName(), libraryNode.getLabel());
} catch (IOException e) { // CoreException. IOException
// SE0023=ERROR,予期しない例外が発生しました。
logger.log(e, Messages.SE0023, "");
} catch (CoreException e) { // CoreException. IOException
// SE0023=ERROR,予期しない例外が発生しました。
logger.log(e, Messages.SE0023, "");
}
}
}
return logger.isSuccess();
}
/**
* ZIPファイルをダウンロードする.
*
* @param libraryNode ライブラリノード
* @param perLibWork libWork
* @param folder フォルダ
* @param monitor モニタ
* @param logger ロガー.
* @return 成功したかどうか.
* @throws IOException IO例外
* @throws CoreException コア例外
*/
private boolean downloadZip(LibraryNode libraryNode, int perLibWork, IContainer folder, IProgressMonitor monitor,
ResultStatus logger) throws IOException, CoreException {
boolean result = true;
boolean addStatus = false;
ZipFile cachedZipFile = null;
String cachedSite = null;
Library library = libraryNode.getValue();
if (!library.getSite().isEmpty()) {
int perSiteWork = Math.max(1, perLibWork / library.getSite().size());
for (Site site : library.getSite()) {
String siteUrl = site.getUrl();
String path = H5IOUtils.getURLPath(siteUrl);
if (path == null) {
logger.log(Messages.SE0082, siteUrl);
continue;
}
boolean setWorked = false;
IContainer savedFolder = folder;
if (site.getExtractPath() != null) {
savedFolder = savedFolder.getFolder(Path.fromOSString(site.getExtractPath()));
}
// ファイルのダウンロード.
IFile iFile = null;
if (path.endsWith(".zip") || path.endsWith(".jar") || site.getFilePattern() != null) {
// Zipダウンロード
// 同じファイルはそのまま使う.
if (!siteUrl.equals(cachedSite)) {
cachedZipFile = download(monitor, perSiteWork, logger, null, siteUrl);
setWorked = true;
if (!lastDownloadStatus || cachedZipFile == null) {
libraryNode.setInError(true);
result = false;
break;
}
cachedSite = siteUrl;
}
final ZipFile zipFile = cachedZipFile;
//未使用 int perZipWork = Math.max(1, perSiteWork / zipFile.size());
// Zip展開.
for (Enumeration<? extends ZipEntry> e = zipFile.entries(); e.hasMoreElements();) {
final ZipEntry zipEntry = e.nextElement();
if (site.getFilePattern() != null
&& !FilenameUtils.wildcardMatch(zipEntry.getName(), site.getFilePattern())) {
// 一致しない.
continue;
}
IContainer savedFolder2 = savedFolder;
String wildCardStr = StringUtils.defaultString(site.getFilePattern());
if (wildCardStr.contains("*") && wildCardStr.contains("/")) {
// 直前のフォルダまで取得する.
wildCardStr = StringUtils.substringBeforeLast(site.getFilePattern(), "/");
}
String entryName = zipEntry.getName();
if (entryName.startsWith(wildCardStr + "/")) {
entryName = entryName.substring(wildCardStr.length() + 1);
}
if (zipEntry.isDirectory()) {
// zipディレクトリは作成するだけ.
if (StringUtils.isNotEmpty(entryName)) {
// フォルダ作成.
savedFolder2 = savedFolder2.getFolder(Path.fromOSString(entryName));
if (libraryNode.isAddable() && !savedFolder2.exists()) {
logger.log(Messages.SE0091, savedFolder2.getFullPath());
H5IOUtils.createParentFolder(savedFolder2, null);
logger.log(Messages.SE0092, savedFolder2.getFullPath());
} else if (libraryNode.getState() == LibraryState.REMOVE && savedFolder2.exists()) {
// 削除.
logger.log(Messages.SE0095, savedFolder2.getFullPath());
H5IOUtils.createParentFolder(savedFolder2, null);
logger.log(Messages.SE0096, savedFolder2.getFullPath());
}
}
} else {
// zip以外ファイル追加.
// ファイル名の変更.
if (site.getReplaceFileName() != null) {
iFile = savedFolder2.getFile(Path.fromOSString(site.getReplaceFileName()));
} else {
iFile = savedFolder2.getFile(Path.fromOSString(entryName));
}
// ファイル保存.
updateFile(monitor, 0, logger, iFile, new ZipFileContentsHandler(zipFile, zipEntry));
addStatus = true;
}
}
if (savedFolder.exists() && savedFolder.members().length == 0) {
// 空のフォルダの場合は削除.
savedFolder.delete(true, monitor);
}
} else {
// ファイル名の変更.
if (site.getReplaceFileName() != null) {
iFile = savedFolder.getFile(Path.fromOSString(site.getReplaceFileName()));
} else {
// ファイル部分.
iFile = savedFolder.getFile(Path.fromOSString(StringUtils.substringAfterLast(path, "/")));
}
// 追加.
download(monitor, perSiteWork, logger, iFile, siteUrl);
setWorked = true;
if (!lastDownloadStatus) {
// SE0101=ERROR,リソース({0})のダウンロードに失敗しました。URL={1}, File={2}
logger.log(
Messages.SE0101,
iFile != null ? iFile.getFullPath().toString() : StringUtils.defaultString(site
.getFilePattern()), site.getUrl(), site.getFilePattern());
libraryNode.setInError(true);
} else {
addStatus = true;
}
}
// ファイルのダウンロードここまで.
// 更新.
if (!addStatus) {
// SE0099=ERROR,ファイルの作成に失敗しました。URL={1}, File={2}
logger.log(Messages.SE0099, site.getUrl(), iFile != null ? iFile.getFullPath().toString()
: StringUtils.defaultString(site.getFilePattern()));
libraryNode.setInError(true);
result = false;
}
// folder.refreshLocal(IResource.DEPTH_ZERO, null);
// // SE0102=INFO,ワークスペースを更新しました。
// logger.log(Messages.SE0102);
// logger.log(Messages.SE0068, iFile.getFullPath());
if (!setWorked) {
monitor.worked(perSiteWork);
}
}
} else {
monitor.worked(perLibWork);
}
return result;
}
/**
* 他で利用しているリソースかどうか.
*
* @param targetLibraryNode ライブラリノード.
* @param folder フォルダ
* @param targetFileName ターゲット名
* @return 他で利用しているリソースかどうか.
*/
private boolean isOtherLibraryResources(LibraryNode targetLibraryNode, IContainer folder, String targetFileName) {
RootNode rootNode = targetLibraryNode.getParent().getParent();
if (rootNode.getChildren() == null) {
return false;
}
for (TreeNode node : rootNode.getChildren()) {
CategoryNode categoryNode = (CategoryNode) node;
if (folder.equals(categoryNode.getInstallFullPath())) {
for (TreeNode node2 : categoryNode.getChildren()) {
LibraryNode libraryNode = (LibraryNode) node2;
if (libraryNode != targetLibraryNode && libraryNode.isExists()) {
for (String fileName : libraryNode.getFileList()) {
if (targetFileName.equals(fileName)) {
return true;
}
}
}
}
}
}
return false;
}
/**
* プロキシサービスを取得する.
*
* @return プロキシサービス
*/
public IProxyService getProxyService() {
return (IProxyService) proxyTracker.getService();
}
}