/*
* Copyright (C) 2012 The Android Open Source Project
*
* 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.android.builder.internal.packaging;
import com.android.builder.packaging.DuplicateFileException;
import com.android.builder.packaging.PackagerException;
import com.android.builder.packaging.SealedPackageException;
import com.android.ide.common.packaging.PackagingUtils;
import java.io.File;
import java.io.IOException;
public class JavaResourceProcessor {
private final IArchiveBuilder mBuilder;
public interface IArchiveBuilder {
/**
* Adds a file to the archive at a given path
* @param file the file to add
* @param archivePath the path of the file inside the APK archive.
* @throws com.android.builder.packaging.PackagerException if an error occurred
* @throws com.android.builder.packaging.SealedPackageException if the archive is already sealed.
* @throws com.android.builder.packaging.DuplicateFileException if a file conflicts with another already added to the APK
* at the same location inside the APK archive.
*/
void addFile(File file, String archivePath) throws PackagerException,
SealedPackageException, DuplicateFileException;
}
public JavaResourceProcessor(IArchiveBuilder builder) {
mBuilder = builder;
}
/**
* Adds the resources from a source folder to a given {@link IArchiveBuilder}
* @param sourceLocation the source folder.
* @throws PackagerException if an error occurred
* @throws SealedPackageException if the APK is already sealed.
* @throws DuplicateFileException if a file conflicts with another already added to the APK
* at the same location inside the APK archive.
*/
public void addSourceFolder(String sourceLocation)
throws PackagerException, DuplicateFileException, SealedPackageException {
File sourceFolder = new File(sourceLocation);
if (sourceFolder.isDirectory()) {
try {
// file is a directory, process its content.
File[] files = sourceFolder.listFiles();
for (File file : files) {
processFileForResource(file, null);
}
} catch (DuplicateFileException e) {
throw e;
} catch (SealedPackageException e) {
throw e;
} catch (Exception e) {
throw new PackagerException(e, "Failed to add %s", sourceFolder);
}
} else {
// not a directory? check if it's a file or doesn't exist
if (sourceFolder.exists()) {
throw new PackagerException("%s is not a folder", sourceFolder);
}
}
}
/**
* Processes a {@link File} that could be an APK {@link File}, or a folder containing
* java resources.
*
* @param file the {@link File} to process.
* @param path the relative path of this file to the source folder.
* Can be <code>null</code> to identify a root file.
* @throws IOException
* @throws DuplicateFileException if a file conflicts with another already added
* to the APK at the same location inside the APK archive.
* @throws PackagerException if an error occurred
* @throws SealedPackageException if the APK is already sealed.
*/
private void processFileForResource(File file, String path)
throws IOException, DuplicateFileException, PackagerException, SealedPackageException {
if (file.isDirectory()) {
// a directory? we check it
if (PackagingUtils.checkFolderForPackaging(file.getName())) {
// if it's valid, we append its name to the current path.
if (path == null) {
path = file.getName();
} else {
path = path + "/" + file.getName();
}
// and process its content.
File[] files = file.listFiles();
for (File contentFile : files) {
processFileForResource(contentFile, path);
}
}
} else {
// a file? we check it to make sure it should be added
if (PackagingUtils.checkFileForPackaging(file.getName())) {
// we append its name to the current path
if (path == null) {
path = file.getName();
} else {
path = path + "/" + file.getName();
}
// and add it to the apk
mBuilder.addFile(file, path);
}
}
}
}