buildframework/helium/sf/java/sysdef/src/com/nokia/helium/sysdef/ant/taskdefs/CreateRootSysdefTask.java
author wbernard
Fri, 13 Aug 2010 14:59:05 +0300
changeset 628 7c4a911dc066
parent 588 c7c26511138f
permissions -rw-r--r--
helium_11.0.0-e00f171ca185
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     1
/*
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     2
* Copyright (c) 2007-2008 Nokia Corporation and/or its subsidiary(-ies).
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     3
* All rights reserved.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     4
* This component and the accompanying materials are made available
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     5
* under the terms of the License "Eclipse Public License v1.0"
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     6
* which accompanies this distribution, and is available
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     8
*
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
     9
* Initial Contributors:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    11
*
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    12
* Contributors:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    13
*
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    14
* Description:  
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    15
*
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    16
*/
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    17
package com.nokia.helium.sysdef.ant.taskdefs;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    18
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    19
import java.io.File;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    20
import java.io.FileOutputStream;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    21
import java.io.IOException;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    22
import java.io.OutputStreamWriter;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    23
import java.io.StringWriter;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    24
import java.util.ArrayList;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    25
import java.util.HashMap;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    26
import java.util.Hashtable;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    27
import java.util.Iterator;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    28
import java.util.List;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    29
import java.util.Map;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    30
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    31
import org.apache.tools.ant.BuildException;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    32
import org.apache.tools.ant.Project;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    33
import org.apache.tools.ant.Task;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    34
import org.apache.tools.ant.types.Resource;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    35
import org.apache.tools.ant.types.ResourceCollection;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    36
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
    37
import com.nokia.helium.sysdef.PackageDefinition;
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
    38
import com.nokia.helium.sysdef.PackageDefinitionParsingException;
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    39
import com.nokia.helium.sysdef.PackageMap;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    40
import com.nokia.helium.sysdef.PackageMapParsingException;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    41
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    42
import freemarker.cache.ClassTemplateLoader;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    43
import freemarker.cache.FileTemplateLoader;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    44
import freemarker.template.Configuration;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    45
import freemarker.template.Template;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    46
import freemarker.template.TemplateException;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    47
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    48
/**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    49
 * Create a root System Definition file based on a set of package_definition.xml 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    50
 * file. All package must also have a package_data.xml file in order to retrieve
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    51
 * the root and the layer location of the package.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    52
 *
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    53
 * Example:
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    54
 * <pre>
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
    55
 * &lt;hlm:createRootSysdef epocroot="E:\sdk" destFile="E:\sdk\sysdef_root.xml" &gt;
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    56
 *     &lt;fileset dir="E:\sdk" includes="root/&#42;&#42;/package_definition.xml"&gt;
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
    57
 * &lt;/hlm:createRootSysdef&gt;
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    58
 * </pre>
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    59
 *
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    60
 * @ant.task name="createRootSysdef" category="Sysdef"
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    61
 */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    62
public class CreateRootSysdefTask extends Task {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    63
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    64
    private File destFile;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    65
    private List<ResourceCollection> resourceCollections = new ArrayList<ResourceCollection>(); 
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
    66
    private Map<String, Map<String, List<Map<String, Object>>>> roots = new HashMap<String, Map<String, List<Map<String, Object>>>>();
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    67
    private Map<String, List<String>> layers = new HashMap<String, List<String>>();
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    68
    private File epocroot;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    69
    private boolean failOnError = true;
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
    70
    private boolean checkPackageExists;
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    71
    private File template;
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
    72
    private String idNamespace;
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    73
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    74
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    75
     * {@inheritDoc}
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    76
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    77
    @SuppressWarnings("unchecked")
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    78
    public void execute() {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    79
        if (getEpocroot() == null) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    80
            throw new BuildException("epocroot attribute has not been set.");
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    81
        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    82
        if (getDestFile() == null) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    83
            throw new BuildException("destFile attribute has not been set.");
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    84
        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    85
        if ((File.separatorChar == '/' && !getDestFile().getAbsolutePath().startsWith(getEpocroot().getAbsolutePath()))
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    86
                || (File.separatorChar == '\\' 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    87
                    && !getDestFile().getAbsolutePath().toLowerCase().startsWith(getEpocroot().getAbsolutePath().toLowerCase()))) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    88
            throw new BuildException(getDestFile().getAbsolutePath() + " must be under " + getEpocroot().getAbsolutePath());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    89
        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    90
        for (ResourceCollection rc : resourceCollections) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    91
            Iterator<Resource> ri = (Iterator<Resource>)rc.iterator();
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    92
            while (ri.hasNext()) {
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
    93
                Resource resource = ri.next();
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
    94
                File pkgDefFile = new File(resource.toString());
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
    95
                log("Package definition file: " + pkgDefFile);
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    96
                if (!pkgDefFile.exists() || 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    97
                        !(pkgDefFile.getName().equalsIgnoreCase(
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    98
                                CreatePackageMappingTask.PACKAGE_DEFINITION_FILENAME))) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
    99
                    throw new BuildException("Missing Package Definition file");
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   100
                }
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   101
                File pkgDir = pkgDefFile.getParentFile();
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   102
                File pkgMapFile  = new File(pkgDir, CreatePackageMappingTask.PACKAGE_MAP_FILENAME);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   103
                try {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   104
                    if (pkgMapFile.exists()) {
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   105
                        log("Package map file: " + pkgMapFile);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   106
                        if (!checkPackageExists) {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   107
                            addPackage(pkgDefFile, pkgMapFile, pkgDir.getName());
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   108
                        } else {
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   109
                            PackageMap pkgMap = new PackageMap(pkgMapFile);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   110
                            File destPkg = new File(epocroot, pkgMap.getRoot() + File.separator +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   111
                                    pkgMap.getLayer() + File.separator + pkgDir.getName() + File.separator +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   112
                                    CreatePackageMappingTask.PACKAGE_DEFINITION_FILENAME);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   113
                            if (destPkg.exists()) {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   114
                                addPackage(pkgDefFile, pkgMapFile, pkgDir.getName());
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   115
                            } else {
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   116
                                log("Could not find " + destPkg.getAbsolutePath() +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   117
                                        " so entry is not added to the root system definition.", Project.MSG_ERR);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   118
                            }
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   119
                        }
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   120
                    } else {
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   121
                        pkgMapFile = new File(pkgDir.getParentFile().getParentFile(), CreatePackageMappingTask.PACKAGE_MAP_FILENAME);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   122
                        log("Package map file: " + pkgMapFile);
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   123
                        if (pkgMapFile.exists()) {
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   124
                            if (!checkPackageExists) {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   125
                                // slash must be use to generate correct path.
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   126
                                addPackage(pkgDefFile, pkgMapFile, pkgMapFile.getParentFile().getName() + "/" +
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   127
                                        pkgDir.getParentFile().getName() + "/" + pkgDir.getName());
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   128
                            } else {
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   129
                                PackageMap pkgMap = new PackageMap(pkgMapFile);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   130
                                File destPkg = new File(epocroot, pkgMap.getRoot() + File.separator +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   131
                                        pkgMap.getLayer() + File.separator +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   132
                                        pkgMapFile.getParentFile().getName() + File.separator +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   133
                                        pkgDir.getParentFile().getName() + File.separator + pkgDir.getName() +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   134
                                        File.separator +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   135
                                        CreatePackageMappingTask.PACKAGE_DEFINITION_FILENAME);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   136
                                if (destPkg.exists()) {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   137
                                    addPackage(destPkg, pkgMapFile, pkgMapFile.getParentFile().getName() + "/" +
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   138
                                            pkgDir.getParentFile().getName() + "/" + pkgDir.getName());
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   139
                                } else {
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   140
                                    log("Could not find " + destPkg.getAbsolutePath() +
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   141
                                            " so entry is not added to the root system definition.", Project.MSG_ERR);
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   142
                                }
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   143
                            }
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   144
                        } else {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   145
                            log("Could not find package_map.xml file for " + pkgDefFile.toString(), Project.MSG_ERR);
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   146
                            if (shouldFailOnError()) {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   147
                                throw new BuildException("Could not find package_map.xml file for " + pkgDefFile.toString());
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   148
                            }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   149
                        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   150
                    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   151
                } catch (PackageMapParsingException e) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   152
                    log("Invalid " + CreatePackageMappingTask.PACKAGE_MAP_FILENAME 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   153
                            + " file: " + pkgMapFile.toString() 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   154
                            + "(" + e.getMessage() + ")", Project.MSG_ERR);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   155
                    if (shouldFailOnError()) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   156
                        throw new BuildException(e.getMessage(), e);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   157
                    }
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   158
                } catch (PackageDefinitionParsingException e) {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   159
                    log("Invalid " + CreatePackageMappingTask.PACKAGE_DEFINITION_FILENAME 
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   160
                            + "(" + e.getMessage() + ")", Project.MSG_ERR);
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   161
                    if (shouldFailOnError()) {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   162
                        throw new BuildException(e.getMessage(), e);
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   163
                    }
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   164
                }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   165
                    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   166
            }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   167
        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   168
        generateRootSysdef();
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   169
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   170
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   171
    private void addPackage(File pkgDefinition, File pkgMapFile, String pkgPath) throws
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   172
        PackageMapParsingException, PackageDefinitionParsingException {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   173
        // Some quick validity checking. 
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   174
        PackageDefinition pkg = new PackageDefinition(pkgDefinition);
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   175
        if (idNamespace == null && (pkg.getIdNamespace() != null && pkg.getIdNamespace().length() > 0)) {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   176
            idNamespace = pkg.getIdNamespace();
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   177
        } else if (idNamespace != null && !idNamespace.equals(pkg.getIdNamespace())) {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   178
            log("Warning: " + pkgDefinition.toString() +
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   179
                    " namespace doesn't match the default one. (" 
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   180
                    + idNamespace + " != " + pkg.getIdNamespace(), Project.MSG_WARN);
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   181
        }
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   182
            
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   183
        // Adding the package in the structure.
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   184
        log("Adding: " + pkgMapFile, Project.MSG_DEBUG);
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   185
        PackageMap pkgMap = new PackageMap(pkgMapFile);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   186
        if (!roots.containsKey(pkgMap.getRoot())) {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   187
            roots.put(pkgMap.getRoot(), new HashMap<String, List<Map<String, Object>>>());
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   188
        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   189
        if (!roots.get(pkgMap.getRoot()).containsKey(pkgMap.getLayer())) {
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   190
            roots.get(pkgMap.getRoot()).put(pkgMap.getLayer(), new ArrayList<Map<String, Object>>());
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   191
            layers.put(pkgMap.getLayer(), new ArrayList<String>());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   192
        }
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   193
        Map<String, Object> data = new HashMap<String, Object>();
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   194
        data.put("path", pkgPath);
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   195
        data.put("id", pkg.getId());
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   196
        data.put("namespaces", pkg.getNamespaces());
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   197
        roots.get(pkgMap.getRoot()).get(pkgMap.getLayer()).add(data);
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   198
        layers.get(pkgMap.getLayer()).add(pkgPath);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   199
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   200
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   201
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   202
     * Defines the location of the generated INI file.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   203
     * @param destFile
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   204
     * @ant.required
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   205
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   206
    public void setDestFile(File destFile) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   207
        this.destFile = destFile;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   208
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   209
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   210
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   211
     * Get the destination file.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   212
     * @return the dest file.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   213
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   214
    public File getDestFile() {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   215
        return destFile;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   216
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   217
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   218
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   219
     * Get epocroot.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   220
     * @return epocroot location
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   221
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   222
    public File getEpocroot() {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   223
        return epocroot;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   224
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   225
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   226
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   227
     * Defines epocroot location
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   228
     * @param epocroot
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   229
     * @ant.required
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   230
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   231
    public void setEpocroot(File epocroot) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   232
        this.epocroot = epocroot;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   233
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   234
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   235
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   236
     * Defines if the task should fail in case of error. 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   237
     * @param failOnError
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   238
     * @ant.not-required Default true
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   239
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   240
    public void setFailOnError(boolean failOnError) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   241
        this.failOnError = failOnError;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   242
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   243
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   244
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   245
     * Shall we fail in case of issue.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   246
     * @return
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   247
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   248
    public boolean shouldFailOnError() {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   249
        return failOnError;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   250
    }
588
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   251
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   252
    /**
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   253
     * Defines if the task should check the existence of the 
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   254
     * target package_definition.xml under epocroot.
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   255
     * @param checkPackageExists
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   256
     * @ant.not-required Default false
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   257
     */
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   258
    public void setCheckPackageExists(boolean checkPackageExists) {
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   259
        this.checkPackageExists = checkPackageExists;
c7c26511138f helium-10.0.0-bc45d50958fe
wbernard
parents: 587
diff changeset
   260
    }
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   261
    
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   262
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   263
     * Support of nested resource collection like path or fileset.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   264
     * Those nested element should define where to find the 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   265
     * packages. 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   266
     * @param resourceCollection
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   267
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   268
    public void add(ResourceCollection resourceCollection) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   269
        resourceCollections.add(resourceCollection);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   270
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   271
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   272
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   273
     * Defines a custom Freemarker template to generate the root sysdef file.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   274
     * @param template
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   275
     * @ant.not-required
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   276
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   277
    public void setTemplate(File template) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   278
        this.template = template;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   279
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   280
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   281
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   282
     * Get the template location.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   283
     * @return
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   284
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   285
    public File getTemplate() {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   286
        return template;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   287
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   288
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   289
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   290
     * Generate the a root sysdef file based on the discovered package. 
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   291
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   292
    protected void generateRootSysdef() {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   293
        try {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   294
            Configuration cfg = new Configuration();
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   295
            Template template = null;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   296
            // Use custom template of default one?
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   297
            if (getTemplate() != null) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   298
                log("Loading template: " + this.getTemplate().getAbsolutePath());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   299
                cfg.setTemplateLoader(new FileTemplateLoader(this.getTemplate().getParentFile()));
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   300
                template = cfg.getTemplate(this.getTemplate().getName());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   301
            } else {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   302
                cfg.setTemplateLoader(new ClassTemplateLoader(this.getClass(), "/com/nokia/helium/sysdef/templates"));
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   303
                template = cfg.getTemplate("root_sysdef_model.xml.ftl");
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   304
            }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   305
            Map<String, Object> data = new Hashtable<String, Object>();
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   306
            // Content by root
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   307
            data.put("roots", roots);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   308
            // Content by layer
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   309
            data.put("layers", layers);
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   310
            // id-namespace
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   311
            if (idNamespace != null) {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   312
                data.put("idnamespace", idNamespace);
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   313
            }
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   314
            // Environment location
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   315
            data.put("epocroot", getEpocroot().getAbsolutePath());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   316
            // Relative path from destFile to epocroot.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   317
            data.put("dest_dir_to_epocroot", getRelativeDiff());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   318
            StringWriter out = new StringWriter();
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   319
            template.process(data, out);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   320
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   321
            // Writing the output.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   322
            log("Creating " + getDestFile().getAbsolutePath());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   323
            OutputStreamWriter output = new OutputStreamWriter(new FileOutputStream(getDestFile()));
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   324
            output.append(out.getBuffer().toString());
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   325
            output.close();            
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   326
        } catch (IOException e) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   327
            log("Error while creating output file: " + e.getMessage(), Project.MSG_ERR);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   328
            if (this.shouldFailOnError()) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   329
                throw new BuildException("Error while creating output file: " + e.getMessage(), e);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   330
            }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   331
        } catch (TemplateException e) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   332
            log("Error while creating output file: " + e.getMessage(), Project.MSG_ERR);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   333
            if (this.shouldFailOnError()) {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   334
                throw new BuildException("Error while creating output file: " + e.getMessage(), e);
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   335
            }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   336
        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   337
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   338
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   339
    /**
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   340
     * Get the relative path to go to epocroot from destdir.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   341
     * @return the path relative path to go to root.
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   342
     */
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   343
    protected String getRelativeDiff() {
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   344
        String rel = getEpocroot().toURI().relativize(getDestFile().getParentFile().toURI()).getPath();
628
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   345
        if (rel.length() > 0) {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   346
            String[] relArray = rel.split("/"); // This is an URI not a File.
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   347
            rel = ""; //"." + File.separatorChar;
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   348
            for (@SuppressWarnings("unused") String string : relArray) {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   349
                rel += ".." + File.separatorChar; 
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   350
            }
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   351
        } else {
7c4a911dc066 helium_11.0.0-e00f171ca185
wbernard
parents: 588
diff changeset
   352
            rel = "." + File.separatorChar;
587
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   353
        }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   354
        return rel;
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   355
    }
85df38eb4012 helium_9.0-a7879c935424
wbernard
parents:
diff changeset
   356
}