1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Eclipse Public License, Version 1.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.eclipse.org/org/documents/epl-v10.php
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.android.ide.eclipse.ndk.internal.templates;
18
19import com.android.ide.eclipse.ndk.internal.Activator;
20import com.android.ide.eclipse.ndk.internal.Messages;
21
22import org.eclipse.cdt.core.templateengine.TemplateCore;
23import org.eclipse.cdt.core.templateengine.process.ProcessArgument;
24import org.eclipse.cdt.core.templateengine.process.ProcessFailureException;
25import org.eclipse.cdt.core.templateengine.process.ProcessRunner;
26import org.eclipse.core.resources.IContainer;
27import org.eclipse.core.resources.IFile;
28import org.eclipse.core.resources.IFolder;
29import org.eclipse.core.resources.IProject;
30import org.eclipse.core.resources.ResourcesPlugin;
31import org.eclipse.core.runtime.CoreException;
32import org.eclipse.core.runtime.FileLocator;
33import org.eclipse.core.runtime.IProgressMonitor;
34import org.eclipse.core.runtime.Path;
35import org.osgi.framework.Bundle;
36
37import java.io.IOException;
38import java.net.URL;
39import java.util.ArrayList;
40import java.util.List;
41
42public class SimpleFile extends ProcessRunner {
43
44    private static final class FileOp {
45        public String source;
46        public String destination;
47    }
48
49    @Override
50    public void process(TemplateCore template, ProcessArgument[] args, String processId,
51            IProgressMonitor monitor)
52            throws ProcessFailureException {
53
54        // Fetch the args
55        String projectName = null;
56        List<FileOp> fileOps = new ArrayList<FileOp>();
57
58        for (ProcessArgument arg : args) {
59            if (arg.getName().equals("projectName")) //$NON-NLS-1$
60                projectName = arg.getSimpleValue();
61            else if (arg.getName().equals("files")) { //$NON-NLS-1$
62                ProcessArgument[][] files = arg.getComplexArrayValue();
63                for (ProcessArgument[] file : files) {
64                    FileOp op = new FileOp();
65                    for (ProcessArgument fileArg : file) {
66                        if (fileArg.getName().equals("source")) //$NON-NLS-1$
67                            op.source = fileArg.getSimpleValue();
68                        else if (fileArg.getName().equals("destination")) //$NON-NLS-1$
69                            op.destination = fileArg.getSimpleValue();
70                    }
71                    if (op.source == null || op.destination == null)
72                        throw new ProcessFailureException(Messages.SimpleFile_Bad_file_operation);
73                    fileOps.add(op);
74                }
75            }
76        }
77
78        if (projectName == null)
79            throw new ProcessFailureException(Messages.SimpleFile_No_project_name);
80        IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName);
81        if (!project.exists())
82            throw new ProcessFailureException(Messages.SimpleFile_Project_does_not_exist);
83
84        // Find bundle to find source files
85        Bundle bundle = Activator.getBundle(template.getTemplateInfo().getPluginId());
86        if (bundle == null)
87            throw new ProcessFailureException(Messages.SimpleFile_Bundle_not_found);
88
89        try {
90            for (FileOp op : fileOps) {
91                IFile destFile = project.getFile(new Path(op.destination));
92                if (destFile.exists())
93                    // don't overwrite files if they exist already
94                    continue;
95
96                // Make sure parent folders are created
97                mkDirs(project, destFile.getParent(), monitor);
98
99                URL sourceURL = FileLocator.find(bundle, new Path(op.source), null);
100                if (sourceURL == null)
101                    throw new ProcessFailureException(Messages.SimpleFile_Could_not_fine_source
102                            + op.source);
103
104                TemplatedInputStream in = new TemplatedInputStream(sourceURL.openStream(),
105                        template.getValueStore());
106                destFile.create(in, true, monitor);
107                in.close();
108            }
109        } catch (IOException e) {
110            throw new ProcessFailureException(e);
111        } catch (CoreException e) {
112            throw new ProcessFailureException(e);
113        }
114
115    }
116
117    private void mkDirs(IProject project, IContainer container, IProgressMonitor monitor)
118            throws CoreException {
119        if (container.exists())
120            return;
121        mkDirs(project, container.getParent(), monitor);
122        ((IFolder) container).create(true, true, monitor);
123    }
124
125}
126