Работа с расширениями файловой системы пакетной загрузки

Приведены простые примеры предоставляемых точек расширения.

Пример FileSystemBatchDataSource

package com.ibm.ram.batch.example;

import java.io.*;
import java.util.*;
import java.util.zip.*;

import com.ibm.ram.client.LocalFileArtifact;
import com.ibm.ram.client.LocalFolderArtifact;
import com.ibm.ram.client.batch.BatchDataSource;
import com.ibm.ram.client.status.RAMStatusMonitor;
import com.ibm.ram.common.data.*;

/**
 * Источник данных для примера расширения клиента пакетной загрузки, создающий ресурсы на основе папок и файлов .zip
 * в конкретной корневой папке. Папки и файлы .zip должны содержать файл .asset_info в формате
 * формате файла .properties (в каждой строке пара ключ=значение... 
 * см. {@link java.util.Properties}) со свойствами ресурса:
 * <ul>
 * <li>name (Необязательное. Если значение не указано, то применяется имя файла/папки.)
 * <li>version (Необязательное. Если значение не указано, то применяется версия 1.0).
 * <li>community (Обязательное)
 * <li>asset_type (Обязательное)
 * <li>short_description (Необязательное. Если значение не указано, то применяется имя файла/папки.)
 * <li>description (Необязательное)
 * </ul>
 * 
 * @author ebordeau
 */
public class FileSystemBatchDataSource extends BatchDataSource {
 
 private static final String NAME = "name";
 private static final String VERSION = "version";
 private static final String COMMUNITY = "community";
 private static final String ASSET_TYPE = "asset_type";
 private static final String SHORT_DESCRIPTION = "short_description";
 private static final String DESCRIPTION = "description";
 private static final String ASSET_INFO = ".asset_info";
 
 private File root;
 private String rootPath;

 public FileSystemBatchDataSource() {}

 public FileSystemBatchDataSource(String path) {
  rootPath = path;
 }
 
 /**
  * Создание и возврат ресурсов с учетом корневого каталога.
  *
  * @see com.ibm.ram.client.batch.BatchDataSource#fetchAssets(com.ibm.ram.client.status.RAMStatusMonitor)
  */
 @Override
 public Asset[] fetchAssets(RAMStatusMonitor monitor) {
  if (root == null) {
   if (rootPath == null) // если путь к корневому каталогу не указан, возвращается пустой массив
    return new Asset[0];
   root = new File(rootPath);
  }
  List<Asset> assets = new ArrayList<Asset>();
  // получение всех файлов из корневого каталога
  File[] files = root.listFiles();
  for (File file : files) {
   // требуется выбрать папку для ресурса
   File folder = null;
   if (file.isDirectory()) {
    // каталог можно использовать в исходном виде
    folder = file;
   } else if (file.getName().toLowerCase().endsWith(".zip")) {
    // файл zip требуется извлечь во временный каталог
    try {
     ZipFile zip = new ZipFile(file);
     folder = extractZip(zip);
    } catch (ZipException e) {
     e.printStackTrace();
    } catch (IOException e) {
     e.printStackTrace();
    }
   } else {
    // обрабатываются только файлы zip и каталоги
    continue;
   }
   
   // анализ файла .asset_info
   File assetInfoFile = new File(folder, ASSET_INFO);
   Asset asset = new Asset();
   parseAssetInfo(assetInfoFile, asset);
   
   // если имя, версия или краткое описание не задано, то применяется значение по умолчанию
   if (asset.getName() == null)
    asset.setName(folder.getName());
   if (asset.getIdentification().getVersion() == null)
    asset.getIdentification().setVersion("1.0");
   if (asset.getShortDescription() == null)
    asset.setShortDescription(folder.getName());
    
   // добавление всех файлов в папке (за исключением .asset_info) в качестве артефактов
   File[] artifactFiles = folder.listFiles();
   List<Artifact> artifacts = new ArrayList<Artifact>();
   for (File artifactFile : artifactFiles) {
    if (artifactFile.getName().toLowerCase().equals(ASSET_INFO)) 
     continue;
    if (artifactFile.isDirectory())
     artifacts.add(new LocalFolderArtifact(artifactFile));
    else
     artifacts.add(new LocalFileArtifact(artifactFile));
   }
   if (!artifacts.isEmpty()) {
    FolderArtifact artifactsRoot = asset.getArtifactsRoot();
    if (artifactsRoot == null) {
     artifactsRoot = new FolderArtifact();
     asset.setArtifactsRoot(artifactsRoot);
    }
    artifactsRoot.setChildren(artifacts.toArray(new Artifact[artifacts.size()]));
   }
   assets.add(asset);
  }
  // возврат созданных ресурсов
  return assets.toArray(new Asset[assets.size()]);
 }
 
 /**
  * Анализ файла .asset_info и задание значений для ресурса.
  */
 private void parseAssetInfo(File assetInfoFile, Asset asset) {
  Properties props = new Properties();
  try {
   props.load(new FileInputStream(assetInfoFile));
   asset.setName(props.getProperty(NAME));
   asset.getIdentification().setVersion(props.getProperty(VERSION));
   
   CommunityInformation community = new CommunityInformation();
   community.setName(props.getProperty(COMMUNITY));
   asset.setCommunity(community);
   
   AssetType assetType = new AssetType();
   assetType.setName(props.getProperty(ASSET_TYPE));
   asset.setAssetType(assetType);
   
   asset.setShortDescription(props.getProperty(SHORT_DESCRIPTION));
   asset.setDescription(props.getProperty(DESCRIPTION));
  } catch (FileNotFoundException e) {
   e.printStackTrace();
  } catch (IOException e) {
   e.printStackTrace();
  }
 }
 
 /**
  * Извлечение содержимого файла .zip во временный каталог с последующим возвратом этого каталога.
  */
 private File extractZip(ZipFile zip) {
  String name = zip.getName();
  int i = name.lastIndexOf(File.separator);
  name = name.substring(i + 1, name.length() - 4);
  File destination = new File(System.getProperty("java.io.tmpdir"), name);
  Enumeration entries = zip.entries();
  while (entries.hasMoreElements()) {
   ZipEntry entry = (ZipEntry)entries.nextElement();
   File tmp = new File(destination, entry.getName());
   tmp.getParentFile().mkdirs();
   InputStream in = null;
   FileOutputStream out = null;
   try {
    in = zip.getInputStream(entry);
    out = new FileOutputStream(tmp);
    byte[] data = new byte[8192];
    int read;
    while ((read = in.read(data)) > -1) {
     out.write(data, 0, read);
    }
   } catch (IOException e) {
   } finally {
    if (in != null) {
     try {
      in.close();
     } catch (IOException e) {}
    }
    if (out != null) {
     try {
      out.close();
     } catch (IOException e) {}
    }
   }
  }
  return destination;
 }
 
 /**
  * Возврат пути к корневому каталогу для источника данных
  */
 public String getRootPath() {
  return rootPath;
 }

 /**
  * ИД расширения источника данных в plugin.xml.
  *
  * @see com.ibm.ram.client.batch.BatchDataSource#getTypeId()
  */
 @Override
 public String getTypeId() {
  return "com.ibm.ram.batch.example.filesystem";
 }

 /**
  * Метаданные представляют собой путь к корневому каталогу
  *
  * @see com.ibm.ram.client.batch.BatchDataSource#initialize(java.lang.String)
  */
 @Override
 public void initialize(String metadata) {
  rootPath = metadata;
 }

 /**
  * Сохраняется только путь к корневому каталогу. В более сложном примере
  * можно было бы сохранить что-нибудь более полезное, например XML.
  *
  * @see com.ibm.ram.client.batch.BatchDataSource#save()
  */
 @Override
 public String save() {
  return rootPath;
 }

}

Пример FileSystemBatchUIContributor

package com.ibm.ram.batch.example;

import org.eclipse.jface.viewers.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.DirectoryDialog;
import org.eclipse.swt.widgets.Shell;

import com.ibm.ram.batch.ui.AbstractBatchUIContributor;
import com.ibm.ram.client.batch.BatchDataSource;
import com.ibm.ram.internal.rich.ui.util.ImageUtil;

/**
 * Дополняющий класс UI пакетной загрузки, в котором используется окно выбора каталога. В нем
 * пользователь может выбрать корневой каталог для создания ресурса. См. {@link FileSystemBatchDataSource}, где
 * описана структура корневого каталога. Кроме того, имеется список провайдеров базовой метки и
 * Content Provider.
 * 
 * @author ebordeau
 */
public class FileSystemBatchUIContributor extends AbstractBatchUIContributor {

 /**
  * Создает новый источник данных путем открытия окна выбора каталога, в котором 
  * пользователь может выбрать корневой каталог.
  * 
  * @see com.ibm.ram.batch.ui.AbstractBatchUIContributor#createNewDataSource(org.eclipse.swt.widgets.Shell)
  */
 @Override
 public BatchDataSource createNewDataSource(Shell shell) {
  DirectoryDialog dialog = new DirectoryDialog(shell, SWT.NONE);
  dialog.setMessage("Select root directory");
  String dir = dialog.open();
  if (dir != null)
   return new FileSystemBatchDataSource(dir);
  return null;
 }

 /**
  * Возвращает поставщика содержимого, который не выполняет никаких действий, поскольку
  * источник данных не содержит дочерних объектов.
  * 
  * @see com.ibm.ram.batch.ui.AbstractBatchUIContributor#getContentProvider()
  */
 @Override
 public ITreeContentProvider getContentProvider() {
  return new ITreeContentProvider() {
   public Object[] getChildren(Object parentElement) {
    return new Object[0];
   }
   public Object getParent(Object element) {
    return null;
   }
   public boolean hasChildren(Object element) {
    return false;
   }
   public Object[] getElements(Object inputElement) {
    return new Object[0];
   }
   public void dispose() {}
   public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {}
  };
 }

 /**
  * Возврат провайдера метки, который создает значок и метку корневого
  * каталога.
  * 
  * @see com.ibm.ram.batch.ui.AbstractBatchUIContributor#getLabelProvider()
  */
 @Override
 public ILabelProvider getLabelProvider() {
  return new LabelProvider() {
   public Image getImage(Object element) {
    if (element instanceof FileSystemBatchDataSource)
     return ImageUtil.FOLDER_IMAGE;
    return super.getImage(element);
   }
   public String getText(Object element) {
    if (element instanceof FileSystemBatchDataSource)
     return ((FileSystemBatchDataSource)element).getRootPath();
    return super.getText(element);
   }
  };
 }

}

Комментарии