Java tutorial
/* * Copyright (c) 2005-2010, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you 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 org.wso2.carbon.repomanager.axis2; import org.apache.axis2.AxisFault; import org.apache.axis2.context.ConfigurationContext; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import org.wso2.carbon.context.CarbonContext; import org.wso2.carbon.core.AbstractAdmin; import org.wso2.carbon.core.multitenancy.utils.TenantAxisUtils; import org.wso2.carbon.server.admin.service.ServerAdmin; import org.wso2.carbon.utils.CarbonUtils; import org.wso2.carbon.utils.multitenancy.MultitenantConstants; import javax.activation.DataHandler; import javax.activation.FileDataSource; import java.io.File; import java.io.FileFilter; import java.io.FileOutputStream; import java.io.IOException; /** * Axis2 repository manager Admin service */ @SuppressWarnings("unused") public class Axis2RepoManager extends AbstractAdmin { private static final Log log = LogFactory.getLog(Axis2RepoManager.class); private static final String RELOAD_REQUIRED = "reload.required"; private static final String DIRECTORIES_LABEL = "dirs"; private static final String FILES_LIST_LABEL = "filelist"; private static final String DIRECTORY_NAME_LABEL = "dirname"; private static final String FILE_NAME_LABEL = "filename"; private static final String LIB_DIR = "lib"; public DirectoryStructureMetaData getDirectoryStructure() throws JSONException { String repo = getAxisConfig().getRepository().getPath(); File folder = new File(repo); JSONObject obj = new JSONObject(); traverseParent(obj, folder, folder.getName()); obj.put(DIRECTORY_NAME_LABEL, folder.getName()); Boolean reloadRequiredProp = (Boolean) getConfigContext().getProperty(RELOAD_REQUIRED); boolean reloadRequired = (reloadRequiredProp != null) ? reloadRequiredProp : false; return new DirectoryStructureMetaData(obj.toString(), reloadRequired); } /** * Function that generates the folder structure * Note that this method only returns common artifacts that are located in the "lib" directory * * @param obj JSONObject object that represents the folder to be traversed recursively * @param folder Actual java.io.File object representing the folder to be traversed * @param parent The Axis2 Repository directory path * @throws JSONException Thrown if the key if null while adding values to JSONObject using put method * The repository is traversed assuming that the directory structure will be as follows; |-server => [repository_parent] |-axis2services => [services_directory] | |-lib => [lib directory] | | |-dependency1.jar | | |-dependency2.jar | |-service1.aar | |-service2.aar |-axis2modules | |-lib | | |-dependency1.jar | | |-dependency2.jar | |-module1.mar | |-module2.mar |-carbonapps | |-xxx | | |-xxx | | |-zzz | |-xxx | |-zzz |-xxxxxx */ private void traverseParent(JSONObject obj, File folder, String parent) throws JSONException { JSONArray dirs = new JSONArray(); JSONArray files = new JSONArray(); FileFilter fileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory() && file.getName().equals(LIB_DIR); } }; // Check if parent directory has a lib directory, add it explicitly if it doesn't. // NOTE: we cannot use the traverseServiceDir() method to travers the parent's lib directory // because it will add a lib within the parent's lib, assuming that this it is a service directory. if (folder.listFiles(fileFilter).length == 0) { JSONObject tempLib = new JSONObject(); tempLib.put(DIRECTORIES_LABEL, new JSONArray()); tempLib.put(FILES_LIST_LABEL, new JSONArray()); tempLib.put(DIRECTORY_NAME_LABEL, LIB_DIR); dirs.put(tempLib); } else { JSONObject tempLibDir = new JSONObject(); JSONArray libFilesArr = new JSONArray(); File[] contents = folder.listFiles(fileFilter)[0].listFiles(); for (File file : contents) { libFilesArr.put(new JSONObject().put(FILE_NAME_LABEL, file.getName())); } tempLibDir.put(DIRECTORIES_LABEL, new JSONArray()); tempLibDir.put(FILES_LIST_LABEL, libFilesArr); tempLibDir.put(DIRECTORY_NAME_LABEL, LIB_DIR); dirs.put(tempLibDir); } File[] folderItems = folder.listFiles(); for (File file : folderItems) { if (file.isDirectory() && !(file.getName().equalsIgnoreCase(LIB_DIR)) && !isMetaDataFile(file)) { dirs.put(new JSONObject().put(DIRECTORY_NAME_LABEL, file.getName())); traverseServiceDir(dirs.getJSONObject(dirs.length() - 1), file); } else if (file.isFile() && !isMetaDataFile(file)) { files.put(new JSONObject().put(FILE_NAME_LABEL, file.getName())); } } obj.put(DIRECTORIES_LABEL, dirs); obj.put(FILES_LIST_LABEL, files); } /** * Traverse the chile directory * @param obj JSONObject object that represents the chile directory * @param folder The java.io.File object representing the child directory to be traversed * @throws JSONException Thrown if an error occurs when manipulating the JSON array */ private void traverseServiceDir(JSONObject obj, File folder) throws JSONException { JSONArray dirs = new JSONArray(); FileFilter fileFilter = new FileFilter() { public boolean accept(File file) { return file.isDirectory() && file.getName().equals(LIB_DIR); } }; if (folder.listFiles(fileFilter).length == 0) { JSONObject tempLib = new JSONObject(); tempLib.put(DIRECTORIES_LABEL, new JSONArray()); tempLib.put(FILES_LIST_LABEL, new JSONArray()); tempLib.put(DIRECTORY_NAME_LABEL, LIB_DIR); dirs.put(tempLib); } else { JSONObject tempLibDir = new JSONObject(); JSONArray libFilesArr = new JSONArray(); File[] contents = folder.listFiles(fileFilter)[0].listFiles(); for (File file : contents) { libFilesArr.put(new JSONObject().put(FILE_NAME_LABEL, file.getName())); } tempLibDir.put(DIRECTORIES_LABEL, new JSONArray()); tempLibDir.put(FILES_LIST_LABEL, libFilesArr); tempLibDir.put(DIRECTORY_NAME_LABEL, LIB_DIR); dirs.put(tempLibDir); } obj.put(DIRECTORIES_LABEL, dirs); obj.put(FILES_LIST_LABEL, new JSONArray()); } /** * @param artifactUploadDataList List containing the Axis2 archive files that are to be uploaded * @param fileUploadDir The name of the directory to upload the atrifacts * @return The status of the artifact upload process * @throws java.io.IOException Thrown if an error occurs while uploading the files */ public boolean uploadArtifact(Axis2ArtifactUploadData[] artifactUploadDataList, String fileUploadDir) throws IOException { final String dir = fileUploadDir; String fileName = null; File destDir; try { File repoFile = new File(getAxisConfig().getRepository().getPath()); if (CarbonUtils.isURL(repoFile.getAbsolutePath())) { throw new AxisFault("Uploading services to URL repo is not supported."); } if (repoFile.getName().equals(fileUploadDir)) { destDir = new File(repoFile.getAbsolutePath() + File.separator + LIB_DIR); } else { FileFilter filter = new FileFilter() { public boolean accept(File file) { return file.isDirectory() && file.getName().equals(dir); } }; File[] temp = repoFile.listFiles(filter); if (temp.length == 0) { throw new AxisFault("The directory you selected is not valid."); } else { destDir = new File(temp[0].getAbsolutePath() + File.separator + LIB_DIR); } } if (!destDir.exists()) { if (!destDir.mkdirs()) { log.error("Could not create lib JAR upload directory " + destDir.getAbsolutePath()); throw new AxisFault("Could not upload artifacts to " + fileUploadDir); } } for (Axis2ArtifactUploadData uploadData : artifactUploadDataList) { fileName = uploadData.getFileName(); writeToFileSystem(destDir.getAbsolutePath(), fileName, uploadData.getDataHandler()); } getConfigContext().setProperty(RELOAD_REQUIRED, Boolean.TRUE); } catch (IOException e) { String msg = "Error occurred while uploading the service " + fileName; log.error(msg, e); throw new AxisFault(msg, e); } return true; } public boolean deleteLib(String libPath) throws AxisFault { boolean deletionStatus; File libPathFile = new File(getAxisConfig().getRepository().getPath() + libPath); if (!libPathFile.exists()) { log.error("The file " + libPathFile.getAbsolutePath() + " does not exist"); throw new AxisFault("The file " + libPathFile.getName() + " does not exist"); } else { if (!libPathFile.canWrite()) { log.error("The file " + libPathFile.getAbsolutePath() + " is write protected"); throw new AxisFault("The file " + libPathFile.getName() + " is write protected"); } else { deletionStatus = libPathFile.delete(); getConfigContext().setProperty(RELOAD_REQUIRED, Boolean.TRUE); } } return deletionStatus; } /** * This method is used to restart the Axis2 server after an artifact has been uploaded. * This method is invoked via the management console. * * @return The status of the Axis2 server restart success/failure * @throws org.apache.axis2.AxisFault If restarting the server in case of a super tenant * reload request fails */ public boolean restartAxis2Server() throws AxisFault { if (CarbonContext.getThreadLocalCarbonContext().getTenantId() == MultitenantConstants.SUPER_TENANT_ID) { // If a super tenant initiates a reload repo, it is equivalent to a restart server request try { new ServerAdmin().restart(); } catch (Exception e) { String msg = "Could not reload super tenant Axis2 repo. Restart failed."; log.error(msg, e); throw new AxisFault(msg, e); } } else { reloadTenantAxis2Repo(); } return true; } private void reloadTenantAxis2Repo() { final ConfigurationContext tenantConfigContext = getConfigContext(); Runnable runnable = new Runnable() { public void run() { TenantAxisUtils.terminateTenantConfigContext(tenantConfigContext); } }; tenantConfigContext.setProperty(RELOAD_REQUIRED, Boolean.FALSE); Thread reloadThread = new Thread(runnable); try { reloadThread.join(); } catch (InterruptedException e) { log.warn("Axis2 repo reload thread was interrupted", e); } reloadThread.start(); } private void writeToFileSystem(String path, String fileName, DataHandler dataHandler) throws IOException { File destFile = new File(path, fileName); FileOutputStream fos = null; try { fos = new FileOutputStream(destFile); dataHandler.writeTo(fos); fos.flush(); } finally { if (fos != null) { try { fos.close(); } catch (IOException e) { log.error("Failed to close FileOutputStream for file " + fileName, e); } } } } /** * Downloads the relevant artifacts from the repository * @param filePath path to the artifacts that should be downloaded, relative to the tenants repository * @return the datahandler corresponding to the artifact that should be downloaded */ public DataHandler downloadArtifact(String filePath) { String resourcePath = getAxisConfig().getRepository().getPath() + filePath; FileDataSource datasource = new FileDataSource(new File(resourcePath)); DataHandler handler = new DataHandler(datasource); return handler; } /** * Make sure current directory or file is not a meta-data file of a * application such as SVN, IDES etc. This will return true if the file or * directory start with "." e.g - .svn, .git, .project * * @param file * @return */ private boolean isMetaDataFile(File file) { if (file.getName().startsWith(".")) { return true; } return false; } }