| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF 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.apache.felix.bundlerepository.impl; |
| |
| import org.apache.felix.bundlerepository.*; |
| import org.apache.felix.service.command.Descriptor; |
| import org.apache.felix.service.command.Parameter; |
| import org.osgi.framework.Bundle; |
| import org.osgi.framework.BundleContext; |
| import org.osgi.framework.InvalidSyntaxException; |
| import org.osgi.framework.Version; |
| |
| import java.io.*; |
| import java.lang.reflect.Array; |
| import java.net.URL; |
| import java.net.URLConnection; |
| import java.util.Comparator; |
| import java.util.Iterator; |
| import java.util.Map; |
| import java.util.TreeMap; |
| import java.util.jar.JarEntry; |
| import java.util.jar.JarInputStream; |
| |
| public class ObrGogoCommand |
| { |
| private static final String REPO_ADD = "add"; |
| private static final String REPO_REMOVE = "remove"; |
| private static final String REPO_LIST = "list"; |
| private static final String REPO_REFRESH = "refresh"; |
| |
| private static final char VERSION_SEPARATOR = '@'; |
| |
| private final BundleContext m_bc; |
| private final RepositoryAdmin m_repositoryAdmin; |
| |
| public ObrGogoCommand(BundleContext bc, RepositoryAdmin repositoryAdmin) |
| { |
| m_bc = bc; |
| m_repositoryAdmin = repositoryAdmin; |
| } |
| |
| private RepositoryAdmin getRepositoryAdmin() |
| { |
| return m_repositoryAdmin; |
| } |
| |
| @Descriptor("manage repositories") |
| public void repos( |
| @Descriptor("( add | list | refresh | remove )") String action, |
| @Descriptor("space-delimited list of repository URLs") String[] args) |
| throws IOException |
| { |
| Object svcObj = getRepositoryAdmin(); |
| if (svcObj == null) |
| { |
| return; |
| } |
| RepositoryAdmin ra = (RepositoryAdmin) svcObj; |
| |
| if (args.length > 0) |
| { |
| for (int i = 0; i < args.length; i++) |
| { |
| try |
| { |
| if (action.equals(REPO_ADD)) |
| { |
| ra.addRepository(args[i]); |
| } |
| else if (action.equals(REPO_REFRESH)) |
| { |
| ra.removeRepository(args[i]); |
| ra.addRepository(args[i]); |
| } |
| else if (action.equals(REPO_REMOVE)) |
| { |
| ra.removeRepository(args[i]); |
| } |
| else |
| { |
| System.out.println("Unknown repository operation: " + action); |
| } |
| } |
| catch (Exception ex) |
| { |
| ex.printStackTrace(System.err); |
| } |
| } |
| } |
| else |
| { |
| org.apache.felix.bundlerepository.Repository[] repos = |
| ra.listRepositories(); |
| if ((repos != null) && (repos.length > 0)) |
| { |
| for (int i = 0; i < repos.length; i++) |
| { |
| System.out.println(repos[i].getURI()); |
| } |
| } |
| else |
| { |
| System.out.println("No repository URLs are set."); |
| } |
| } |
| } |
| |
| @Descriptor("list repository resources") |
| public void list( |
| @Descriptor("display all versions") |
| @Parameter(names={ "-v", "--verbose" }, presentValue="true", |
| absentValue="false") boolean verbose, |
| @Descriptor("optional strings used for name matching") String[] args) |
| throws IOException, InvalidSyntaxException |
| { |
| Object svcObj = getRepositoryAdmin(); |
| if (svcObj == null) |
| { |
| return; |
| } |
| RepositoryAdmin ra = (RepositoryAdmin) svcObj; |
| |
| // Create a filter that will match presentation name or symbolic name. |
| StringBuffer sb = new StringBuffer(); |
| if ((args == null) || (args.length == 0)) |
| { |
| sb.append("(|(presentationname=*)(symbolicname=*))"); |
| } |
| else |
| { |
| StringBuffer value = new StringBuffer(); |
| for (int i = 0; i < args.length; i++) |
| { |
| if (i > 0) |
| { |
| value.append(" "); |
| } |
| value.append(args[i]); |
| } |
| sb.append("(|(presentationname=*"); |
| sb.append(value); |
| sb.append("*)(symbolicname=*"); |
| sb.append(value); |
| sb.append("*))"); |
| } |
| // Use filter to get matching resources. |
| Resource[] resources = ra.discoverResources(sb.toString()); |
| |
| // Group the resources by symbolic name in descending version order, |
| // but keep them in overall sorted order by presentation name. |
| Map revisionMap = new TreeMap(new Comparator() { |
| public int compare(Object o1, Object o2) |
| { |
| Resource r1 = (Resource) o1; |
| Resource r2 = (Resource) o2; |
| // Assume if the symbolic name is equal, then the two are equal, |
| // since we are trying to aggregate by symbolic name. |
| int symCompare = r1.getSymbolicName().compareTo(r2.getSymbolicName()); |
| if (symCompare == 0) |
| { |
| return 0; |
| } |
| // Otherwise, compare the presentation name to keep them sorted |
| // by presentation name. If the presentation names are equal, then |
| // use the symbolic name to differentiate. |
| int compare = (r1.getPresentationName() == null) |
| ? -1 |
| : (r2.getPresentationName() == null) |
| ? 1 |
| : r1.getPresentationName().compareToIgnoreCase( |
| r2.getPresentationName()); |
| if (compare == 0) |
| { |
| return symCompare; |
| } |
| return compare; |
| } |
| }); |
| for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++) |
| { |
| Resource[] revisions = (Resource[]) revisionMap.get(resources[resIdx]); |
| revisionMap.put(resources[resIdx], addResourceByVersion(revisions, resources[resIdx])); |
| } |
| |
| // Print any matching resources. |
| for (Iterator i = revisionMap.entrySet().iterator(); i.hasNext(); ) |
| { |
| Map.Entry entry = (Map.Entry) i.next(); |
| Resource[] revisions = (Resource[]) entry.getValue(); |
| String name = revisions[0].getPresentationName(); |
| name = (name == null) ? revisions[0].getSymbolicName() : name; |
| System.out.print(name); |
| |
| if (verbose && revisions[0].getPresentationName() != null) |
| { |
| System.out.print(" [" + revisions[0].getSymbolicName() + "]"); |
| } |
| |
| System.out.print(" ("); |
| int revIdx = 0; |
| do |
| { |
| if (revIdx > 0) |
| { |
| System.out.print(", "); |
| } |
| System.out.print(revisions[revIdx].getVersion()); |
| revIdx++; |
| } |
| while (verbose && (revIdx < revisions.length)); |
| if (!verbose && (revisions.length > 1)) |
| { |
| System.out.print(", ..."); |
| } |
| System.out.println(")"); |
| } |
| |
| if ((resources == null) || (resources.length == 0)) |
| { |
| System.out.println("No matching bundles."); |
| } |
| } |
| |
| @Descriptor("retrieve resource description from repository") |
| public void info( |
| @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...") |
| String[] args) |
| throws IOException, InvalidSyntaxException |
| { |
| Object svcObj = getRepositoryAdmin(); |
| if (svcObj == null) |
| { |
| return; |
| } |
| RepositoryAdmin ra = (RepositoryAdmin) svcObj; |
| |
| for (int argIdx = 0; (args != null) && (argIdx < args.length); argIdx++) |
| { |
| // Find the target's bundle resource. |
| String targetName = args[argIdx]; |
| String targetVersion = null; |
| int idx = args[argIdx].indexOf(VERSION_SEPARATOR); |
| if (idx > 0) |
| { |
| targetName = args[argIdx].substring(0, idx); |
| targetVersion = args[argIdx].substring(idx + 1); |
| } |
| Resource[] resources = searchRepository(ra, targetName, targetVersion); |
| if ((resources == null) || (resources.length == 0)) |
| { |
| System.err.println("Unknown bundle and/or version: " + args[argIdx]); |
| } |
| else |
| { |
| for (int resIdx = 0; resIdx < resources.length; resIdx++) |
| { |
| if (resIdx > 0) |
| { |
| System.out.println(""); |
| } |
| printResource(System.out, resources[resIdx]); |
| } |
| } |
| } |
| } |
| |
| @Descriptor("deploy resource from repository") |
| public void deploy( |
| @Descriptor("start deployed bundles") |
| @Parameter(names={ "-s", "--start" }, presentValue="true", |
| absentValue="false") boolean start, |
| @Descriptor("deploy required bundles only") |
| @Parameter(names={ "-ro", "--required-only" }, presentValue="true", |
| absentValue="false") boolean requiredOnly, |
| @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...") |
| String[] args) |
| throws IOException, InvalidSyntaxException |
| { |
| Object svcObj = getRepositoryAdmin(); |
| if (svcObj == null) |
| { |
| return; |
| } |
| RepositoryAdmin ra = (RepositoryAdmin) svcObj; |
| |
| Resolver resolver = ra.resolver(); |
| for (int argIdx = 0; (args != null) && (argIdx < args.length); argIdx++) |
| { |
| // Find the target's bundle resource. |
| String targetName = args[argIdx]; |
| String targetVersion = null; |
| int idx = args[argIdx].indexOf(VERSION_SEPARATOR); |
| if (idx > 0) |
| { |
| targetName = args[argIdx].substring(0, idx); |
| targetVersion = args[argIdx].substring(idx + 1); |
| } |
| Resource resource = selectNewestVersion( |
| searchRepository(ra, targetName, targetVersion)); |
| if (resource != null) |
| { |
| resolver.add(resource); |
| } |
| else |
| { |
| System.err.println("Unknown bundle - " + args[argIdx]); |
| } |
| } |
| |
| if ((resolver.getAddedResources() != null) && |
| (resolver.getAddedResources().length > 0)) |
| { |
| if (resolver.resolve()) |
| { |
| System.out.println("Target resource(s):"); |
| System.out.println(getUnderlineString(19)); |
| Resource[] resources = resolver.getAddedResources(); |
| for (int resIdx = 0; (resources != null) && (resIdx < resources.length); resIdx++) |
| { |
| System.out.println(" " + resources[resIdx].getPresentationName() |
| + " (" + resources[resIdx].getVersion() + ")"); |
| } |
| resources = resolver.getRequiredResources(); |
| if ((resources != null) && (resources.length > 0)) |
| { |
| System.out.println("\nRequired resource(s):"); |
| System.out.println(getUnderlineString(21)); |
| for (int resIdx = 0; resIdx < resources.length; resIdx++) |
| { |
| System.out.println(" " + resources[resIdx].getPresentationName() |
| + " (" + resources[resIdx].getVersion() + ")"); |
| } |
| } |
| if (!requiredOnly) |
| { |
| resources = resolver.getOptionalResources(); |
| if ((resources != null) && (resources.length > 0)) |
| { |
| System.out.println("\nOptional resource(s):"); |
| System.out.println(getUnderlineString(21)); |
| for (int resIdx = 0; resIdx < resources.length; resIdx++) |
| { |
| System.out.println(" " + resources[resIdx].getPresentationName() |
| + " (" + resources[resIdx].getVersion() + ")"); |
| } |
| } |
| } |
| |
| try |
| { |
| System.out.print("\nDeploying...\n"); |
| int options = 0; |
| if (start) |
| { |
| options |= Resolver.START; |
| } |
| if (requiredOnly) |
| { |
| options |= Resolver.NO_OPTIONAL_RESOURCES; |
| } |
| resolver.deploy(options); |
| System.out.println("done."); |
| } |
| catch (IllegalStateException ex) |
| { |
| System.err.println(ex); |
| } |
| } |
| else |
| { |
| Reason[] reqs = resolver.getUnsatisfiedRequirements(); |
| if ((reqs != null) && (reqs.length > 0)) |
| { |
| System.out.println("Unsatisfied requirement(s):"); |
| System.out.println(getUnderlineString(27)); |
| for (int reqIdx = 0; reqIdx < reqs.length; reqIdx++) |
| { |
| System.out.println(" " + reqs[reqIdx].getRequirement().getFilter()); |
| System.out.println(" " + reqs[reqIdx].getResource().getPresentationName()); |
| } |
| } |
| else |
| { |
| System.out.println("Could not resolve targets."); |
| } |
| } |
| } |
| } |
| |
| @Descriptor("retrieve resource source code from repository") |
| public void source( |
| @Descriptor("extract source code") |
| @Parameter(names={ "-x", "--extract" }, presentValue="true", |
| absentValue="false") boolean extract, |
| @Descriptor("local target directory") File localDir, |
| @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...") |
| String[] args) |
| throws IOException, InvalidSyntaxException |
| { |
| Object svcObj = getRepositoryAdmin(); |
| if (svcObj == null) |
| { |
| return; |
| } |
| RepositoryAdmin ra = (RepositoryAdmin) svcObj; |
| |
| for (int argIdx = 0; argIdx < args.length; argIdx++) |
| { |
| // Find the target's bundle resource. |
| String targetName = args[argIdx]; |
| String targetVersion = null; |
| int idx = args[argIdx].indexOf(VERSION_SEPARATOR); |
| if (idx > 0) |
| { |
| targetName = args[argIdx].substring(0, idx); |
| targetVersion = args[argIdx].substring(idx + 1); |
| } |
| Resource resource = selectNewestVersion( |
| searchRepository(ra, targetName, targetVersion)); |
| if (resource == null) |
| { |
| System.err.println("Unknown bundle and/or version: " + args[argIdx]); |
| } |
| else |
| { |
| String srcURI = (String) resource.getProperties().get(Resource.SOURCE_URI); |
| if (srcURI != null) |
| { |
| downloadSource( |
| System.out, System.err, new URL(srcURI), |
| localDir, extract); |
| } |
| else |
| { |
| System.err.println("Missing source URL: " + args[argIdx]); |
| } |
| } |
| } |
| } |
| |
| @Descriptor("retrieve resource JavaDoc from repository") |
| public void javadoc( |
| @Descriptor("extract documentation") |
| @Parameter(names={"-x", "--extract" }, presentValue="true", |
| absentValue="false") boolean extract, |
| @Descriptor("local target directory") File localDir, |
| @Descriptor("( <bundle-name> | <symbolic-name> | <bundle-id> )[@<version>] ...") |
| String[] args) |
| throws IOException, InvalidSyntaxException |
| { |
| Object svcObj = getRepositoryAdmin(); |
| if (svcObj == null) |
| { |
| return; |
| } |
| RepositoryAdmin ra = (RepositoryAdmin) svcObj; |
| |
| for (int argIdx = 0; argIdx < args.length; argIdx++) |
| { |
| // Find the target's bundle resource. |
| String targetName = args[argIdx]; |
| String targetVersion = null; |
| int idx = args[argIdx].indexOf(VERSION_SEPARATOR); |
| if (idx > 0) |
| { |
| targetName = args[argIdx].substring(0, idx); |
| targetVersion = args[argIdx].substring(idx + 1); |
| } |
| Resource resource = selectNewestVersion( |
| searchRepository(ra, targetName, targetVersion)); |
| if (resource == null) |
| { |
| System.err.println("Unknown bundle and/or version: " + args[argIdx]); |
| } |
| else |
| { |
| URL docURL = (URL) resource.getProperties().get("javadoc"); |
| if (docURL != null) |
| { |
| downloadSource( |
| System.out, System.err, docURL, localDir, extract); |
| } |
| else |
| { |
| System.err.println("Missing javadoc URL: " + args[argIdx]); |
| } |
| } |
| } |
| } |
| |
| private Resource[] searchRepository( |
| RepositoryAdmin ra, String targetId, String targetVersion) |
| throws InvalidSyntaxException |
| { |
| // Try to see if the targetId is a bundle ID. |
| try |
| { |
| Bundle bundle = m_bc.getBundle(Long.parseLong(targetId)); |
| if (bundle != null) |
| { |
| targetId = bundle.getSymbolicName(); |
| } |
| else |
| { |
| return null; |
| } |
| } |
| catch (NumberFormatException ex) |
| { |
| // It was not a number, so ignore. |
| } |
| |
| // The targetId may be a bundle name or a bundle symbolic name, |
| // so create the appropriate LDAP query. |
| StringBuffer sb = new StringBuffer("(|(presentationname="); |
| sb.append(targetId); |
| sb.append(")(symbolicname="); |
| sb.append(targetId); |
| sb.append("))"); |
| if (targetVersion != null) |
| { |
| sb.insert(0, "(&"); |
| sb.append("(version="); |
| sb.append(targetVersion); |
| sb.append("))"); |
| } |
| return ra.discoverResources(sb.toString()); |
| } |
| |
| private Resource selectNewestVersion(Resource[] resources) |
| { |
| int idx = -1; |
| Version v = null; |
| for (int i = 0; (resources != null) && (i < resources.length); i++) |
| { |
| if (i == 0) |
| { |
| idx = 0; |
| v = resources[i].getVersion(); |
| } |
| else |
| { |
| Version vtmp = resources[i].getVersion(); |
| if (vtmp.compareTo(v) > 0) |
| { |
| idx = i; |
| v = vtmp; |
| } |
| } |
| } |
| |
| return (idx < 0) ? null : resources[idx]; |
| } |
| |
| private void printResource(PrintStream out, Resource resource) |
| { |
| String presentationName = resource.getPresentationName(); |
| if (presentationName == null) |
| presentationName = resource.getSymbolicName(); |
| |
| System.out.println(getUnderlineString(presentationName.length())); |
| out.println(presentationName); |
| System.out.println(getUnderlineString(presentationName.length())); |
| |
| Map map = resource.getProperties(); |
| for (Iterator iter = map.entrySet().iterator(); iter.hasNext(); ) |
| { |
| Map.Entry entry = (Map.Entry) iter.next(); |
| if (entry.getValue().getClass().isArray()) |
| { |
| out.println(entry.getKey() + ":"); |
| for (int j = 0; j < Array.getLength(entry.getValue()); j++) |
| { |
| out.println(" " + Array.get(entry.getValue(), j)); |
| } |
| } |
| else |
| { |
| out.println(entry.getKey() + ": " + entry.getValue()); |
| } |
| } |
| |
| Requirement[] reqs = resource.getRequirements(); |
| if ((reqs != null) && (reqs.length > 0)) |
| { |
| out.println("Requires:"); |
| for (int i = 0; i < reqs.length; i++) |
| { |
| out.println(" " + reqs[i].getFilter()); |
| } |
| } |
| |
| Capability[] caps = resource.getCapabilities(); |
| if ((caps != null) && (caps.length > 0)) |
| { |
| out.println("Capabilities:"); |
| for (int i = 0; i < caps.length; i++) |
| { |
| out.println(" " + caps[i].getPropertiesAsMap()); |
| } |
| } |
| } |
| |
| private static Resource[] addResourceByVersion(Resource[] revisions, Resource resource) |
| { |
| // We want to add the resource into the array of revisions |
| // in descending version sorted order (i.e., newest first) |
| Resource[] sorted = null; |
| if (revisions == null) |
| { |
| sorted = new Resource[] { resource }; |
| } |
| else |
| { |
| Version version = resource.getVersion(); |
| Version middleVersion = null; |
| int top = 0, bottom = revisions.length - 1, middle = 0; |
| while (top <= bottom) |
| { |
| middle = (bottom - top) / 2 + top; |
| middleVersion = revisions[middle].getVersion(); |
| // Sort in reverse version order. |
| int cmp = middleVersion.compareTo(version); |
| if (cmp < 0) |
| { |
| bottom = middle - 1; |
| } |
| else |
| { |
| top = middle + 1; |
| } |
| } |
| |
| // Ignore duplicates. |
| if ((top >= revisions.length) || (revisions[top] != resource)) |
| { |
| sorted = new Resource[revisions.length + 1]; |
| System.arraycopy(revisions, 0, sorted, 0, top); |
| System.arraycopy(revisions, top, sorted, top + 1, revisions.length - top); |
| sorted[top] = resource; |
| } |
| } |
| return sorted; |
| } |
| |
| private final static StringBuffer m_sb = new StringBuffer(); |
| |
| public static String getUnderlineString(int len) |
| { |
| synchronized (m_sb) |
| { |
| m_sb.delete(0, m_sb.length()); |
| for (int i = 0; i < len; i++) |
| { |
| m_sb.append('-'); |
| } |
| return m_sb.toString(); |
| } |
| } |
| |
| public static void downloadSource( |
| PrintStream out, PrintStream err, |
| URL srcURL, File localDir, boolean extract) |
| { |
| // Get the file name from the URL. |
| String fileName = (srcURL.getFile().lastIndexOf('/') > 0) |
| ? srcURL.getFile().substring(srcURL.getFile().lastIndexOf('/') + 1) |
| : srcURL.getFile(); |
| |
| try |
| { |
| out.println("Connecting..."); |
| |
| if (!localDir.exists()) |
| { |
| err.println("Destination directory does not exist."); |
| } |
| File file = new File(localDir, fileName); |
| |
| OutputStream os = new FileOutputStream(file); |
| URLConnection conn = srcURL.openConnection(); |
| setProxyAuth(conn); |
| int total = conn.getContentLength(); |
| InputStream is = conn.getInputStream(); |
| |
| if (total > 0) |
| { |
| out.println("Downloading " + fileName |
| + " ( " + total + " bytes )."); |
| } |
| else |
| { |
| out.println("Downloading " + fileName + "."); |
| } |
| byte[] buffer = new byte[4096]; |
| for (int len = is.read(buffer); len > 0; len = is.read(buffer)) |
| { |
| os.write(buffer, 0, len); |
| } |
| |
| os.close(); |
| is.close(); |
| |
| if (extract) |
| { |
| is = new FileInputStream(file); |
| JarInputStream jis = new JarInputStream(is); |
| out.println("Extracting..."); |
| unjar(jis, localDir); |
| jis.close(); |
| file.delete(); |
| } |
| } |
| catch (Exception ex) |
| { |
| err.println(ex); |
| } |
| } |
| |
| public static void setProxyAuth(URLConnection conn) throws IOException |
| { |
| // Support for http proxy authentication |
| String auth = System.getProperty("http.proxyAuth"); |
| if ((auth != null) && (auth.length() > 0)) |
| { |
| if ("http".equals(conn.getURL().getProtocol()) |
| || "https".equals(conn.getURL().getProtocol())) |
| { |
| String base64 = Base64Encoder.base64Encode(auth); |
| conn.setRequestProperty("Proxy-Authorization", "Basic " + base64); |
| } |
| } |
| } |
| |
| public static void unjar(JarInputStream jis, File dir) |
| throws IOException |
| { |
| // Reusable buffer. |
| byte[] buffer = new byte[4096]; |
| |
| // Loop through JAR entries. |
| for (JarEntry je = jis.getNextJarEntry(); |
| je != null; |
| je = jis.getNextJarEntry()) |
| { |
| if (je.getName().startsWith("/")) |
| { |
| throw new IOException("JAR resource cannot contain absolute paths."); |
| } |
| |
| File target = new File(dir, je.getName()); |
| |
| // Check to see if the JAR entry is a directory. |
| if (je.isDirectory()) |
| { |
| if (!target.exists()) |
| { |
| if (!target.mkdirs()) |
| { |
| throw new IOException("Unable to create target directory: " |
| + target); |
| } |
| } |
| // Just continue since directories do not have content to copy. |
| continue; |
| } |
| |
| int lastIndex = je.getName().lastIndexOf('/'); |
| String name = (lastIndex >= 0) ? |
| je.getName().substring(lastIndex + 1) : je.getName(); |
| String destination = (lastIndex >= 0) ? |
| je.getName().substring(0, lastIndex) : ""; |
| |
| // JAR files use '/', so convert it to platform separator. |
| destination = destination.replace('/', File.separatorChar); |
| copy(jis, dir, name, destination, buffer); |
| } |
| } |
| |
| public static void copy( |
| InputStream is, File dir, String destName, String destDir, byte[] buffer) |
| throws IOException |
| { |
| if (destDir == null) |
| { |
| destDir = ""; |
| } |
| |
| // Make sure the target directory exists and |
| // that is actually a directory. |
| File targetDir = new File(dir, destDir); |
| if (!targetDir.exists()) |
| { |
| if (!targetDir.mkdirs()) |
| { |
| throw new IOException("Unable to create target directory: " |
| + targetDir); |
| } |
| } |
| else if (!targetDir.isDirectory()) |
| { |
| throw new IOException("Target is not a directory: " |
| + targetDir); |
| } |
| |
| BufferedOutputStream bos = new BufferedOutputStream( |
| new FileOutputStream(new File(targetDir, destName))); |
| int count = 0; |
| while ((count = is.read(buffer)) > 0) |
| { |
| bos.write(buffer, 0, count); |
| } |
| bos.close(); |
| } |
| } |